/etc/zsh/zshrc: check for potentially old files in 'completion.d'
[grml-etc-core.git] / etc / zsh / zshrc
1 # Filename:      zshrc
2 # Purpose:       config file for zsh (z shell)
3 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
4 # Bug-Reports:   see http://grml.org/bugs/
5 # License:       This file is licensed under the GPL v2.
6 # Latest change: Fre Mai 25 02:03:29 CEST 2007 [mika]
7 ################################################################################
8 # This file is sourced only for interactive shells. It
9 # should contain commands to set up aliases, functions,
10 # options, key bindings, etc.
11 #
12 # Global Order: zshenv, zprofile, zshrc, zlogin
13 ################################################################################
14
15 # zsh profiling {{{
16 # just execute 'ZSH_PROFILE_RC=1 zsh' and run 'zprof' to get the details
17   if [[ -n $ZSH_PROFILE_RC ]] ; then
18      zmodload zsh/zprof
19   fi
20 # }}}
21
22 # check for potentially old files in 'completion.d' {{{
23   setopt extendedglob
24   xof=(/etc/zsh/completion.d/*~/etc/zsh/completion.d/_*(N))
25   if (( ${#xof} > 0 )) ; then
26     printf '\n -!- INFORMATION\n\n'
27     printf ' -!- %s file(s) not starting with an underscore (_) found in\n' ${#xof}
28     printf ' -!- /etc/zsh/completion.d/.\n\n'
29     printf ' -!- While this has been the case in old versions of grml-etc-core,\n'
30     printf ' -!- recent versions of the grml-zsh-setup have all these files rewritten\n'
31     printf ' -!- and renamed. Furthermore, the grml-zsh-setup will *only* add files\n'
32     printf ' -!- named _* to that directory.\n\n'
33     printf ' -!- If you added functions to completion.d yourself, please consider\n'
34     printf ' -!- moving them to /etc/zsh/functions.d/. Files in that directory, not\n'
35     printf ' -!- starting with an underscore are marked for automatic loading\n'
36     printf ' -!- by default (so that is quite convenient).\n\n'
37     printf ' -!- If there are files *not* starting with an underscore from an older\n'
38     printf ' -!- grml-etc-core in completion.d, you may safely remove them.\n\n'
39     printf ' -!- Delete the files for example via running:\n\n'
40     printf "      rm ${xof}\n\n"
41     printf ' -!- Note, that this message will *not* go away, unless you yourself\n'
42     printf ' -!- resolve the situation manually.\n\n'
43   fi
44   unset xof
45 # }}}
46
47 # {{{ check for version/system
48 # check for versions (compatibility reasons)
49   if autoload is-at-least && is-at-least 2>/dev/null ; then
50      is4() { is-at-least 4 }
51      is42() { is-at-least 4.2 }
52   else
53     is4(){
54       [[ $ZSH_VERSION == 4.* ]] && return 0
55       return 1
56     }
57     is42(){
58       [[ $ZSH_VERSION == 4.<2->* ]] && return 0
59       return 1
60     }
61   fi
62
63 # grml specific stuff
64   isgrml(){
65     [ -f /etc/grml_version ] && return 0
66     return 1
67   }
68
69   isgrmlcd(){
70     [ -f /etc/grml_cd ] && return 0
71     return 1
72   }
73
74   if isgrml ; then
75     isgrmlsmall() {
76     [[ ${${${(f)"$(</etc/grml_version)"}%% *}##*-} == 'small' ]] && return 0 ; return 1
77   }
78   else
79     isgrmlsmall() { return 1 }
80   fi
81
82   # are we running within an utf environment?
83   isutfenv() {
84     case "$LANG $CHARSET $LANGUAGE" in
85       *utf*) return 0 ;;
86       *UTF*) return 0 ;;
87       *)     return 1 ;;
88     esac
89   }
90
91 # check for user, if not running as root set $SUDO to sudo
92  (( EUID != 0 )) && SUDO='sudo' || SUDO=''
93
94   function salias() {
95     # creates an alias and precedes the command with
96     # sudo if $EUID is not zero.
97     local only=0 ; local multi=0
98     while [[ ${1} == -* ]] ; do
99       case ${1} in
100         (-o) only=1 ;;
101         (-a) multi=1 ;;
102         (--) shift ; break ;;
103         (-h)
104           printf 'usage: salias [-h|-o|-a] <alias-expression>\n'
105           printf '  -h      shows this help text.\n'
106           printf '  -a      replace '\'' ; '\'' sequences with '\'' ; sudo '\''.\n'
107           printf '          be careful using this option.\n'
108           printf '  -o      only sets an alias if a preceding sudo would be needed.\n'
109           return 0
110           ;;
111         (*) printf "unkown option: '%s'\n" "${1}" ; return 1 ;;
112       esac
113       shift
114     done
115     if (( ${#argv} > 1 )) ; then
116       printf 'Too many arguments %s\n' "${#argv}"
117       return 1
118     fi
119     key="${1%%\=*}" ;  val="${1#*\=}"
120     if (( EUID == 0 )) && (( only == 0 )); then
121       alias -- "${key}=${val}"
122     elif (( EUID > 0 )) ; then
123       (( multi > 0 )) && val="${val// ; / ; sudo }"
124       alias -- "${key}=sudo ${val}"
125     fi
126     return 0
127   }
128
129 # change directory to home on first invocation of zsh
130 # important for rungetty -> autologin
131 # Thanks go to Bart Schaefer!
132   isgrml && checkhome() {
133   if [[ -z "$ALREADY_DID_CD_HOME" ]]; then
134      export ALREADY_DID_CD_HOME=$HOME
135      cd
136   fi
137   }
138 # }}}
139
140 # {{{ set some variables
141   export EDITOR=${EDITOR:-vim}
142   export MAIL=${MAIL:-/var/mail/$USER}
143   # if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/
144   export SHELL='/bin/zsh'
145   [[ -f ~/.terminfo/m/mostlike ]] && MYLESS='LESS=C TERMINFO=~/.terminfo TERM=mostlike less' || MYLESS='less'
146   [ -x $(which dircolors) ] && eval `dircolors -b`
147
148 # Search path for the cd comman
149 #  cdpath=(.. ~)
150
151 # completion functions go to /etc/zsh/completion.d
152 # function files may be put into /etc/zsh/functions.d, from where they
153 # will be automatically autoloaded.
154   [[ -d /etc/zsh/completion.d ]] && fpath+=( /etc/zsh/completion.d )
155   if [[ -d /etc/zsh/functions.d ]] ; then
156     fpath+=( /etc/zsh/functions.d )
157     for func in /etc/zsh/functions.d/[^_]*[^~] ; do
158       autoload -U ${func:t}
159     done
160   fi
161
162 # automatically remove duplicates from these arrays
163   typeset -U path cdpath fpath manpath
164 # }}}
165
166 # {{{ keybindings
167  if [[ "$TERM" != emacs ]]; then
168   [[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
169   [[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
170   [[ -z "$terminfo[kend]"  ]] || bindkey -M emacs "$terminfo[kend]"  end-of-line
171   [[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
172   [[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
173   [[ -z "$terminfo[kend]"  ]] || bindkey -M vicmd "$terminfo[kend]"  vi-end-of-line
174   [[ -z "$terminfo[cuu1]"  ]] || bindkey -M viins "$terminfo[cuu1]"  vi-up-line-or-history
175   [[ -z "$terminfo[cuf1]"  ]] || bindkey -M viins "$terminfo[cuf1]"  vi-forward-char
176   [[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
177   [[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
178   [[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
179   [[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char
180   # ncurses stuff:
181   [[ "$terminfo[kcuu1]" == "\eO"* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history
182   [[ "$terminfo[kcud1]" == "\eO"* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history
183   [[ "$terminfo[kcuf1]" == "\eO"* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char
184   [[ "$terminfo[kcub1]" == "\eO"* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char
185   [[ "$terminfo[khome]" == "\eO"* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line
186   [[ "$terminfo[kend]"  == "\eO"* ]] && bindkey -M viins "${terminfo[kend]/O/[}"  end-of-line
187   [[ "$terminfo[khome]" == "\eO"* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line
188   [[ "$terminfo[kend]"  == "\eO"* ]] && bindkey -M emacs "${terminfo[kend]/O/[}"  end-of-line
189 fi
190
191 ## keybindings (run 'bindkeys' for details, more details via man zshzle)
192 # use emacs style per default:
193   bindkey -e
194 # use vi style:
195 # bindkey -v
196
197 #if [[ "$TERM" == screen ]]; then
198   bindkey '\e[1~' beginning-of-line       # home
199   bindkey '\e[4~' end-of-line             # end
200   bindkey "^[[A"  up-line-or-search       # cursor up
201   bindkey "^[[B"  down-line-or-search     # <ESC>-
202   bindkey '^x'    history-beginning-search-backward # alternative ways of searching the shell history
203 # bindkey -s '^L' "|less\n"             # ctrl-L pipes to less
204 # bindkey -s '^B' " &\n"                # ctrl-B runs it in the background
205 # if terminal type is set to 'rxvt':
206   bindkey '\e[7~' beginning-of-line       # home
207   bindkey '\e[8~' end-of-line             # end
208 #fi
209
210 # insert unicode character
211 # usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an ยง
212 # See for example http://unicode.org/charts/ for unicode characters code
213   autoload insert-unicode-char
214   zle -N insert-unicode-char
215   bindkey '^Xi' insert-unicode-char
216
217 # just type 'cd ...' to get 'cd ../..'
218 #  rationalise-dot() {
219 #  if [[ $LBUFFER = *.. ]]; then
220 #    LBUFFER+=/..
221 #  else
222 #    LBUFFER+=.
223 #  fi
224 #  }
225 #  zle -N rationalise-dot
226 #  bindkey . rationalise-dot
227
228 #  bindkey '\eq' push-line-or-edit
229 # }}}
230
231 # power completion - abbreviation expansion {{{
232 # power completion / abbreviation expansion / buffer expansion
233 # see http://zshwiki.org/home/examples/zleiab for details
234 # less risky than the global aliases but powerful as well
235 # just type the abbreviation key and afterwards ',.' to expand it
236   declare -A abk
237   setopt extendedglob
238   setopt interactivecomments
239   abk=(
240    # key  # value
241    'C'    '| wc -l'
242    '...' '../..'
243    '....' '../../..'
244    'BG' '& exit'
245    'C' '| wc -l'
246    'G' '|& grep --color=auto'
247    'H' '| head'
248    'Hl' ' --help |& less -r'
249    'L' '| less'
250    'LL' '|& less -r'
251    'M' '| most'
252    'N' '&>/dev/null'
253    'R' '| tr A-z N-za-m'
254    'SL' '| sort | less'
255    'S' '| sort -u'
256    'T' '| tail'
257    'V' '|& vim -'
258    'hide' "echo -en '\033]50;nil2\007'"
259    'tiny' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-80-*-*-c-*-iso8859-15\007"'
260    'small' 'echo -en "\033]50;6x10\007"'
261    'medium' 'echo -en "\033]50;-misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-15\007"'
262    'default' 'echo -e "\033]50;-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-15\007"'
263    'large' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-150-*-*-c-*-iso8859-15\007"'
264    'huge' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-210-*-*-c-*-iso8859-15\007"'
265    'smartfont' 'echo -en "\033]50;-artwiz-smoothansi-*-*-*-*-*-*-*-*-*-*-*-*\007"'
266    'semifont' 'echo -en "\033]50;-misc-fixed-medium-r-semicondensed-*-*-120-*-*-*-*-iso8859-15\007"'
267    'da' 'du -sch'
268    'j' 'jobs -l'
269    'u' 'translate -i'
270    'co' "./configure && make && sudo make install"
271    'CH' "./configure --help"
272    'conkeror' 'firefox -chrome chrome://conkeror/content'
273    'dir' 'ls -lSrah'
274    'lad' $'ls -d .*(/)\n# only show dot-directories'
275    'lsa' $'ls -a .*(.)\n# only show dot-files'
276    'lss' $'ls -l *(s,S,t)\n# only files with setgid/setuid/sticky flag'
277    'lsl' $'ls -l *(@[1,10])\n# only symlinks'
278    'lsx' $'ls -l *(*[1,10])\n# only executables'
279    'lsw' $'ls -ld *(R,W,X.^ND/)\n# world-{readable,writable,executable} files'
280    'lsbig' $'ls -flh *(.OL[1,10])\n# display the biggest files'
281    'lsd' $'ls -d *(/)\n# only show directories'
282    'lse' $'ls -d *(/^F)\n# only show empty directories'
283    'lsnew' $'ls -rl *(D.om[1,10])\n# display the newest files'
284    'lsold' $'ls -rtlh *(D.om[-11,-1])\n # display the oldest files'
285    'lssmall' $'ls -Srl *(.oL[1,10])\n# display the smallest files'
286    'rw-' 'chmod 600'
287    '600' 'chmod u+rw-x,g-rwx,o-rwx'
288    'rwx' 'chmod u+rwx'
289    '700' 'chmod u+rwx,g-rwx,o-rwx'
290    'r--' 'chmod u+r-wx,g-rwx,o-rwx'
291    '644' $'chmod u+rw-x,g+r-wx,o+r-wx\n # 4=r,2=w,1=x'
292    '755' 'chmod u+rwx,g+r-w+x,o+r-w+x'
293    'md' 'mkdir -p '
294    'cmplayer' 'mplayer -vo -fs -zoom fbdev'
295    'fbmplayer' 'mplayer -vo -fs -zoom fbdev'
296    'fblinks' 'links2 -driver fb'
297    'insecssh' 'ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
298    'insecscp' 'scp -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
299    'fori' 'for i ({..}) { }'
300    'cx' 'chmod +x'
301    'e'  'print -l'
302    'se' 'setopt interactivecomments'
303    'va' 'valac --vapidir=../vapi/ --pkg=gtk+-2.0 gtktest.vala'
304    'fb2' '=mplayer -vo fbdev -fs -zoom 1>/dev/null -xy 2'
305    'fb3' '=mplayer -vo fbdev -fs  -zoom 1>/dev/null -xy 3'
306    'ci' 'centericq'
307    'D'  'export DISPLAY=:0.0'
308    'mp' 'mplayer -vo xv -fs -zoom'
309   )
310
311   globalias () {
312         local MATCH
313         matched_chars='[.-|_a-zA-Z0-9]#'
314         LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
315         LBUFFER+=${abk[$MATCH]:-$MATCH}
316   }
317
318   zle -N globalias
319   bindkey ",." globalias
320 # }}}
321
322 # {{{ autoloading
323   autoload -U zmv    # who needs mmv or rename?
324   autoload history-search-end
325
326   # we don't want to quote/espace URLs on our own...
327   # if autoload -U url-quote-magic ; then
328   #    zle -N self-insert url-quote-magic
329   #    zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}='
330   # else
331   #    print 'Notice: no url-quote-magic available :('
332   # fi
333   alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic'
334
335   alias run-help >&/dev/null && unalias run-help
336   autoload run-help # use via 'esc-h'
337
338 # completion system
339   if autoload -U compinit && compinit 2>/dev/null ; then
340      compinit 2>/dev/null || print 'Notice: no compinit available :('
341    else
342      print 'Notice: no compinit available :('
343      function zstyle { }
344      function compdef { }
345   fi
346
347   is4 && autoload -U zed                  # use ZLE editor to edit a file or function
348
349   is4 && for mod in complist deltochar mathfunc ; do
350              zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :("
351          done
352
353 # autoload zsh modules when they are referenced
354   is4 && for opt mod in a  stat    \
355                         a  zpty    \
356                         ap zprof   \
357                         ap mapfile ; do
358              zmodload -${opt} zsh/${mod} ${mod}
359          done ; unset opt mod
360
361   is4 && autoload -U insert-files && \
362   zle -N insert-files && \
363   bindkey "^Xf" insert-files # C-x-f
364
365   bindkey ' '   magic-space    # also do history expansion on space
366   bindkey '\ei' menu-complete  # menu completion via esc-i
367
368 # press esc-e for editing command line in $EDITOR or $VISUAL
369   is4 && autoload -U edit-command-line && \
370   zle -N edit-command-line && \
371   bindkey '\ee' edit-command-line
372
373 # menu selection: pick item but stay in the menu (press esc-return)
374   is4 && bindkey -M menuselect '\e^M' accept-and-menu-complete
375
376 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
377   _bkdate() { BUFFER="$BUFFER$(date '+%F')"; CURSOR=$#BUFFER; }
378   bindkey '\C-ed' _bkdate
379   zle -N _bkdate
380
381 # press esc-m for inserting last typed word again (thanks to caphuso!)
382   insert-last-typed-word() { zle insert-last-word -- 0 -1 }; \
383   zle -N insert-last-typed-word; bindkey "\em" insert-last-typed-word
384
385 # set command prediction from history, see 'man 1 zshcontrib'
386 #  is4 && autoload -U predict-on && \
387 #  zle -N predict-on         && \
388 #  zle -N predict-off        && \
389 #  bindkey "^X^Z" predict-on && \
390 #  bindkey "^Z" predict-off
391
392 # put job into foreground via ctrl-z:
393   bindkey -s '^z' "fg\n"
394
395 # press ctrl-q to quote line:
396 #  mquote () {
397 #        zle beginning-of-line
398 #        zle forward-word
399 #        # RBUFFER="'$RBUFFER'"
400 #        RBUFFER=${(q)RBUFFER}
401 #        zle end-of-line
402 #  }
403 #  zle -N mquote && bindkey '^q' mquote
404
405 # run command line as user root via sudo:
406   _sudo-command-line() {
407     [[ $BUFFER != sudo\ * ]] && LBUFFER="sudo $LBUFFER"
408   }
409   zle -N sudo-command-line _sudo-command-line
410   bindkey "^Os" sudo-command-line
411 # }}}
412
413 # {{{ set some important options
414   (( EUID != 0 )) && umask 002 || umask 022
415
416 # history:
417   setopt append_history       # append history list to the history file (important for multiple parallel zsh sessions!)
418   is4 && setopt SHARE_HISTORY # import new commands from the history file also in other zsh-session
419   setopt extended_history     # save each command's beginning timestamp and the duration to the history file
420   is4 && setopt histignorealldups # If  a  new  command  line being added to the history
421                               # list duplicates an older one, the older command is removed from the list
422   setopt histignorespace      # remove command lines from the history list when
423                               # the first character on the line is a space
424 #  setopt histallowclobber    # add `|' to output redirections in the history
425 #  setopt NO_clobber          # warning if file exists ('cat /dev/null > ~/.zshrc')
426   setopt auto_cd              # if a command is issued that can't be executed as a normal command,
427                               # and the command is the name of a directory, perform the cd command to that directory
428   setopt extended_glob        # in order to use #, ~ and ^ for filename generation
429                               # grep word *~(*.gz|*.bz|*.bz2|*.zip|*.Z) ->
430                               # -> searches for word not in compressed files
431                               # don't forget to quote '^', '~' and '#'!
432   setopt notify               # report the status of backgrounds jobs immediately
433   setopt hash_list_all        # Whenever a command completion is attempted, make sure \
434                               # the entire command path is hashed first.
435   setopt completeinword       # not just at the end
436 # setopt nocheckjobs          # don't warn me about bg processes when exiting
437   setopt nohup                # and don't kill them, either
438 # setopt printexitvalue       # alert me if something failed
439 # setopt dvorak               # with spelling correction, assume dvorak kb
440   setopt auto_pushd           # make cd push the old directory onto the directory stack.
441   setopt nonomatch            # try to avoid the 'zsh: no matches found...'
442   setopt nobeep               # avoid "beep"ing
443
444   MAILCHECK=30       # mailchecks
445   REPORTTIME=5       # report about cpu-/system-/user-time of command if running longer than 5 secondes
446   watch=(notme root) # watch for everyone but me and root
447
448 # define word separators (for stuff like backward-word, forward-word, backward-kill-word,..)
449 #  WORDCHARS='*?_-.[]~=/&;!#$%^(){}<>' # the default
450 #  WORDCHARS=.
451 #  WORDCHARS='*?_[]~=&;!#$%^(){}'
452 #  WORDCHARS='${WORDCHARS:s@/@}'
453
454 # only slash should be considered as a word separator:
455   slash-backward-kill-word() {
456     local WORDCHARS="${WORDCHARS:s@/@}"
457     # zle backward-word
458     zle backward-kill-word
459   }
460   zle -N slash-backward-kill-word
461   bindkey '\ev' slash-backward-kill-word # press esc-v to delete a word until its last '/' (not the same as ctrl-w!)
462 # }}}
463
464 # {{{ history
465   export ZSHDIR=$HOME/.zsh
466   HISTFILE=$HOME/.zsh_history
467   isgrmlcd && HISTSIZE=500  || HISTSIZE=5000
468   isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
469 # }}}
470
471 # dirstack handling {{{
472   DIRSTACKSIZE=20
473   if [[ -f ~/.zdirs ]] && [[ ${#dirstack[*]} -eq 0 ]]; then
474      dirstack=( ${(uf)"$(< ~/.zdirs)"} )
475      # "cd -" won't work after login by just setting $OLDPWD, so
476      [[ -d $dirstack[0] ]] && cd $dirstack[0] && cd $OLDPWD
477   fi
478   chpwd() {
479     builtin dirs -pl >! ~/.zdirs
480   }
481 # }}}
482
483 # {{{ display battery status on right side of prompt via running 'BATTERY=1 zsh'
484   if [ -n "$BATTERY" ] ; then
485      if [ -x $(which acpi) ] ; then
486         PERCENT="${(C)${(s| |)$(acpi 2>/dev/null)}[4]}"
487         [ -z "$PERCENT" ] && PERCENT='acpi not present'
488         if [ "${PERCENT%%%}" -lt 20 ] ; then
489            PERCENT="warning: ${PERCENT}%"
490         fi
491      fi
492   fi
493 # }}}
494
495 # {{{ set prompt
496   if autoload promptinit && promptinit 2>/dev/null ; then
497      promptinit # people should be able to use their favourite prompt
498   else
499      print 'Notice: no promptinit available :('
500   fi
501
502 # precmd() => a function which is executed just before each prompt
503 # use 'NOPRECMD=1' to disable the precmd + preexec commands
504
505   # precmd () { setopt promptsubst; [[ -o interactive ]] && jobs -l;
506
507   # make sure to use right prompt only when not running a command
508   is4 && setopt transient_rprompt
509
510   is4 && [[ -z $NOPRECMD ]] && precmd () {
511       [[ -n $NOPRECMD ]] && return 0
512       # allow manual overwriting of RPROMPT
513       if [[ -n $RPROMPT ]] ; then
514          [[ $TERM == screen* ]] && echo -n $'\ekzsh\e\\'
515          return 0
516       fi
517       # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
518       if [[ -z $DONTSETRPROMPT ]] ; then
519          if [[ -n $BATTERY ]] ; then
520             RPROMPT="%(?..:()% ${PERCENT}${SCREENTITLE}"
521             # RPROMPT="${PERCENT}${SCREENTITLE}"
522          else
523             RPROMPT="%(?..:()% ${SCREENTITLE}"
524             # RPROMPT="${SCREENTITLE}"
525          fi
526       fi
527       # adjust title of xterm
528       # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
529       case $TERM in (xterm*|rxvt)
530         print -Pn "\e]0;%n@%m: %~\a"
531         ;;
532       esac
533   }
534
535 # chpwd () => a function which is executed whenever the directory is changed
536
537 # preexec() => a function running before every command
538   is4 && [[ -z $NOPRECMD ]] && preexec () {
539       [[ -n $NOPRECMD ]] && return 0
540   # set hostname if not running on host with name 'grml'
541       local HOSTNAME=$(hostname)
542       if [[ "$HOSTNAME" != grml ]] ; then
543          NAME="@$HOSTNAME"
544       fi
545   # get the name of the program currently running and hostname of local machine
546   # set screen window title if running in a screen
547       if [[ "$TERM" == screen* ]]; then
548          # local CMD=${1[(wr)^(*=*|sudo|ssh|-*)]}       # dont't use hostname
549          local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME" # use hostname
550          echo -ne "\ek$CMD\e\\"
551       fi
552   # set the screen title to "zsh" when sitting at the command prompt:
553       if [[ "$TERM" == screen* ]]; then
554          SCREENTITLE=$'%{\ekzsh\e\\%}'
555       else
556          SCREENTITLE=''
557       fi
558   # adjust title of xterm
559       case $TERM in (xterm*|rxvt)
560         print -Pn "\e]0;%n@%m: $1\a"
561         ;;
562       esac
563   }
564
565 # set colors
566   if autoload colors && colors 2>/dev/null ; then
567      BLUE="%{${fg[blue]}%}"
568      RED="%{${fg_bold[red]}%}"
569      GREEN="%{${fg[green]}%}"
570      CYAN="%{${fg[cyan]}%}"
571      WHITE="%{${fg[white]}%}"
572      NO_COLOUR="%{${reset_color}%}"
573   else
574      BLUE="%{\e[1;34m%}"
575      RED="%{\e[1;31m%}"
576      GREEN="%{\e[1;32m%}"
577      CYAN="%{\e[1;36m%}"
578      WHITE="%{\e[1;37m%}"
579      NO_COLOUR="%{\e[0m%}"
580   fi
581
582   EXITCODE="%(?..%?%1v )"
583   PS2='`%_> '       # secondary prompt, printed when the shell needs more information to complete a command.
584   PS3='?# '         # selection prompt used within a select loop.
585   PS4='+%N:%i:%_> ' # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
586
587   # set variable debian_chroot if running in a chroot with /etc/debian_chroot
588   if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
589     debian_chroot=$(cat /etc/debian_chroot)
590   fi
591
592   # don't use colors on dumb terminals (like emacs):
593   if [[ "$TERM" == dumb ]] ; then
594      PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< %# "
595   else
596     # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended prompt
597     # set variable identifying the chroot you work in (used in the prompt below)
598     if [[ -n $GRMLPROMPT ]]; then
599       PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
600 ${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# "
601     else
602       if (( EUID != 0 )); then
603         PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
604       else
605         PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
606       fi
607     fi
608   fi
609
610   # if we are inside a grml-chroot set a specific prompt theme
611   if [ -n "$GRML_CHROOT" ] ; then
612      PROMPT="%{$fg[red]%}(CHROOT) %{$fg_bold[red]%}%n%{$fg_no_bold[white]%}@%m %40<...<%B%~%b%<< %\# "
613   fi
614 # }}}
615
616 # {{{ 'hash' some often used directories
617   hash -d deb=/var/cache/apt/archives
618   hash -d doc=/usr/share/doc
619   hash -d linux=/lib/modules/$(command uname -r)/build/
620   hash -d log=/var/log
621   hash -d slog=/var/log/syslog
622   hash -d src=/usr/src
623   hash -d templ=/usr/share/doc/grml-templates
624   hash -d tt=/usr/share/doc/texttools-doc
625   hash -d www=/var/www
626 # }}}
627
628 # {{{ some aliases
629   if [ $UID = 0 ] ; then
630      [ -r /etc/grml/screenrc ] && alias screen='/usr/bin/screen -c /etc/grml/screenrc'
631   elif [ -r $HOME/.screenrc ] ; then
632      alias screen="/usr/bin/screen -c $HOME/.screenrc"
633   else
634      [ -r /etc/grml/screenrc_grml ] && alias screen='/usr/bin/screen -c /etc/grml/screenrc_grml'
635   fi
636
637   if ls --help 2>/dev/null |grep -- --color= >/dev/null && [ "$TERM" != dumb ] ; then
638      alias ls='ls -b -CF --color=auto' # do we have GNU ls with color-support?
639      alias la='ls -la --color=auto'
640      alias ll='ls -l --color=auto'
641      alias lh='ls -hAl --color=auto'
642      alias l='ls -lF --color=auto'
643   else
644      alias ls='ls -b -CF'
645      alias la='ls -la'
646      alias ll='ls -l'
647      alias lh='ls -hAl'
648      alias l='ls -lF'
649   fi
650
651   alias mdstat='cat /proc/mdstat'
652   alias ...='cd ../../'
653
654   alias cp='nocorrect cp'         # no spelling correction on cp
655   alias mkdir='nocorrect mkdir'   # no spelling correction on mkdir
656   alias mv='nocorrect mv'         # no spelling correction on mv
657   alias rm='nocorrect rm'         # no spelling correction on rm
658
659   alias rd='rmdir'
660   alias md='mkdir'
661
662   # see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
663   alias term2iso="echo 'Setting terminal to iso mode' ; echo -e '\e%@'"
664   alias term2utf="echo 'Setting terminal to utf-8 mode'; echo -e '\e%G'"
665
666   alias utf2iso='if isutfenv ; then
667    for ENV in `env | grep UTF` ; do
668        eval export "$(echo $ENV | sed 's/UTF-8/iso885915/')"
669    done
670    fi'
671   alias iso2utf='if isutfenv ; then
672    for ENV in `env | grep '\.iso'` ; do
673        eval export "$(echo $ENV | sed 's/iso.*/UTF-8/')"
674    done
675    fi'
676
677 # set up software synthesizer via speakup
678   alias swspeak='
679     aumix -w 90 -v 90 -p 90 -m 90
680     if ! [ -r /dev/softsynth ] ; then
681        flite -o play -t "Sorry, software synthesizer not available. Did you boot with swspeak bootoption?"
682        return 1
683     else
684        setopt singlelinezle
685        unsetopt prompt_cr
686        export PS1="%m%# "
687        nice -n -20 speechd-up
688        sleep 2
689        flite -o play -t "Finished setting up software synthesizer"
690     fi
691   '
692
693   # I like clean prompt, so provide simple way to get that
694   alias 0 &>/dev/null || functions 0 &>/dev/null || alias 0='return 0'
695
696 # truecrypt; use e.g. via 'truec /dev/ice /mnt/ice' or 'truec -i'
697   if [ -x $(which truecrypt) ] ; then
698      if isutfenv ; then
699         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077,utf8" '
700      else
701         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077" '
702      fi
703   fi
704
705   zsh-help(){print "$bg[white]$fg[black]
706 zsh-help - hints for use of zsh on grml
707 =======================================$reset_color
708
709 Main configuration of zsh happens in /etc/zsh/zshrc (global)
710 and /etc/skel/.zshrc which is copied to \$HOME/.zshrc once.
711 The files are part of the package grml-etc-core, if you want to
712 use them on a non-grml-system just get the tar.gz from
713 http://deb.grml.org/ or get the files from the mercurial
714 repository:
715
716   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
717   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
718
719 If you want to stay in sync with zsh configuration of grml
720 run 'ln -sf /etc/skel/.zshrc \$HOME/.zshrc' and configure
721 your own stuff in \$HOME/.zshrc.local. System wide configuration
722 without touching configuration files of grml can take place
723 in /etc/zsh/zshrc.local.
724
725 If you want to use the configuration of user grml also when
726 running as user root just run 'zshskel' which will source
727 the file /etc/skel/.zshrc.
728
729 For information regarding zsh start at http://grml.org/zsh/
730
731 Take a look at grml's zsh refcard:
732 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
733
734 Check out the main zsh refcard:
735 % $BROWSER http://www.bash2zsh.com/zsh_refcard/refcard.pdf
736
737 And of course visit the zsh-lovers:
738 % man zsh-lovers
739
740 You can adjust some options through environment variables when
741 invoking zsh without having to edit configuration files.
742 Basically meant for bash users who are not used to the power of
743 the zsh yet. :)
744
745   \"NOCOR=1    zsh\" => deactivate automatic correction
746   \"NOMENU=1   zsh\" => do not use menu completion (note: use strg-d for completion instead!)
747   \"NOPRECMD=1 zsh\" => disable the precmd + preexec commands (set GNU screen title)
748   \"BATTERY=1  zsh\" => activate battery status (via acpi) on right side of prompt
749 $bg[white]$fg[black]
750 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
751 Enjoy your grml system with the zsh!$reset_color"
752 }
753
754 # debian stuff
755   if [ -r /etc/debian_version ] ; then
756     alias acs='apt-cache search'
757     alias acsh='apt-cache show'
758     alias acp='apt-cache policy'
759     salias adg="apt-get dist-upgrade"
760     salias agi="apt-get install"
761     salias ati="aptitude install"
762     salias ag="apt-get upgrade"
763     salias au="apt-get update"
764     salias -a up="aptitude update ; aptitude upgrade"
765     alias dbp='dpkg-buildpackage'
766     alias ge='grep-excuses'
767
768     # debian upgrade
769     upgrade () {
770       if [ -z "$1" ] ; then
771           $SUDO apt-get update
772           $SUDO apt-get -u upgrade
773       else
774           ssh $1 $SUDO apt-get update
775           # ask before the upgrade
776           local dummy
777           ssh $1 $SUDO apt-get --no-act upgrade
778           echo -n 'Process the upgrade?'
779           read -q dummy
780           if [[ $dummy == "y" ]] ; then
781               ssh $1 $SUDO apt-get -u upgrade --yes
782           fi
783       fi
784     }
785
786     isgrmlcd && alias su="sudo su"          # change to user root
787     alias tlog="tail -f /var/log/syslog"    # take a look at the syslog
788     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
789   fi
790
791 # sort installed Debian-packages by size
792   if [ -x $(which grep-status) ] ; then
793      alias debs-by-size='grep-status -FStatus -sInstalled-Size,Package \
794                 -n "install ok installed" | paste -sd "  \n" | sort -rn'
795   fi
796
797 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
798   if [ -L /usr/bin/cdrecord -o ! -x $(which cdrecord) ] ; then
799      if [ -x $(which wodim) ] ; then
800         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
801 See #377109 in the BTS of Debian for more details.
802
803 Please use the wodim binary instead' ; return 1"
804      fi
805   fi
806
807 # get_tw_cli has been renamed into get_3ware
808   if [ -x $(which get_3ware) ] ; then
809      get_tw_cli() {
810        echo 'Warning: get_tw_cli has been renamed into get_3ware. Invoking get_3ware for you.'>&2
811        get_3ware
812      }
813   fi
814
815 # I hate lacking backward compability, so provide an alternative therefore
816   if ! [ -x $(which apache2-ssl-certificate) ] ; then
817    function apache2-ssl-certificate(){
818
819      print 'Debian does not ship apache2-ssl-certificate anymore (see #398520). :('
820      print 'You might want to take a look at Debian the package ssl-cert as well.'
821      print 'To generate a certificate for use with apache2 follow the instructions:'
822
823      echo '
824
825 export RANDFILE=/dev/random
826 mkdir /etc/apache2/ssl/
827 openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
828 chmod 600 /etc/apache2/ssl/apache.pem
829
830 Run "grml-tips ssl-certificate" if you need further instructions.
831 '
832    }
833   fi
834 # }}}
835
836 # {{{ Use hard limits, except for a smaller stack and no core dumps
837   unlimit
838   limit stack 8192
839   isgrmlcd && limit core 0 # important for a live-cd-system
840   limit -s
841 # }}}
842
843 # {{{ completion stuff
844
845 # called later (via is4 && grmlcomp)
846 # notice: use 'zstyle' for getting current settings
847 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
848 grmlcomp() {
849 ## completion system
850   zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )' # allow one error for every three characters typed in approximate completer
851   zstyle ':completion:*:complete:-command-::commands' ignored-patterns '*\~' # don't complete backup files as executables
852   zstyle ':completion:*:correct:*'       insert-unambiguous true             # start menu completion only if it could find no unambiguous initial string
853   zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}' #
854   zstyle ':completion:*:correct:*'       original true                       #
855   zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}      # activate color-completion(!)
856   zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'  # format on completion
857   zstyle ':completion:*:*:cd:*:directory-stack' menu yes select              # complete 'cd -<tab>' with menu
858   zstyle ':completion:*:expand:*'        tag-order all-expansions            # insert all expansions for expand completer
859   zstyle ':completion:*:history-words'   list false                          #
860   zstyle ':completion:*:history-words'   menu yes                            # activate menu
861   zstyle ':completion:*:history-words'   remove-all-dups yes                 # ignore duplicate entries
862   zstyle ':completion:*:history-words'   stop yes                            #
863   zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'        # match uppercase from lowercase
864   zstyle ':completion:*:matches'         group 'yes'                         # separate matches into groups
865   zstyle ':completion:*'                 group-name ''
866   if [[ -z "$NOMENU" ]] ; then
867     zstyle ':completion:*'               menu select=5                       # if there are more than 5 options allow selecting from a menu
868   else
869     setopt no_auto_menu # don't use any menus at all
870   fi
871   zstyle ':completion:*:messages'        format '%d'                         #
872   zstyle ':completion:*:options'         auto-description '%d'               #
873   zstyle ':completion:*:options'         description 'yes'                   # describe options in full
874   zstyle ':completion:*:processes'       command 'ps -au$USER'               # on processes completion complete all user processes
875   zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters        # offer indexes before parameters in subscripts
876   zstyle ':completion:*'                 verbose true                        # provide verbose completion information
877   zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' # set format for warnings
878   zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'       # define files to ignore for zcompile
879   zstyle ':completion:correct:'          prompt 'correct to: %e'             #
880   zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'    # Ignore completion functions for commands you don't have:
881
882 # complete manual by their section
883   zstyle ':completion:*:manuals'    separate-sections true
884   zstyle ':completion:*:manuals.*'  insert-sections   true
885   zstyle ':completion:*:man:*'      menu yes select
886
887 ## correction
888 # run rehash on completion so new installed program are found automatically:
889   _force_rehash() {
890       (( CURRENT == 1 )) && rehash
891          return 1 # Because we didn't really complete anything
892     }
893 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
894   if [[ -n "$NOCOR" ]] ; then
895     zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files
896     setopt nocorrect # do not try to correct the spelling if possible
897   else
898 #    zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _correct _approximate _files
899     setopt correct  # try to correct the spelling if possible
900     zstyle -e ':completion:*' completer '
901         if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]]; then
902           _last_try="$HISTNO$BUFFER$CURSOR"
903           reply=(_complete _match _prefix _files)
904         else
905           if [[ $words[1] = (rm|mv) ]]; then
906             reply=(_complete _files)
907           else
908             reply=(_oldlist _expand _force_rehash _complete _correct _approximate _files)
909           fi
910         fi'
911   fi
912 # zstyle ':completion:*' completer _complete _correct _approximate
913 # zstyle ':completion:*' expand prefix suffix
914
915 # automatic rehash? Credits go to Frank Terbeck
916 # function my_accept () {
917 #   local buf
918 #   [[ -z ${BUFFER} ]] && zle accept-line && return
919 #   buf=( ${(z)BUFFER}  )
920 #   [[ -z ${commands[${buf[1]}]} ]] && rehash
921 #   zle accept-line
922 # }
923 # zle -N my_accept
924 # bindkey "^M" my_accept
925
926 # command for process lists, the local web server details and host completion
927   zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
928
929 # caching
930   [ -d $ZSHDIR/cache ] && zstyle ':completion:*' use-cache yes && \
931                           zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
932
933 # host completion /* add brackets as vim can't parse zsh's complex cmdlines 8-) {{{ */
934   if is42 ; then
935     [ -r ~/.ssh/known_hosts ] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
936     [ -r /etc/hosts ] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
937   else
938     _ssh_hosts=()
939     _etc_hosts=()
940   fi
941   hosts=(
942       `hostname`
943       "$_ssh_hosts[@]"
944       "$_etc_hosts[@]"
945       grml.org
946       localhost
947   )
948   zstyle ':completion:*:hosts' hosts $hosts
949 #  zstyle '*' hosts $hosts
950
951 # specify your logins:
952 # my_accounts=(
953 #  {grml,grml1}@foo.invalid
954 #  grml-devel@bar.invalid
955 # )
956 # other_accounts=(
957 #  {fred,root}@foo.invalid
958 #  vera@bar.invalid
959 # )
960 # zstyle ':completion:*:my-accounts' users-hosts $my_accounts
961 # zstyle ':completion:*:other-accounts' users-hosts $other_accounts
962
963 # specify specific port/service settings:
964 #  telnet_users_hosts_ports=(
965 #    user1@host1:
966 #    user2@host2:
967 #    @mail-server:{smtp,pop3}
968 #    @news-server:nntp
969 #    @proxy-server:8000
970 #  )
971 # zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
972
973 # use generic completion system for programs not yet defined:
974   compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
975
976 # see upgrade function in this file
977   compdef _hosts upgrade
978 }
979 # }}}
980
981 # {{{ grmlstuff
982 grmlstuff() {
983 # people should use 'grml-x'!
984   function startx() {
985     if [ -e /etc/X11/xorg.conf ] ; then
986        [ -x /usr/bin/startx ] && /usr/bin/startx || /usr/X11R6/bin/startx
987     else
988       echo "Please use the script \"grml-x\" for starting the X Window System
989 because there does not exist /etc/X11/xorg.conf yet.
990 If you want to use startx anyway please call \"/usr/bin/startx\"."
991       return -1
992     fi
993   }
994
995   function xinit() {
996     if [ -e /etc/X11/xorg.conf ] ; then
997        [ -x /usr/bin/xinit ] && /usr/bin/xinit || /usr/X11R6/bin/xinit
998     else
999       echo "Please use the script \"grml-x\" for starting the X Window System.
1000 because there does not exist /etc/X11/xorg.conf yet.
1001 If you want to use xinit anyway please call \"/usr/bin/xinit\"."
1002       return -1
1003     fi
1004   }
1005
1006   if [ -x $(which 915resolution) ] ; then
1007      alias 855resolution='echo -e "Please use 915resolution as resolution modify tool for Intel graphic chipset."; return -1'
1008   fi
1009
1010   alias grml-version='cat /etc/grml_version'
1011
1012   if [ -x $(which rebuildfstab) ] ; then
1013      alias grml-rebuildfstab='rebuildfstab -v -r -config'
1014   fi
1015
1016   if [ -x $(which grml-debootstrap) ] ; then
1017      alias debian2hd='print "Installing debian to harddisk is possible via using grml-debootstrap." ; return 1'
1018   fi
1019 }
1020 # }}}
1021
1022 # {{{ now run the functions
1023   isgrml && checkhome
1024   is4    && isgrml    && grmlstuff
1025   is4    && grmlcomp
1026 # }}}
1027
1028 # {{{ keephack
1029   [ -r /etc/zsh/keephack ] && is4 && source /etc/zsh/keephack
1030 # }}}
1031
1032 # {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson
1033 # You use it as follows:
1034 # $ NTREF=/reference/file
1035 # $ ls -l *(e:nt:)
1036 # This lists all the files in the current directory newer than the reference file.
1037 # You can also specify the reference file inline; note quotes:
1038 # $ ls -l *(e:'nt ~/.zshenv':)
1039   is4 && nt() {
1040     if [[ -n $1 ]]; then
1041       local NTREF=${~1}
1042     fi
1043     [[ $REPLY -nt $NTREF ]]
1044   }
1045 # }}}
1046
1047 # shell functions {{{
1048   setenv()  { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }  # csh compatibility
1049   freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
1050   reload () {
1051    if [[ "$#*" -eq 0 ]]; then
1052       [ -r ~/.zshrc ] && . ~/.zshrc
1053    else
1054       local fn
1055       for fn in "$@"; do
1056           unfunction $fn
1057           autoload -U $fn
1058       done
1059    fi
1060   }
1061   compdef _functions reload freload
1062
1063   # list symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
1064   sll() {
1065     [ -z "$1" ] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
1066     for i in "$@" ; do
1067       file=$i
1068       while [ -h "$file" ] ; do
1069         ls -l $file
1070         file=$(readlink "$file")
1071       done
1072     done
1073   }
1074
1075   # fast manual access
1076   if type -p qma &>/dev/null ; then
1077      manzsh()  { qma zshall "$1" }
1078      compdef _man qma
1079   else
1080      manzsh()  { /usr/bin/man zshall |  vim -c "se ft=man| se hlsearch" +/"$1" - ; }
1081      # manzsh()  { /usr/bin/man zshall |  most +/"$1" ; }
1082      # manzsh()  { man zshall | $MYLESS -p $1 ; }
1083   fi
1084
1085   if [ -x $(which most) ] ; then
1086   # use "dchange <package-name>" to view Debian's changelog of the package:
1087     dchange() {
1088       if [ -r /usr/share/doc/${1}/changelog.Debian.gz ] ; then
1089          most /usr/share/doc/${1}/changelog.Debian.gz
1090       else
1091          if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1092             most /usr/share/doc/${1}/changelog.gz
1093          else
1094             echo "No changelog for package $1 found, sorry."
1095             return 1
1096          fi
1097       fi
1098     }
1099     _dchange() { _files -W /usr/share/doc -/ }
1100     compdef _dchange dchange
1101
1102   # use "uchange <package-name>" to view upstream's changelog of the package:
1103     uchange() {
1104       if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1105          most /usr/share/doc/${1}/changelog.gz
1106       else
1107          echo "No changelog for package $1 found, sorry."
1108          return 1
1109       fi
1110     }
1111     _uchange() { _files -W /usr/share/doc -/ }
1112     compdef _uchange uchange
1113   fi
1114
1115 # zsh profiling
1116   profile () {
1117       ZSH_PROFILE_RC=1 $SHELL "$@"
1118   }
1119
1120 # edit alias via zle:
1121   edalias() {
1122     [ -z "$1" ] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
1123   }
1124   compdef _aliases edalias
1125
1126 # edit function via zle:
1127   edfunc() {
1128     [ -z "$1" ] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
1129   }
1130   compdef _functions edfunc
1131
1132 # use it e.g. via 'Restart apache2'
1133  if [ -d /etc/init.d ] ; then
1134   for i in Start Restart Stop Force-Reload Reload ; do
1135     eval "$i() { $SUDO /etc/init.d/\$1 ${i:l} \$2 ; }"
1136   done
1137   # now the completion for this:
1138   compctl -g "$(echo /etc/init.d/*(:t))" Start Restart Stop Force-Reload Reload
1139  fi
1140
1141 # provide useful information on globbing
1142   H-Glob() {
1143   echo -e "
1144       /      directories
1145       .      plain files
1146       @      symbolic links
1147       =      sockets
1148       p      named pipes (FIFOs)
1149       *      executable plain files (0100)
1150       %      device files (character or block special)
1151       %b     block special files
1152       %c     character special files
1153       r      owner-readable files (0400)
1154       w      owner-writable files (0200)
1155       x      owner-executable files (0100)
1156       A      group-readable files (0040)
1157       I      group-writable files (0020)
1158       E      group-executable files (0010)
1159       R      world-readable files (0004)
1160       W      world-writable files (0002)
1161       X      world-executable files (0001)
1162       s      setuid files (04000)
1163       S      setgid files (02000)
1164       t      files with the sticky bit (01000)
1165
1166    print *(m-1)          # Files modified up to a day ago
1167    print *(a1)           # Files accessed a day ago
1168    print *(@)            # Just symlinks
1169    print *(Lk+50)        # Files bigger than 50 kilobytes
1170    print *(Lk-50)        # Files smaller than 50 kilobytes
1171    print **/*.c          # All *.c files recursively starting in \$PWD
1172    print **/*.c~file.c   # Same as above, but excluding 'file.c'
1173    print (foo|bar).*     # Files starting with 'foo' or 'bar'
1174    print *~*.*           # All Files that do not contain a dot
1175    chmod 644 *(.^x)      # make all plain non-executable files publically readable
1176    print -l *(.c|.h)     # Lists *.c and *.h
1177    print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
1178    echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
1179   }
1180   alias help-zshglob=H-Glob
1181
1182   type -p qma &>/dev/null && alias ?='qma zshall'
1183
1184   # grep for running process, like: 'any vim'
1185   any() {
1186   if [ -z "$1" ] ; then
1187      echo "any - grep for process(es) by keyword" >&2
1188      echo "Usage: any <keyword>" >&2 ; return 1
1189   else
1190      local STRING=$1
1191      local LENGTH=$(expr length $STRING)
1192      local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
1193      local REST=$(echo $(expr substr $STRING 2 $LENGTH))
1194      ps xauwww| grep "[$FIRSCHAR]$REST"
1195   fi
1196   }
1197
1198   # After resuming from suspend, system is paging heavilly, leading to very bad interactivity.
1199   # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
1200   [ -r /proc/1/maps ] && deswap() {
1201      print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
1202      cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
1203      print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
1204   }
1205
1206   # print hex value of a number
1207   hex() {
1208     [ -n "$1" ] && printf "%x\n" $1 || { print 'Usage: hex <number-to-convert>' ; return 1 }
1209   }
1210
1211   # calculate (or eval at all ;-)) with perl => p[erl-]eval
1212   # hint: also take a look at zcalc -> 'autoload zcalc' -> 'man zshmodules | less -p MATHFUNC'
1213   peval() {
1214     [ -n "$1" ] && CALC="$*" || print "Usage: calc [expression]"
1215     perl -e "print eval($CALC),\"\n\";"
1216   }
1217   functions peval &>/dev/null && alias calc=peval
1218
1219   # brltty seems to have problems with utf8 environment and/or font Uni3-Terminus16 under
1220   # certain circumstances, so work around it, no matter which environment we have
1221   brltty() {
1222     if [ -z "$DISPLAY" ] ; then
1223        consolechars -f /usr/share/consolefonts/default8x16.psf.gz
1224        command brltty "$@"
1225     else
1226        command brltty "$@"
1227     fi
1228   }
1229
1230   # Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
1231   # bash() {
1232   #  NO_SWITCH="yes" command bash "$@"
1233   # }
1234   # restart () {
1235   #  exec $SHELL $SHELL_ARGS "$@"
1236   # }
1237
1238 # }}}
1239
1240 # log out? set timeout in seconds {{{
1241 # TMOUT=1800
1242 # do not log out in some specific terminals:
1243 #  if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]]; then
1244 #    unset TMOUT
1245 #  fi
1246 # }}}
1247
1248 # {{{ make sure our environment is clean regarding colors
1249   for color in BLUE RED GREEN CYAN WHITE ; unset $color
1250 # }}}
1251
1252 # source another config file if present {{{
1253   if [ -r /etc/zsh/zshrc.local ]; then
1254    source /etc/zsh/zshrc.local
1255   fi
1256 # }}}
1257
1258 # "persistent history" {{{
1259 # just write important commands you always need to ~/.important_commands
1260   if [ -r ~/.important_commands ] ; then
1261      fc -R ~/.important_commands
1262   fi
1263 # }}}
1264
1265 ## END OF FILE #################################################################
1266 # vim:foldmethod=marker expandtab