/etc/zsh/zshrc: support displaying version control information inside prompt
[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: Don Okt 18 10:22: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 # display version control information on right side of prompt if $VCS is set {{{
627 # based on Mike Hommey's http://web.glandium.org/blog/?p=170
628   __vcs_dir() {
629     local vcs base_dir sub_dir ref
630     sub_dir() {
631       local sub_dir
632       sub_dir=$(readlink -f "${PWD}")
633       sub_dir=${sub_dir#$1}
634       echo ${sub_dir#/}
635     }
636
637     git_dir() {
638       base_dir=$(git-rev-parse --show-cdup 2>/dev/null) || return 1
639       base_dir=$(readlink -f "$base_dir/..")
640       sub_dir=$(git-rev-parse --show-prefix)
641       sub_dir=${sub_dir%/}
642       ref=$(git-symbolic-ref -q HEAD || git-name-rev --name-only HEAD 2>/dev/null)
643       ref=${ref#refs/heads/}
644       vcs="git"
645     }
646
647     svn_dir() {
648       [ -d ".svn" ] || return 1
649       base_dir="."
650       while [ -d "$base_dir/../.svn" ]; do base_dir="$base_dir/.."; done
651       base_dir=$(readlink -f "$base_dir")
652       sub_dir=$(sub_dir "${base_dir}")
653       ref=$(svn info "$base_dir" | awk '/^URL/ { sub(".*/","",$0); r=$0 } /^Revision/ { sub("[^0-9]*","",$0); print r":"$0 }')
654       vcs="svn"
655     }
656
657     svk_dir() {
658       [ -f ~/.svk/config ] || return 1
659       base_dir=$(awk '/: *$/ { sub(/^ */,"",$0); sub(/: *$/,"",$0); if (match("'${PWD}'", $0"(/|$)")) { print $0; d=1; } } /depotpath/ && d == 1 { sub(".*/","",$0); r=$0 } /revision/ && d == 1 { print r ":" $2; exit 1 }' ~/.svk/config) && return 1
660       ref=${base_dir##*
661   }
662       base_dir=${base_dir%%
663   *}
664       sub_dir=$(sub_dir "${base_dir}")
665       vcs="svk"
666     }
667
668     hg_dir() {
669       base_dir="."
670       while [ ! -d "$base_dir/.hg" ]; do base_dir="$base_dir/.."; [ $(readlink -f "${base_dir}") = "/" ] && return 1; done
671       base_dir=$(readlink -f "$base_dir")
672       sub_dir=$(sub_dir "${base_dir}")
673       ref=$(< "${base_dir}/.hg/branch")
674       vcs="hg"
675     }
676
677     hg_dir  ||
678     git_dir ||
679     svn_dir ||
680     svk_dir # ||
681   #  base_dir="$PWD"
682   #  echo "${vcs:+($vcs)}${base_dir/$HOME/~}${vcs:+[$ref]${sub_dir}}"
683     echo "${vcs:+($vcs)}${base_dir}${vcs:+[$ref]${sub_dir}}"
684   }
685 # }}}
686
687 # {{{ set prompt
688   if autoload promptinit && promptinit 2>/dev/null ; then
689      promptinit # people should be able to use their favourite prompt
690   else
691      print 'Notice: no promptinit available :('
692   fi
693
694
695 # precmd() => a function which is executed just before each prompt
696 # use 'NOPRECMD=1' to disable the precmd + preexec commands
697
698   # precmd () { setopt promptsubst; [[ -o interactive ]] && jobs -l;
699
700   # make sure to use right prompt only when not running a command
701   is4 && setopt transient_rprompt
702
703   is4 && [[ -z $NOPRECMD ]] && precmd () {
704       [[ -n $NOPRECMD ]] && return 0
705       # allow manual overwriting of RPROMPT
706       if [[ -n $RPROMPT ]] ; then
707          [[ $TERM == screen* ]] && echo -n $'\ekzsh\e\\'
708          # return 0
709       fi
710       # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
711       if [[ -z $DONTSETRPROMPT ]] ; then
712          if [[ -n $BATTERY ]] ; then
713             RPROMPT="%(?..:()% ${PERCENT}${SCREENTITLE}"
714             # RPROMPT="${PERCENT}${SCREENTITLE}"
715          elif [[ -n $VCS ]] ; then
716             RPROMPT="%(?..:()% $(__vcs_dir)${SCREENTITLE}"
717          else
718             RPROMPT="%(?..:()% ${SCREENTITLE}"
719             # RPROMPT="${SCREENTITLE}"
720          fi
721       fi
722       # adjust title of xterm
723       # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
724       case $TERM in (xterm*|rxvt)
725         print -Pn "\e]0;%n@%m: %~\a"
726         ;;
727       esac
728   }
729
730 # chpwd () => a function which is executed whenever the directory is changed
731
732 # preexec() => a function running before every command
733   is4 && [[ -z $NOPRECMD ]] && preexec () {
734       [[ -n $NOPRECMD ]] && return 0
735   # set hostname if not running on host with name 'grml'
736       local HOSTNAME=$(hostname)
737       if [[ "$HOSTNAME" != grml ]] ; then
738          NAME="@$HOSTNAME"
739       fi
740   # get the name of the program currently running and hostname of local machine
741   # set screen window title if running in a screen
742       if [[ "$TERM" == screen* ]]; then
743          # local CMD=${1[(wr)^(*=*|sudo|ssh|-*)]}       # don't use hostname
744          local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME" # use hostname
745          echo -ne "\ek$CMD\e\\"
746       fi
747   # set the screen title to "zsh" when sitting at the command prompt:
748       if [[ "$TERM" == screen* ]]; then
749          SCREENTITLE=$'%{\ekzsh\e\\%}'
750       else
751          SCREENTITLE=''
752       fi
753   # adjust title of xterm
754       case $TERM in (xterm*|rxvt)
755         print -Pn "\e]0;%n@%m: $1\a"
756         ;;
757       esac
758   }
759
760 # set colors
761   if autoload colors && colors 2>/dev/null ; then
762      BLUE="%{${fg[blue]}%}"
763      RED="%{${fg_bold[red]}%}"
764      GREEN="%{${fg[green]}%}"
765      CYAN="%{${fg[cyan]}%}"
766      WHITE="%{${fg[white]}%}"
767      NO_COLOUR="%{${reset_color}%}"
768   else
769      BLUE=$'%{\e[1;34m%}'
770      RED=$'%{\e[1;31m%}'
771      GREEN=$'%{\e[1;32m%}'
772      CYAN=$'%{\e[1;36m%}'
773      WHITE=$'%{\e[1;37m%}'
774      NO_COLOUR=$'%{\e[0m%}'
775   fi
776
777   EXITCODE="%(?..%?%1v )"
778   PS2='`%_> '       # secondary prompt, printed when the shell needs more information to complete a command.
779   PS3='?# '         # selection prompt used within a select loop.
780   PS4='+%N:%i:%_> ' # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
781
782   # set variable debian_chroot if running in a chroot with /etc/debian_chroot
783   if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
784     debian_chroot=$(cat /etc/debian_chroot)
785   fi
786
787   # don't use colors on dumb terminals (like emacs):
788   if [[ "$TERM" == dumb ]] ; then
789      PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< %# "
790   else
791     # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended prompt
792     # set variable identifying the chroot you work in (used in the prompt below)
793     if [[ -n $GRMLPROMPT ]]; then
794       PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
795 ${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# "
796     else
797       if (( EUID != 0 )); then
798         PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
799       else
800         PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
801       fi
802     fi
803   fi
804
805   # if we are inside a grml-chroot set a specific prompt theme
806   if [ -n "$GRML_CHROOT" ] ; then
807      PROMPT="%{$fg[red]%}(CHROOT) %{$fg_bold[red]%}%n%{$fg_no_bold[white]%}@%m %40<...<%B%~%b%<< %\# "
808   fi
809 # }}}
810
811 # {{{ 'hash' some often used directories
812   #d# start
813   hash -d deb=/var/cache/apt/archives
814   hash -d doc=/usr/share/doc
815   hash -d linux=/lib/modules/$(command uname -r)/build/
816   hash -d log=/var/log
817   hash -d slog=/var/log/syslog
818   hash -d src=/usr/src
819   hash -d templ=/usr/share/doc/grml-templates
820   hash -d tt=/usr/share/doc/texttools-doc
821   hash -d www=/var/www
822   #d# end
823 # }}}
824
825 # {{{ some aliases
826   if [ $UID = 0 ] ; then
827      [ -r /etc/grml/screenrc ] && alias screen='/usr/bin/screen -c /etc/grml/screenrc'
828   elif [ -r $HOME/.screenrc ] ; then
829      alias screen="/usr/bin/screen -c $HOME/.screenrc"
830   else
831      [ -r /etc/grml/screenrc_grml ] && alias screen='/usr/bin/screen -c /etc/grml/screenrc_grml'
832   fi
833
834   # do we have GNU ls with color-support?
835   if ls --help 2>/dev/null |grep -- --color= >/dev/null && [ "$TERM" != dumb ] ; then
836      #a1# execute \kbd{@a@}:\quad ls with colors
837      alias ls='ls -b -CF --color=auto'
838      #a1# execute \kbd{@a@}:\quad list all files, with colors
839      alias la='ls -la --color=auto'
840      #a1# long colored list, without dotfiles (@a@)
841      alias ll='ls -l --color=auto'
842      #a1# long colored list, human readable sizes (@a@)
843      alias lh='ls -hAl --color=auto'
844      #a1# List files, append qualifier to filenames \\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
845      alias l='ls -lF --color=auto'
846   else
847      alias ls='ls -b -CF'
848      alias la='ls -la'
849      alias ll='ls -l'
850      alias lh='ls -hAl'
851      alias l='ls -lF'
852   fi
853
854   alias mdstat='cat /proc/mdstat'
855   alias ...='cd ../../'
856
857   # generate alias named "$KERNELVERSION-reboot" so you can use boot with kexec:
858   if [ -x /sbin/kexec -a -r /proc/cmdline ] ; then
859      alias "$(uname -r)-reboot"="kexec -l --initrd=/boot/initrd.img-"$(uname -r)" --command-line=\"$(cat /proc/cmdline)\" /boot/vmlinuz-"$(uname -r)""
860   fi
861
862   alias cp='nocorrect cp'         # no spelling correction on cp
863   alias mkdir='nocorrect mkdir'   # no spelling correction on mkdir
864   alias mv='nocorrect mv'         # no spelling correction on mv
865   alias rm='nocorrect rm'         # no spelling correction on rm
866
867   #a1# Execute \kbd{rmdir}
868   alias rd='rmdir'
869   #a1# Execute \kbd{rmdir}
870   alias md='mkdir'
871
872   # see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
873   alias term2iso="echo 'Setting terminal to iso mode' ; print -n '\e%@'"
874   alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
875
876   # make sure it is not assigned yet
877   [[ $(whence -w utf2iso &>/dev/null) == 'utf2iso: alias' ]] && unalias utf2iso
878   utf2iso() {
879     if isutfenv ; then
880        for ENV in $(env | command grep -i '.utf') ; do
881            eval export "$(echo $ENV | sed 's/UTF-8/iso885915/ ; s/utf8/iso885915/')"
882        done
883      fi
884   }
885
886   # make sure it is not assigned yet
887   [[ $(whence -w iso2utf &>/dev/null) == 'iso2utf: alias' ]] && unalias iso2utf
888   iso2utf() {
889    if ! isutfenv ; then
890       for ENV in $(env | command grep -i '\.iso') ; do
891           eval export "$(echo $ENV | sed 's/iso.*/UTF-8/ ; s/ISO.*/UTF-8/')"
892       done
893    fi
894  }
895
896 # set up software synthesizer via speakup
897   alias swspeak='
898     aumix -w 90 -v 90 -p 90 -m 90
899     if ! [ -r /dev/softsynth ] ; then
900        flite -o play -t "Sorry, software synthesizer not available. Did you boot with swspeak bootoption?"
901        return 1
902     else
903        setopt singlelinezle
904        unsetopt prompt_cr
905        export PS1="%m%# "
906        nice -n -20 speechd-up
907        sleep 2
908        flite -o play -t "Finished setting up software synthesizer"
909     fi
910   '
911
912 # I like clean prompt, so provide simple way to get that
913   alias 0 &>/dev/null || functions 0 &>/dev/null || alias 0='return 0'
914
915 # for really lazy people like mika:
916   type S &>/dev/null || alias S='screen'
917   type s &>/dev/null || alias s='ssh'
918
919 # get top 10 shell commands:
920   alias top10='print -l ? ${(o)history%% *} | uniq -c | sort -nr | head -n 10'
921
922 # truecrypt; use e.g. via 'truec /dev/ice /mnt/ice' or 'truec -i'
923   if [ -x $(which truecrypt) ] ; then
924      if isutfenv ; then
925         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077,utf8" '
926      else
927         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077" '
928      fi
929   fi
930
931 #f1# Hints for the use of zsh on grml
932   zsh-help(){print "$bg[white]$fg[black]
933 zsh-help - hints for use of zsh on grml
934 =======================================$reset_color
935
936 Main configuration of zsh happens in /etc/zsh/zshrc (global)
937 and /etc/skel/.zshrc which is copied to \$HOME/.zshrc once.
938 The files are part of the package grml-etc-core, if you want to
939 use them on a non-grml-system just get the tar.gz from
940 http://deb.grml.org/ or get the files from the mercurial
941 repository:
942
943   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
944   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
945
946 If you want to stay in sync with zsh configuration of grml
947 run 'ln -sf /etc/skel/.zshrc \$HOME/.zshrc' and configure
948 your own stuff in \$HOME/.zshrc.local. System wide configuration
949 without touching configuration files of grml can take place
950 in /etc/zsh/zshrc.local.
951
952 If you want to use the configuration of user grml also when
953 running as user root just run 'zshskel' which will source
954 the file /etc/skel/.zshrc.
955
956 For information regarding zsh start at http://grml.org/zsh/
957
958 Take a look at grml's zsh refcard:
959 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
960
961 Check out the main zsh refcard:
962 % $BROWSER http://www.bash2zsh.com/zsh_refcard/refcard.pdf
963
964 And of course visit the zsh-lovers:
965 % man zsh-lovers
966
967 You can adjust some options through environment variables when
968 invoking zsh without having to edit configuration files.
969 Basically meant for bash users who are not used to the power of
970 the zsh yet. :)
971
972   \"NOCOR=1    zsh\" => deactivate automatic correction
973   \"NOMENU=1   zsh\" => do not use menu completion (note: use strg-d for completion instead!)
974   \"NOPRECMD=1 zsh\" => disable the precmd + preexec commands (set GNU screen title)
975   \"BATTERY=1  zsh\" => activate battery status (via acpi) on right side of prompt
976 $bg[white]$fg[black]
977 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
978 Enjoy your grml system with the zsh!$reset_color"
979 }
980
981 # debian stuff
982   if [ -r /etc/debian_version ] ; then
983     #a3# Execute \kbd{apt-cache search}
984     alias acs='apt-cache search'
985     #a3# Execute \kbd{apt-cache show}
986     alias acsh='apt-cache show'
987     #a3# Execute \kbd{apt-cache policy}
988     alias acp='apt-cache policy'
989     #a3# Execute \kbd{apt-get dist-upgrade}
990     salias adg="apt-get dist-upgrade"
991     #a3# Execute \kbd{apt-get install}
992     salias agi="apt-get install"
993     #a3# Execute \kbd{aptitude install}
994     salias ati="aptitude install"
995     #a3# Execute \kbd{apt-get upgrade}
996     salias ag="apt-get upgrade"
997     #a3# Execute \kbd{apt-get update}
998     salias au="apt-get update"
999     #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
1000     salias -a up="aptitude update ; aptitude safe-upgrade"
1001     #a3# Execute \kbd{dpkg-buildpackage}
1002     alias dbp='dpkg-buildpackage'
1003     #a3# Execute \kbd{grep-excuses}
1004     alias ge='grep-excuses'
1005
1006     # debian upgrade
1007     #f3# Execute \kbd{apt-get update \&\& }\\&\quad \kbd{apt-get dist-upgrade}
1008     upgrade () {
1009       if [ -z "$1" ] ; then
1010           $SUDO apt-get update
1011           $SUDO apt-get -u upgrade
1012       else
1013           ssh $1 $SUDO apt-get update
1014           # ask before the upgrade
1015           local dummy
1016           ssh $1 $SUDO apt-get --no-act upgrade
1017           echo -n 'Process the upgrade?'
1018           read -q dummy
1019           if [[ $dummy == "y" ]] ; then
1020               ssh $1 $SUDO apt-get -u upgrade --yes
1021           fi
1022       fi
1023     }
1024
1025     isgrmlcd && alias su="sudo -s"          # get a root shell
1026     #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
1027     alias llog="$PAGER /var/log/syslog"     # take a look at the syslog
1028     #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
1029     alias tlog="tail -f /var/log/syslog"    # follow the syslog
1030     #a1# (Re)-source \kbd{/etc/skel/.zshrc}
1031     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
1032   fi
1033
1034 # sort installed Debian-packages by size
1035   if [ -x $(which grep-status) ] ; then
1036      #a3# List installed Debian-packages sorted by size
1037      alias debs-by-size='grep-status -FStatus -sInstalled-Size,Package -n "install ok installed" | paste -sd "  \n" | sort -rn'
1038   fi
1039
1040 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
1041   if [ -L /usr/bin/cdrecord -o ! -x $(which cdrecord) ] ; then
1042      if [ -x $(which wodim) ] ; then
1043         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
1044 See #377109 in the BTS of Debian for more details.
1045
1046 Please use the wodim binary instead' ; return 1"
1047      fi
1048   fi
1049
1050 # get_tw_cli has been renamed into get_3ware
1051   if [ -x $(which get_3ware) ] ; then
1052      get_tw_cli() {
1053        echo 'Warning: get_tw_cli has been renamed into get_3ware. Invoking get_3ware for you.'>&2
1054        get_3ware
1055      }
1056   fi
1057
1058 # I hate lacking backward compatibility, so provide an alternative therefore
1059   if ! [ -x $(which apache2-ssl-certificate) ] ; then
1060      apache2-ssl-certificate(){
1061
1062      print 'Debian does not ship apache2-ssl-certificate anymore (see #398520). :('
1063      print 'You might want to take a look at Debian the package ssl-cert as well.'
1064      print 'To generate a certificate for use with apache2 follow the instructions:'
1065
1066      echo '
1067
1068 export RANDFILE=/dev/random
1069 mkdir /etc/apache2/ssl/
1070 openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
1071 chmod 600 /etc/apache2/ssl/apache.pem
1072
1073 Run "grml-tips ssl-certificate" if you need further instructions.
1074 '
1075    }
1076   fi
1077 # }}}
1078
1079 # {{{ Use hard limits, except for a smaller stack and no core dumps
1080   unlimit
1081   limit stack 8192
1082   isgrmlcd && limit core 0 # important for a live-cd-system
1083   limit -s
1084 # }}}
1085
1086 # {{{ completion stuff
1087
1088 # called later (via is4 && grmlcomp)
1089 # notice: use 'zstyle' for getting current settings
1090 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
1091 grmlcomp() {
1092 ## completion system
1093   zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )' # allow one error for every three characters typed in approximate completer
1094   zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)' # don't complete backup files as executables
1095   zstyle ':completion:*:correct:*'       insert-unambiguous true             # start menu completion only if it could find no unambiguous initial string
1096   zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}' #
1097   zstyle ':completion:*:correct:*'       original true                       #
1098   zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}      # activate color-completion(!)
1099   zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'  # format on completion
1100   zstyle ':completion:*:*:cd:*:directory-stack' menu yes select              # complete 'cd -<tab>' with menu
1101   zstyle ':completion:*:expand:*'        tag-order all-expansions            # insert all expansions for expand completer
1102   zstyle ':completion:*:history-words'   list false                          #
1103   zstyle ':completion:*:history-words'   menu yes                            # activate menu
1104   zstyle ':completion:*:history-words'   remove-all-dups yes                 # ignore duplicate entries
1105   zstyle ':completion:*:history-words'   stop yes                            #
1106   zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'        # match uppercase from lowercase
1107   zstyle ':completion:*:matches'         group 'yes'                         # separate matches into groups
1108   zstyle ':completion:*'                 group-name ''
1109   if [[ -z "$NOMENU" ]] ; then
1110     zstyle ':completion:*'               menu select=5                       # if there are more than 5 options allow selecting from a menu
1111   else
1112     setopt no_auto_menu # don't use any menus at all
1113   fi
1114   zstyle ':completion:*:messages'        format '%d'                         #
1115   zstyle ':completion:*:options'         auto-description '%d'               #
1116   zstyle ':completion:*:options'         description 'yes'                   # describe options in full
1117   zstyle ':completion:*:processes'       command 'ps -au$USER'               # on processes completion complete all user processes
1118   zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters        # offer indexes before parameters in subscripts
1119   zstyle ':completion:*'                 verbose true                        # provide verbose completion information
1120   zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' # set format for warnings
1121   zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'       # define files to ignore for zcompile
1122   zstyle ':completion:correct:'          prompt 'correct to: %e'             #
1123   zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'    # Ignore completion functions for commands you don't have:
1124
1125 # complete manual by their section
1126   zstyle ':completion:*:manuals'    separate-sections true
1127   zstyle ':completion:*:manuals.*'  insert-sections   true
1128   zstyle ':completion:*:man:*'      menu yes select
1129
1130 ## correction
1131 # run rehash on completion so new installed program are found automatically:
1132   _force_rehash() {
1133       (( CURRENT == 1 )) && rehash
1134          return 1 # Because we didn't really complete anything
1135     }
1136 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
1137   if [[ -n "$NOCOR" ]] ; then
1138     zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
1139     setopt nocorrect # do not try to correct the spelling if possible
1140   else
1141 #    zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _ignored _correct _approximate _files
1142     setopt correct  # try to correct the spelling if possible
1143     zstyle -e ':completion:*' completer '
1144         if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]]; then
1145           _last_try="$HISTNO$BUFFER$CURSOR"
1146           reply=(_complete _match _ignored _prefix _files)
1147         else
1148           if [[ $words[1] = (rm|mv) ]]; then
1149             reply=(_complete _files)
1150           else
1151             reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files)
1152           fi
1153         fi'
1154   fi
1155 # zstyle ':completion:*' completer _complete _correct _approximate
1156 # zstyle ':completion:*' expand prefix suffix
1157
1158 # automatic rehash? Credits go to Frank Terbeck
1159 # my_accept() {
1160 #   local buf
1161 #   [[ -z ${BUFFER} ]] && zle accept-line && return
1162 #   buf=( ${(z)BUFFER}  )
1163 #   [[ -z ${commands[${buf[1]}]} ]] && rehash
1164 #   zle accept-line
1165 # }
1166 # zle -N my_accept
1167 # bindkey "^M" my_accept
1168
1169 # command for process lists, the local web server details and host completion
1170   zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
1171
1172 # caching
1173   [ -d $ZSHDIR/cache ] && zstyle ':completion:*' use-cache yes && \
1174                           zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
1175
1176 # host completion /* add brackets as vim can't parse zsh's complex cmdlines 8-) {{{ */
1177   if is42 ; then
1178     [ -r ~/.ssh/known_hosts ] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
1179     [ -r /etc/hosts ] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
1180   else
1181     _ssh_hosts=()
1182     _etc_hosts=()
1183   fi
1184   hosts=(
1185       `hostname`
1186       "$_ssh_hosts[@]"
1187       "$_etc_hosts[@]"
1188       grml.org
1189       localhost
1190   )
1191   zstyle ':completion:*:hosts' hosts $hosts
1192 #  zstyle '*' hosts $hosts
1193
1194 # specify your logins:
1195 # my_accounts=(
1196 #  {grml,grml1}@foo.invalid
1197 #  grml-devel@bar.invalid
1198 # )
1199 # other_accounts=(
1200 #  {fred,root}@foo.invalid
1201 #  vera@bar.invalid
1202 # )
1203 # zstyle ':completion:*:my-accounts' users-hosts $my_accounts
1204 # zstyle ':completion:*:other-accounts' users-hosts $other_accounts
1205
1206 # specify specific port/service settings:
1207 #  telnet_users_hosts_ports=(
1208 #    user1@host1:
1209 #    user2@host2:
1210 #    @mail-server:{smtp,pop3}
1211 #    @news-server:nntp
1212 #    @proxy-server:8000
1213 #  )
1214 # zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
1215
1216 # use generic completion system for programs not yet defined:
1217   compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
1218
1219 # see upgrade function in this file
1220   compdef _hosts upgrade
1221 }
1222 # }}}
1223
1224 # {{{ grmlstuff
1225 grmlstuff() {
1226 # people should use 'grml-x'!
1227   startx() {
1228     if [ -e /etc/X11/xorg.conf ] ; then
1229        [ -x /usr/bin/startx ] && /usr/bin/startx "$@" || /usr/X11R6/bin/startx "$@"
1230     else
1231       echo "Please use the script \"grml-x\" for starting the X Window System
1232 because there does not exist /etc/X11/xorg.conf yet.
1233 If you want to use startx anyway please call \"/usr/bin/startx\"."
1234       return -1
1235     fi
1236   }
1237
1238   xinit() {
1239     if [ -e /etc/X11/xorg.conf ] ; then
1240        [ -x /usr/bin/xinit ] && /usr/bin/xinit || /usr/X11R6/bin/xinit
1241     else
1242       echo "Please use the script \"grml-x\" for starting the X Window System.
1243 because there does not exist /etc/X11/xorg.conf yet.
1244 If you want to use xinit anyway please call \"/usr/bin/xinit\"."
1245       return -1
1246     fi
1247   }
1248
1249   if [ -x $(which 915resolution) ] ; then
1250      alias 855resolution='echo -e "Please use 915resolution as resolution modify tool for Intel graphic chipset."; return -1'
1251   fi
1252
1253   #a1# Output version of running grml
1254   alias grml-version='cat /etc/grml_version'
1255
1256   if [ -x $(which rebuildfstab) ] ; then
1257      #a1# Rebuild /etc/fstab
1258      alias grml-rebuildfstab='rebuildfstab -v -r -config'
1259   fi
1260
1261   if [ -x $(which grml-debootstrap) ] ; then
1262      alias debian2hd='print "Installing debian to harddisk is possible via using grml-debootstrap." ; return 1'
1263   fi
1264 }
1265 # }}}
1266
1267 # {{{ now run the functions
1268   isgrml && checkhome
1269   is4    && isgrml    && grmlstuff
1270   is4    && grmlcomp
1271 # }}}
1272
1273 # {{{ keephack
1274   [ -r /etc/zsh/keephack ] && is4 && source /etc/zsh/keephack
1275 # }}}
1276
1277 # {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson
1278 # You use it as follows:
1279 # $ NTREF=/reference/file
1280 # $ ls -l *(e:nt:)
1281 # This lists all the files in the current directory newer than the reference file.
1282 # You can also specify the reference file inline; note quotes:
1283 # $ ls -l *(e:'nt ~/.zshenv':)
1284   is4 && nt() {
1285     if [[ -n $1 ]]; then
1286       local NTREF=${~1}
1287     fi
1288     [[ $REPLY -nt $NTREF ]]
1289   }
1290 # }}}
1291
1292 # shell functions {{{
1293   #f1# Provide csh compatibility
1294   setenv()  { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }  # csh compatibility
1295   #f1# Reload an autoloadable function
1296   freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
1297   #f1# Reload zsh setup
1298   reload () {
1299    if [[ "$#*" -eq 0 ]]; then
1300       [ -r ~/.zshrc ] && . ~/.zshrc
1301    else
1302       local fn
1303       for fn in "$@"; do
1304           unfunction $fn
1305           autoload -U $fn
1306       done
1307    fi
1308   }
1309   compdef _functions reload freload
1310
1311   #f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
1312   sll() {
1313     [ -z "$1" ] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
1314     for i in "$@" ; do
1315       file=$i
1316       while [ -h "$file" ] ; do
1317         ls -l $file
1318         file=$(readlink "$file")
1319       done
1320     done
1321   }
1322
1323   # fast manual access
1324   if type -p qma &>/dev/null ; then
1325   #f1# View the zsh manual
1326      manzsh()  { qma zshall "$1" }
1327      compdef _man qma
1328   else
1329      manzsh()  { /usr/bin/man zshall |  vim -c "se ft=man| se hlsearch" +/"$1" - ; }
1330      # manzsh()  { /usr/bin/man zshall |  most +/"$1" ; }
1331      # [[ -f ~/.terminfo/m/mostlike ]] && MYLESS='LESS=C TERMINFO=~/.terminfo TERM=mostlike less' || MYLESS='less'
1332      # manzsh()  { man zshall | $MYLESS -p $1 ; }
1333   fi
1334
1335   if [ -x $(which most) ] ; then
1336   #f1# View Debian's changelog of a given package
1337     dchange() {
1338       if [ -r /usr/share/doc/${1}/changelog.Debian.gz ] ; then
1339          most /usr/share/doc/${1}/changelog.Debian.gz
1340       elif [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1341          most /usr/share/doc/${1}/changelog.gz
1342       else
1343          if type -p aptitude &>/dev/null ; then
1344             echo "No changelog for package $1 found, using aptitude to retrieve it."
1345             if isgrml ; then
1346               aptitude -t unstable changelog ${1}
1347             else
1348               aptitude changelog ${1}
1349             fi
1350          else
1351             echo "No changelog for package $1 found, sorry."
1352             return 1
1353          fi
1354       fi
1355     }
1356     _dchange() { _files -W /usr/share/doc -/ }
1357     compdef _dchange dchange
1358
1359   #f1# View Debian's NEWS of a given package
1360     dnews() {
1361       if [ -r /usr/share/doc/${1}/NEWS.Debian.gz ] ; then
1362          most /usr/share/doc/${1}/NEWS.Debian.gz
1363       else
1364          if [ -r /usr/share/doc/${1}/NEWS.gz ] ; then
1365             most /usr/share/doc/${1}/NEWS.gz
1366          else
1367             echo "No NEWS file for package $1 found, sorry."
1368             return 1
1369          fi
1370       fi
1371     }
1372     _dnews() { _files -W /usr/share/doc -/ }
1373     compdef _dnews dnews
1374
1375   #f1# View upstream's changelog of a given package
1376     uchange() {
1377       if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1378          most /usr/share/doc/${1}/changelog.gz
1379       else
1380          echo "No changelog for package $1 found, sorry."
1381          return 1
1382       fi
1383     }
1384     _uchange() { _files -W /usr/share/doc -/ }
1385     compdef _uchange uchange
1386   fi
1387
1388 # zsh profiling
1389   profile () {
1390       ZSH_PROFILE_RC=1 $SHELL "$@"
1391   }
1392
1393 #f1# Edit an alias via zle
1394   edalias() {
1395     [ -z "$1" ] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
1396   }
1397   compdef _aliases edalias
1398
1399 #f1# Edit a function via zle
1400   edfunc() {
1401     [ -z "$1" ] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
1402   }
1403   compdef _functions edfunc
1404
1405 # use it e.g. via 'Restart apache2'
1406 #m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
1407 #m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
1408 #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
1409 #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
1410 #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
1411  if [ -d /etc/init.d ] ; then
1412   for i in Start Restart Stop Force-Reload Reload ; do
1413     eval "$i() { $SUDO /etc/init.d/\$1 ${i:l} \$2 ; }"
1414   done
1415  fi
1416
1417   #f1# Provides useful information on globbing
1418   H-Glob() {
1419   echo -e "
1420       /      directories
1421       .      plain files
1422       @      symbolic links
1423       =      sockets
1424       p      named pipes (FIFOs)
1425       *      executable plain files (0100)
1426       %      device files (character or block special)
1427       %b     block special files
1428       %c     character special files
1429       r      owner-readable files (0400)
1430       w      owner-writable files (0200)
1431       x      owner-executable files (0100)
1432       A      group-readable files (0040)
1433       I      group-writable files (0020)
1434       E      group-executable files (0010)
1435       R      world-readable files (0004)
1436       W      world-writable files (0002)
1437       X      world-executable files (0001)
1438       s      setuid files (04000)
1439       S      setgid files (02000)
1440       t      files with the sticky bit (01000)
1441
1442    print *(m-1)          # Files modified up to a day ago
1443    print *(a1)           # Files accessed a day ago
1444    print *(@)            # Just symlinks
1445    print *(Lk+50)        # Files bigger than 50 kilobytes
1446    print *(Lk-50)        # Files smaller than 50 kilobytes
1447    print **/*.c          # All *.c files recursively starting in \$PWD
1448    print **/*.c~file.c   # Same as above, but excluding 'file.c'
1449    print (foo|bar).*     # Files starting with 'foo' or 'bar'
1450    print *~*.*           # All Files that do not contain a dot
1451    chmod 644 *(.^x)      # make all plain non-executable files publically readable
1452    print -l *(.c|.h)     # Lists *.c and *.h
1453    print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
1454    echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
1455   }
1456   alias help-zshglob=H-Glob
1457
1458   type -p qma &>/dev/null && alias ?='qma zshall'
1459
1460   # grep for running process, like: 'any vim'
1461   any() {
1462   if [ -z "$1" ] ; then
1463      echo "any - grep for process(es) by keyword" >&2
1464      echo "Usage: any <keyword>" >&2 ; return 1
1465   else
1466      local STRING=$1
1467      local LENGTH=$(expr length $STRING)
1468      local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
1469      local REST=$(echo $(expr substr $STRING 2 $LENGTH))
1470      ps xauwww| grep "[$FIRSCHAR]$REST"
1471   fi
1472   }
1473
1474   # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
1475   # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
1476   [ -r /proc/1/maps ] && deswap() {
1477      print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
1478      cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
1479      print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
1480   }
1481
1482   # print hex value of a number
1483   hex() {
1484     [ -n "$1" ] && printf "%x\n" $1 || { print 'Usage: hex <number-to-convert>' ; return 1 }
1485   }
1486
1487   # calculate (or eval at all ;-)) with perl => p[erl-]eval
1488   # hint: also take a look at zcalc -> 'autoload zcalc' -> 'man zshmodules | less -p MATHFUNC'
1489   peval() {
1490     [ -n "$1" ] && CALC="$*" || print "Usage: calc [expression]"
1491     perl -e "print eval($CALC),\"\n\";"
1492   }
1493   functions peval &>/dev/null && alias calc=peval
1494
1495   # brltty seems to have problems with utf8 environment and/or font Uni3-Terminus16 under
1496   # certain circumstances, so work around it, no matter which environment we have
1497   brltty() {
1498     if [ -z "$DISPLAY" ] ; then
1499        consolechars -f /usr/share/consolefonts/default8x16.psf.gz
1500        command brltty "$@"
1501     else
1502        command brltty "$@"
1503     fi
1504   }
1505
1506   # just press 'asdf' keys to toggle between dvorak and us keyboard layout
1507   aoeu() {
1508      echo -n 'Switching to us keyboard layout: '
1509      [ -z "$DISPLAY" ] && $SUDO loadkeys us &>/dev/null || setxkbmap us &>/dev/null
1510      echo 'Done'
1511   }
1512   asdf() {
1513      echo -n 'Switching to dvorak keyboard layout: '
1514      [ -z "$DISPLAY" ] && $SUDO loadkeys dvorak &>/dev/null || setxkbmap dvorak &>/dev/null
1515      echo 'Done'
1516   }
1517   # just press 'asdf' key to toggle from neon layout to us keyboard layout
1518   uiae() {
1519      echo -n 'Switching to us keyboard layout: '
1520      setxkbmap us && echo 'Done' || echo 'Failed'
1521   }
1522
1523   # set up an ipv6 tunnel
1524   ipv6-tunnel() {
1525     case $1 in
1526       start)
1527        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1528           print 'ipv6 tunnel already set up, nothing to be done.'
1529           print 'execute: "ifconfig sit1 down ; ifconfig sit0 down" to remove ipv6-tunnel.' ; return 1
1530        else
1531           [ -n "$PUBLIC_IP" ] || local PUBLIC_IP=$(ifconfig $(route -n | awk '/^0\.0\.0\.0/{print $8; exit}') | \
1532                                              awk '/inet addr:/ {print $2}' | tr -d 'addr:')
1533           [ -n "$PUBLIC_IP" ] || { print 'No $PUBLIC_IP set and could not determine default one.' ; return 1 }
1534           local IPV6ADDR=$(printf "2002:%02x%02x:%02x%02x:1::1" $(print ${PUBLIC_IP//./ }))
1535           print -n "Setting up ipv6 tunnel $IPV6ADDR via ${PUBLIC_IP}: "
1536           ifconfig sit0 tunnel ::192.88.99.1 up
1537           ifconfig sit1 add "$IPV6ADDR" && print done || print failed
1538        fi
1539        ;;
1540       status)
1541        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1542           print 'ipv6 tunnel available' ; return 0
1543        else
1544           print 'ipv6 tunnel not available' ; return 1
1545        fi
1546        ;;
1547       stop)
1548        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1549           print -n 'Stopping ipv6 tunnel (sit0 + sit1): '
1550           ifconfig sit1 down ; ifconfig sit0 down && print done || print failed
1551        else
1552           print 'No ipv6 tunnel found, nothing to be done.' ; return 1
1553        fi
1554        ;;
1555       *)
1556        print "Usage: ipv6-tunnel [start|stop|status]">&2 ; return 1
1557        ;;
1558     esac
1559   }
1560
1561   # run dhclient for wireless device
1562   iwclient() {
1563     salias dhclient "$(wavemon -d | awk '/device/{print $2}')"
1564   }
1565
1566   # spawn a minimally set up ksh - useful if you want to umount /usr/.
1567   minimal-shell() {
1568     exec env -i ENV="/etc/minimal-shellrc" HOME="$HOME" TERM="$TERM" ksh
1569   }
1570
1571   # make a backup of a file
1572   bk() {
1573     cp -a "$1" "${1}_$(date --iso-8601=seconds)"
1574   }
1575
1576   # Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
1577   # bash() {
1578   #  NO_SWITCH="yes" command bash "$@"
1579   # }
1580   # restart () {
1581   #  exec $SHELL $SHELL_ARGS "$@"
1582   # }
1583
1584 # }}}
1585
1586 # log out? set timeout in seconds {{{
1587 # TMOUT=1800
1588 # do not log out in some specific terminals:
1589 #  if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]]; then
1590 #    unset TMOUT
1591 #  fi
1592 # }}}
1593
1594 # {{{ make sure our environment is clean regarding colors
1595   for color in BLUE RED GREEN CYAN WHITE ; unset $color
1596 # }}}
1597
1598 # source another config file if present {{{
1599   if [ -r /etc/zsh/zshrc.local ]; then
1600    source /etc/zsh/zshrc.local
1601   fi
1602 # }}}
1603
1604 # "persistent history" {{{
1605 # just write important commands you always need to ~/.important_commands
1606   if [ -r ~/.important_commands ] ; then
1607      fc -R ~/.important_commands
1608   fi
1609 # }}}
1610
1611 ## genrefcard.pl settings {{{
1612 ### example: split functions-search 8,16,24,32
1613 #@# split functions-search 8
1614 ## }}}
1615
1616 # add variable to be able to check whether the file has been read {{{
1617   ZSHRC_GLOBAL_HAS_BEEN_READ=1
1618 # }}}
1619
1620 ## END OF FILE #################################################################
1621 # vim:foldmethod=marker expandtab