]> git.sev.monster Git - dotfiles.git/blame - etc/zsh/.zshrc
zsh: remove some pointless code and comments
[dotfiles.git] / etc / zsh / .zshrc
CommitLineData
43016843 1### options
1795d46e 2setopts=(
3 ## 16.2.1 Changing Directories
4 AUTO_CD CDABLE_VARS
5 ## 16.2.2 Completion
6 COMPLETE_IN_WORD GLOB_COMPLETE REC_EXACT
7 ## 16.2.3 Expansion and Globbing
8 EXTENDED_GLOB GLOB_DOTS GLOB_STAR_SHORT MAGIC_EQUAL_SUBST MARK_DIRS
9 NUMERIC_GLOB_SORT
10 ## 16.2.4 History
11 # NOTE: NO_HIST_SAVE_BY_COPY to allow saving histfile if updating another
12 # user's histfile. this is for compatibility with zsu.
77e83154 13 EXTENDED_HISTORY HIST_FCNTL_LOCK HIST_IGNORE_ALL_DUPS HIST_IGNORE_DUPS
14 HIST_IGNORE_SPACE HIST_LEX_WORDS HIST_NO_STORE HIST_REDUCE_BLANKS
15 NO_HIST_SAVE_BY_COPY HIST_SAVE_NO_DUPS SHARE_HISTORY
1795d46e 16 ## 16.2.6 Input/Output
17 NO_CLOBBER CLOBBER_EMPTY CORRECT_ALL INTERACTIVE_COMMENTS
18 HASH_EXECUTABLES_ONLY
19 ## 16.2.7 Job Control
20 AUTO_CONTINUE LONG_LIST_JOBS
21 ## 16.2.12 Zle
22 NO_BEEP
23)
24setopt $setopts
25unset setopts
43016843 26
79d4a356 27### exports
28## common
8d4a98e1 29export EDITOR=${$(whence -p nvim vim vi micro nano emacs)[(f)1]}
30export PAGER=${$(whence -p less micro nano more)[(f)1]:s/micro/& -readonly true -multiopen tab/:s/nano/& --view}
79d4a356 31## grep
32# XXX: deprecated in GNU
33export GREP_OPTIONS=--color=auto
34## histfile
35export HISTFILE=~/.histfile
1795d46e 36export HISTSIZE=10000
37export SAVEHIST=$HISTSIZE
79d4a356 38## python
8d4a98e1 39export PYTHONSTARTUP=${XDG_CONFIG_HOME:-~/.config}/pythonrc
40## vim
e69caf64 41export VIMINIT='let$MYVIMRC=($XDG_CONFIG_HOME??($HOME."/.config"))."/vim/.vimrc"|execute"source"$MYVIMRC'
79d4a356 42
2bf94bab 43### imports
44autoload -Uz zmv
45autoload -Uz zmathfunc && zmathfunc
46
47## vcs
48zstyle ':vcs_info:*' enable git
49#zstyle ':vcs_info:git*' check-for-changes true #too slow
50zstyle ':vcs_info:git*:dotfiles' check-for-changes true
51zstyle ':vcs_info:git*' check-for-staged-changes true
52autoload -Uz vcs_info
53
54## compinit
55zstyle ':completion:*' auto-description '[arg] %d'
56zstyle ':completion:*' expand suffix
57zstyle ':completion:*' format '# %d'
58zstyle ':completion:*' group-name ''
59zstyle ':completion:*' ignore-parents parent
60zstyle ':completion:*' insert-unambiguous false
61zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
62zstyle ':completion:*' list-prompt '%B%i%b'
63zstyle ':completion:*' list-suffixes true
64zstyle ':completion:*' matcher-list '' 'm:{[:lower:]}={[:upper:]}' 'm:{[:lower:][:upper:]}={[:upper:][:lower:]} r:|[._-]=* r:|=*' 'm:{[:lower:][:upper:]}={[:upper:][:lower:]} l:|=* r:|=*'
65zstyle ':completion:*' menu select=1
66zstyle ':completion:*' original false
67zstyle ':completion:*' select-prompt '%B%l%b'
68zstyle ':completion:*' verbose true
69autoload -Uz compinit
70cache=${XDG_CACHE_HOME:-~/.cache}/zsh
71[[ -d $cache ]] || mkdir -p $cache
72compinit -d $cache/.zcompdump
73unset cache
74
43016843 75### keys
b484bab8 76## set up zkbd-style key array
77if [[ ! -v _sev_force_zkbd && ( -v terminfo || -v termcap ) ]] {
78 # use application (keypad transmit) mode if the terminal supports it
79 # NOTE: we have to do this because termcap/terminfo keys are usually
80 # defined in application mode. terminals that do not define these
81 # capabilities are assumed to always be in application mode.
82 if [[ ( -v terminfo[smkx] && -v terminfo[rmkx] ) ||
83 ( -v termcap[ks] && -v terminfo[ke] ) ]] {
84 autoload -Uz add-zle-hook-widget
85 function _enter-application-mode {
86 [[ -v terminfo[smkx] ]] && echoti smkx || echotc ks
87 }
88 add-zle-hook-widget line-init _enter-application-mode
89 function _exit-application-mode {
90 [[ -v terminfo[rmkx] ]] && echoti rmkx || echotc ke
91 }
92 add-zle-hook-widget line-finish _exit-application-mode
93 trap _exit-application-mode EXIT
94 }
95 # pull keys from terminfo/termcap
96 # TODO: Menu and more Shift- modifiers
97 typeset -gA key
98 typeset -lA newkey
99 if [[ -v terminfo ]] {
100 src=terminfo
101 newkey=(F1 kf1 F2 kf2 F3 kf3 F4 kf4 F5 kf5 F6 kf6 F7 kf7 F8 kf8 F9 kf9
102 F10 kf10 F11 kf11 F12 kf12
103 Backspace kbs
104 Shift-Tab kcbt
105 Insert kich1
106 Home khome
107 PageUp kpp
108 Delete kdch1
109 End kend
110 PageDown knp
111 Up kcuu1
112 Down kcud1
113 Left kcub1
114 Right kcuf1
115 )
116 } elif [[ -v termcap ]] {
117 src=termcap
118 newkey=(F1 k1 F2 k2 F3 k3 F4 k4 F5 k5 F6 k6 F7 k7 F8 k8 F9 k9
119 F10 k\; F11 F1 F12 F2
120 Backspace kb
121 Shift-Tab kB
122 Insert kI
123 Home kh
124 PageUp kP
125 Delete kD
126 End @7
127 PageDown kN
128 Up ku
129 Down kd
130 Left kl
131 Right kr
132 )
133 }
134 for k v (${(kv)newkey}) {
135 key[$k]=${${(P)src}[$v]}
136 }
137 unset k v src newkey
138} else {
139 # use zkbd if termcap/terminfo unavailable
43016843 140 function find_keymap {
8d4a98e1 141 for f in ${ZDOTDIR:-~}/.zkbd/$TERM{-${DISPLAY:-$VENDOR-$OSTYPE},}
43016843 142 [[ -f $f ]] && keymap=$f && break
143 }
144 find_keymap
145 if [[ -z $keymap ]] {
3cebacf8 146 if (read -q "?Can't read terminfo. Add new zkbd keymap? [y/N]") {
43016843 147 echo
388772f1 148 {
149 autoload -Uz zkbd && zkbd
150 } always {
151 TRY_BLOCK_ERROR=0
152 unfunction zkbd
153 }
43016843 154 find_keymap
3cebacf8 155 }
43016843 156 echo
157 }
158 if [[ -n $keymap ]] {
159 source $keymap
160 } else {
294ed44e 161 echo -E "Failed to source keymap file $keymap" >&2
43016843 162 }
163 unfunction find_keymap; unset keymap
43016843 164}
2bf94bab 165
5b9a654a 166## load history search
43016843 167autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
168zle -N up-line-or-beginning-search
43016843 169zle -N down-line-or-beginning-search
43016843 170
5b9a654a 171## bind keys in both viins and vicmd modes
b484bab8 172# NOTE: cursor keys are bound to normal/raw/nontransmit mode strings by
173# default, and keys like Home and End are not bound at all, so we rebind
174# everything to cover all scenarios
5b9a654a 175typeset -A a
176a=(
177 #key viins vicmd
178 Backspace 'backward-delete-char vi-backward-char'
179 Insert 'overwrite-mode vi-insert'
180 Home 'beginning-of-line'
181 PageUp 'up-history -'
182 Delete 'delete-char'
183 End 'end-of-line'
184 PageDown 'down-history -'
185 Up 'up-line-or-beginning-search vi-up-line-or-history'
186 Down 'down-line-or-beginning-search vi-down-line-or-history'
187 Left 'backward-char'
188 Right 'forward-char'
189)
b484bab8 190for k v (${(kv)a}) {
5b9a654a 191 k=$key[$k]
b484bab8 192 if [[ -z $k ]] { continue }
5b9a654a 193 v=($=v)
194 bindkey -- $k $v[1]
b484bab8 195 if [[ $v[2] == - ]] {
5b9a654a 196 # copy viins to vicmd verbatim
197 bindkey -a -- $k $v[1]
198 } elif (( $#v != 1 )) {
199 # set vicmd to any other value
200 bindkey -a -- $k $v[2]
201 } else {
202 # copy viins to vicmd and prepend vi- to it
203 bindkey -a -- $k vi-$v[1]
204 }
b484bab8 205}
5b9a654a 206unset a k v
207
e45f1c99 208## fzf
d928d58f 209# bash-style reverse-search-history (i.e. reverse-i-search)
e45f1c99 210if [[ -v commands[fzf] ]] {
211 function _history-incremental-pattern-search-fzf {
da38ca4b 212 fc -AI
213 # XXX: this shit is cursed and sometimes doesn't work
214 # TODO: remove doesn't work over newlines, fzf replaces them with \n,
215 # and sed of course hates newlines and would need to be massaged
216 # TODO: interactive history refresh... can't get zsh to load histfile:
217 # +reload(HISTFILE='"$h HISTSIZE=$HISTSIZE SAVEHIST=$SAVEHIST \$0 +Z -dfimc 'setopt EXTENDED_HISTORY;fc -R \$HISTFILE;$c' </dev/null 2>&1)" \
218 local c='fc -lt%F -1 0'
219 local h="'${HISTFILE//\'/\'\\\'\'}'"
220 local l=(${(f)"$($=c | fzf \
221 --scheme=history -e -n 1,3.. \
222 +s \
223 -m --bind 'ctrl-d:execute-silent(sed -i -f <(
224 sed -Ee '\''s/[$*.[\^/]/\\&/g;s~.*~/^\\(: [0-9]\\+:[0-9]\\+;\\)\\?&$/d~'\'' {+f3..}
225 ) '$h')+abort' \
226 --preview-window=hidden --height=20% \
227 --with-shell "${0:a} -dfc" \
228 ${BUFFER:+-q $BUFFER})"})
229 # XXX: this sucks, I hate this. no other way to flush internal history?
230 HISTFILE= HISTSIZE=0 fc -p $HISTFILE $HISTSIZE $SAVEHIST
e45f1c99 231 l=$(for x ("${l[@]}") { echo ${${=x}:3}; })
232 BUFFER="$l"
da38ca4b 233 zle reset-prompt
e45f1c99 234 }
235 zle -N _history-incremental-pattern-search-fzf
236 bindkey '^R' _history-incremental-pattern-search-fzf
237} else {
238 bindkey '^R' history-incremental-pattern-search-backward
239}
d928d58f 240
8a92a2c0 241### aliases
242## builtins
243alias rehash='_sev_setpath; rehash'
244## utils
8d4a98e1 245alias h='fc -l -25'
5b9a654a 246alias j='jobs -l'
247alias l='ls -AF'
43016843 248if [[ "$OSTYPE" =~ '^(free|net)bsd' ]] {
5b9a654a 249 alias ll='ls -lAFho'
43016843 250} else {
5b9a654a 251 alias ll='ls -lAFh'
43016843 252}
b053a418 253alias p=\$PAGER
254alias e=\$EDITOR
43016843 255alias se=sudoedit
44bf4f6c 256alias syncwatch='sync & watch -d grep -Fe Dirty: -e Writeback: /proc/meminfo'
b7e624f5 257if [[ -v commands[grep] ]] {
258 [[ -v commands[fgrep] ]] || alias fgrep='grep -F'
259 [[ -v commands[egrep] ]] || alias fgrep='grep -E'
260}
261for x (cat cmp diff grep test update) {
262 [[ -v commands[zutils-z$x] ]] || alias z$x=zutils-z$x
263}
5b9a654a 264# be paranoid
43016843 265alias cp='cp -ip'
266alias mv='mv -i'
4ab73520 267# zsh zmv with noglob wildcards
bfbd0519 268alias zm='noglob zmv -WiM'
269alias zc='noglob zmv -WiC'
270alias zl='noglob zmv -WiL'
271alias sm='noglob zmv -Wip"sudo mv"'
272alias sc='noglob zmv -Wip"sudo cp"'
273alias sl='noglob zmv -Wip"sudo ln"'
43016843 274if [[ "$OSTYPE" =~ '^freebsd' ]] {
275 # don't confirm if only a few files are deleted
276 alias rm='rm -I'
277} else {
278 # TODO: similar behavior for non-freebsd, or impliment in zsh
279 alias rm='rm -i'
280}
8d4a98e1 281[[ -v commands[trash-put] ]] && alias t=trash-put
4ab73520 282# ps
c0bfd3fe 283if [[ -v commands[pstree] && $commands[pstree]:A:t != busybox ]] {
43016843 284 # use pstree, but NOT busybox pstree because it kinda sucks
dd6dcbd4 285 ps='pstree -wg3'
c0bfd3fe 286} elif [[ "$OSTYPE" =~ '^freebsd' ]] {
dd6dcbd4 287 ps='ps -aSdfxwwouser=USR -ogroup=GRP -opid,nice=NI \
288 -o%cpu,%mem,tty,stat,start=START -oetime,command'
c0bfd3fe 289} elif [[ $commands[ps]:A:t == busybox ]] {
43016843 290 # busybox compatible
291 ps="ps -eouser='USR ' -ogroup='GRP ' \
292 -opid=' PID' -onice=' NI' -ovsz=' MEM' \
293 -otty,stat,etime,comm"
c0bfd3fe 294} else {
43016843 295 # XXX: untested, posix
296 # TODO: support gnu ps
dd6dcbd4 297 ps='ps -eouser=USR -ogroup=GRP -opid,nice=NI \
298 -opcpu=CPU -ovsz=MEM -otty,stat,etime,comm'
c0bfd3fe 299}
43016843 300if [[ "$(basename "$PAGER")" = "less" ]] {
109fad20 301 ps="$ps | less -S"
43016843 302} else {
303 ps="$ps | \"${PAGER:-more}\""
304}
79d4a356 305alias pa=$ps
43016843 306alias spa="sudo $ps"
307unset ps
4ab73520 308## py venv
309alias va='source bin/activate'
310alias vd=deactivate
a03b8371 311alias vu="python3 -mvenv --upgrade"
b3d00f21 312alias svu="sudo python3 -mvenv --upgrade"
2bf94bab 313## git
390f6e67 314alias g=git
4851c231 315alias gd='git diff'
2bf94bab 316alias gdh='git diff HEAD'
5052ea51 317alias gdp='git diff HEAD\^'
57f9ed7a 318alias gds='git diff --staged'
2bf94bab 319alias ga='git add'
0ca7cf36 320alias ga.='git add .'
57f9ed7a 321alias gai='git add -i'
322alias gap='git add -p'
2bf94bab 323alias gc='git commit'
324alias gca='git commit --amend'
325alias gp='git push'
4851c231 326alias gu='git pull'
390f6e67 327alias gl='git log'
328alias gt='git tree' # from gitconfig
1e14973b 329alias gsh='git show'
5052ea51 330alias gshn='git show --name-status'
1e14973b 331alias gst='git status'
5052ea51 332alias gsts='git status --short'
1e14973b 333alias gs='git stash'
57f9ed7a 334alias gsp='git stash pop'
d2204ed1 335alias gsd='git stash drop'
336alias gss='git stash show -p'
5052ea51 337alias grc='git rebase --continue'
2bf94bab 338## cd/zoxide
5b9a654a 339function up {
b053a418 340 \cd $(printf '../%.0s' {1..${1:-1}})
5b9a654a 341}
79d4a356 342alias u=up
b053a418 343if [[ -v commands[zoxide] ]] {
8a92a2c0 344 # https://github.com/ajeetdsouza/zoxide/issues/513
345 eval "${$(zoxide init zsh):s#_files -/#_cd#}"
6c74cef6 346 alias cd=z
692a75d3 347 alias z-='z -'
b053a418 348}
0ca7cf36 349alias cd..=up
4851c231 350## dotfiles
7ed1509a 351alias dfu='function {
352 pushd -q ${$(echo -E - ~/.zshenv):P:h:h}
4ab73520 353 git pull &&
354 git submodule init &&
355 git submodule sync &&
356 git submodule update
7ed1509a 357 popd -q
8ec56e91 358}'
4ab73520 359## nocorrect
360# zsh doesnt really handle sudo very well, so ignore it
361alias sudo='nocorrect sudo'
362## docker compose
363alias dcp='sudo docker compose pull'
364alias dcu='sudo docker compose up -d'
365alias dcr='sudo docker compose restart'
366alias dcl='sudo docker compose logs -f'
5b9a654a 367
43016843 368### hooks
369autoload -Uz add-zsh-hook
5437a0d2 370typeset -gi _sev_exectime
43016843 371function sev_preexec {
372 # change terminal title to show command
373 print -n "\e]2;$(print -P '%#')${SSH_CLIENT+$USER@$HOST:}$1\e\\"
374 # save last exec time for bell
375 # XXX: does not run for blank cmdline
376 _sev_exectime=$SECONDS
1ef46e01 377 # update gpg forward, to always have unique filename and avoid clashes
378 if [[ -v _GNUPG_SOCK_DEST_EXT ]] {
379 export _GNUPG_SOCK_DEST_EXT=$(date +%s).$RANDOM
380 export _GNUPG_SOCK_DEST=$_GNUPG_SOCK_DEST_BASE.$_GNUPG_SOCK_DEST_EXT
381 }
43016843 382}
383add-zsh-hook preexec sev_preexec
384function sev_precmd {
385 # change terminal title
386 # TODO: update and send BEL when job status changes
387 print -Pn "\e]2;%(1j,%j,)%#${SSH_CLIENT+$USER@$HOST:}%~\e\\"
388 # bell if exec takes 5s
389 if (( SECONDS - _sev_exectime >= 5 )) print "\a"
390 # we could update vcs_info here, but let prompt take care of it
391 # if it doesn't use vcs, it can be ignored safely
392}
393add-zsh-hook precmd sev_precmd
394function sev_chpwd {
395 # echo dir on cwd change
396 ls -AF
397}
398add-zsh-hook chpwd sev_chpwd
399
43016843 400### prompt
401autoload -Uz promptinit && promptinit
402prompt arrows
403
d3e867c0 404### plugins
405load-plugins zshrc
406
8eb81f95 407### load site-specific
4ced48ed 408load-site-dotfile zshrc
This page took 0.172131 seconds and 4 git commands to generate.