Added aliases S, s, top10 and function weather()
[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 # 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 upgrade}
927     salias -a up="aptitude update ; aptitude 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 '*\~' # 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
1066     setopt nocorrect # do not try to correct the spelling if possible
1067   else
1068 #    zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _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 _prefix _files)
1074         else
1075           if [[ $words[1] = (rm|mv) ]]; then
1076             reply=(_complete _files)
1077           else
1078             reply=(_oldlist _expand _force_rehash _complete _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      # manzsh()  { man zshall | $MYLESS -p $1 ; }
1259   fi
1260
1261   if [ -x $(which most) ] ; then
1262   #f1# View Debian's changelog of a given package
1263     dchange() {
1264       if [ -r /usr/share/doc/${1}/changelog.Debian.gz ] ; then
1265          most /usr/share/doc/${1}/changelog.Debian.gz
1266       elif [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1267          most /usr/share/doc/${1}/changelog.gz
1268       else
1269          if type -p aptitude &>/dev/null ; then
1270             echo "No changelog for package $1 found, using aptitude to retrieve it."
1271             if isgrml ; then
1272               aptitude -t unstable changelog ${1}
1273             else
1274               aptitude changelog ${1}
1275             fi
1276          else
1277             echo "No changelog for package $1 found, sorry."
1278             return 1
1279          fi
1280       fi
1281     }
1282     _dchange() { _files -W /usr/share/doc -/ }
1283     compdef _dchange dchange
1284
1285   #f1# View Debian's NEWS of a given package
1286     dnews() {
1287       if [ -r /usr/share/doc/${1}/NEWS.Debian.gz ] ; then
1288          most /usr/share/doc/${1}/NEWS.Debian.gz
1289       else
1290          if [ -r /usr/share/doc/${1}/NEWS.gz ] ; then
1291             most /usr/share/doc/${1}/NEWS.gz
1292          else
1293             echo "No NEWS file for package $1 found, sorry."
1294             return 1
1295          fi
1296       fi
1297     }
1298     _dnews() { _files -W /usr/share/doc -/ }
1299     compdef _dnews dnews
1300
1301   #f1# View upstream's changelog of a given package
1302     uchange() {
1303       if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1304          most /usr/share/doc/${1}/changelog.gz
1305       else
1306          echo "No changelog for package $1 found, sorry."
1307          return 1
1308       fi
1309     }
1310     _uchange() { _files -W /usr/share/doc -/ }
1311     compdef _uchange uchange
1312   fi
1313
1314 # zsh profiling
1315   profile () {
1316       ZSH_PROFILE_RC=1 $SHELL "$@"
1317   }
1318
1319 #f1# Edit an alias via zle
1320   edalias() {
1321     [ -z "$1" ] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
1322   }
1323   compdef _aliases edalias
1324
1325 #f1# Edit a function via zle
1326   edfunc() {
1327     [ -z "$1" ] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
1328   }
1329   compdef _functions edfunc
1330
1331 # use it e.g. via 'Restart apache2'
1332 #m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
1333 #m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
1334 #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
1335 #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
1336 #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
1337  if [ -d /etc/init.d ] ; then
1338   for i in Start Restart Stop Force-Reload Reload ; do
1339     eval "$i() { $SUDO /etc/init.d/\$1 ${i:l} \$2 ; }"
1340   done
1341  fi
1342
1343   #f1# Provides useful information on globbing
1344   H-Glob() {
1345   echo -e "
1346       /      directories
1347       .      plain files
1348       @      symbolic links
1349       =      sockets
1350       p      named pipes (FIFOs)
1351       *      executable plain files (0100)
1352       %      device files (character or block special)
1353       %b     block special files
1354       %c     character special files
1355       r      owner-readable files (0400)
1356       w      owner-writable files (0200)
1357       x      owner-executable files (0100)
1358       A      group-readable files (0040)
1359       I      group-writable files (0020)
1360       E      group-executable files (0010)
1361       R      world-readable files (0004)
1362       W      world-writable files (0002)
1363       X      world-executable files (0001)
1364       s      setuid files (04000)
1365       S      setgid files (02000)
1366       t      files with the sticky bit (01000)
1367
1368    print *(m-1)          # Files modified up to a day ago
1369    print *(a1)           # Files accessed a day ago
1370    print *(@)            # Just symlinks
1371    print *(Lk+50)        # Files bigger than 50 kilobytes
1372    print *(Lk-50)        # Files smaller than 50 kilobytes
1373    print **/*.c          # All *.c files recursively starting in \$PWD
1374    print **/*.c~file.c   # Same as above, but excluding 'file.c'
1375    print (foo|bar).*     # Files starting with 'foo' or 'bar'
1376    print *~*.*           # All Files that do not contain a dot
1377    chmod 644 *(.^x)      # make all plain non-executable files publically readable
1378    print -l *(.c|.h)     # Lists *.c and *.h
1379    print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
1380    echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
1381   }
1382   alias help-zshglob=H-Glob
1383
1384   type -p qma &>/dev/null && alias ?='qma zshall'
1385
1386   # grep for running process, like: 'any vim'
1387   any() {
1388   if [ -z "$1" ] ; then
1389      echo "any - grep for process(es) by keyword" >&2
1390      echo "Usage: any <keyword>" >&2 ; return 1
1391   else
1392      local STRING=$1
1393      local LENGTH=$(expr length $STRING)
1394      local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
1395      local REST=$(echo $(expr substr $STRING 2 $LENGTH))
1396      ps xauwww| grep "[$FIRSCHAR]$REST"
1397   fi
1398   }
1399
1400   # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
1401   # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
1402   [ -r /proc/1/maps ] && deswap() {
1403      print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
1404      cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
1405      print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
1406   }
1407
1408   # print hex value of a number
1409   hex() {
1410     [ -n "$1" ] && printf "%x\n" $1 || { print 'Usage: hex <number-to-convert>' ; return 1 }
1411   }
1412
1413   # calculate (or eval at all ;-)) with perl => p[erl-]eval
1414   # hint: also take a look at zcalc -> 'autoload zcalc' -> 'man zshmodules | less -p MATHFUNC'
1415   peval() {
1416     [ -n "$1" ] && CALC="$*" || print "Usage: calc [expression]"
1417     perl -e "print eval($CALC),\"\n\";"
1418   }
1419   functions peval &>/dev/null && alias calc=peval
1420
1421   # brltty seems to have problems with utf8 environment and/or font Uni3-Terminus16 under
1422   # certain circumstances, so work around it, no matter which environment we have
1423   brltty() {
1424     if [ -z "$DISPLAY" ] ; then
1425        consolechars -f /usr/share/consolefonts/default8x16.psf.gz
1426        command brltty "$@"
1427     else
1428        command brltty "$@"
1429     fi
1430   }
1431
1432   # just press 'asdf' keys to toggle between dvorak and us keyboard layout
1433   aoeu() {
1434      echo -n 'Switching to us keyboard layout: '
1435      [ -z "$DISPLAY" ] && $SUDO loadkeys us &>/dev/null || setxkbmap us &>/dev/null
1436      echo 'Done'
1437   }
1438   asdf() {
1439      echo -n 'Switching to dvorak keyboard layout: '
1440      [ -z "$DISPLAY" ] && $SUDO loadkeys dvorak &>/dev/null || setxkbmap dvorak &>/dev/null
1441      echo 'Done'
1442   }
1443   # just press 'asdf' key to toggle from neon layout to us keyboard layout
1444   uiae() {
1445      echo -n 'Switching to us keyboard layout: '
1446      setxkbmap us && echo 'Done' || echo 'Failed'
1447   }
1448
1449   # set up an ipv6 tunnel
1450   ipv6-tunnel() {
1451     case $1 in
1452       start)
1453        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1454           print 'ipv6 tunnel already set up, nothing to be done.'
1455           print 'execute: "ifconfig sit1 down ; ifconfig sit0 down" to remove ipv6-tunnel.' ; return 1
1456        else
1457           [ -n "$PUBLIC_IP" ] || local PUBLIC_IP=$(ifconfig $(route -n | awk '/^0\.0\.0\.0/{print $8; exit}') | \
1458                                              awk '/inet addr:/ {print $2}' | tr -d 'addr:')
1459           [ -n "$PUBLIC_IP" ] || { print 'No $PUBLIC_IP set and could not determine default one.' ; return 1 }
1460           local IPV6ADDR=$(printf "2002:%02x%02x:%02x%02x:1::1" $(print ${PUBLIC_IP//./ }))
1461           print -n "Setting up ipv6 tunnel $IPV6ADDR via ${PUBLIC_IP}: "
1462           ifconfig sit0 tunnel ::192.88.99.1 up
1463           ifconfig sit1 add "$IPV6ADDR" && print done || print failed
1464        fi
1465        ;;
1466       status)
1467        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1468           print 'ipv6 tunnel available' ; return 0
1469        else
1470           print 'ipv6 tunnel not available' ; return 1
1471        fi
1472        ;;
1473       stop)
1474        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1475           print -n 'Stopping ipv6 tunnel (sit0 + sit1): '
1476           ifconfig sit1 down ; ifconfig sit0 down && print done || print failed
1477        else
1478           print 'No ipv6 tunnel found, nothing to be done.' ; return 1
1479        fi
1480        ;;
1481       *)
1482        print "Usage: ipv6-tunnel [start|stop|status]">&2 ; return 1
1483        ;;
1484     esac
1485   }
1486
1487   # run dhclient for wireless device
1488   iwclient() {
1489     salias dhclient "$(wavemon -d | awk '/device/{print $2}')"
1490   }
1491
1492   # spawn a minimally set up ksh - useful if you want to umount /usr/.
1493   minimal-shell() {
1494     exec env -i ENV="/etc/minimal-shellrc" HOME="$HOME" TERM="$TERM" ksh
1495   }
1496
1497   # Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
1498   # bash() {
1499   #  NO_SWITCH="yes" command bash "$@"
1500   # }
1501   # restart () {
1502   #  exec $SHELL $SHELL_ARGS "$@"
1503   # }
1504
1505 # }}}
1506
1507 # log out? set timeout in seconds {{{
1508 # TMOUT=1800
1509 # do not log out in some specific terminals:
1510 #  if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]]; then
1511 #    unset TMOUT
1512 #  fi
1513 # }}}
1514
1515 # {{{ make sure our environment is clean regarding colors
1516   for color in BLUE RED GREEN CYAN WHITE ; unset $color
1517 # }}}
1518
1519 # source another config file if present {{{
1520   if [ -r /etc/zsh/zshrc.local ]; then
1521    source /etc/zsh/zshrc.local
1522   fi
1523 # }}}
1524
1525 # "persistent history" {{{
1526 # just write important commands you always need to ~/.important_commands
1527   if [ -r ~/.important_commands ] ; then
1528      fc -R ~/.important_commands
1529   fi
1530 # }}}
1531
1532 ## genrefcard.pl settings {{{
1533 ### example: split functions-search 8,16,24,32
1534 #@# split functions-search 8
1535 ## }}}
1536
1537 # add variable to be able to check whether the file has been read {{{
1538   ZSHRC_GLOBAL_HAS_BEEN_READ=1
1539 # }}}
1540
1541 ## END OF FILE #################################################################
1542 # vim:foldmethod=marker expandtab