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