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