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