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