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