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