init.zsh 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. # Main zsh config file
  2. # Enable completions
  3. FPATH="${HOME}/.local/share/zsh/site-functions:${FPATH}"
  4. autoload -U compinit && compinit
  5. # Some utility stuff
  6. ZSH_PLUGIN_DIR="${ZSH_CONFIG_DIR}/plugins"
  7. # load_plugin <name>
  8. function load_plugin {
  9. source "${ZSH_PLUGIN_DIR}/${1}/${1}.plugin.zsh"
  10. }
  11. # cmd_exists <name>
  12. function cmd_exists {
  13. hash "${1}" >/dev/null 2>&1
  14. }
  15. # source_user_file <name>
  16. function source_user_file {
  17. local machine_specific="${ZSH_CONFIG_DIR}/${1}.${HOST}.zsh"
  18. local default="${ZSH_CONFIG_DIR}/${1}.zsh"
  19. if [ -e "${machine_specific}" ]; then
  20. source "${machine_specific}"
  21. elif [ -e "${default}" ]; then
  22. source "${default}"
  23. fi
  24. }
  25. # Load user early init file
  26. source_user_file "early-init"
  27. # Some options
  28. setopt autocd extendedglob rm_star_silent completealiases rc_quotes histignorespace
  29. unsetopt beep notify
  30. # Some general, random configuration
  31. # History stuff
  32. [ -v HISTFILE ] || HISTFILE="${HOME}/.cache/zsh/history"
  33. [ ! -d "${HISTFILE:h}" ] && mkdir -p "${HISTFILE:h}"
  34. HISTSIZE=1000
  35. SAVEHIST=10000
  36. # Tools for graphical sessions
  37. export BROWSER=mullvad-browser
  38. export READER=zathura
  39. if [[ -v WAYLAND_DISPLAY ]]; then
  40. function clip {
  41. (( ${#} >= 1 )) && (cat "${@}" | wl-copy) || wl-copy
  42. }
  43. else
  44. alias clip="xclip -selection clipboard"
  45. fi
  46. # I mess this up a lot
  47. alias cd..="cd .."
  48. # Make xargs, sudo, etc. understand aliases
  49. alias xargs='xargs '
  50. if cmd_exists doas; then
  51. __zsh_sudo_cmd=doas
  52. alias sudo='doas '
  53. alias doas='doas '
  54. alias sudoedit="doas $EDITOR "
  55. alias se="doas $EDITOR "
  56. else
  57. __zsh_sudo_cmd=sudo
  58. alias sudo='sudo '
  59. alias se='sudoedit '
  60. fi
  61. # Emacs and Neovim stuff
  62. if [[ -v NVIM ]]; then
  63. export EDITOR=nvr
  64. alias n=nvr
  65. alias nvim=nvr
  66. alias e=nvr
  67. alias emacs=nvr
  68. elif [[ -v INSIDE_EMACS ]]; then
  69. export EDITOR='emacsclient'
  70. alias e='emacsclient '
  71. alias emacs='emacsclient '
  72. alias n='emacsclient '
  73. else
  74. export EDITOR='emacsclient -a nvim -nw'
  75. # Because I keep using n by mistake
  76. alias emacs="${EDITOR} "
  77. alias n=emacs
  78. alias e=emacs
  79. fi
  80. export VISUAL="${EDITOR}"
  81. # Make SBCL *slightly* less frustrating to use on the command line
  82. alias sbcl='rlwrap -pblue -q "\"" sbcl'
  83. # Safer file functions
  84. alias cp="cp -i"
  85. alias mv="mv -i"
  86. # Ledger stuff
  87. alias ldg='ledger -f "${HOME}/finance/finances.ledger"'
  88. # Trash put for safety
  89. if cmd_exists trash-put; then
  90. alias rm='echo "rm: I''m unsafe! Don''t use me."; false'
  91. alias tp=trash-put
  92. alias trr=trash-restore
  93. alias trl=trash-list
  94. alias tre=trash-empty
  95. alias trm=trash-rm
  96. else
  97. local rm_confirm_flag='-i'
  98. uname | grep -i linux >/dev/null && rm_confirm_flag='-I'
  99. alias rm="rm ${rm_confirm_flag}"
  100. fi
  101. # Enable mouse support in less
  102. export LESS="--mouse"
  103. # Bat configuration
  104. if cmd_exists bat; then
  105. # Pager
  106. export PAGER="bat --paging=always"
  107. # Less syntax highlighting in interactive shells
  108. alias less="bat --paging=always"
  109. # Use bat instead of cat
  110. alias cat="bat --paging=never"
  111. alias pcat="bat -pp"
  112. alias ncat="bat -pp --color=never"
  113. # Bat as man pager
  114. export MANPAGER="zsh -c 'col -bx | bat -l man --paging=always --style=plain'"
  115. export MANROFFOPT="-c"
  116. fi
  117. # Eza configuration
  118. if cmd_exists eza; then
  119. alias ls="eza --git -F=auto"
  120. alias la="ls -a"
  121. alias l="ls -l"
  122. alias ll="ls -al"
  123. fi
  124. # Delta configuration
  125. if cmd_exists delta; then
  126. export DELTA_FEATURES='unobtrusive-line-numbers decorations side-by-side'
  127. export DELTA_PAGER='bat -p'
  128. export GIT_PAGER='delta'
  129. fi
  130. # Git aliases
  131. alias ga="git add"
  132. alias gaa="git add -A"
  133. alias gco="git commit"
  134. gcm() {
  135. git commit -m "${${@}}"
  136. }
  137. alias gca="git commit -a"
  138. gcam() {
  139. git commit -am "${${@}}"
  140. }
  141. alias gp="git push"
  142. alias gu="git pull"
  143. alias gf="git fetch"
  144. alias gt="git status"
  145. alias gd="git diff"
  146. # Sudo last line with <Esc><Esc>
  147. sudo-command-line() {
  148. [[ -z $BUFFER ]] && zle up-history
  149. if [[ $BUFFER == ${__zsh_sudo_cmd}\ * ]]; then
  150. LBUFFER="${LBUFFER#${__zsh_sudo_cmd} }"
  151. else
  152. LBUFFER="${__zsh_sudo_cmd} ${LBUFFER}"
  153. fi
  154. }
  155. zle -N sudo-command-line
  156. bindkey -M vicmd "^f" sudo-command-line
  157. bindkey -M viins "^f" sudo-command-line
  158. # Use vi mode
  159. bindkey -v
  160. # Fast switch of modes
  161. KEYTIMEOUT=1
  162. # Implement a replace mode
  163. bindkey -N virep viins
  164. bindkey -M vicmd "R" overwrite-mode
  165. function overwrite-mode {
  166. zle -K virep
  167. zle .overwrite-mode
  168. }
  169. zle -N overwrite-mode
  170. # Fancy prompt (starship)
  171. eval "$(starship init zsh)"
  172. # Change cursor shape for different vi modes.
  173. function __zsh_vim_key_prompt_handler {
  174. SPACESHIP_CHAR_SYMBOL="❮"
  175. local _shape=0
  176. case "${KEYMAP}" in
  177. main) _shape=6 ;; # vi insert: line
  178. viins) _shape=6 ;; # vi insert: line
  179. isearch) _shape=6 ;; # inc search: line
  180. virep) _shape=4 ;; # vi replace: underscore
  181. command) _shape=4 ;; # read a command: underscore
  182. vicmd) _shape=2 ;; # vi cmd: block
  183. visual) _shape=2 ;; # vi visual mode: block
  184. viopp) _shape=1 ;; # vi operation pending: blinking block
  185. *) _shape=0 ;;
  186. esac
  187. zle reset-prompt
  188. printf '\e[%d q' "${_shape}"
  189. }
  190. function zle-keymap-select {
  191. __zsh_vim_key_prompt_handler
  192. }
  193. function zle-line-init {
  194. printf '\e[6 q'
  195. }
  196. zle -N zle-keymap-select
  197. zle -N zle-line-init
  198. # Clear scrollback on ^l
  199. __zsh_clear_screen_and_scrollback() {
  200. echoti civis >"$TTY"
  201. printf '%b' '\e[H\e[2J' >"$TTY"
  202. printf '%b' '\e[3J' >"$TTY"
  203. echoti cnorm >"$TTY"
  204. zle .reset-prompt
  205. zle -R
  206. }
  207. zle -N __zsh_clear_screen_and_scrollback
  208. bindkey '^L' __zsh_clear_screen_and_scrollback
  209. # Direnv
  210. if cmd_exists direnv; then
  211. eval "$(direnv hook zsh)"
  212. fi
  213. # Pyenv
  214. if cmd_exists pyenv; then
  215. export PYENV_ROOT="${HOME}/.pyenv"
  216. [[ -d "${PYENV_ROOT/bin}" ]] && export PATH="${PYENV_ROOT}/bin:${PATH}"
  217. eval "$(pyenv init - zsh)"
  218. fi
  219. # Bookmarks
  220. [[ -v BM_CWD_LS ]] || BM_CWD_LS=1
  221. [[ -v BM_MODE ]] || BM_MODE=daemon
  222. [[ -v BM_AUTO_RELOAD ]] || BM_AUTO_RELOAD=1
  223. source "${ZSH_CONFIG_DIR}/emacs-bookmark.zsh"
  224. # Platform specific stuff
  225. [ -f /usr/bin/pacman ] && source "${ZSH_CONFIG_DIR}/arch.zsh"
  226. # FZF Integration
  227. load_plugin fzf-tab
  228. # Disable sort when completing `git checkout`
  229. zstyle ':completion:*:git-checkout:*' sort false
  230. # Set descriptions format to enable group support
  231. zstyle ':completion:*:descriptions' format '[%d]'
  232. # Set list-colors to enable filename colorizing
  233. zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
  234. # Preview directory's content with eza when completing cd
  235. zstyle ':fzf-tab:complete:cd:*' fzf-preview 'eza -1 --color=always $realpath'
  236. # Remove the '.' prefix at the start of every completion
  237. zstyle ':fzf-tab:*' prefix ''
  238. # Switch groups
  239. zstyle ':fzf-tab:*' switch-group 'ctrl-h' 'ctrl-l'
  240. # Toggle selected for all visible entries
  241. zstyle ':fzf-tab:*' fzf-bindings 'ctrl-a:toggle-all'
  242. # Autosuggestions
  243. load_plugin zsh-autosuggestions
  244. ZSH_AUTOSUGGEST_STRATEGY=(history completion)
  245. bindkey '^ ' autosuggest-accept
  246. # Load user init file
  247. source_user_file 'local'
  248. # THE FOLLOWING PLUGINS MUST COME LAST
  249. # More completions
  250. load_plugin zsh-completions
  251. # Syntax highlighting
  252. load_plugin fast-syntax-highlighting
  253. # History substring search
  254. load_plugin zsh-history-substring-search
  255. bindkey '^[[A' history-substring-search-up
  256. bindkey '^[[B' history-substring-search-down
  257. #bindkey '^k' history-substring-search-up
  258. #bindkey '^j' history-substring-search-down
  259. #bindkey -M vicmd '^k' history-substring-search-up
  260. #bindkey -M vicmd '^j' history-substring-search-down
  261. bindkey -M vicmd 'k' history-substring-search-up
  262. bindkey -M vicmd 'j' history-substring-search-down
  263. bindkey -M emacs '^P' history-substring-search-up
  264. bindkey -M emacs '^N' history-substring-search-down
  265. # Only match at the beginning of the line
  266. HISTORY_SUBSTRING_SEARCH_PREFIXED="true"
  267. HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND=""
  268. setopt histignoredups
  269. # Run fortune and cowsay if we are not in nvim or ssh
  270. if cmd_exists fortune && cmd_exists cowsay; then
  271. [[ -v NVIM ]] || [[ -v SSH_CLIENT ]] || \
  272. fortune | cowsay -felephant-in-snake -n
  273. fi
  274. # Clean up internal functions
  275. unfunction load_plugin
  276. unfunction cmd_exists
  277. unfunction source_user_file