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