dchange() function: remove hardcoded option
[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   [[ -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   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 # truecrypt; use e.g. via 'truec /dev/ice /mnt/ice' or 'truec -i'
843   if [ -x $(which truecrypt) ] ; then
844      if isutfenv ; then
845         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077,utf8" '
846      else
847         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077" '
848      fi
849   fi
850
851 #f1# Hints for the use of zsh on grml
852   zsh-help(){print "$bg[white]$fg[black]
853 zsh-help - hints for use of zsh on grml
854 =======================================$reset_color
855
856 Main configuration of zsh happens in /etc/zsh/zshrc (global)
857 and /etc/skel/.zshrc which is copied to \$HOME/.zshrc once.
858 The files are part of the package grml-etc-core, if you want to
859 use them on a non-grml-system just get the tar.gz from
860 http://deb.grml.org/ or get the files from the mercurial
861 repository:
862
863   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
864   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
865
866 If you want to stay in sync with zsh configuration of grml
867 run 'ln -sf /etc/skel/.zshrc \$HOME/.zshrc' and configure
868 your own stuff in \$HOME/.zshrc.local. System wide configuration
869 without touching configuration files of grml can take place
870 in /etc/zsh/zshrc.local.
871
872 If you want to use the configuration of user grml also when
873 running as user root just run 'zshskel' which will source
874 the file /etc/skel/.zshrc.
875
876 For information regarding zsh start at http://grml.org/zsh/
877
878 Take a look at grml's zsh refcard:
879 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
880
881 Check out the main zsh refcard:
882 % $BROWSER http://www.bash2zsh.com/zsh_refcard/refcard.pdf
883
884 And of course visit the zsh-lovers:
885 % man zsh-lovers
886
887 You can adjust some options through environment variables when
888 invoking zsh without having to edit configuration files.
889 Basically meant for bash users who are not used to the power of
890 the zsh yet. :)
891
892   \"NOCOR=1    zsh\" => deactivate automatic correction
893   \"NOMENU=1   zsh\" => do not use menu completion (note: use strg-d for completion instead!)
894   \"NOPRECMD=1 zsh\" => disable the precmd + preexec commands (set GNU screen title)
895   \"BATTERY=1  zsh\" => activate battery status (via acpi) on right side of prompt
896 $bg[white]$fg[black]
897 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
898 Enjoy your grml system with the zsh!$reset_color"
899 }
900
901 # debian stuff
902   if [ -r /etc/debian_version ] ; then
903     #a3# Execute \kbd{apt-cache search}
904     alias acs='apt-cache search'
905     #a3# Execute \kbd{apt-cache show}
906     alias acsh='apt-cache show'
907     #a3# Execute \kbd{apt-cache policy}
908     alias acp='apt-cache policy'
909     #a3# Execute \kbd{apt-get dist-upgrade}
910     salias adg="apt-get dist-upgrade"
911     #a3# Execute \kbd{apt-get install}
912     salias agi="apt-get install"
913     #a3# Execute \kbd{aptitude install}
914     salias ati="aptitude install"
915     #a3# Execute \kbd{apt-get upgrade}
916     salias ag="apt-get upgrade"
917     #a3# Execute \kbd{apt-get update}
918     salias au="apt-get update"
919     #a3# Execute \kbd{aptitude update ; aptitude upgrade}
920     salias -a up="aptitude update ; aptitude upgrade"
921     #a3# Execute \kbd{dpkg-buildpackage}
922     alias dbp='dpkg-buildpackage'
923     #a3# Execute \kbd{grep-excuses}
924     alias ge='grep-excuses'
925
926     # debian upgrade
927     #f3# Execute \kbd{apt-get update \&\& }\\&\quad \kbd{apt-get dist-upgrade}
928     upgrade () {
929       if [ -z "$1" ] ; then
930           $SUDO apt-get update
931           $SUDO apt-get -u upgrade
932       else
933           ssh $1 $SUDO apt-get update
934           # ask before the upgrade
935           local dummy
936           ssh $1 $SUDO apt-get --no-act upgrade
937           echo -n 'Process the upgrade?'
938           read -q dummy
939           if [[ $dummy == "y" ]] ; then
940               ssh $1 $SUDO apt-get -u upgrade --yes
941           fi
942       fi
943     }
944
945     isgrmlcd && alias su="sudo -s"          # get a root shell
946     #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
947     alias llog="$PAGER /var/log/syslog"     # take a look at the syslog
948     #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
949     alias tlog="tail -f /var/log/syslog"    # follow the syslog
950     #a1# (Re)-source \kbd{/etc/skel/.zshrc}
951     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
952   fi
953
954 # sort installed Debian-packages by size
955   if [ -x $(which grep-status) ] ; then
956      #a3# List installed Debian-packages sorted by size
957      alias debs-by-size='grep-status -FStatus -sInstalled-Size,Package -n "install ok installed" | paste -sd "  \n" | sort -rn'
958   fi
959
960 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
961   if [ -L /usr/bin/cdrecord -o ! -x $(which cdrecord) ] ; then
962      if [ -x $(which wodim) ] ; then
963         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
964 See #377109 in the BTS of Debian for more details.
965
966 Please use the wodim binary instead' ; return 1"
967      fi
968   fi
969
970 # get_tw_cli has been renamed into get_3ware
971   if [ -x $(which get_3ware) ] ; then
972      get_tw_cli() {
973        echo 'Warning: get_tw_cli has been renamed into get_3ware. Invoking get_3ware for you.'>&2
974        get_3ware
975      }
976   fi
977
978 # I hate lacking backward compatibility, so provide an alternative therefore
979   if ! [ -x $(which apache2-ssl-certificate) ] ; then
980      apache2-ssl-certificate(){
981
982      print 'Debian does not ship apache2-ssl-certificate anymore (see #398520). :('
983      print 'You might want to take a look at Debian the package ssl-cert as well.'
984      print 'To generate a certificate for use with apache2 follow the instructions:'
985
986      echo '
987
988 export RANDFILE=/dev/random
989 mkdir /etc/apache2/ssl/
990 openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
991 chmod 600 /etc/apache2/ssl/apache.pem
992
993 Run "grml-tips ssl-certificate" if you need further instructions.
994 '
995    }
996   fi
997 # }}}
998
999 # {{{ Use hard limits, except for a smaller stack and no core dumps
1000   unlimit
1001   limit stack 8192
1002   isgrmlcd && limit core 0 # important for a live-cd-system
1003   limit -s
1004 # }}}
1005
1006 # {{{ completion stuff
1007
1008 # called later (via is4 && grmlcomp)
1009 # notice: use 'zstyle' for getting current settings
1010 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
1011 grmlcomp() {
1012 ## completion system
1013   zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )' # allow one error for every three characters typed in approximate completer
1014   zstyle ':completion:*:complete:-command-::commands' ignored-patterns '*\~' # don't complete backup files as executables
1015   zstyle ':completion:*:correct:*'       insert-unambiguous true             # start menu completion only if it could find no unambiguous initial string
1016   zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}' #
1017   zstyle ':completion:*:correct:*'       original true                       #
1018   zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}      # activate color-completion(!)
1019   zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'  # format on completion
1020   zstyle ':completion:*:*:cd:*:directory-stack' menu yes select              # complete 'cd -<tab>' with menu
1021   zstyle ':completion:*:expand:*'        tag-order all-expansions            # insert all expansions for expand completer
1022   zstyle ':completion:*:history-words'   list false                          #
1023   zstyle ':completion:*:history-words'   menu yes                            # activate menu
1024   zstyle ':completion:*:history-words'   remove-all-dups yes                 # ignore duplicate entries
1025   zstyle ':completion:*:history-words'   stop yes                            #
1026   zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'        # match uppercase from lowercase
1027   zstyle ':completion:*:matches'         group 'yes'                         # separate matches into groups
1028   zstyle ':completion:*'                 group-name ''
1029   if [[ -z "$NOMENU" ]] ; then
1030     zstyle ':completion:*'               menu select=5                       # if there are more than 5 options allow selecting from a menu
1031   else
1032     setopt no_auto_menu # don't use any menus at all
1033   fi
1034   zstyle ':completion:*:messages'        format '%d'                         #
1035   zstyle ':completion:*:options'         auto-description '%d'               #
1036   zstyle ':completion:*:options'         description 'yes'                   # describe options in full
1037   zstyle ':completion:*:processes'       command 'ps -au$USER'               # on processes completion complete all user processes
1038   zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters        # offer indexes before parameters in subscripts
1039   zstyle ':completion:*'                 verbose true                        # provide verbose completion information
1040   zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' # set format for warnings
1041   zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'       # define files to ignore for zcompile
1042   zstyle ':completion:correct:'          prompt 'correct to: %e'             #
1043   zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'    # Ignore completion functions for commands you don't have:
1044
1045 # complete manual by their section
1046   zstyle ':completion:*:manuals'    separate-sections true
1047   zstyle ':completion:*:manuals.*'  insert-sections   true
1048   zstyle ':completion:*:man:*'      menu yes select
1049
1050 ## correction
1051 # run rehash on completion so new installed program are found automatically:
1052   _force_rehash() {
1053       (( CURRENT == 1 )) && rehash
1054          return 1 # Because we didn't really complete anything
1055     }
1056 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
1057   if [[ -n "$NOCOR" ]] ; then
1058     zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files
1059     setopt nocorrect # do not try to correct the spelling if possible
1060   else
1061 #    zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _correct _approximate _files
1062     setopt correct  # try to correct the spelling if possible
1063     zstyle -e ':completion:*' completer '
1064         if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]]; then
1065           _last_try="$HISTNO$BUFFER$CURSOR"
1066           reply=(_complete _match _prefix _files)
1067         else
1068           if [[ $words[1] = (rm|mv) ]]; then
1069             reply=(_complete _files)
1070           else
1071             reply=(_oldlist _expand _force_rehash _complete _correct _approximate _files)
1072           fi
1073         fi'
1074   fi
1075 # zstyle ':completion:*' completer _complete _correct _approximate
1076 # zstyle ':completion:*' expand prefix suffix
1077
1078 # automatic rehash? Credits go to Frank Terbeck
1079 # my_accept() {
1080 #   local buf
1081 #   [[ -z ${BUFFER} ]] && zle accept-line && return
1082 #   buf=( ${(z)BUFFER}  )
1083 #   [[ -z ${commands[${buf[1]}]} ]] && rehash
1084 #   zle accept-line
1085 # }
1086 # zle -N my_accept
1087 # bindkey "^M" my_accept
1088
1089 # command for process lists, the local web server details and host completion
1090   zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
1091
1092 # caching
1093   [ -d $ZSHDIR/cache ] && zstyle ':completion:*' use-cache yes && \
1094                           zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
1095
1096 # host completion /* add brackets as vim can't parse zsh's complex cmdlines 8-) {{{ */
1097   if is42 ; then
1098     [ -r ~/.ssh/known_hosts ] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
1099     [ -r /etc/hosts ] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
1100   else
1101     _ssh_hosts=()
1102     _etc_hosts=()
1103   fi
1104   hosts=(
1105       `hostname`
1106       "$_ssh_hosts[@]"
1107       "$_etc_hosts[@]"
1108       grml.org
1109       localhost
1110   )
1111   zstyle ':completion:*:hosts' hosts $hosts
1112 #  zstyle '*' hosts $hosts
1113
1114 # specify your logins:
1115 # my_accounts=(
1116 #  {grml,grml1}@foo.invalid
1117 #  grml-devel@bar.invalid
1118 # )
1119 # other_accounts=(
1120 #  {fred,root}@foo.invalid
1121 #  vera@bar.invalid
1122 # )
1123 # zstyle ':completion:*:my-accounts' users-hosts $my_accounts
1124 # zstyle ':completion:*:other-accounts' users-hosts $other_accounts
1125
1126 # specify specific port/service settings:
1127 #  telnet_users_hosts_ports=(
1128 #    user1@host1:
1129 #    user2@host2:
1130 #    @mail-server:{smtp,pop3}
1131 #    @news-server:nntp
1132 #    @proxy-server:8000
1133 #  )
1134 # zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
1135
1136 # use generic completion system for programs not yet defined:
1137   compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
1138
1139 # see upgrade function in this file
1140   compdef _hosts upgrade
1141 }
1142 # }}}
1143
1144 # {{{ grmlstuff
1145 grmlstuff() {
1146 # people should use 'grml-x'!
1147   startx() {
1148     if [ -e /etc/X11/xorg.conf ] ; then
1149        [ -x /usr/bin/startx ] && /usr/bin/startx || /usr/X11R6/bin/startx
1150     else
1151       echo "Please use the script \"grml-x\" for starting the X Window System
1152 because there does not exist /etc/X11/xorg.conf yet.
1153 If you want to use startx anyway please call \"/usr/bin/startx\"."
1154       return -1
1155     fi
1156   }
1157
1158   xinit() {
1159     if [ -e /etc/X11/xorg.conf ] ; then
1160        [ -x /usr/bin/xinit ] && /usr/bin/xinit || /usr/X11R6/bin/xinit
1161     else
1162       echo "Please use the script \"grml-x\" for starting the X Window System.
1163 because there does not exist /etc/X11/xorg.conf yet.
1164 If you want to use xinit anyway please call \"/usr/bin/xinit\"."
1165       return -1
1166     fi
1167   }
1168
1169   if [ -x $(which 915resolution) ] ; then
1170      alias 855resolution='echo -e "Please use 915resolution as resolution modify tool for Intel graphic chipset."; return -1'
1171   fi
1172
1173   #a1# Output version of running grml
1174   alias grml-version='cat /etc/grml_version'
1175
1176   if [ -x $(which rebuildfstab) ] ; then
1177      #a1# Rebuild /etc/fstab
1178      alias grml-rebuildfstab='rebuildfstab -v -r -config'
1179   fi
1180
1181   if [ -x $(which grml-debootstrap) ] ; then
1182      alias debian2hd='print "Installing debian to harddisk is possible via using grml-debootstrap." ; return 1'
1183   fi
1184 }
1185 # }}}
1186
1187 # {{{ now run the functions
1188   isgrml && checkhome
1189   is4    && isgrml    && grmlstuff
1190   is4    && grmlcomp
1191 # }}}
1192
1193 # {{{ keephack
1194   [ -r /etc/zsh/keephack ] && is4 && source /etc/zsh/keephack
1195 # }}}
1196
1197 # {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson
1198 # You use it as follows:
1199 # $ NTREF=/reference/file
1200 # $ ls -l *(e:nt:)
1201 # This lists all the files in the current directory newer than the reference file.
1202 # You can also specify the reference file inline; note quotes:
1203 # $ ls -l *(e:'nt ~/.zshenv':)
1204   is4 && nt() {
1205     if [[ -n $1 ]]; then
1206       local NTREF=${~1}
1207     fi
1208     [[ $REPLY -nt $NTREF ]]
1209   }
1210 # }}}
1211
1212 # shell functions {{{
1213   #f1# Provide csh compatibility
1214   setenv()  { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }  # csh compatibility
1215   #f1# Reload an autoloadable function
1216   freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
1217   #f1# Reload zsh setup
1218   reload () {
1219    if [[ "$#*" -eq 0 ]]; then
1220       [ -r ~/.zshrc ] && . ~/.zshrc
1221    else
1222       local fn
1223       for fn in "$@"; do
1224           unfunction $fn
1225           autoload -U $fn
1226       done
1227    fi
1228   }
1229   compdef _functions reload freload
1230
1231   #f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
1232   sll() {
1233     [ -z "$1" ] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
1234     for i in "$@" ; do
1235       file=$i
1236       while [ -h "$file" ] ; do
1237         ls -l $file
1238         file=$(readlink "$file")
1239       done
1240     done
1241   }
1242
1243   # fast manual access
1244   if type -p qma &>/dev/null ; then
1245   #f1# View the zsh manual
1246      manzsh()  { qma zshall "$1" }
1247      compdef _man qma
1248   else
1249      manzsh()  { /usr/bin/man zshall |  vim -c "se ft=man| se hlsearch" +/"$1" - ; }
1250      # manzsh()  { /usr/bin/man zshall |  most +/"$1" ; }
1251      # manzsh()  { man zshall | $MYLESS -p $1 ; }
1252   fi
1253
1254   if [ -x $(which most) ] ; then
1255   #f1# View Debian's changelog of a given package
1256     dchange() {
1257       if [ -r /usr/share/doc/${1}/changelog.Debian.gz ] ; then
1258          most /usr/share/doc/${1}/changelog.Debian.gz
1259       else
1260          if type -p aptitude &>/dev/null ; then
1261             echo "No changelog for package $1 found, using aptitude to retrieve it."
1262             if isgrml ; then
1263               aptitude -t unstable changelog ${1}
1264             else
1265               aptitude changelog ${1}
1266             fi
1267          else
1268             echo "No changelog for package $1 found, sorry."
1269             return 1
1270          fi
1271       fi
1272     }
1273     _dchange() { _files -W /usr/share/doc -/ }
1274     compdef _dchange dchange
1275
1276   #f1# View Debian's NEWS of a given package
1277     dnews() {
1278       if [ -r /usr/share/doc/${1}/NEWS.Debian.gz ] ; then
1279          most /usr/share/doc/${1}/NEWS.Debian.gz
1280       else
1281          if [ -r /usr/share/doc/${1}/NEWS.gz ] ; then
1282             most /usr/share/doc/${1}/NEWS.gz
1283          else
1284             echo "No NEWS file for package $1 found, sorry."
1285             return 1
1286          fi
1287       fi
1288     }
1289     _dnews() { _files -W /usr/share/doc -/ }
1290     compdef _dnews dnews
1291
1292   #f1# View upstream's changelog of a given package
1293     uchange() {
1294       if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1295          most /usr/share/doc/${1}/changelog.gz
1296       else
1297          echo "No changelog for package $1 found, sorry."
1298          return 1
1299       fi
1300     }
1301     _uchange() { _files -W /usr/share/doc -/ }
1302     compdef _uchange uchange
1303   fi
1304
1305 # zsh profiling
1306   profile () {
1307       ZSH_PROFILE_RC=1 $SHELL "$@"
1308   }
1309
1310 #f1# Edit an alias via zle
1311   edalias() {
1312     [ -z "$1" ] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
1313   }
1314   compdef _aliases edalias
1315
1316 #f1# Edit a function via zle
1317   edfunc() {
1318     [ -z "$1" ] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
1319   }
1320   compdef _functions edfunc
1321
1322 # use it e.g. via 'Restart apache2'
1323 #m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
1324 #m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
1325 #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
1326 #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
1327 #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
1328  if [ -d /etc/init.d ] ; then
1329   for i in Start Restart Stop Force-Reload Reload ; do
1330     eval "$i() { $SUDO /etc/init.d/\$1 ${i:l} \$2 ; }"
1331   done
1332  fi
1333
1334   #f1# Provides useful information on globbing
1335   H-Glob() {
1336   echo -e "
1337       /      directories
1338       .      plain files
1339       @      symbolic links
1340       =      sockets
1341       p      named pipes (FIFOs)
1342       *      executable plain files (0100)
1343       %      device files (character or block special)
1344       %b     block special files
1345       %c     character special files
1346       r      owner-readable files (0400)
1347       w      owner-writable files (0200)
1348       x      owner-executable files (0100)
1349       A      group-readable files (0040)
1350       I      group-writable files (0020)
1351       E      group-executable files (0010)
1352       R      world-readable files (0004)
1353       W      world-writable files (0002)
1354       X      world-executable files (0001)
1355       s      setuid files (04000)
1356       S      setgid files (02000)
1357       t      files with the sticky bit (01000)
1358
1359    print *(m-1)          # Files modified up to a day ago
1360    print *(a1)           # Files accessed a day ago
1361    print *(@)            # Just symlinks
1362    print *(Lk+50)        # Files bigger than 50 kilobytes
1363    print *(Lk-50)        # Files smaller than 50 kilobytes
1364    print **/*.c          # All *.c files recursively starting in \$PWD
1365    print **/*.c~file.c   # Same as above, but excluding 'file.c'
1366    print (foo|bar).*     # Files starting with 'foo' or 'bar'
1367    print *~*.*           # All Files that do not contain a dot
1368    chmod 644 *(.^x)      # make all plain non-executable files publically readable
1369    print -l *(.c|.h)     # Lists *.c and *.h
1370    print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
1371    echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
1372   }
1373   alias help-zshglob=H-Glob
1374
1375   type -p qma &>/dev/null && alias ?='qma zshall'
1376
1377   # grep for running process, like: 'any vim'
1378   any() {
1379   if [ -z "$1" ] ; then
1380      echo "any - grep for process(es) by keyword" >&2
1381      echo "Usage: any <keyword>" >&2 ; return 1
1382   else
1383      local STRING=$1
1384      local LENGTH=$(expr length $STRING)
1385      local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
1386      local REST=$(echo $(expr substr $STRING 2 $LENGTH))
1387      ps xauwww| grep "[$FIRSCHAR]$REST"
1388   fi
1389   }
1390
1391   # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
1392   # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
1393   [ -r /proc/1/maps ] && deswap() {
1394      print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
1395      cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
1396      print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
1397   }
1398
1399   # print hex value of a number
1400   hex() {
1401     [ -n "$1" ] && printf "%x\n" $1 || { print 'Usage: hex <number-to-convert>' ; return 1 }
1402   }
1403
1404   # calculate (or eval at all ;-)) with perl => p[erl-]eval
1405   # hint: also take a look at zcalc -> 'autoload zcalc' -> 'man zshmodules | less -p MATHFUNC'
1406   peval() {
1407     [ -n "$1" ] && CALC="$*" || print "Usage: calc [expression]"
1408     perl -e "print eval($CALC),\"\n\";"
1409   }
1410   functions peval &>/dev/null && alias calc=peval
1411
1412   # brltty seems to have problems with utf8 environment and/or font Uni3-Terminus16 under
1413   # certain circumstances, so work around it, no matter which environment we have
1414   brltty() {
1415     if [ -z "$DISPLAY" ] ; then
1416        consolechars -f /usr/share/consolefonts/default8x16.psf.gz
1417        command brltty "$@"
1418     else
1419        command brltty "$@"
1420     fi
1421   }
1422
1423   # just press 'asdf' keys to toggle between dvorak and us keyboard layout
1424   aoeu() {
1425      echo -n 'Switching to us keyboard layout: '
1426      [ -z "$DISPLAY" ] && $SUDO loadkeys us &>/dev/null || setxkbmap us &>/dev/null
1427      echo 'Done'
1428   }
1429   asdf() {
1430      echo -n 'Switching to dvorak keyboard layout: '
1431      [ -z "$DISPLAY" ] && $SUDO loadkeys dvorak &>/dev/null || setxkbmap dvorak &>/dev/null
1432      echo 'Done'
1433   }
1434   # just press 'asdf' key to toggle from neon layout to us keyboard layout
1435   uiae() {
1436      echo -n 'Switching to us keyboard layout: '
1437      setxkbmap us && echo 'Done' || echo 'Failed'
1438   }
1439
1440   # set up an ipv6 tunnel
1441   ipv6-tunnel() {
1442     case $1 in
1443       start)
1444        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1445           print 'ipv6 tunnel already set up, nothing to be done.'
1446           print 'execute: "ifconfig sit1 down ; ifconfig sit0 down" to remove ipv6-tunnel.' ; return 1
1447        else
1448           [ -n "$PUBLIC_IP" ] || local PUBLIC_IP=$(ifconfig $(route -n | awk '/^0\.0\.0\.0/{print $8; exit}') | \
1449                                              awk '/inet addr:/ {print $2}' | tr -d 'addr:')
1450           [ -n "$PUBLIC_IP" ] || { print 'No $PUBLIC_IP set and could not determine default one.' ; return 1 }
1451           local IPV6ADDR=$(printf "2002:%02x%02x:%02x%02x:1::1" $(print ${PUBLIC_IP//./ }))
1452           print -n "Setting up ipv6 tunnel $IPV6ADDR via ${PUBLIC_IP}: "
1453           ifconfig sit0 tunnel ::192.88.99.1 up
1454           ifconfig sit1 add "$IPV6ADDR" && print done || print failed
1455        fi
1456        ;;
1457       status)
1458        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1459           print 'ipv6 tunnel available' ; return 0
1460        else
1461           print 'ipv6 tunnel not available' ; return 1
1462        fi
1463        ;;
1464       stop)
1465        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1466           print -n 'Stopping ipv6 tunnel (sit0 + sit1): '
1467           ifconfig sit1 down ; ifconfig sit0 down && print done || print failed
1468        else
1469           print 'No ipv6 tunnel found, nothing to be done.' ; return 1
1470        fi
1471        ;;
1472       *)
1473        print "Usage: ipv6-tunnel [start|stop|status]">&2 ; return 1
1474        ;;
1475     esac
1476   }
1477
1478   # run dhclient for wireless device
1479   iwclient() {
1480     salias dhclient "$(wavemon -d | awk '/device/{print $2}')"
1481   }
1482
1483   # spawn a minimally set up ksh - useful if you want to umount /usr/.
1484   minimal-shell() {
1485     exec env -i ENV="/etc/minimal-shellrc" HOME="$HOME" TERM="$TERM" ksh
1486   }
1487
1488   # Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
1489   # bash() {
1490   #  NO_SWITCH="yes" command bash "$@"
1491   # }
1492   # restart () {
1493   #  exec $SHELL $SHELL_ARGS "$@"
1494   # }
1495
1496 # }}}
1497
1498 # log out? set timeout in seconds {{{
1499 # TMOUT=1800
1500 # do not log out in some specific terminals:
1501 #  if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]]; then
1502 #    unset TMOUT
1503 #  fi
1504 # }}}
1505
1506 # {{{ make sure our environment is clean regarding colors
1507   for color in BLUE RED GREEN CYAN WHITE ; unset $color
1508 # }}}
1509
1510 # source another config file if present {{{
1511   if [ -r /etc/zsh/zshrc.local ]; then
1512    source /etc/zsh/zshrc.local
1513   fi
1514 # }}}
1515
1516 # "persistent history" {{{
1517 # just write important commands you always need to ~/.important_commands
1518   if [ -r ~/.important_commands ] ; then
1519      fc -R ~/.important_commands
1520   fi
1521 # }}}
1522
1523 ## genrefcard.pl settings {{{
1524 ### example: split functions-search 8,16,24,32
1525 #@# split functions-search 8
1526 ## }}}
1527
1528 # add variable to be able to check whether the file has been read {{{
1529   ZSHRC_GLOBAL_HAS_BEEN_READ=1
1530 # }}}
1531
1532 ## END OF FILE #################################################################
1533 # vim:foldmethod=marker expandtab