dotfiles

My personal shell configs and stuff
git clone git://git.alex.balgavy.eu/dotfiles.git
Log | Files | Refs | Submodules | README | LICENSE

zshrc (23169B)


      1 # -*- mode: shell-script; -*-
      2 # vim: foldmethod=marker foldlevel=0
      3 srcpath="$HOME/Documents/dotfiles/shell"
      4 export DOTFILES="$HOME/Documents/dotfiles"
      5 [ -f "$DOTFILES/shell/secret_env" ] && . "$DOTFILES/shell/secret_env"
      6 
      7 if [ -n "$VIM_TERMINAL" ]; then EDITOR=vimsend
      8 elif [ -n "$INSIDE_EMACS" ]; then EDITOR=emacsclient
      9 elif command -v nvim >/dev/null 2>&1; then EDITOR="$(command -v nvim)"
     10 else EDITOR="$(command -v vim)"; fi
     11 export EDITOR
     12 
     13 export CHOOSER=dmenuchoose
     14 export MUSIC_DIR="/Volumes/HDD/Music/Libraries/Mine"
     15 export PAGER="less"
     16 export LESS="-RicX"
     17 
     18 export LANG="en_US.UTF-8"
     19 export LC_ALL="en_US.UTF-8"
     20 export LC_COLLATE="en_US.UTF-8"
     21 export LC_CTYPE="en_US.UTF-8"
     22 export LC_MESSAGES="en_US.UTF-8"
     23 export LC_MONETARY="en_US.UTF-8"
     24 export LC_NUMERIC="en_US.UTF-8"
     25 export LC_TIME="en_US.UTF-8"
     26 
     27 [ -z "$DISPLAY" ] && export DISPLAY=":0"
     28 
     29 export TTRV_BROWSER=~/.scripts/linkhandler
     30 if command -v brave >/dev/null 2>&1; then
     31   export BROWSER=brave
     32 else
     33   export BROWSER="open"
     34 fi
     35 
     36 [ -f "$HOME"/.nix-profile/etc/profile.d/hm-session-vars.sh ] && . "$HOME"/.nix-profile/etc/profile.d/hm-session-vars.sh
     37 if [ -f /usr/local/bin/virtualenvwrapper.sh ]; then
     38   export WORKON_HOME=$HOME/.config/virtualenvs
     39   VIRTUALENVWRAPPER_PYTHON=$(which python3); export VIRTUALENVWRAPPER_PYTHON
     40   export VIRTUALENVWRAPPER_SCRIPT=/usr/local/bin/virtualenvwrapper.sh
     41 fi
     42 
     43 export WWW_HOME="https://tab.alex.balgavy.eu"
     44 # Icons for lf {{{1
     45 export LF_ICONS="\
     46 bd=:\
     47 cd=:\
     48 di=:\
     49 st=:\
     50 tw=:\
     51 ow=:\
     52 pi=ﳣ:\
     53 fi=:\
     54 sg=:\
     55 su=:\
     56 so=杻:\
     57 ln=:\
     58 or=:\
     59 ex=:\
     60 *.vimrc=:\
     61 *.viminfo=:\
     62 *.gitignore=:\
     63 *.c=:\
     64 *.cc=:\
     65 *.clj=:\
     66 *.coffee=:\
     67 *.cpp=:\
     68 *.css=:\
     69 *.d=:\
     70 *.dart=:\
     71 *.erl=:\
     72 *.exs=:\
     73 *.fs=:\
     74 *.go=:\
     75 *.h=:\
     76 *.hh=:\
     77 *.hpp=:\
     78 *.hs=:\
     79 *.html=:\
     80 *.java=:\
     81 *.jl=:\
     82 *.js=:\
     83 *.json=:\
     84 *.lua=:\
     85 *.md=:\
     86 *.php=:\
     87 *.pl=:\
     88 *.pro=:\
     89 *.py=:\
     90 *.rb=:\
     91 *.rs=:\
     92 *.scala=:\
     93 *.ts=:\
     94 *.vim=:\
     95 *.cmd=:\
     96 *.ps1=:\
     97 *.sh=:\
     98 *.bash=:\
     99 *.zsh=:\
    100 *.fish=:\
    101 *.tar=:\
    102 *.tgz=:\
    103 *.arc=:\
    104 *.arj=:\
    105 *.taz=:\
    106 *.lha=:\
    107 *.lz4=:\
    108 *.lzh=:\
    109 *.lzma=:\
    110 *.tlz=:\
    111 *.txz=:\
    112 *.tzo=:\
    113 *.t7z=:\
    114 *.zip=:\
    115 *.z=:\
    116 *.dz=:\
    117 *.gz=:\
    118 *.lrz=:\
    119 *.lz=:\
    120 *.lzo=:\
    121 *.xz=:\
    122 *.zst=:\
    123 *.tzst=:\
    124 *.bz2=:\
    125 *.bz=:\
    126 *.tbz=:\
    127 *.tbz2=:\
    128 *.tz=:\
    129 *.deb=:\
    130 *.rpm=:\
    131 *.jar=:\
    132 *.war=:\
    133 *.ear=:\
    134 *.sar=:\
    135 *.rar=:\
    136 *.alz=:\
    137 *.ace=:\
    138 *.zoo=:\
    139 *.cpio=:\
    140 *.7z=:\
    141 *.rz=:\
    142 *.cab=:\
    143 *.wim=:\
    144 *.swm=:\
    145 *.dwm=:\
    146 *.esd=:\
    147 *.jpg=:\
    148 *.jpeg=:\
    149 *.mjpg=:\
    150 *.mjpeg=:\
    151 *.gif=:\
    152 *.bmp=:\
    153 *.pbm=:\
    154 *.pgm=:\
    155 *.ppm=:\
    156 *.tga=:\
    157 *.xbm=:\
    158 *.xpm=:\
    159 *.tif=:\
    160 *.tiff=:\
    161 *.png=:\
    162 *.svg=:\
    163 *.svgz=:\
    164 *.mng=:\
    165 *.pcx=:\
    166 *.mov=:\
    167 *.mpg=:\
    168 *.mpeg=:\
    169 *.m2v=:\
    170 *.mkv=:\
    171 *.webm=:\
    172 *.ogm=:\
    173 *.mp4=:\
    174 *.m4v=:\
    175 *.mp4v=:\
    176 *.vob=:\
    177 *.qt=:\
    178 *.nuv=:\
    179 *.wmv=:\
    180 *.asf=:\
    181 *.rm=:\
    182 *.rmvb=:\
    183 *.flc=:\
    184 *.avi=:\
    185 *.fli=:\
    186 *.flv=:\
    187 *.gl=:\
    188 *.dl=:\
    189 *.xcf=:\
    190 *.xwd=:\
    191 *.yuv=:\
    192 *.cgm=:\
    193 *.emf=:\
    194 *.ogv=:\
    195 *.ogx=:\
    196 *.aac=:\
    197 *.au=:\
    198 *.flac=:\
    199 *.m4a=:\
    200 *.mid=:\
    201 *.midi=:\
    202 *.mka=:\
    203 *.mp3=:\
    204 *.mpc=:\
    205 *.ogg=:\
    206 *.ra=:\
    207 *.wav=:\
    208 *.oga=:\
    209 *.opus=:\
    210 *.spx=:\
    211 *.xspf=:\
    212 *.pdf=:\
    213 *.nix=:\
    214 "
    215 # Force use of XDG Base Directory {{{1
    216 export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
    217 [ -d "$XDG_CONFIG_HOME" ] || mkdir -p "$XDG_CONFIG_HOME"
    218 export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
    219 [ -d "$XDG_DATA_HOME" ] || mkdir -p "$XDG_DATA_HOME"
    220 export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
    221 [ -d "$XDG_CACHE_HOME" ] || mkdir -p "$XDG_CACHE_HOME"
    222 export XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}"
    223 [ -d "$XDG_STATE_HOME" ] || mkdir -p "$XDG_STATE_HOME"
    224 
    225 # Other env {{{1
    226 export GOPATH="$XDG_DATA_HOME"/go
    227 export JUPYTER_CONFIG_DIR="$XDG_CONFIG_HOME/jupyter"
    228 export BUNDLE_USER_HOME="$XDG_CONFIG_HOME/bundle"
    229 export BUNDLE_USER_CACHE="$XDG_CACHE_HOME/bundle"
    230 export _Z_DATA="$XDG_CACHE_HOME/z/z-data"
    231 export HTTPIE_CONFIG_DIR="$XDG_CONFIG_HOME/httpie"
    232 export CABAL_DIR="$XDG_CONFIG_HOME/cabal"
    233 export GHCUP_INSTALL_BASE_PREFIX="$XDG_CONFIG_HOME"
    234 export ZDOTDIR="$XDG_CONFIG_HOME/zsh"
    235 # export GEM_HOME="$XDG_DATA_HOME/gem"
    236 # export GEM_SPEC_CACHE="$XDG_CACHE_HOME/gem"
    237 export NOTMUCH_CONFIG="$XDG_CONFIG_HOME/notmuch/config"
    238 export GNUPGHOME="$XDG_CONFIG_HOME/gnupg"
    239 export R_PROFILE_USER="$XDG_CONFIG_HOME/R/Rprofile"
    240 export MAILCAPS="$XDG_CONFIG_HOME/mailcap"
    241 eval "$(perl -I$XDG_DATA_HOME/perl5/lib/perl5 -Mlocal::lib=$XDG_DATA_HOME/perl5)"
    242 alias glow='glow --config "$XDG_CONFIG_HOME/glow/glow.yml"'
    243 export RUSTUP_HOME="$XDG_DATA_HOME/rustup"
    244 export CARGO_HOME="$XDG_DATA_HOME/cargo"
    245 export RBENV_ROOT="$XDG_DATA_HOME/rbenv"
    246 export ANDROID_HOME="$XDG_DATA_HOME/android"
    247 export DOCKER_CONFIG="$XDG_CONFIG_HOME/docker"
    248 export ELECTRUMDIR="$XDG_DATA_HOME/electrum"
    249 alias gdb='gdb -n -x $XDG_CONFIG_HOME/gdb/init'
    250 export GDBHISTFILE="$XDG_CONFIG_HOME"/gdb/.gdb_history
    251 export SCREENRC="$XDG_CONFIG_HOME"/screen/screenrc
    252 export IPYTHONDIR="${XDG_CONFIG_HOME}/ipython"
    253 export LESSHISTFILE="$XDG_CACHE_HOME"/less/history
    254 export STACK_ROOT="$XDG_DATA_HOME"/stack
    255 export VAGRANT_HOME="$XDG_DATA_HOME"/vagrant
    256 export RIPGREP_CONFIG_PATH="$XDG_CONFIG_HOME/ripgrep/config"
    257 export ZDOTDIR=$HOME/.config/zsh
    258 export HISTFILE=$ZDOTDIR/.zsh_history
    259 # }}}
    260 
    261 # Paths {{{1
    262 [ -x /usr/libexec/path_helper ] && unset PATH && eval "$(/usr/libexec/path_helper -s)"
    263 
    264 [ -d "$HOME/.local/bin" ] || [ -L "$HOME/.local/bin" ]                           && [ -n "${PATH##*"$HOME/.local/bin"*}" ]                  && PATH="$HOME/.local/bin:$PATH"
    265 [ -d "$GOPATH/bin" ] || [ -L "$GOPATH/bin" ]                                     && [ -n "${PATH##*"$GOPATH/bin"*}" ]                       && PATH="$GOPATH/bin:$PATH"
    266 [ -d "/usr/local/opt/util-linux/bin" ] || [ -L "/usr/local/opt/util-linux/bin" ] && [ -n "${PATH##*"/usr/local/opt/util-linux/bin"*}" ]     && PATH="/usr/local/opt/util-linux/bin:$PATH"
    267 [ -d "$XDG_CONFIG_HOME/.ghcup/bin" ] || [ -L "$XDG_CONFIG_HOME/.ghcup/bin" ]     && [ -n "${PATH##*"$XDG_CONFIG_HOME/.ghcup/bin"*}" ]       && PATH="$XDG_CONFIG_HOME/.ghcup/bin:$PATH"
    268 [ -d "/usr/local/sbin" ] || [ -L "/usr/local/sbin" ]                             && [ -n "${PATH##*"/usr/local/sbin"*}" ]                   && PATH="/usr/local/sbin:$PATH"
    269 [ -d "$HOME/.local/gnat/bin" ] || [ -L "$HOME/.local/gnat/bin" ]                 && [ -n "${PATH##*"$HOME/.local/gnat/bin"*}" ]             && PATH="$HOME/.local/gnat/bin:$PATH"
    270 [ -d "$HOME/bin" ] || [ -L "$HOME/bin" ]                                         && [ -n "${PATH##*"$HOME/bin"*}" ]                         && PATH="$HOME/bin:$PATH"
    271 [ -d "$HOME/.bin" ] || [ -L "$HOME/.bin" ]                                       && [ -n "${PATH##*"$HOME/.bin"*}" ]                        && PATH="$HOME/.bin:$PATH"
    272 [ -d "$DOTFILES/scripts" ] || [ -L "$DOTFILES/scripts" ]                               && [ -n "${PATH##*"$DOTFILES/scripts"*}" ]                    && PATH="$DOTFILES/scripts:$PATH"
    273 [ -d "$XDG_DATA_HOME/gem/bin" ] || [ -L "$XDG_DATA_HOME/gem/bin" ]               && [ -n "${PATH##*"$XDG_DATA_HOME/gem/bin"*}" ]            && PATH="$XDG_DATA_HOME/gem/bin:$PATH"
    274 [ -d "$HOME/.elan/bin" ]                                                         && [ -n "${PATH##*"$HOME/.elan/bin"*}" ]                   && PATH="$HOME/.elan/bin:$PATH"
    275 [ -d /usr/local/opt/man-db/libexec/bin ]                                         && [ -n "${PATH##*"/usr/local/opt/man-db/libexec/bin"*}" ] && PATH="/usr/local/opt/man-db/libexec/bin:$PATH"
    276 [ -d "$DOTFILES/tools/shfm" ]                                                    && [ -n "${PATH##*"$DOTFILES/tools/shfm"*}" ]              && PATH="$DOTFILES/tools/shfm:$PATH"
    277 [ -d "$DOTFILES/tools/pfetch" ]                                                  && [ -n "${PATH##*"$DOTFILES/tools/pfetch"*}" ]            && PATH="$DOTFILES/tools/pfetch:$PATH"
    278 [ -d "$DOTFILES/tools/tuxi" ]                                                    && [ -n "${PATH##*"$DOTFILES/tools/tuxi"*}" ]              && PATH="$DOTFILES/tools/tuxi:$PATH"
    279 [ -d "$DOTFILES/tools/speedread" ]                                               && [ -n "${PATH##*"$DOTFILES/tools/speedread"*}" ]         && PATH="$DOTFILES/tools/speedread:$PATH"
    280 [ -d "$DOTFILES/tools/fzf/bin" ]                                                 && [ -n "${PATH##*"$DOTFILES/tools/fzf/bin"*}" ]           && PATH="$DOTFILES/tools/fzf/bin:$PATH"
    281 [ -d "$DOTFILES/tools/solvitaire" ]                                              && [ -n "${PATH##*"$DOTFILES/tools/solvitaire"*}" ]        && PATH="$DOTFILES/tools/solvitaire:$PATH"
    282 [ -d "$XDG_DATA_HOME/perl5/bin" ]                                                && [ -n "${PATH##*"$XDG_DATA_HOME/perl5/bin"*}" ]          && PATH="$XDG_DATA_HOME/perl5/bin:$PATH"
    283 [ -d "$HOME/.jenv/bin" ]                                                         && [ -n "${PATH##*"$HOME/.jenv/bin"*}" ]                   && PATH="$HOME/.jenv/bin:$PATH"
    284 [ -d "$XDG_DATA_HOME/cargo/bin" ]                                                && [ -n "${PATH##*"$XDG_DATA_HOME/cargo/bin"*}" ]          && PATH="$XDG_DATA_HOME/cargo/bin:$PATH"
    285 [ -d "/usr/local/go/bin" ] || [ -L "/usr/local/go/bin" ]                         && [ -n "${PATH##*"/usr/local/go/bin"*}" ]                 && PATH="/usr/local/go/bin:$PATH"
    286 [ -d "/usr/local/opt/ruby/bin" ] || [ -L "/usr/local/opt/ruby/bin" ]             && [ -n "${PATH##*"/usr/local/opt/ruby/bin"*}" ]           && PATH="/usr/local/opt/ruby/bin:$PATH"
    287 [ -d "/usr/local/opt/sqlite" ]                                                   && [ -n "${PATH##*"/usr/local/opt/sqlite/bin"*}" ]         && PATH="/usr/local/opt/sqlite/bin:$PATH"
    288 [ -d "$HOME/.rvm/bin" ]                                                   && [ -n "${PATH##*"$HOME/.rvm/bin"*}" ]         && PATH="$HOME/.rvm/bin:$PATH"
    289 [ -d "$HOME/.local/share/gem/bin" ]                                                   && [ -n "${PATH##*"$HOME/.local/share/gem/bin"*}" ]         && PATH="$HOME/.local/share/gem/bin:$PATH"
    290 export PATH
    291 # }}}
    292 
    293 # ZSH-specific inits
    294 if command -v startx >/dev/null 2>&1 && [ "$(tty)" = "/dev/tty1" ]; then
    295   pgrep dwm || startx
    296 fi
    297 [ -n "$DOTFILES" ] || { printf '$DOTFILES not set, press enter to quit' && read -r && exit 1; }
    298 
    299 (cat ~/.cache/wal/sequences &)
    300 . ~/.cache/wal/colors-tty.sh
    301 
    302 # Enable custom aliases and functions
    303 alias irssi='irssi --config="$XDG_CONFIG_HOME"/irssi/config --home="$XDG_CONFIG_HOME"/irssi'
    304 alias tmux='tmux -f $XDG_CONFIG_HOME/tmux/tmux.conf'
    305 alias w3m='w3m -config $XDG_CONFIG_HOME/w3m/config -bookmark $XDG_CONFIG_HOME/w3m/bookmark.html'
    306 alias monero-wallet-cli='monero-wallet-cli --config-file ~/.config/bitmonero/monero-wallet-cli.conf'
    307 alias docker='sudo -E docker'
    308 alias fucking="sudo"                                                            # Because sometimes I'm frustrated
    309 alias cp='cp -ivR'                                                              # Prompt if overwrite, verbose
    310 alias grep='grep --color=auto'
    311 alias mv='mv -iv'                                                               # Prompt if overwrite, verbose
    312 alias lynx='lynx -vikeys'
    313 alias mkdir='mkdir -pv'                                                         # Create intermediate dirs, verbose
    314 alias ls="command ls -lh"                                                       # List in long format, human-readable sizes
    315 alias l="command ls -lah"                                                       # Ls but with all files
    316 alias ll="command ls -FGlAhpO@"                                                 # Ls but show everything you can
    317 alias l.="command ls -a | grep '^\.'"                                           # Ls but only dotfiles
    318 alias less='less -RicX'                                                         # Search ig case, fix ANSI colors, don't send init strings, clear screen
    319 alias du="du -sh"                                                              # Show entry for each file, human-readable sizes
    320 alias df="df -h"                                                                # Show human-readable sizes
    321 alias bc="bc -ql"                                                               # Don't print welcome message, use the standard math lib
    322 alias jobs="jobs -l"                                                            # Show everything including PIDs
    323 alias g='git'                                                                   # Make git easier to type
    324 alias wheredef='type -a'                                                        # Where is a function defined?
    325 alias j='joplin'
    326 alias tree="tree -CAFa -I 'CVS|*.*.package|.svn|.git|node_modules' --dirsfirst" # Colorize, ANSI graphics hack, indicate ft with appendices, print all files, ignore certain patterns, list dirs first
    327 alias lsblk="lsblk -o NAME,LABEL,PARTLABEL,TYPE,FSTYPE,SIZE,MOUNTPOINT,STATE"   # The columns I want to see in lsblk
    328 alias confucius="curl confucius-quote.herokuapp.com"                            # A joke curl service I made
    329 alias tx="tmuxinator"
    330 alias mpva="mpv --no-audio-display --no-video --volume=50"
    331 alias irrsi="irssi --home=~/.config/irssi"
    332 # alias irssi="ssh -t vps 'screen -r irssi'"
    333 alias scim="sc-im"
    334 alias mbsync='mbsync -c $HOME/.config/mbsync/mbsyncrc'
    335 alias mutt="neomutt"
    336 alias gotop='sudo gotop -C $XDG_CONFIG_HOME/gotop/gotop.conf'
    337 alias vim=nvim
    338 [ -n "$VIM_TERMINAL" ] && alias vim=vimsend
    339 [ -f "$DOTFILES"/docs/pbib/README.md ] && alias pbib='vim +$(nl -b a '$DOTFILES"/docs/pbib/README.md | fzf --with-nth 2.. -e -q '^# ' | sed 's/[^0-9]//g') "$DOTFILES"/docs/pbib/README.md"
    340 command -v scrcpy >/dev/null 2>&1 && alias scrcpy='scrcpy --no-audio --shortcut-mod=ralt -b2M -S'
    341 command -v lazydocker >/dev/null 2>&1 && alias lzd=lazydocker
    342 cd() { builtin cd -P "$@" || return; }                                  # list contents after cding
    343 mkcd() { mkdir -p -- "$1" && cd -P -- "$1" || return; }                 # make dir and cd at the same time
    344 procinfo() { pgrep -f "$1"; }                                           # get info about a process (by name)
    345 rmempty() { find "${1-.}"  -type d -empty -depth -delete; }             # remove empty directories
    346 hr() { : $((i=0)); while [ $((i<$(tput cols))) -ne 0 ]; do printf "#"; _=$((i=i+1)); done; echo; }  # insert a <hr> in the terminal
    347 vimq() { vim -q <(eval "$(fc -nl -1 | sed 's/^rg\b/rgv/')"); }                                  # load results of last command (often ag) in vim quickfix. eval necessary to handle escaped quotes.
    348 nls() { printf $((`ls -l | wc -l | xargs echo` - 1)); }                        # Count the number of files in the directory
    349 reload-completions() { rm ~/.zcompdump && compinit; }
    350 reload() {
    351   local START_TIME=$SECONDS
    352   if [[ $SHELL = *"zsh"* ]]; then
    353     source "$HOME"/.zshrc
    354   elif [[ $SHELL = *"bash"* ]]; then
    355     source "$HOME"/.bash_profile
    356   fi
    357   echo "Reloaded config ($(( SECONDS-START_TIME )) sec)."
    358 }
    359 extract () {
    360   if [ -f "$1" ] ; then
    361     case $1 in
    362       *.tar.bz2)   tar xjf "$1"     ;;
    363       *.tar.gz)    tar xzf "$1"     ;;
    364       *.bz2)       bunzip2 "$1"     ;;
    365       *.rar)       unrar e "$1"     ;;
    366       *.gz)        gunzip "$1"      ;;
    367       *.tar)       tar xf "$1"      ;;
    368       *.tbz2)      tar xjf "$1"     ;;
    369       *.tgz)       tar xzf "$1"     ;;
    370       *.zip)       unzip "$1"       ;;
    371       *.Z)         uncompress "$1"  ;;
    372       *.7z)        7z x "$1"        ;;
    373       *)     echo "'$1' cannot be extracted via extract()" ;;
    374     esac
    375   else
    376     echo "'$1' is not a valid file"
    377   fi
    378 }
    379 
    380 # Docker functions
    381 if command -v docker &>/dev/null; then
    382   eslint_here() {
    383     docker run -it --rm -v $(pwd):/data cytopia/eslint . -f unix;
    384   }
    385 fi
    386 
    387 # Applescript-reliant functions
    388 if command -v osascript &> /dev/null; then
    389   # cd to current Finder directory
    390   cdf() {
    391     target="$(osascript -e 'tell application "Finder" to if (count of Finder windows) > 0 then get POSIX path of (target of front Finder window as text)')"
    392     if [ -n "$target" ]; then
    393       cd "$target" || printf "Could not cd to %s.\n" >&2
    394       pwd
    395     else
    396       printf 'No Finder window found.\n' >&2
    397     fi
    398   }
    399 
    400   # echo current Finder directory
    401   gdf() {
    402     osascript -e 'tell application "Finder" to if (count of Finder windows) > 0 then get POSIX path of (target of front Finder window as text)'
    403   }
    404   # echo selected Finder file
    405   gsf() {
    406     osascript -e 'tell application "Finder" to return POSIX path of (first item of (get selection as alias list) as alias)' | rev | sed 's/^\///' | rev;
    407   }
    408 fi
    409 
    410 if command -v qlmanage &> /dev/null; then
    411   qlf() { qlmanage -p "$@" &> /dev/null; }
    412 fi
    413 
    414 # fzf-reliant functions
    415 if command -v fzf >/dev/null 2>&1; then
    416   { [ -f ~/.config/dark-theme ] && export BAT_THEME='1337'; } || export BAT_THEME='GitHub'
    417   export FZF_DEFAULT_OPTS="--preview-window right:100:hidden:wrap --bind '?:toggle-preview' --preview='(bat --style=numbers --theme=$BAT_THEME --color=always {} || cat {}) 2>/dev/null | head -500'"
    418   export FZF_DEFAULT_COMMAND="rg -l -H \"\""
    419   # script edit
    420   se() {
    421     local files
    422     IFS=$'\n' files=($(command find "$DOTFILES/scripts" -type f -or -type l -not -ipath "*/.git/*" | fzf -m --inline-info --prompt="edit> " --height=40 --reverse))
    423     [[ -n "$files" ]] && ${EDITOR:-vim} "${files[@]}"
    424   }
    425   # script create
    426   sc() {
    427     [ -z "$1" ] && echo "Filename must be passed as an argument." && return 1
    428     vim $DOTFILES/scripts/"$1" && chmod +x $DOTFILES/scripts/"$1"
    429   }
    430 
    431   # script find
    432   sf() {
    433     local f
    434     IFS=$'\n' f=($(command find "$DOTFILES"/scripts -type f -not -ipath "*/.git/*" | fzf +m --prompt="find> " --height=40 --reverse --cycle))
    435     [[ -n "$f" ]] && printf "$f"
    436   }
    437 
    438   # config edit
    439   ce() {
    440     local files
    441     IFS=$'\n' files=($(command find "$DOTFILES" -type f ! -ipath "*/scripts/*" ! -ipath "*/.git/*" ! -ipath "*/bin/*" ! -ipath "*/oh-my-zsh/*" ! -name ".DS_Store" | fzf -m --inline-info --prompt="edit> " --height=40 --reverse))
    442     [[ -n "$files" ]] && ${EDITOR:-vim} "${files[@]}"
    443   }
    444 
    445   # config find
    446   cf() {
    447     local f
    448     IFS=$'\n' f=($(command find "$DOTFILES" -type f ! -ipath "*/.git/*" ! -ipath "*/bin/*" ! -ipath "*/oh-my-zsh/*" ! -name ".DS_Store" | fzf +m --prompt="find> " --height=40 --reverse --cycle))
    449     [[ -n "$f" ]] && printf "$f"
    450   }
    451 
    452   # vim setting edit
    453   ve() {
    454     local files
    455     IFS=$'\n' files=($(command find ~/.dotfiles/vim -type f -not -ipath "*/.git/*" | fzf -m --inline-info --prompt="edit (vim)> " --height=40 --reverse))
    456     [[ -n "$files" ]] && ${EDITOR:-vim} "${files[@]}"
    457   }
    458   # run python
    459   rp() {
    460     fzf --print-query --preview-window=right:50% --preview 'python -c {q}' <<<''
    461   }
    462   # Run ruby
    463   rr() {
    464     fzf --print-query --preview-window=right:50% --preview 'ruby -e {q}' <<<''
    465   }
    466   # run bash
    467   rb() {
    468     fzf --print-query --preview-window=right:50% --preview 'bash -c {q}' <<<''
    469   }
    470   # run json
    471   rj() {
    472     fzf --preview "cat $1 | jq {q}"
    473   }
    474 
    475   # list man pages
    476   mans() {
    477     sec="${1:-1|4}"
    478     # (sorry, couldn't be arsed to deal with escaping parentheses for variable passing in awk)
    479     manlist=$(man -k . 2>/dev/null | awk "$(printf 'BEGIN {FS=OFS="- "} /\([%s]\)/ {gsub(/\([0-9]\)/, "", $1); if (!seen[$0]++) { print }}' "$sec")" | fzf) \
    480       && man "$(echo "$manlist" | awk -F' |,' '{print $1}')" \
    481       && unset manlist
    482   }
    483 
    484   # list env variables
    485   envs() {
    486     var=$(printenv | cut -d= -f1 | fzf) \
    487       && echo "$var=$(printenv "$var")" \
    488       && unset var
    489   }
    490 fi
    491 
    492 if command -v rg >/dev/null 2>&1; then
    493   alias rgv='rg --vimgrep'
    494 fi
    495 # lf-reliant functions
    496 if command -v lf >/dev/null 2>&1; then
    497   lfcd() {
    498     tmp="$(mktemp)"
    499     lf -last-dir-path="$tmp" "$@"
    500     if [ -f "$tmp" ]; then
    501       dir="$(cat "$tmp")"
    502       rm "$tmp"
    503       [ -d "$dir" ] && [ "$dir" != "$(pwd)" ] && cd "$dir" || return
    504     fi
    505   }
    506 fi
    507 
    508 # Options
    509 if [ -n "$VIMRUNTIME" ]; then set -o vi
    510 else set -o emacs; fi
    511 
    512 setopt alwaystoend         # On completion, move cursor to end of word
    513 setopt autocd              # If I forget 'cd' before a path
    514 setopt autopushd           # Make cd push old directory onto stack
    515 setopt completeinword      # Completion from both ends of word
    516 setopt extendedhistory     # Save timestamp and duration of commands in histfile
    517 setopt interactivecomments # Allow comments
    518 setopt monitor             # Allow job control
    519 setopt nocaseglob          # Globs should be case insensitive
    520 setopt noflowcontrol       # Disable ^S and ^Q
    521 setopt promptsubst         # Parameter expansion, command subst, arithmetic expansion done in prompt
    522 setopt pushdignoredups     # Don't pushd duplicate directories
    523 setopt pushdminus          # Exchange meanings of + and - on directory stack
    524 
    525 # History options
    526 setopt sharehistory        # Import commands from histfile and append typed to histfile
    527 setopt appendhistory       # Append to history
    528 setopt incappendhistory    # Append immediately, not at shell exit
    529 setopt histexpiredupsfirst # When trimming history, remove duplicates first
    530 setopt histignoredups      # Don't save command into history if duplicate of previous
    531 setopt histignorespace     # Don't save command into history if starts with space
    532 setopt histfindnodups      # Ignore duplicates when searching
    533 setopt histreduceblanks    # Remove blank lines from history
    534 setopt histverify          # Show expansion first before executing
    535 
    536 # Enable extra completions
    537 # fpath=($DOTFILES/shell/zsh-completions/src $DOTFILES/shell/osx-zsh-completions/ $DOTFILES/shell/zsh-completions-mine/ $fpath)
    538 autoload -U compinit && compinit
    539 source $DOTFILES/shell/oh-my-zsh-defaults/completion.zsh
    540 source $DOTFILES/shell/oh-my-zsh-defaults/directories.zsh
    541 source $DOTFILES/shell/oh-my-zsh-defaults/history.zsh
    542 source $DOTFILES/shell/oh-my-zsh-defaults/keys.zsh
    543 
    544 # Allow pasting bare URLs
    545 autoload -Uz url-quote-magic
    546 zle -N self-insert url-quote-magic
    547 autoload -Uz bracketed-paste-magic
    548 zle -N bracketed-paste bracketed-paste-magic
    549 
    550 # Auto correct commands, with exceptions (from oh-my-zsh)
    551 alias g='nocorrect git'
    552 alias git='nocorrect git'
    553 alias man='nocorrect man'
    554 alias sudo='nocorrect sudo'
    555 setopt correct
    556 setopt correct_all
    557 
    558 # Built-in Tetris (because why not)
    559 alias tetris="autoload -Uz tetriscurses && tetriscurses"
    560 
    561 # FZF for fuzzy finding
    562 . "$DOTFILES"/tools/fzf/shell/completion.zsh
    563 . "$DOTFILES"/tools/fzf/shell/key-bindings.zsh
    564 . "${XDG_CONFIG_HOME:-$HOME/.config}"/fzf/fzf.zsh
    565 
    566 insert-arg-of-prev-cmd() {
    567 : ${NUMERIC:-1}
    568 (( NUMERIC++ ))
    569 words=($(fc -ln -1))
    570 RBUFFER+="$words[$NUMERIC] "
    571 zle end-of-line
    572 }
    573 zle -N insert-arg-of-prev-cmd
    574 bindkey "\e^y" insert-arg-of-prev-cmd
    575 
    576 bindkey '\e#' pound-insert
    577 bindkey '^]' vi-find-next-char
    578 bindkey '\e^]' vi-find-prev-char
    579 bindkey -s '\el' '\C-e| less'
    580 bindkey -s '\e&' '\C-e&>/dev/null'
    581 
    582 # Bind lfcd (lf with cd) to ctrl-o
    583 bindkey -s '^o' '^ulfcd\n'
    584 
    585 # Ctrl-Z to fg
    586 _zsh_cli_fg() { fg; }
    587 zle -N _zsh_cli_fg
    588 bindkey '^Z' _zsh_cli_fg
    589 
    590 . $DOTFILES/shell/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
    591 
    592 # Zoxide
    593 command -v zoxide &>/dev/null && eval "$(zoxide init zsh)"
    594 
    595 . "$XDG_DATA_HOME/cargo/env"
    596 eval "$(starship init zsh)"