Summary Files Commits Branches @commit @diff @stats
path: root / bash
diff options
context:
space:
mode:
Commit375d11b33142e971a82f28ddb4cc7d386e3551cf (patch)
Author
 Syndamia <kamen@syndamia.com>
2026-11-01 17:50:07 +0200
Committer
 Syndamia <kamen@syndamia.com>
2026-11-01 17:50:07 +0200
Files85373ae415fcff7142ee1194594e8bb1e381176b /bash
.files-375d11b33142e971a82f28ddb4cc7d386e3551cf.tar
.files-375d11b33142e971a82f28ddb4cc7d386e3551cf.tar.gz
.files-375d11b33142e971a82f28ddb4cc7d386e3551cf.zip
Parente41b78ee956a6adcfc07b3c453f70198214ca599 (diff)
feat!: Rework how .files are managed
4 files changed, 680 insertions, 0 deletions
-rw-r--r--bash/.bash_logout2
-rw-r--r--bash/.bash_profile8
-rw-r--r--bash/.bashrc657
-rw-r--r--bash/.inputrc13
diff --git a/bash/.bash_logout b/bash/.bash_logout
new file mode 100644
index 0000000..af7c6fd
--- /dev/null
+++ b/bash/.bash_logout
@@ -0,0 +1,2 @@
+# ~/.bash_logout
+
diff --git a/bash/.bash_profile b/bash/.bash_profile
new file mode 100644
index 0000000..55136b9
--- /dev/null
+++ b/bash/.bash_profile
@@ -0,0 +1,8 @@
+# .bash_profile
+
+# Get the aliases and functions
+if [ -f ~/.bashrc ]; then
+ . ~/.bashrc
+fi
+
+# User specific environment and startup programs
diff --git a/bash/.bashrc b/bash/.bashrc
new file mode 100644
index 0000000..86967cc
--- /dev/null
+++ b/bash/.bashrc
@@ -0,0 +1,657 @@
+# .bashrc
+# vi:foldmethod=marker
+
+# Source global definitions
+[ -f /etc/bashrc ] && . /etc/bashrc
+
+# When running nix develop you get your interactive bash shell, however the
+# $SHELL variable is set to the non-interactive bash
+# This variable change happens after .bashrc sourcing
+# As an awful workaround, only on the first PROMPT_COMMAND after a new shell
+# is started, we check and fix $SHELL
+shell_var_fix() {
+ if [ -x '/run/current-system/sw/bin/bash' ] && \
+ [[ "$SHELL" =~ /nix/store.*-bash-[[:digit:]].* ]]
+ then
+ export SHELL='/run/current-system/sw/bin/bash'
+ fi
+
+ # Don't ever run this function again
+ export PROMPT_COMMAND="${PROMPT_COMMAND/shell_var_fix;/}"
+ unset -f shell_var_fix
+}
+# This has a second purpose, to reset PROMPT_COMMAND, since subshells would
+# inherit it from the parent and inside the Prompt we prepend it
+# However, without this workaround, we wouldn't need to prepend in the first
+# place
+export PROMPT_COMMAND="shell_var_fix;"
+
+# Prompt {{{
+ [ "$(tput colors)" -ge 256 ]; _hc=$?
+ hc_mode() { return $_hc ; }
+
+ # $1 foreground color [REQUIRED]
+ # $2 background color [REQUIRED]
+ colors_prt() {
+ if hc_mode
+ then
+ printf "\001\e[38;5;${1}m\e[48;5;${2}m\002"
+ elif [ "$TERM" != 'dumb' ]
+ then
+ printf "\001\e[${1}m\e[${2}m\002"
+ fi
+ }
+ colors_res() {
+ if [ "$TERM" != 'dumb' ]
+ then
+ printf "\001\e[0m\002"
+ fi
+ }
+
+ # $1 cap colour [OPTIONAL]
+ # $2 cap character [OPTIONAL]
+ #
+ # Entering "o" for $1 and $2 or leaving them unset uses the defaults
+ left_cap() {
+ [ "$1" = 'o' -o -z "$1" ] && set "$PS_USER_BG" "$2"
+ [ "$2" = 'o' -o -z "$2" ] && set "$1" "$PS_LEFT_SEMI"
+
+ if hc_mode
+ then
+ colors_prt "$1" "$PS_BG"
+ printf "$2"
+ colors_prt "$PS_FG" "$1"
+ else
+ colors_prt "$PS_FG" "$1"
+ printf "$2"
+ fi
+ }
+ right_cap() {
+ [ "$2" = 'o' -o -z "$2" ] && set "$1" "$PS_RIGHT_SEMI"
+ left_cap "$1" "$2"
+ colors_res
+ }
+
+ PS_BG=0
+ hc_mode && PS_FG=223 || PS_FG=37
+ hc_mode && PS_USER_BG=66 || PS_USER_BG=44
+ # Thanks https://github.com/NixOS/nix/issues/9174#issuecomment-2054057401
+ [ -n "$IN_NIX_SHELL" -o -n "$NIX_GCROOT" ] && {
+ hc_mode && PS_USER_BG=67 || PS_USER_BG=46;
+ }
+ [ -n "$SSH_TTY" ] && {
+ hc_mode && PS_USER_BG=64 || PS_USER_BG=42;
+ }
+
+ # Colors for reporting changes
+ hc_mode && PS_ERR=160 || PS_ERR=41
+ hc_mode && PS_WARN=172 || PS_WARN=43
+ hc_mode && PS_INFO=97 || PS_INFO=45
+ hc_mode && PS_DBG=52 || PS_DBG=41
+
+ # From readline 8.3 (+ patch 1), multibyte characters are
+ # counted differently: every byte is counted as contributing
+ # to the length of the line. So, the hc_mode unicode symbols
+ # are counted as 2+ characters, instead of as 1.
+ # As a workaround, we're making the unicode chars non-visible
+ # with \001 and \002, which makes them count as 0 chars,
+ # and then we add a blank character (\024 is 20, "Device Control 4")
+ # which doesn't (sometimes?) visually appear but is counted as
+ # 1 character.
+ hc_mode && PS_TRIANGLE="\001\002\024" || PS_TRIANGLE='|'
+ hc_mode && PS_TRIANGLE_BOT="\001\002\024" || PS_TRIANGLE='|'
+ hc_mode && PS_LEFT_SEMI="\001\002\024" || PS_LEFT_SEMI='('
+ hc_mode && PS_LEFT_SLAB="\001█\002\024" || PS_LEFT_SLAB='| '
+ hc_mode && PS_RIGHT_SLAB="\001█\002\024" || PS_RIGHT_SLAB=' |'
+ hc_mode && PS_RIGHT_SEMI="\001\002\024" || PS_RIGHT_SEMI=')'
+ hc_mode && PS_PREC="\001\002\024" || PS_PREC='>'
+ hc_mode && PS_PREC_GIT="\001\002\024" || PS_PREC_GIT='{}'
+
+ ___dirchanged=""
+
+ ps_commands() {
+ has=""
+ for i in "$@"
+ do
+ case $i in
+ (git)
+ [ -n "$___git_printed" ] && has="y" && break ;;
+ (ex)
+ [ "$EXSTAT" != '0' ] && has="y" && break ;;
+ (dur)
+ [ -z "$___timer" -a "$seconds" -gt 10 ] && has="y" && break ;;
+ (dir)
+ [ -n "$___dirchanged" ] && has="y" && break ;;
+ esac
+ done
+ [ -n "$has" ]
+ }
+ right_slab() {
+ ps_commands "$@" && echo "$PS_RIGHT_SLAB"
+ }
+
+ ps_space() {
+ ps_commands git ex dur dir && printf ' '
+ }
+ ps_nl() {
+ ps_commands git ex dur dir && printf '\n'
+ }
+
+ ps_git() {
+ if git rev-parse --is-inside-work-tree >/dev/null 2>&1
+ then
+ branch_name=$(git symbolic-ref -q HEAD)
+ branch_name=${branch_name##refs/heads/}
+ branch_name=${branch_name:-HEAD}
+
+ ___changes="true"
+
+ if [ -n "$___dirchanged" ]
+ then
+ left_cap $PS_INFO "$PS_LEFT_SLAB"
+ printf "$branch_name"
+ right_cap $PS_INFO "$(right_slab ex dur dir)"
+ ___git_printed="y"
+ fi
+ fi
+ }
+
+ ps_exit() {
+ if [ "$EXSTAT" != '0' ]
+ then
+ left_cap $PS_ERR "$PS_LEFT_SLAB"
+ printf "$EXSTAT"
+
+ right_cap $PS_ERR "$(right_slab dur dir)"
+ fi
+ }
+
+ ps_duration() {
+ [ -n "$___timer" ] && return
+
+ if [ "$seconds" -gt 10 ]
+ then
+ left_cap $PS_DBG "$PS_LEFT_SLAB"
+ if [ "$seconds" -lt 60 ]; then TZ='UTC+24' printf '%ds' "$seconds"
+ elif [ "$seconds" -le 3600 ]; then TZ='UTC+24' printf '%(%Mm %Ss)T' "$seconds"
+ elif [ "$seconds" -le 86400 ]; then TZ='UTC+24' printf '%(%Hh %Mm %Ss)T' "$seconds"
+ else TZ='UTC+24' printf '%(%j %Hh %Mm %Ss)T' "$seconds"
+ fi
+ right_cap $PS_DBG "$(right_slab dir)"
+ fi
+ }
+
+ ps_dir() {
+ DIRCOLOR=$PS_INFO
+ [ ! -w . ] && DIRCOLOR=$PS_WARN
+
+ DIR="${PWD/#$HOME/\~}"
+ [ -z "$___dirchanged" ] && DIR=''
+
+ if [ -n "$DIR" ]
+ then
+ left_cap $DIRCOLOR "$PS_LEFT_SLAB"
+ printf "$DIR"
+ right_cap $DIRCOLOR
+ fi
+ }
+
+ jobs_count() {
+ info="$(jobs -p | tr "\012" " ")"
+ info="${info//[^ ]}"
+ echo ${#info}
+ }
+
+ ps_user() {
+ name="${USER#kamen}@$HOSTNAME"
+
+ njobs="$(jobs_count)"
+ # Our git rev-parse adds a background process, so if we have git, we'll
+ # always get at least one job. But, without git, we'll always get at least 0 jobs.
+ [ "$njobs" -gt "$(command -v git >/dev/null 2>&1; echo $?)" ] \
+ && name="\001\e[4m\\002$name\001\e[24m\002"
+
+ printf "$name"
+ }
+
+ ps_precursor() {
+ colors_res
+ [ ! -w . ] && colors_prt "$PS_WARN" "$PS_BG"
+ if [ -n "$___changes" ]
+ then
+ printf "$PS_PREC_GIT"
+ else
+ printf "$PS_PREC"
+ fi
+ colors_res
+ }
+
+ trap "SECONDS=0;___timer=''" SIGUSR2
+
+ export PS_COMM="ps_space; ps_git; ps_exit; ps_duration; ps_dir; ps_nl"
+ export PS1="$(left_cap)\$(ps_user)$(right_cap) \$(ps_precursor)\$(stty sane) "
+ # Show time below command:
+ # export PS0=" $(left_cap 'o' "$PS_TRIANGLE_BOT") \A$(right_cap)\n\$(kill -s SIGUSR2 $$)"
+ export PS0="\$(kill -s SIGUSR2 $$)"
+
+ export PROMPT_COMMAND="$PROMPT_COMMAND"'EXSTAT="$?";seconds="$SECONDS";___changes="";___git_printed="";'$PS_COMM';___dirchanged=''; ___timer="n"'
+# }}}
+
+# vi mode {{{
+ if [[ $- =~ i ]]
+ then
+ bind 'set editing-mode vi'
+ bind 'set show-mode-in-prompt on'
+ bind "set vi-ins-mode-string \"$(left_cap)i$(right_cap)\""
+ bind "set vi-cmd-mode-string \"$(left_cap $PS_WARN)n$(right_cap $PS_WARN)\""
+
+ bind -m vi-command '"ca\"":"F\"cf\""'
+ bind -m vi-command '"ca'\''":"F'\''cf'\''"'
+ bind -m vi-command '"ci\"":"T\"ct\""'
+ bind -m vi-command '"ci'\''":"T'\''ct'\''"'
+
+ # Huge thanks to: https://lists.gnu.org/archive/html/help-bash/2022-02/msg00023.html
+ bind -x "\"\xC0\a\":set_tab_title \"\$READLINE_LINE\";printf \"$(left_cap $PS_DBG)%(%T)T$(right_cap $PS_DBG)\""
+ bind '"\xC0\r":accept-line'
+ bind '"\r":"\xC0\a\xC0\r"'
+ fi
+
+ # Thanks https://stackoverflow.com/a/13773343
+ set_tab_title() {
+ printf '\e]2;%s\a' "$*"
+ }
+# }}}
+
+# History {{{
+ if [[ $- =~ i ]]
+ then
+ bind '"\e[A":history-search-backward'
+ bind '"\e[B":history-search-forward'
+ fi
+ # Thanks to https://stackoverflow.com/a/19533853
+ shopt -s histappend
+ export HISTCONTROL=ignoredups HISTFILESIZE= HISTSIZE= HISTFILE=~/bash_history
+# }}}
+
+# Changing directory {{{
+ pushd() {
+ ___dirchanged="y"
+ set "${1:-$HOME}"
+ [ ! -e "$1" ] && set "$HOME/$1"
+ builtin pushd "$1" >/dev/null
+ }
+ popd() {
+ ___dirchanged="$PWD"
+ builtin popd >/dev/null 2>&1 && forward_dirs[${#forward_dirs[@]}]="$___dirchanged" || builtin popd +1
+ }
+ # Huge thanks to: https://tldp.org/LDP/abs/html/arrays.html#EMPTYARRAY
+ repushd() {
+ ___dirchanged="y"
+ [ "${#forward_dirs[@]}" -eq 0 ] && echo "bash: repushd: forward directory stack empty" && return 1
+
+ builtin pushd "${forward_dirs[${#forward_dirs[@]}-1]:-$HOME}" >/dev/null
+ unset forward_dirs[${#forward_dirs[@]}-1]
+ }
+ alias cd="pushd" # change directory
+ alias bd="popd" # back directory
+ alias fd="repushd"
+
+ cdrepo() {
+ cd "$HOME/Programming/$1/$2"
+ }
+ # Huge thanks to: https://stackoverflow.com/a/39729507
+ _cdrepo_comp() {
+ case "$1" in
+ (cdl) _folder='GitLab-repos' ;;
+ (cdg) _folder='GitHub-repos' ;;
+ (cds) _folder='source' ;;
+ esac
+
+ while IFS= read line
+ do
+ [ -z "$line" ] && continue
+ line="${line##"$HOME"/Programming/"$_folder"/}/"
+ line="${line// /\\ }"
+ COMPREPLY+=("$line")
+ done <<EOF
+$(compgen -d "$HOME"/Programming/"$_folder"/"$2")
+EOF
+ }
+
+ alias cdl="cdrepo GitLab-repos "
+ complete -o nospace -F _cdrepo_comp cdl
+
+ alias cdg="cdrepo GitHub-repos "
+ complete -o nospace -F _cdrepo_comp cdg
+
+ alias cds="cdrepo source "
+ complete -o nospace -F _cdrepo_comp cds
+
+ n() {
+ # Block nesting of nnn in subshells
+ [ "${NNNLVL:-0}" -eq 0 ] || {
+ echo "nnn is already running"
+ return
+ }
+
+ # The behaviour is set to cd on quit (nnn checks if NNN_TMPFILE is set)
+ # If NNN_TMPFILE is set to a custom path, it must be exported for nnn to
+ # see. To cd on quit only on ^G, remove the "export" and make sure not to
+ # use a custom path, i.e. set NNN_TMPFILE *exactly* as follows:
+ NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
+ # export NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
+
+ # Unmask ^Q (, ^V etc.) (if required, see `stty -a`) to Quit nnn
+ # stty start undef
+ # stty stop undef
+ # stty lwrap undef
+ # stty lnext undef
+
+ # The command builtin allows one to alias nnn to n, if desired, without
+ # making an infinitely recursive alias
+ command nnn -deHoJU "$@"
+
+ [ ! -f "$NNN_TMPFILE" ] || {
+ . "$NNN_TMPFILE"
+ rm -f -- "$NNN_TMPFILE" > /dev/null
+ }
+ }
+# }}}
+
+# Processes {{{
+ # Run in the background
+ bgr() {
+ nohup sh -c "$@" >~/nohup.out 2>&1 &
+ disown
+ }
+
+ # Kill process and run in the background
+ res() {
+ pkill "$@"
+ bgr "$@"
+ }
+
+ # Launch .desktop application (either full path or just name)
+ dela() {
+ name=$1
+ if [[ ${name:0:1} != "/" ]]; then
+ name="/usr/share/applications/${name}"
+ fi
+ if [[ ! $name =~ .desktop$ ]]; then
+ name+=".desktop"
+ fi
+ comm=($(awk -F= '$1=="Exec"{$1=""; print}' "$name"))
+ bgr "$comm"
+ }
+
+ shopt -s checkjobs
+# }}}
+
+# Variables {{{
+ export NIX_SHELL_PRESERVE_PROMPT=1
+ export VISUAL=nvim
+# }}}
+
+# File operations {{{
+ cp() {
+ command cp -p "$@"
+ }
+
+ metas() {
+ for file in *; do
+ [ "$file" != 'cover.jpeg' ] && \
+ kid3-cli -c "set title \"$(echo "$file" | sed -e "s/\.[^.]*$//")\"" \
+ -c "set artist \"$1\"" -c "set album \"$2\"" -c "set date \"$3\"" \
+ -c 'set picture:"./cover.jpeg" ""' "$file" \
+ || :
+ done
+ }
+# }}}
+
+# Bindings {{{
+ if [[ $- =~ i ]]
+ then
+ bind '"\C-l":clear-screen'
+ bind '"\C-h":backward-kill-word'
+
+ bind -x '"\xC0\021":lazygit'
+ bind '"\C-g":"\xC0\021\n"'
+
+ # From readline 8.3 (+ patch 1) or bash 5.3 (+ patch 3)
+ # something changed and now, if you do Ctrl-Z after Ctrl-F,
+ # the readline input breaks. The only way I've found to fix
+ # it is via accepting the current line (bound to \n).
+ # To make the output less cluttered, I also go up two lines.
+ fgrl() {
+ builtin fg >/dev/null
+ printf "\e[2A"
+ }
+
+ bind -x '"\xC0\022":fgrl'
+ bind '"\C-f":"\xC0\022\n"'
+ fi
+# }}}
+
+# ANSI tests {{{
+ try_code() {
+ local type=$1
+ local val=$2
+ local mod=$3
+
+ case "$val" in
+ (n) echo; return ;;
+ esac
+
+ case "$type" in
+ (sgr) printf "\e[${mod}${val}m% 3s\e[0m " "$val" ;;
+ esac
+ }
+
+ colors() {
+ echo 'SGR format: \e[X;Y;Z;...m'
+ echo '== Modifiers =='
+ for i in {0..9} n {10..20} n {21..29} n {50..62} n {63..75}
+ do
+ try_code sgr "$i"
+ printf '\e[10m' # Alternate fonts fix
+ done
+ echo
+ echo '== 4 bit colors =='
+ echo '\e[Xm'
+ for i in {30..37} n {40..47} n {90..97} n {100..107}
+ do
+ try_code sgr "$i"
+ done
+ echo
+
+ echo '== 8 bit colors =='
+ echo '\e[38;5;Xm'
+ for i in {0..7} n {8..15} n \
+ n \
+ {16..33} n {34..51} n \
+ {52..69} n {70..87} n \
+ {88..105} n {106..123} n \
+ {124..141} n {142..159} n \
+ {160..177} n {178..195} n \
+ {196..213} n {214..231} n \
+ n \
+ {232..243} n {244..255}
+ do
+ try_code sgr "$i" '38;5;'
+ done
+ echo
+ echo '\e[48;5;Xm'
+ for i in {0..7} n {8..15} n \
+ n \
+ {16..33} n {34..51} n \
+ {52..69} n {70..87} n \
+ {88..105} n {106..123} n \
+ {124..141} n {142..159} n \
+ {160..177} n {178..195} n \
+ {196..213} n {214..231} n \
+ n \
+ {232..243} n {244..255}
+ do
+ printf '\e[30m'
+ try_code sgr "$i" '48;5;'
+ done
+ echo
+ }
+# }}}
+
+if [ -n "$ZSHRC_FUNTOO" ]
+then
+ pre-sync() {
+ echo '(.zshrc) Running pre-sync function...'
+
+ # Since in post-sync I change the EAPI of a lot of the ebuilds,
+ # the overlay can't be synced properly
+ _pwd=$(pwd)
+ cd /var/db/repos/gentoo
+ sudo git reset --hard
+ cd $_pwd
+
+ echo '(.zshrc) pre-sync finished! :}'
+ }
+
+ post-sync() {
+ echo '(.zshrc) Running post-sync function...'
+
+ # Fixes the elusive
+ # "!!! Repository name or alias 'gentoo', defined for repository 'core-kit', overrides existing alias or repository."
+ # error when enabling gentoo overlay
+ sudo sed -i 's/aliases = gentoo/#aliases = gentoo/g' /var/git/meta-repo/kits/core-kit/metadata/layout.conf
+
+ # In the gentoo overlay, most packages don't actually use EAPI 8 specific features, so
+ # they can safely be rolled back to EAPI 7 (funtoo's portage doesn't support EAPI 8 yet).
+ # However, there are still some that do need EAPI 8, so they should be left alone.
+ # Since I'm incredibly lazy, for now, this is how I'm gonna do it.
+ find '/var/db/repos/gentoo' -type f -name "*.ebuild" ! -path "*dev-qt*" ! -path "*kde-frameworks*" ! -path "*kde-plasma*" \
+ | xargs sudo sed -i 's/EAPI=8/EAPI=7/g'
+
+ echo '(.zshrc) post-sync finished! :]'
+ }
+
+ alias sen="pre-sync && sudo ego sync && post-sync && sudo emerge --quiet-build -vuDN @world"
+fi
+
+# plumb.sh
+# plumb-store-cwd () {
+# pwd > /tmp/plumb-cwd
+# }
+# zle -N plumb-store-cwd
+# bindkey "^[[5;7~" plumb-store-cwd
+
+# Open vim with .vim-session file, if it exists and the vim command doesn't have any parameters
+v() {
+ if [ -f ".vim-session" ] && [ -z "$1" ]; then
+ vim -S .vim-session
+ else
+ vim "$@"
+ fi
+}
+
+# Add to grit parent, where first value is parent number and everything else is node value
+grap() {
+ parent="$1"
+ shift
+ grit add -p $parent -- "$@"
+}
+
+onemo() {
+ bgr "nemo ./"
+}
+
+#
+# Aliases
+#
+
+if [ -x "$(command -v emerge)" ]
+then
+ alias seq="sudo emerge --quiet-build -v"
+ alias sep="sudo emerge -pv"
+ alias ses="sudo emerge -s"
+ alias seS="sudo emerge -S"
+ alias senc="sudo emaint sync -A"
+ alias sen="sudo emaint sync -A && sudo emerge --quiet-build -vuDN @world"
+ alias senp="sudo emaint sync -A && sudo emerge --quiet-build -pvuDN @world"
+ alias seN="sudo emerge --quiet-build -vuDN @world"
+ alias seNp="sudo emerge --quiet-build -pvuDN @world"
+ sedi() {
+ sudo emerge --deselect "$1" && sudo emerge --depclean "$1"
+ }
+
+ alias use="sudo vim /etc/portage/package.use"
+ alias unmask="sudo vim /etc/portage/package.unmask"
+ alias mask="sudo vim /etc/portage/package.mask"
+fi
+
+if [ -x "$(command -v dnf)" ]
+then
+ alias sdi="sudo dnf install -y"
+ alias sdr="sudo dnf remove -y"
+ alias sda="sudo dnf autoremove -y"
+ # If you're using dotnet from the "packages-microsoft-com-prod" repo, make sure to
+ # add "exclude=dotnet* aspnetcore* netstandard*" inside the /etc/yum.repos.d/fedora.repo, /etc/yum.repos.d/fedora-updates.repo and potentially /etc/yum.repos.d/fedora33.repo
+ alias sdu="sudo dnf upgrade -y && sudo dnf autoremove -y && sudo youtube-dl --update && wget -O - https://raw.githubusercontent.com/laurent22/joplin/master/Joplin_install_and_update.sh | bash && needs-restarting -r"
+ alias sdudiscord="wget -O discord.tar.gz \"https://discord.com/api/download?platform=linux&format=tar.gz\" && tar -xzf discord.tar.gz && sudo rm -rf /opt/Discord && sudo mv Discord /opt"
+
+ alias ds="dnf search"
+ alias dcs="dnf copr search"
+ alias dp="dnf provides"
+ alias di="dnf info"
+
+ alias sdce="sudo dnf copr enable -y"
+ alias sdcei='f() { sudo dnf copr enable -y $1 && sudo dnf install -y $2; unset -f f }; f'
+fi
+
+if [ -x "$(command -v apt-get)" ]; then
+ alias sasy="sudo apt install -y"
+ alias sary="sudo apt remove -y"
+ alias saty="sudo apt autoremove -y"
+ alias sagt="sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y && sudo youtube-dl --update && wget -O - https://raw.githubusercontent.com/laurent22/joplin/master/Joplin_install_and_update.sh | bash"
+fi
+
+if [ -x "$(command -v exa)" ]
+then
+ alias ll="exa --icons --group-directories-first --git --time-style long-iso -a -labh"
+ alias lk="exa --icons --group-directories-first --git --time-style long-iso -labhTL"
+ alias l.="exa --icons --group-directories-first --git --time-style long-iso -labhTL 2"
+ alias l="exa --icons --group-directories-first --time-style long-iso -abh"
+else
+ alias ll="la -alF"
+ alias la="ls -A"
+ alias l="ls -CF"
+fi
+
+if [ -x "$(command -v grit)" ]
+then
+ alias gr="grit"
+ alias gra="grit add --"
+ alias grc="grit check"
+ alias grls="grit tree"
+fi
+
+if [ -x "$(command -v youtube-dl)" ]
+then
+ alias ydl="youtube-dl -o '%(title)s.%(ext)s'"
+ alias ydlba="youtube-dl -o '%(title)s.%(ext)s' --audio-format best -x"
+fi
+
+if [ -x "$(command -v gs)" ]
+then
+ alias combinepdf="gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=temp.pdf"
+fi
+
+alias wudo="sudo -u www-data"
+
+alias q="exit"
+alias x="exit"
+
+#
+# Added by scripts:
+#
+
+export PATH="/home/kamen/bin/Sencha/Cmd:$PATH"
+
+export NVM_DIR="$HOME/.nvm"
diff --git a/bash/.inputrc b/bash/.inputrc
new file mode 100644
index 0000000..f12eb5f
--- /dev/null
+++ b/bash/.inputrc
@@ -0,0 +1,13 @@
+# Readline config
+
+# Respect default shortcuts.
+$include /etc/inputrc
+
+## arrow up
+#
+"\e[A":history-search-backward
+## arrow down
+"\e[B":history-search-forward
+
+set show-all-if-ambiguous on
+set completion-ignore-case on