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