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