]> git.sev.monster Git - dotfiles.git/blame_incremental - etc/zsh/.zshrc
zsh: remove some pointless code and comments
[dotfiles.git] / etc / zsh / .zshrc
... / ...
CommitLineData
1### options
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.
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
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
26
27### exports
28## common
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}
31## grep
32# XXX: deprecated in GNU
33export GREP_OPTIONS=--color=auto
34## histfile
35export HISTFILE=~/.histfile
36export HISTSIZE=10000
37export SAVEHIST=$HISTSIZE
38## python
39export PYTHONSTARTUP=${XDG_CONFIG_HOME:-~/.config}/pythonrc
40## vim
41export VIMINIT='let$MYVIMRC=($XDG_CONFIG_HOME??($HOME."/.config"))."/vim/.vimrc"|execute"source"$MYVIMRC'
42
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
75### keys
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
140 function find_keymap {
141 for f in ${ZDOTDIR:-~}/.zkbd/$TERM{-${DISPLAY:-$VENDOR-$OSTYPE},}
142 [[ -f $f ]] && keymap=$f && break
143 }
144 find_keymap
145 if [[ -z $keymap ]] {
146 if (read -q "?Can't read terminfo. Add new zkbd keymap? [y/N]") {
147 echo
148 {
149 autoload -Uz zkbd && zkbd
150 } always {
151 TRY_BLOCK_ERROR=0
152 unfunction zkbd
153 }
154 find_keymap
155 }
156 echo
157 }
158 if [[ -n $keymap ]] {
159 source $keymap
160 } else {
161 echo -E "Failed to source keymap file $keymap" >&2
162 }
163 unfunction find_keymap; unset keymap
164}
165
166## load history search
167autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
168zle -N up-line-or-beginning-search
169zle -N down-line-or-beginning-search
170
171## bind keys in both viins and vicmd modes
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
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)
190for k v (${(kv)a}) {
191 k=$key[$k]
192 if [[ -z $k ]] { continue }
193 v=($=v)
194 bindkey -- $k $v[1]
195 if [[ $v[2] == - ]] {
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 }
205}
206unset a k v
207
208## fzf
209# bash-style reverse-search-history (i.e. reverse-i-search)
210if [[ -v commands[fzf] ]] {
211 function _history-incremental-pattern-search-fzf {
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
231 l=$(for x ("${l[@]}") { echo ${${=x}:3}; })
232 BUFFER="$l"
233 zle reset-prompt
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}
240
241### aliases
242## builtins
243alias rehash='_sev_setpath; rehash'
244## utils
245alias h='fc -l -25'
246alias j='jobs -l'
247alias l='ls -AF'
248if [[ "$OSTYPE" =~ '^(free|net)bsd' ]] {
249 alias ll='ls -lAFho'
250} else {
251 alias ll='ls -lAFh'
252}
253alias p=\$PAGER
254alias e=\$EDITOR
255alias se=sudoedit
256alias syncwatch='sync & watch -d grep -Fe Dirty: -e Writeback: /proc/meminfo'
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}
264# be paranoid
265alias cp='cp -ip'
266alias mv='mv -i'
267# zsh zmv with noglob wildcards
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"'
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}
281[[ -v commands[trash-put] ]] && alias t=trash-put
282# ps
283if [[ -v commands[pstree] && $commands[pstree]:A:t != busybox ]] {
284 # use pstree, but NOT busybox pstree because it kinda sucks
285 ps='pstree -wg3'
286} elif [[ "$OSTYPE" =~ '^freebsd' ]] {
287 ps='ps -aSdfxwwouser=USR -ogroup=GRP -opid,nice=NI \
288 -o%cpu,%mem,tty,stat,start=START -oetime,command'
289} elif [[ $commands[ps]:A:t == busybox ]] {
290 # busybox compatible
291 ps="ps -eouser='USR ' -ogroup='GRP ' \
292 -opid=' PID' -onice=' NI' -ovsz=' MEM' \
293 -otty,stat,etime,comm"
294} else {
295 # XXX: untested, posix
296 # TODO: support gnu ps
297 ps='ps -eouser=USR -ogroup=GRP -opid,nice=NI \
298 -opcpu=CPU -ovsz=MEM -otty,stat,etime,comm'
299}
300if [[ "$(basename "$PAGER")" = "less" ]] {
301 ps="$ps | less -S"
302} else {
303 ps="$ps | \"${PAGER:-more}\""
304}
305alias pa=$ps
306alias spa="sudo $ps"
307unset ps
308## py venv
309alias va='source bin/activate'
310alias vd=deactivate
311alias vu="python3 -mvenv --upgrade"
312alias svu="sudo python3 -mvenv --upgrade"
313## git
314alias g=git
315alias gd='git diff'
316alias gdh='git diff HEAD'
317alias gdp='git diff HEAD\^'
318alias gds='git diff --staged'
319alias ga='git add'
320alias ga.='git add .'
321alias gai='git add -i'
322alias gap='git add -p'
323alias gc='git commit'
324alias gca='git commit --amend'
325alias gp='git push'
326alias gu='git pull'
327alias gl='git log'
328alias gt='git tree' # from gitconfig
329alias gsh='git show'
330alias gshn='git show --name-status'
331alias gst='git status'
332alias gsts='git status --short'
333alias gs='git stash'
334alias gsp='git stash pop'
335alias gsd='git stash drop'
336alias gss='git stash show -p'
337alias grc='git rebase --continue'
338## cd/zoxide
339function up {
340 \cd $(printf '../%.0s' {1..${1:-1}})
341}
342alias u=up
343if [[ -v commands[zoxide] ]] {
344 # https://github.com/ajeetdsouza/zoxide/issues/513
345 eval "${$(zoxide init zsh):s#_files -/#_cd#}"
346 alias cd=z
347 alias z-='z -'
348}
349alias cd..=up
350## dotfiles
351alias dfu='function {
352 pushd -q ${$(echo -E - ~/.zshenv):P:h:h}
353 git pull &&
354 git submodule init &&
355 git submodule sync &&
356 git submodule update
357 popd -q
358}'
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'
367
368### hooks
369autoload -Uz add-zsh-hook
370typeset -gi _sev_exectime
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
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 }
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
400### prompt
401autoload -Uz promptinit && promptinit
402prompt arrows
403
404### plugins
405load-plugins zshrc
406
407### load site-specific
408load-site-dotfile zshrc
This page took 0.040654 seconds and 4 git commands to generate.