zshrc: Adding support for darcs repositories to vcs_info()
[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: Wed Aug 06 23:50:53 CEST 2008 [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 # {{{ check for version/system
96 # check for versions (compatibility reasons)
97 is4(){
98     [[ $ZSH_VERSION == <4->* ]] && return 0
99     return 1
100 }
101
102 is41(){
103     [[ $ZSH_VERSION == 4.<1->* || $ZSH_VERSION == <5->* ]] && return 0
104     return 1
105 }
106
107 is42(){
108     [[ $ZSH_VERSION == 4.<2->* || $ZSH_VERSION == <5->* ]] && return 0
109     return 1
110 }
111
112 is43(){
113     [[ $ZSH_VERSION == 4.<3->* || $ZSH_VERSION == <5->* ]] && return 0
114     return 1
115 }
116
117 #f1# Checks whether or not you're running grml
118 isgrml(){
119     [[ -f /etc/grml_version ]] && return 0
120     return 1
121 }
122
123 #f1# Checks whether or not you're running a grml cd
124 isgrmlcd(){
125     [[ -f /etc/grml_cd ]] && return 0
126     return 1
127 }
128
129 if isgrml ; then
130 #f1# Checks whether or not you're running grml-small
131     isgrmlsmall() {
132         [[ ${${${(f)"$(</etc/grml_version)"}%% *}##*-} == 'small' ]] && return 0 ; return 1
133     }
134 else
135     isgrmlsmall() { return 1 }
136 fi
137
138 #f1# are we running within an utf environment?
139 isutfenv() {
140     case "$LANG $CHARSET $LANGUAGE" in
141         *utf*) return 0 ;;
142         *UTF*) return 0 ;;
143         *)     return 1 ;;
144     esac
145 }
146
147 # check for user, if not running as root set $SUDO to sudo
148 (( EUID != 0 )) && SUDO='sudo' || SUDO=''
149
150 # change directory to home on first invocation of zsh
151 # important for rungetty -> autologin
152 # Thanks go to Bart Schaefer!
153 isgrml && checkhome() {
154     if [[ -z "$ALREADY_DID_CD_HOME" ]] ; then
155         export ALREADY_DID_CD_HOME=$HOME
156         cd
157     fi
158 }
159
160 # check for zsh v3.1.7+
161
162 if ! [[ ${ZSH_VERSION} == 3.1.<7->*      \
163      || ${ZSH_VERSION} == 3.<2->.<->*    \
164      || ${ZSH_VERSION} == <4->.<->*   ]] ; then
165
166     printf '-!-\n'
167     printf '-!- In this configuration we try to make use of features, that only\n'
168     printf '-!- require version 3.1.7 of the shell; That way this setup can be\n'
169     printf '-!- used with a wide range of zsh versions, while using fairly\n'
170     printf '-!- advanced features in all supported versions.\n'
171     printf '-!-\n'
172     printf '-!- However, you are running zsh version %s.\n' "$ZSH_VERSION"
173     printf '-!-\n'
174     printf '-!- While this *may* work, it might as well fail.\n'
175     printf '-!- Please consider updating to at least version 3.1.7 of zsh.\n'
176     printf '-!-\n'
177     printf '-!- DO NOT EXPECT THIS TO WORK FLAWLESSLY!\n'
178     printf '-!- If it does today, you'\''ve been lucky.\n'
179     printf '-!-\n'
180     printf '-!- Ye been warned!\n'
181     printf '-!-\n'
182
183     function zstyle() { : }
184 fi
185
186 # }}}
187
188 # utility functions {{{
189 # this function checks if a command exists and returns either true
190 # or false. This avoids using 'which' and 'whence', which will
191 # avoid problems with aliases for which on certain weird systems. :-)
192 check_com() {
193     local -i comonly
194
195     if [[ ${1} == '-c' ]] ; then
196         (( comonly = 1 ))
197         shift
198     else
199         (( comonly = 0 ))
200     fi
201
202     if (( ${#argv} != 1 )) ; then
203         printf 'usage: check_com [-c] <command>\n' >&2
204         return 1
205     fi
206
207     if (( comonly > 0 )) ; then
208         [[ -n ${commands[$1]}  ]] && return 0
209         return 1
210     fi
211
212     if   [[ -n ${commands[$1]}    ]] \
213       || [[ -n ${functions[$1]}   ]] \
214       || [[ -n ${aliases[$1]}     ]] \
215       || [[ -n ${reswords[(r)$1]} ]] ; then
216
217         return 0
218     fi
219
220     return 1
221 }
222
223 # creates an alias and precedes the command with
224 # sudo if $EUID is not zero.
225 salias() {
226     local only=0 ; local multi=0
227     while [[ ${1} == -* ]] ; do
228         case ${1} in
229             (-o) only=1 ;;
230             (-a) multi=1 ;;
231             (--) shift ; break ;;
232             (-h)
233                 printf 'usage: salias [-h|-o|-a] <alias-expression>\n'
234                 printf '  -h      shows this help text.\n'
235                 printf '  -a      replace '\'' ; '\'' sequences with '\'' ; sudo '\''.\n'
236                 printf '          be careful using this option.\n'
237                 printf '  -o      only sets an alias if a preceding sudo would be needed.\n'
238                 return 0
239                 ;;
240             (*) printf "unkown option: '%s'\n" "${1}" ; return 1 ;;
241         esac
242         shift
243     done
244
245     if (( ${#argv} > 1 )) ; then
246         printf 'Too many arguments %s\n' "${#argv}"
247         return 1
248     fi
249
250     key="${1%%\=*}" ;  val="${1#*\=}"
251     if (( EUID == 0 )) && (( only == 0 )); then
252         alias -- "${key}=${val}"
253     elif (( EUID > 0 )) ; then
254         (( multi > 0 )) && val="${val// ; / ; sudo }"
255         alias -- "${key}=sudo ${val}"
256     fi
257
258     return 0
259 }
260
261 # a "print -l ${(u)foo}"-workaround for pre-4.2.0 shells
262 # usage: uprint foo
263 #   Where foo is the *name* of the parameter you want printed.
264 #   Note that foo is no typo; $foo would be wrong here!
265 if ! is42 ; then
266     uprint () {
267         local -a u
268         local w
269         local parameter=${1}
270
271         if [[ -z ${parameter} ]] ; then
272             printf 'usage: uprint <parameter>\n'
273             return 1
274         fi
275
276         for w in ${(P)parameter} ; do
277             [[ -z ${(M)u:#${w}} ]] && u=( ${u} ${w} )
278         done
279
280         builtin print -l ${u}
281     }
282 fi
283
284 # Check if we can read given files and source those we can.
285 xsource() {
286     if (( ${#argv} < 1 )) ; then
287         printf 'usage: xsource FILE(s)...\n' >&2
288         return 1
289     fi
290
291     while (( ${#argv} > 0 )) ; do
292         [[ -r ${1} ]] && source ${1}
293         shift
294     done
295     return 0
296 }
297
298 # Check if we can read a given file and 'cat(1)' it.
299 xcat() {
300     if (( ${#argv} != 1 )) ; then
301         printf 'usage: xcat FILE\n' >&2
302         return 1
303     fi
304
305     [[ -r ${1} ]] && cat ${1}
306     return 0
307 }
308
309 # Remove these functions again, they are of use only in these
310 # setup files. This should be called at the end of .zshrc.
311 xunfunction() {
312     local -a funcs
313     funcs=(salias xcat xsource xunfunction zrcautoload)
314
315     for func in $funcs ; do
316         [[ -n ${functions[$func]} ]] \
317             && unfunction $func
318     done
319     return 0
320 }
321
322 # autoload wrapper - use this one instead of autoload directly
323 function zrcautoload() {
324     setopt local_options extended_glob
325     local fdir ffile
326     local -i ffound
327
328     ffile=${1}
329     (( found = 0 ))
330     for fdir in ${fpath} ; do
331         [[ -e ${fdir}/${ffile} ]] && (( ffound = 1 ))
332     done
333
334     (( ffound == 0 )) && return 1
335     if [[ $ZSH_VERSION == 3.1.<6-> || $ZSH_VERSION == <4->* ]] ; then
336         autoload -U ${ffile} || return 1
337     else
338         autoload ${ffile} || return 1
339     fi
340     return 0
341 }
342
343 #}}}
344
345 # Load is-at-least() for more precise version checks {{{
346
347 # Note that this test will *always* fail, if the is-at-least
348 # function could not be marked for autoloading.
349 zrcautoload is-at-least || is-at-least() { return 1 }
350
351 # }}}
352
353 # locale setup {{{
354 if [[ -z "$LANG" ]] ; then
355    xsource "/etc/default/locale"
356 fi
357
358 export LANG=${LANG:-en_US.iso885915}
359 for var in LC_ALL LC_MESSAGES ; do
360     [[ -n ${(P)var} ]] && export $var
361 done
362
363 xsource "/etc/sysconfig/keyboard"
364
365 TZ=$(xcat /etc/timezone)
366 # }}}
367
368 # check for potentially old files in 'completion.d' {{{
369 setopt extendedglob
370 xof=(/etc/zsh/completion.d/*~/etc/zsh/completion.d/_*(N))
371 if (( ${#xof} > 0 )) ; then
372     printf '\n -!- INFORMATION\n\n'
373     printf ' -!- %s file(s) not starting with an underscore (_) found in\n' ${#xof}
374     printf ' -!- /etc/zsh/completion.d/.\n\n'
375     printf ' -!- While this has been the case in old versions of grml-etc-core,\n'
376     printf ' -!- recent versions of the grml-zsh-setup have all these files rewritten\n'
377     printf ' -!- and renamed. Furthermore, the grml-zsh-setup will *only* add files\n'
378     printf ' -!- named _* to that directory.\n\n'
379     printf ' -!- If you added functions to completion.d yourself, please consider\n'
380     printf ' -!- moving them to /etc/zsh/functions.d/. Files in that directory, not\n'
381     printf ' -!- starting with an underscore are marked for automatic loading\n'
382     printf ' -!- by default (so that is quite convenient).\n\n'
383     printf ' -!- If there are files *not* starting with an underscore from an older\n'
384     printf ' -!- grml-etc-core in completion.d, you may safely remove them.\n\n'
385     printf ' -!- Delete the files for example via running:\n\n'
386     printf "      rm ${xof}\n\n"
387     printf ' -!- Note, that this message will *not* go away, unless you yourself\n'
388     printf ' -!- resolve the situation manually.\n\n'
389     BROKEN_COMPLETION_DIR=1
390 fi
391 unset xof
392 # }}}
393
394 # {{{ set some variables
395 if check_com -c vim ; then
396 #v#
397     export EDITOR=${EDITOR:-vim}
398 else
399     export EDITOR=${EDITOR:-vi}
400 fi
401
402 #v#
403 export PAGER=${PAGER:-less}
404
405 #v#
406 export MAIL=${MAIL:-/var/mail/$USER}
407
408 # if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/
409 export SHELL='/bin/zsh'
410
411 # color setup for ls:
412 check_com -c dircolors && eval $(dircolors -b)
413
414 # set width of man pages to 80 for more convenient reading
415 # export MANWIDTH=${MANWIDTH:-80}
416
417 # Search path for the cd command
418 #  cdpath=(.. ~)
419
420 # completion functions go to /etc/zsh/completion.d
421 # function files may be put into /etc/zsh/functions.d, from where they
422 # will be automatically autoloaded.
423 if [[ -n "$BROKEN_COMPLETION_DIR" ]] ; then
424     print 'Warning: not setting completion directories because broken files have been found.' >&2
425 else
426     [[ -d /etc/zsh/completion.d ]] && fpath=( $fpath /etc/zsh/completion.d )
427     if [[ -d /etc/zsh/functions.d ]] ; then
428         fpath+=( /etc/zsh/functions.d )
429         for func in /etc/zsh/functions.d/[^_]*[^~] ; do
430             zrcautoload -U ${func:t}
431         done
432     fi
433 fi
434
435 # automatically remove duplicates from these arrays
436 typeset -U path cdpath fpath manpath
437 # }}}
438
439 # {{{ keybindings
440 if [[ "$TERM" != emacs ]] ; then
441     [[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
442     [[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
443     [[ -z "$terminfo[kend]"  ]] || bindkey -M emacs "$terminfo[kend]"  end-of-line
444     [[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
445     [[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
446     [[ -z "$terminfo[kend]"  ]] || bindkey -M vicmd "$terminfo[kend]"  vi-end-of-line
447     [[ -z "$terminfo[cuu1]"  ]] || bindkey -M viins "$terminfo[cuu1]"  vi-up-line-or-history
448     [[ -z "$terminfo[cuf1]"  ]] || bindkey -M viins "$terminfo[cuf1]"  vi-forward-char
449     [[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
450     [[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
451     [[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
452     [[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char
453     # ncurses stuff:
454     [[ "$terminfo[kcuu1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history
455     [[ "$terminfo[kcud1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history
456     [[ "$terminfo[kcuf1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char
457     [[ "$terminfo[kcub1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char
458     [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line
459     [[ "$terminfo[kend]"  == $'\eO'* ]] && bindkey -M viins "${terminfo[kend]/O/[}"  end-of-line
460     [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line
461     [[ "$terminfo[kend]"  == $'\eO'* ]] && bindkey -M emacs "${terminfo[kend]/O/[}"  end-of-line
462 fi
463
464 ## keybindings (run 'bindkeys' for details, more details via man zshzle)
465 # use emacs style per default:
466 bindkey -e
467 # use vi style:
468 # bindkey -v
469
470 #if [[ "$TERM" == screen ]] ; then
471 bindkey '\e[1~' beginning-of-line       # home
472 bindkey '\e[4~' end-of-line             # end
473 bindkey '\e[A'  up-line-or-search       # cursor up
474 bindkey '\e[B'  down-line-or-search     # <ESC>-
475
476 bindkey '^xp'   history-beginning-search-backward
477 bindkey '^xP'   history-beginning-search-forward
478 # bindkey -s '^L' "|less\n"             # ctrl-L pipes to less
479 # bindkey -s '^B' " &\n"                # ctrl-B runs it in the background
480 # if terminal type is set to 'rxvt':
481 bindkey '\e[7~' beginning-of-line       # home
482 bindkey '\e[8~' end-of-line             # end
483 #fi
484
485 # insert unicode character
486 # usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an Â§
487 # See for example http://unicode.org/charts/ for unicode characters code
488 zrcautoload insert-unicode-char
489 zle -N insert-unicode-char
490 #k# Insert Unicode character
491 bindkey '^Xi' insert-unicode-char
492
493 # just type 'cd ...' to get 'cd ../..'
494 #  rationalise-dot() {
495 #  if [[ $LBUFFER == *.. ]] ; then
496 #    LBUFFER+=/..
497 #  else
498 #    LBUFFER+=.
499 #  fi
500 #  }
501 #  zle -N rationalise-dot
502 #  bindkey . rationalise-dot
503
504 #  bindkey '\eq' push-line-or-edit
505
506 ## toggle the ,. abbreviation feature on/off
507 # NOABBREVIATION: default abbreviation-state
508 #                 0 - enabled (default)
509 #                 1 - disabled
510 NOABBREVIATION=${NOABBREVIATION:-0}
511
512 grml_toggle_abbrev() {
513     if (( ${NOABBREVIATION} > 0 )) ; then
514         NOABBREVIATION=0
515     else
516         NOABBREVIATION=1
517     fi
518 }
519
520 zle -N grml_toggle_abbrev
521 bindkey '^xA' grml_toggle_abbrev
522
523 # }}}
524
525 # a generic accept-line wrapper {{{
526
527 # This widget can prevent unwanted autocorrections from command-name
528 # to _command-name, rehash automatically on enter and call any number
529 # of builtin and user-defined widgets in different contexts.
530 #
531 # For a broader description, see:
532 # <http://bewatermyfriend.org/posts/2007/12-26.11-50-38-tooltime.html>
533 #
534 # The code is imported from the file 'zsh/functions/accept-line' from
535 # <http://ft.bewatermyfriend.org/comp/zsh/zsh-dotfiles.tar.bz2>, which
536 # distributed under the same terms as zsh itself.
537
538 # A newly added command will may not be found or will cause false
539 # correction attempts, if you got auto-correction set. By setting the
540 # following style, we force accept-line() to rehash, if it cannot
541 # find the first word on the command line in the $command[] hash.
542 zstyle ':acceptline:*' rehash true
543
544 function Accept-Line() {
545     setopt localoptions noksharrays
546     local -a subs
547     local -xi aldone
548     local sub
549
550     zstyle -a ":acceptline:${alcontext}" actions subs
551
552     (( ${#subs} < 1 )) && return 0
553
554     (( aldone = 0 ))
555     for sub in ${subs} ; do
556         [[ ${sub} == 'accept-line' ]] && sub='.accept-line'
557         zle ${sub}
558
559         (( aldone > 0 )) && break
560     done
561 }
562
563 function Accept-Line-getdefault() {
564     local default_action
565
566     zstyle -s ":acceptline:${alcontext}" default_action default_action
567     case ${default_action} in
568         ((accept-line|))
569             printf ".accept-line"
570             ;;
571         (*)
572             printf ${default_action}
573             ;;
574     esac
575 }
576
577 function accept-line() {
578     setopt localoptions noksharrays
579     local -a cmdline
580     local -x alcontext
581     local buf com fname format msg default_action
582
583     alcontext='default'
584     buf="${BUFFER}"
585     cmdline=(${(z)BUFFER})
586     com="${cmdline[1]}"
587     fname="_${com}"
588
589     zstyle -t ":acceptline:${alcontext}" rehash \
590         && [[ -z ${commands[$com]} ]]           \
591         && rehash
592
593     if    [[ -n ${reswords[(r)$com]} ]] \
594        || [[ -n ${aliases[$com]}     ]] \
595        || [[ -n ${functions[$com]}   ]] \
596        || [[ -n ${builtins[$com]}    ]] \
597        || [[ -n ${commands[$com]}    ]] ; then
598
599         # there is something sensible to execute, just do it.
600         alcontext='normal'
601         zle Accept-Line
602
603         default_action=$(Accept-Line-getdefault)
604         zstyle -T ":acceptline:${alcontext}" call_default \
605             && zle ${default_action}
606         return
607     fi
608
609     if    [[ -o correct              ]] \
610        || [[ -o correctall           ]] \
611        && [[ -n ${functions[$fname]} ]] ; then
612
613         # nothing there to execute but there is a function called
614         # _command_name; a completion widget. Makes no sense to
615         # call it on the commandline, but the correct{,all} options
616         # will ask for it nevertheless, so warn the user.
617         if [[ ${LASTWIDGET} == 'accept-line' ]] ; then
618             # Okay, we warned the user before, he called us again,
619             # so have it his way.
620             alcontext='force'
621             zle Accept-Line
622
623             default_action=$(Accept-Line-getdefault)
624             zstyle -T ":acceptline:${alcontext}" call_default \
625                 && zle ${default_action}
626             return
627         fi
628
629         # prepare warning message for the user, configurable via zstyle.
630         zstyle -s ":acceptline:${alcontext}" compwarnfmt msg
631
632         if [[ -z ${msg} ]] ; then
633             msg="%c will not execute and completion %f exists."
634         fi
635
636         zformat -f msg "${msg}" "c:${com}" "f:${fname}"
637
638         zle -M -- "${msg}"
639         return
640     elif [[ -n ${buf//[$' \t\n']##/} ]] ; then
641         # If we are here, the commandline contains something that is not
642         # executable, which is neither subject to _command_name correction
643         # and is not empty. might be a variable assignment
644         alcontext='misc'
645         zle Accept-Line
646
647         default_action=$(Accept-Line-getdefault)
648         zstyle -T ":acceptline:${alcontext}" call_default \
649             && zle ${default_action}
650         return
651     fi
652
653     # If we got this far, the commandline only contains whitespace, or is empty.
654     alcontext='empty'
655     zle Accept-Line
656
657     default_action=$(Accept-Line-getdefault)
658     zstyle -T ":acceptline:${alcontext}" call_default \
659         && zle ${default_action}
660 }
661
662 zle -N accept-line
663 zle -N Accept-Line
664
665 # }}}
666
667 # power completion - abbreviation expansion {{{
668 # power completion / abbreviation expansion / buffer expansion
669 # see http://zshwiki.org/home/examples/zleiab for details
670 # less risky than the global aliases but powerful as well
671 # just type the abbreviation key and afterwards ',.' to expand it
672 declare -A abk
673 setopt extendedglob
674 setopt interactivecomments
675 abk=(
676 # key  # value                (#d additional doc string)
677 #A# start
678     '...' '../..'
679     '....' '../../..'
680     'BG' '& exit'
681     'C' '| wc -l'
682     'G' '|& grep --color=auto'
683     'H' '| head'
684     'Hl' ' --help |& less -r'      #d (Display help in pager)
685     'L' '| less'
686     'LL' '|& less -r'
687     'M' '| most'
688     'N' '&>/dev/null'              #d (No Output)
689     'R' '| tr A-z N-za-m'          #d (ROT13)
690     'SL' '| sort | less'
691     'S' '| sort -u'
692     'T' '| tail'
693     'V' '|& vim -'
694 #A# end
695     'hide' "echo -en '\033]50;nil2\007'"
696     'tiny' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-80-*-*-c-*-iso8859-15\007"'
697     'small' 'echo -en "\033]50;6x10\007"'
698     'medium' 'echo -en "\033]50;-misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-15\007"'
699     'default' 'echo -e "\033]50;-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-15\007"'
700     'large' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-150-*-*-c-*-iso8859-15\007"'
701     'huge' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-210-*-*-c-*-iso8859-15\007"'
702     'smartfont' 'echo -en "\033]50;-artwiz-smoothansi-*-*-*-*-*-*-*-*-*-*-*-*\007"'
703     'semifont' 'echo -en "\033]50;-misc-fixed-medium-r-semicondensed-*-*-120-*-*-*-*-iso8859-15\007"'
704     'da' 'du -sch'
705     'j' 'jobs -l'
706     'u' 'translate -i'
707     'co' "./configure && make && sudo make install"
708     'CH' "./configure --help"
709     'conkeror' 'firefox -chrome chrome://conkeror/content'
710     'dir' 'ls -lSrah'
711     'lad' $'ls -d .*(/)\n# only show dot-directories'
712     'lsa' $'ls -a .*(.)\n# only show dot-files'
713     'lss' $'ls -l *(s,S,t)\n# only files with setgid/setuid/sticky flag'
714     'lsl' $'ls -l *(@[1,10])\n# only symlinks'
715     'lsx' $'ls -l *(*[1,10])\n# only executables'
716     'lsw' $'ls -ld *(R,W,X.^ND/)\n# world-{readable,writable,executable} files'
717     'lsbig' $'ls -flh *(.OL[1,10])\n# display the biggest files'
718     'lsd' $'ls -d *(/)\n# only show directories'
719     'lse' $'ls -d *(/^F)\n# only show empty directories'
720     'lsnew' $'ls -rl *(D.om[1,10])\n# display the newest files'
721     'lsold' $'ls -rtlh *(D.om[-11,-1])\n # display the oldest files'
722     'lssmall' $'ls -Srl *(.oL[1,10])\n# display the smallest files'
723     'rw-' 'chmod 600'
724     '600' 'chmod u+rw-x,g-rwx,o-rwx'
725     'rwx' 'chmod u+rwx'
726     '700' 'chmod u+rwx,g-rwx,o-rwx'
727     'r--' 'chmod u+r-wx,g-rwx,o-rwx'
728     '644' $'chmod u+rw-x,g+r-wx,o+r-wx\n # 4=r,2=w,1=x'
729     '755' 'chmod u+rwx,g+r-w+x,o+r-w+x'
730     'md' 'mkdir -p '
731     'cmplayer' 'mplayer -vo -fs -zoom fbdev'
732     'fbmplayer' 'mplayer -vo -fs -zoom fbdev'
733     'fblinks' 'links2 -driver fb'
734     'insecssh' 'ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
735     'insecscp' 'scp -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
736     'fori' 'for i ({..}) { }'
737     'cx' 'chmod +x'
738     'e'  'print -l'
739     'se' 'setopt interactivecomments'
740     'va' 'valac --vapidir=../vapi/ --pkg=gtk+-2.0 gtktest.vala'
741     'fb2' '=mplayer -vo fbdev -fs -zoom 1>/dev/null -xy 2'
742     'fb3' '=mplayer -vo fbdev -fs  -zoom 1>/dev/null -xy 3'
743     'ci' 'centericq'
744     'D'  'export DISPLAY=:0.0'
745     'mp' 'mplayer -vo xv -fs -zoom'
746 )
747
748 globalias() {
749     local MATCH
750
751     if (( NOABBREVIATION > 0 )) ; then
752         LBUFFER="${LBUFFER},."
753         return 0
754     fi
755
756     matched_chars='[.-|_a-zA-Z0-9]#'
757     LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
758     LBUFFER+=${abk[$MATCH]:-$MATCH}
759 }
760
761 zle -N globalias
762 bindkey ",." globalias
763 # }}}
764
765 # {{{ autoloading
766 zrcautoload zmv    # who needs mmv or rename?
767 zrcautoload history-search-end
768
769 # we don't want to quote/espace URLs on our own...
770 # if autoload -U url-quote-magic ; then
771 #    zle -N self-insert url-quote-magic
772 #    zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}='
773 # else
774 #    print 'Notice: no url-quote-magic available :('
775 # fi
776 alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic'
777
778 #m# k ESC-h Call \kbd{run-help} for the 1st word on the command line
779 alias run-help >&/dev/null && unalias run-help
780 zrcautoload run-help # use via 'esc-h'
781
782 # completion system
783 if zrcautoload compinit && compinit 2>/dev/null ; then
784     compinit 2>/dev/null || print 'Notice: no compinit available :('
785 else
786     print 'Notice: no compinit available :('
787     function zstyle { }
788     function compdef { }
789 fi
790
791 is4 && zrcautoload zed # use ZLE editor to edit a file or function
792
793 is4 && \
794 for mod in complist deltochar mathfunc ; do
795     zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :("
796 done
797
798 # autoload zsh modules when they are referenced
799 if is4 ; then
800     tmpargs=(
801         a   stat
802         a   zpty
803         ap  zprof
804         ap  mapfile
805     )
806
807     while (( ${#tmpargs} > 0 )) ; do
808         zmodload -${tmpargs[1]} zsh/${tmpargs[2]} ${tmpargs[2]}
809         shift 2 tmpargs
810     done
811     unset tmpargs
812 fi
813
814 if is4 && zrcautoload insert-files && zle -N insert-files ; then
815     #k# Insert files
816     bindkey "^Xf" insert-files # C-x-f
817 fi
818
819 bindkey ' '   magic-space    # also do history expansion on space
820 #k# Trigger menu-complete
821 bindkey '\ei' menu-complete  # menu completion via esc-i
822
823 # press esc-e for editing command line in $EDITOR or $VISUAL
824 if is4 && zrcautoload edit-command-line && zle -N edit-command-line ; then
825     #k# Edit the current line in \kbd{\$EDITOR}
826     bindkey '\ee' edit-command-line
827 fi
828
829 if is4 && [[ -n ${(k)modules[zsh/complist]} ]] ; then
830     #k# menu selection: pick item but stay in the menu
831     bindkey -M menuselect '\e^M' accept-and-menu-complete
832
833     # use the vi navigation keys (hjkl) besides cursor keys in menu completion
834     #bindkey -M menuselect 'h' vi-backward-char        # left
835     #bindkey -M menuselect 'k' vi-up-line-or-history   # up
836     #bindkey -M menuselect 'l' vi-forward-char         # right
837     #bindkey -M menuselect 'j' vi-down-line-or-history # bottom
838
839     # accept a completion and try to complete again by using menu
840     # completion; very useful with completing directories
841     # by using 'undo' one's got a simple file browser
842     bindkey -M menuselect '^o' accept-and-infer-next-history
843 fi
844
845 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
846 _bkdate() { BUFFER="$BUFFER$(date '+%F')"; CURSOR=$#BUFFER; }
847 zle -N _bkdate
848
849 #k# Insert a timestamp on the command line (yyyy-mm-dd)
850 bindkey '^Ed' _bkdate
851
852 # press esc-m for inserting last typed word again (thanks to caphuso!)
853 insert-last-typed-word() { zle insert-last-word -- 0 -1 };
854 zle -N insert-last-typed-word;
855
856 #k# Insert last typed word
857 bindkey "\em" insert-last-typed-word
858
859 # set command prediction from history, see 'man 1 zshcontrib'
860 #  is4 && zrcautoload predict-on && \
861 #  zle -N predict-on         && \
862 #  zle -N predict-off        && \
863 #  bindkey "^X^Z" predict-on && \
864 #  bindkey "^Z" predict-off
865
866 #k# Shortcut for \kbd{fg<enter>}
867 bindkey -s '^z' "fg\n"
868
869 # press ctrl-q to quote line:
870 #  mquote () {
871 #        zle beginning-of-line
872 #        zle forward-word
873 #        # RBUFFER="'$RBUFFER'"
874 #        RBUFFER=${(q)RBUFFER}
875 #        zle end-of-line
876 #  }
877 #  zle -N mquote && bindkey '^q' mquote
878
879 # run command line as user root via sudo:
880 sudo-command-line() {
881     [[ -z $BUFFER ]] && zle up-history
882     [[ $BUFFER != sudo\ * ]] && BUFFER="sudo $BUFFER"
883 }
884 zle -N sudo-command-line
885
886 #k# Put the current command line into a \kbd{sudo} call
887 bindkey "^Os" sudo-command-line
888
889 ### jump behind the first word on the cmdline.
890 ### useful to add options.
891 function jump_after_first_word() {
892     local words
893     words=(${(z)BUFFER})
894
895     if (( ${#words} <= 1 )) ; then
896         CURSOR=${#BUFFER}
897     else
898         CURSOR=${#${words[1]}}
899     fi
900 }
901 zle -N jump_after_first_word
902
903 bindkey '^x1' jump_after_first_word
904
905 # }}}
906
907 # {{{ set some important options
908 # Please update these tags, if you change the umask settings below.
909 #o# r_umask     002
910 #o# r_umaskstr  rwxrwxr-x
911 #o# umask       022
912 #o# umaskstr    rwxr-xr-x
913 (( EUID != 0 )) && umask 002 || umask 022
914
915 # history:
916 setopt append_history       # append history list to the history file (important for multiple parallel zsh sessions!)
917 is4 && setopt SHARE_HISTORY # import new commands from the history file also in other zsh-session
918 setopt extended_history     # save each command's beginning timestamp and the duration to the history file
919 is4 && setopt histignorealldups # If  a  new  command  line being added to the history
920                             # list duplicates an older one, the older command is removed from the list
921 setopt histignorespace      # remove command lines from the history list when
922                             # the first character on the line is a space
923 #  setopt histallowclobber    # add `|' to output redirections in the history
924 #  setopt NO_clobber          # warning if file exists ('cat /dev/null > ~/.zshrc')
925 setopt auto_cd              # if a command is issued that can't be executed as a normal command,
926                             # and the command is the name of a directory, perform the cd command to that directory
927 setopt extended_glob        # in order to use #, ~ and ^ for filename generation
928                             # grep word *~(*.gz|*.bz|*.bz2|*.zip|*.Z) ->
929                             # -> searches for word not in compressed files
930                             # don't forget to quote '^', '~' and '#'!
931 setopt longlistjobs         # display PID when suspending processes as well
932 setopt notify               # report the status of backgrounds jobs immediately
933 setopt hash_list_all        # Whenever a command completion is attempted, make sure \
934                             # the entire command path is hashed first.
935 setopt completeinword       # not just at the end
936 # setopt nocheckjobs          # don't warn me about bg processes when exiting
937 setopt nohup                # and don't kill them, either
938 # setopt printexitvalue       # alert me if something failed
939 # setopt dvorak               # with spelling correction, assume dvorak kb
940 setopt auto_pushd           # make cd push the old directory onto the directory stack.
941 setopt nonomatch            # try to avoid the 'zsh: no matches found...'
942 setopt nobeep               # avoid "beep"ing
943 setopt pushd_ignore_dups    # don't push the same dir twice.
944
945 MAILCHECK=30       # mailchecks
946 REPORTTIME=5       # report about cpu-/system-/user-time of command if running longer than 5 seconds
947 watch=(notme root) # watch for everyone but me and root
948
949 # define word separators (for stuff like backward-word, forward-word, backward-kill-word,..)
950 #  WORDCHARS='*?_-.[]~=/&;!#$%^(){}<>' # the default
951 #  WORDCHARS=.
952 #  WORDCHARS='*?_[]~=&;!#$%^(){}'
953 #  WORDCHARS='${WORDCHARS:s@/@}'
954
955 # only slash should be considered as a word separator:
956 slash-backward-kill-word() {
957     local WORDCHARS="${WORDCHARS:s@/@}"
958     # zle backward-word
959     zle backward-kill-word
960 }
961 zle -N slash-backward-kill-word
962
963 #k# Kill everything in a word up to its last \kbd{/}
964 bindkey '\ev' slash-backward-kill-word
965
966 # }}}
967
968 # {{{ history
969
970 ZSHDIR=$HOME/.zsh
971
972 #v#
973 HISTFILE=$HOME/.zsh_history
974 isgrmlcd && HISTSIZE=500  || HISTSIZE=5000
975 isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
976
977 # }}}
978
979 # dirstack handling {{{
980
981 DIRSTACKSIZE=${DIRSTACKSIZE:-20}
982 DIRSTACKFILE=${DIRSTACKFILE:-${HOME}/.zdirs}
983
984 if [[ -f ${DIRSTACKFILE} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then
985     dirstack=( ${(f)"$(< $DIRSTACKFILE)"} )
986     # "cd -" won't work after login by just setting $OLDPWD, so
987     [[ -d $dirstack[0] ]] && cd $dirstack[0] && cd $OLDPWD
988 fi
989
990 chpwd() {
991     if is42 ; then
992         builtin print -l ${(u)dirstack} >! ${DIRSTACKFILE}
993     else
994         uprint dirstack >! ${DIRSTACKFILE}
995     fi
996 }
997
998 # }}}
999
1000 # {{{ display battery status on right side of prompt via running 'BATTERY=1 zsh'
1001 if [[ -n "$BATTERY" ]] ; then
1002     if check_com -c acpi ; then
1003         PERCENT="${(C)${(s| |)$(acpi 2>/dev/null)}[4]}"
1004         [[ -z "$PERCENT" ]] && PERCENT='acpi not present'
1005
1006         if [[ "${PERCENT%%%}" -lt 20 ]] ; then
1007             PERCENT="warning: ${PERCENT}%"
1008         fi
1009     fi
1010 fi
1011 # }}}
1012
1013 # set colors for use in prompts {{{
1014 if zrcautoload colors && colors 2>/dev/null ; then
1015     BLUE="%{${fg[blue]}%}"
1016     RED="%{${fg_bold[red]}%}"
1017     GREEN="%{${fg[green]}%}"
1018     CYAN="%{${fg[cyan]}%}"
1019     MAGENTA="%{${fg[magenta]}%}"
1020     YELLOW="%{${fg[yellow]}%}"
1021     WHITE="%{${fg[white]}%}"
1022     NO_COLOUR="%{${reset_color}%}"
1023 else
1024     BLUE=$'%{\e[1;34m%}'
1025     RED=$'%{\e[1;31m%}'
1026     GREEN=$'%{\e[1;32m%}'
1027     CYAN=$'%{\e[1;36m%}'
1028     WHITE=$'%{\e[1;37m%}'
1029     MAGENTA=$'%{\e[1;35m%}'
1030     YELLOW=$'%{\e[1;33m%}'
1031     NO_COLOUR=$'%{\e[0m%}'
1032 fi
1033
1034 # }}}
1035
1036 # gather version control information for inclusion in a prompt {{{
1037
1038 # vcs_info() documentation: {{{
1039 #
1040 # The vcs_info() feature can be configured via zstyle:
1041 #   First, the context in which we are working:
1042 #       :vcs_info:<vcs-string>
1043 #   ...where <vcs-string> is one of:
1044 #       - git, git-svn, hg, darcs, bzr, svn or svk
1045 #
1046 #   You can of course use ':vcs_info:*' to match all VCSs at once.
1047 #
1048 # There is one special context named 'init', that is in effect as long
1049 # as there was no decision what vcs backend to use.
1050 #
1051 # There are currently two styles, that are looked up:
1052 #   promptformat        - Used in most circumstances.
1053 #   promptactionformat  - Used if a there is a special action going on;
1054 #                         (like an interactive rebase or a merge conflict)
1055 #   enable              - check in the 'init' context. If set to false,
1056 #                         vcs_info() will do nothing.
1057 #   disable             - provide a list of systems, you don't want
1058 #                         the prompt to check for repositories (checked
1059 #                         in the 'init' context, too).
1060 #
1061 # The default values for these in all contexts are:
1062 #   promptformat        " (%s)-[%b|%a]-"
1063 #   promptactionformat  " (%s)-[%b]-"
1064 #   enable              true
1065 #
1066 # In these formats, the following replacements are done:
1067 #   %s  - The vcs in use (git, hg, svn etc.)
1068 #   %b  - Information about the current branch.
1069 #   %a  - An identifier, that describes the action.
1070 #         Only makes sense in promptactionformat.
1071 #   %R  - base directory of the repository.
1072 #   %r  - repository name
1073 #         If %R is '/foo/bar/repoXY', %r is 'repoXY'.
1074 #
1075 # Not all vcs backends may support all replacements
1076 #
1077 # Examples:
1078 #   Don't use vcs_info at all (even though it's in your prompt):
1079 #   % zstyle ':vcs_info:*' enable false
1080 #
1081 #   Don't provide prompt info for bzr and svk:
1082 #   % zstyle ':vcs_info:*' disable bzr svk
1083 #
1084 #   Provide a prompt specifically for git:
1085 #   % zstyle ':vcs_info:git' promptformat       ' GIT, BABY! [%b]'
1086 #   % zstyle ':vcs_info:git' promptactionformat ' GIT ACTION! [%b|%a]'
1087 #
1088 # If you want colors, make sure you enclose the color codes in %{...%}, because
1089 # the string provided by vcs_info() is used for prompts.
1090 #
1091 #   Example: PROMPT='%(?..[%?]-)%3~%$(vcs_info)#'
1092 #
1093 # This *requires* 'setopt prompt_subst'.
1094 # }}}
1095 VCS_INFO_adjust () { #{{{
1096     [[ -n ${vcs_comm[overwrite_name]} ]] && vcs=${vcs_comm[overwrite_name]}
1097     return 0
1098 }
1099 # }}}
1100 VCS_INFO_format () { # {{{
1101     local msg
1102
1103     if [[ -n ${1} ]] ; then
1104         zstyle -s ":vcs_info:${vcs}" promptactionformat msg
1105         [[ -z ${msg} ]] && msg=' (%s)-[%b|%a]-'
1106     else
1107         zstyle -s ":vcs_info:${vcs}" promptformat msg
1108         [[ -z ${msg} ]] && msg=' (%s)-[%b]-'
1109     fi
1110     printf '%s' ${msg}
1111 }
1112 # }}}
1113 VCS_INFO_realpath () { #{{{
1114     # replacing 'readlink -f', which is really not portable.
1115
1116     # If there *is* a chpwd() function unfunction it here.
1117     # The *real* zsh does not loose its chpwd(), because we run
1118     # in a different context (process substitution in $PROMPT).
1119     (( ${+functions[chpwd]} )) && unfunction chpwd
1120     setopt chaselinks
1121     cd $1 2>/dev/null && pwd
1122 }
1123 # }}}
1124 VCS_INFO_git_getaction () { #{{{
1125     local gitaction='' gitdir=${1}
1126     local tmp
1127
1128     for tmp in "${gitdir}/rebase-apply" \
1129                "${gitdir}/rebase"       \
1130                "${gitdir}/../.dotest" ; do
1131         if [[ -d ${tmp} ]] ; then
1132             if   [[ -f "${tmp}/rebasing" ]] ; then
1133                 gitaction="rebase"
1134             elif [[ -f "${tmp}/applying" ]] ; then
1135                 gitaction="am"
1136             else
1137                 gitaction="am/rebase"
1138             fi
1139             printf '%s' ${gitaction}
1140             return 0
1141         fi
1142     done
1143
1144     for tmp in "${gitdir}/rebase-merge/interactive" \
1145                "${gitdir}/.dotest-merge/interactive" ; do
1146         if [[ -f "${tmp}" ]] ; then
1147             printf '%s' "rebase-i"
1148             return 0
1149         fi
1150     done
1151
1152     for tmp in "${gitdir}/rebase-merge" \
1153                "${gitdir}/.dotest-merge" ; do
1154         if [[ -d "${tmp}" ]] ; then
1155             printf '%s' "rebase-m"
1156             return 0
1157         fi
1158     done
1159
1160     if [[ -f "${gitdir}/MERGE_HEAD" ]] ; then
1161         printf '%s' "merge"
1162     else
1163         if [[ -f "${gitdir}/BISECT_LOG" ]] ; then
1164             printf '%s' "bisect"
1165         fi
1166     fi
1167
1168     return 1
1169 }
1170 # }}}
1171 VCS_INFO_git_getbranch () { #{{{
1172     local gitbranch gitdir=${1}
1173     local gitsymref='git symbolic-ref HEAD'
1174
1175     if    [[ -d "${gitdir}/rebase-apply" ]] \
1176        || [[ -d "${gitdir}/rebase" ]]       \
1177        || [[ -d "${gitdir}/../.dotest" ]]   \
1178        || [[ -f "${gitdir}/MERGE_HEAD" ]] ; then
1179         gitbranch="$(${(z)gitsymref} 2> /dev/null)"
1180         [[ -z ${gitbranch} ]] && gitbranch="$(< ${gitdir}/rebase-apply/head-name)"
1181
1182     elif   [[ -f "${gitdir}/rebase-merge/interactive" ]] \
1183         || [[ -d "${gitdir}/rebase-merge" ]] ; then
1184         gitbranch="$(< ${gitdir}/rebase-merge/head-name)"
1185
1186     elif   [[ -f "${gitdir}/.dotest-merge/interactive" ]] \
1187         || [[ -d "${gitdir}/.dotest-merge" ]] ; then
1188         gitbranch="$(< ${gitdir}/.dotest-merge/head-name)"
1189
1190     else
1191         gitbranch="$(${(z)gitsymref} 2> /dev/null)"
1192
1193         if [[ $? -ne 0 ]] ; then
1194             gitbranch="$(git describe --exact-match HEAD 2>/dev/null)"
1195
1196             if [[ $? -ne 0 ]] ; then
1197                 gitbranch="${${"$(< $gitdir/HEAD)"}[1,7]}..."
1198             fi
1199         fi
1200     fi
1201
1202     printf '%s' "${gitbranch##refs/heads/}"
1203 }
1204 # }}}
1205 VCS_INFO_git_get_data () { # {{{
1206     setopt localoptions extendedglob
1207     local gitdir gitbase gitbranch gitaction msg
1208
1209     gitdir=${vcs_comm[gitdir]}
1210     gitbranch="$(VCS_INFO_git_getbranch ${gitdir})"
1211
1212     if [[ -z ${gitdir} ]] || [[ -z ${gitbranch} ]] ; then
1213         return
1214     fi
1215
1216     VCS_INFO_adjust
1217     gitaction="$(VCS_INFO_git_getaction ${gitdir})"
1218     msg=$(VCS_INFO_format ${gitaction})
1219
1220     gitbase=${PWD%/${$(git rev-parse --show-prefix)%/##}}
1221
1222     zformat -f msg "${msg}" "a:${gitaction}" "b:${gitbranch}" "s:${vcs}" "r:${gitbase:t}" "R:${gitbase}"
1223     printf '%s' ${msg}
1224 }
1225 # }}}
1226 VCS_INFO_darcs_get_data () { # {{{
1227     local msg darcsbase
1228
1229     darcsbase=${vcs_comm[basedir]}
1230     msg=$(VCS_INFO_format)
1231     zformat -f msg "${msg}" "a:" "b:${darcsbase:t}" "s:${vcs}" "r:${darcsbase:t}" "R:${darcsbase}"
1232     printf '%s' ${msg}
1233 }
1234 # }}}
1235 VCS_INFO_hg_get_data () { # {{{
1236     local msg hgbranch hgbase
1237
1238     hgbase=${vcs_comm[basedir]}
1239     hgbranch=$(< ${hgbase}/.hg/branch)
1240     msg=$(VCS_INFO_format)
1241     zformat -f msg "${msg}" "a:" "b:${hgbranch}" "s:${vcs}" "r:${hgbase:t}" "R:${hgbase}"
1242     printf '%s' ${msg}
1243 }
1244 # }}}
1245 VCS_INFO_svk_get_data () { # {{{
1246     local msg svkbranch svkbase
1247
1248     svkbase=${vcs_comm[basedir]}
1249     svkbranch=${svkbase##*
1250   }
1251     svkbase=${svkbase%%
1252   *}
1253
1254     msg=$(VCS_INFO_format)
1255     zformat -f msg "${msg}" "a:" "b:${svkbranch}" "s:${vcs}" "r:${svkbase:t}" "R:${svkbase}"
1256     printf '%s' ${msg}
1257 }
1258 # }}}
1259 VCS_INFO_svn_get_data () { # {{{
1260     local msg svnbranch svnbase
1261
1262     svnbase="."
1263     while [[ -d "${svnbase}/../.svn" ]]; do
1264         svnbase="${svnbase}/.."
1265     done
1266     svnbase=$(VCS_INFO_realpath ${svnbase})
1267     svnbranch=$(svn info "$base_dir" | awk '/^URL/ { sub(".*/","",$0); r=$0 } /^Revision/ { sub("[^0-9]*","",$0); print r":"$0 }')
1268
1269     msg=$(VCS_INFO_format)
1270     zformat -f msg "${msg}" "a:" "b:${svnbranch}" "s:${vcs}" "r:${svnbase:t}" "R:${svnbase}"
1271     printf '%s' ${msg}
1272 }
1273 # }}}
1274 VCS_INFO_bzr_get_data () { # {{{
1275     local msg bzrbranch bzrbase bzrrevno i j
1276
1277     bzrbase=$(bzr info | sed -rne 's, *branch root: ,,p')
1278     case ${bzrbase} in
1279         .) bzrbase=${PWD} ;;
1280     esac
1281
1282     bzr version-info | while read i j; do
1283         case "${i}" in
1284             revno:)
1285                 bzrrevno=${j} ;;
1286             branch-nick:)
1287                 bzrbranch=${j} ;;
1288         esac
1289     done
1290
1291     msg=$(VCS_INFO_format)
1292     zformat -f msg "${msg}" "a:" "b:${bzrbranch}:${bzrrevno}" "s:${vcs}" "r:${bzrbase:t}" "R:${bzrbase}"
1293     printf '%s' ${msg}
1294 }
1295 # }}}
1296 # VCS_INFO_*_detect () {{{
1297
1298 VCS_INFO_detect_by_dir() {
1299     local dirname=${1}
1300     local basedir="." realbasedir
1301
1302     realbasedir=$(VCS_INFO_realpath ${basedir})
1303     while [[ ${realbasedir} != '/' ]]; do
1304         if [[ -n ${vcs_comm[detect_need_file]} ]] ; then
1305             [[ -d ${basedir}/${dirname} ]] && \
1306             [[ -f ${basedir}/${dirname}/${vcs_comm[detect_need_file]} ]] && \
1307                 break
1308         else
1309             [[ -d ${basedir}/${dirname} ]] && break
1310         fi
1311
1312         basedir=${basedir}/..
1313         realbasedir=$(VCS_INFO_realpath ${basedir})
1314     done
1315
1316     [[ ${realbasedir} == "/" ]] && return 1
1317     vcs_comm[basedir]=${realbasedir}
1318     return 0
1319 }
1320
1321 VCS_INFO_bzr_detect() {
1322     check_com -c bzr || return 1
1323     VCS_INFO_detect_by_dir '.bzr'
1324     return $?
1325 }
1326
1327 VCS_INFO_darcs_detect() {
1328     check_com -c darcs || return 1
1329     vcs_comm[detect_need_file]=format
1330     VCS_INFO_detect_by_dir '_darcs'
1331     return $?
1332 }
1333
1334 VCS_INFO_git_detect() {
1335     if check_com -c git && git rev-parse --is-inside-work-tree &> /dev/null ; then
1336         vcs_comm[gitdir]="$(git rev-parse --git-dir 2> /dev/null)" || return 1
1337         [[ -d ${vcs_comm[gitdir]}/svn ]] && vcs_comm[overwrite_name]='git-svn'
1338         return 0
1339     fi
1340     return 1
1341 }
1342
1343 VCS_INFO_hg_detect() {
1344     check_com -c hg || return 1
1345     vcs_comm[detect_need_file]=branch
1346     VCS_INFO_detect_by_dir '.hg'
1347     return $?
1348 }
1349
1350 VCS_INFO_svk_detect() {
1351     local basedir
1352
1353     check_com -c svk || return 1
1354     [[ -f ~/.svk/config ]] || return 1
1355
1356     basedir=$(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
1357
1358     vcs_comm[basedir]=${basedir}
1359     return 0
1360 }
1361
1362 VCS_INFO_svn_detect() {
1363     check_com -c svn || return 1
1364     [[ -d ".svn" ]] && return 0
1365     return 1
1366 }
1367
1368 # }}}
1369 vcs_info () { # {{{
1370     local string
1371     local -i found
1372     local -a VCSs disabled
1373     local -x vcs
1374     local -Ax vcs_comm
1375
1376     vcs="init"
1377     zstyle -T ":vcs_info:${vcs}" "enable" || return 0
1378     zstyle -a ":vcs_info:${vcs}" "disable" disabled
1379
1380     VCSs=(git hg bzr darcs svn svk)
1381
1382     (( found = 0 ))
1383     for vcs in ${VCSs} ; do
1384         [[ -n ${(M)disabled:#${vcs}} ]] && continue
1385         vcs_comm=()
1386         VCS_INFO_${vcs}_detect && (( found = 1 )) && break
1387     done
1388
1389     (( found == 0 )) && return 0
1390
1391     string=$(VCS_INFO_${vcs}_get_data) || return 1
1392     printf '%s' ${string}
1393     return 0
1394 }
1395 # }}}
1396
1397 # change vcs_info formats for the grml prompt
1398 if [[ "$TERM" == dumb ]] ; then
1399     zstyle ':vcs_info:*' promptactionformat "(%s%)-[%b|%a] "
1400     zstyle ':vcs_info:*' promptformat       "(%s%)-[%b] "
1401 else
1402     # these are the same, just with a lot of colours:
1403     zstyle ':vcs_info:*' promptactionformat "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOUR} "
1404     zstyle ':vcs_info:*' promptformat       "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOUR}%} "
1405 fi
1406
1407 # }}}
1408
1409 # {{{ set prompt
1410 if zrcautoload promptinit && promptinit 2>/dev/null ; then
1411     promptinit # people should be able to use their favourite prompt
1412 else
1413     print 'Notice: no promptinit available :('
1414 fi
1415
1416 setopt prompt_subst
1417
1418 # precmd() => a function which is executed just before each prompt
1419 # use 'NOPRECMD=1' to disable the precmd + preexec commands
1420
1421 # precmd () { setopt promptsubst; [[ -o interactive ]] && jobs -l;
1422
1423 # make sure to use right prompt only when not running a command
1424 is41 && setopt transient_rprompt
1425
1426 is4 && [[ -z $NOPRECMD ]] && precmd () {
1427     [[ -n $NOPRECMD ]] && return 0
1428     # allow manual overwriting of RPROMPT
1429     if [[ -n $RPROMPT ]] ; then
1430         [[ $TERM == screen* ]] && echo -n $'\ekzsh\e\\'
1431         # return 0
1432     fi
1433     # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
1434     if [[ -z $DONTSETRPROMPT ]] ; then
1435         if [[ -n $BATTERY ]] ; then
1436             RPROMPT="%(?..:()% ${PERCENT}${SCREENTITLE}"
1437             # RPROMPT="${PERCENT}${SCREENTITLE}"
1438         else
1439             RPROMPT="%(?..:()% ${SCREENTITLE}"
1440             # RPROMPT="${SCREENTITLE}"
1441         fi
1442     fi
1443     # adjust title of xterm
1444     # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
1445     case $TERM in
1446         (xterm*|rxvt)
1447             print -Pn "\e]0;%n@%m: %~\a"
1448             ;;
1449     esac
1450 }
1451
1452 # chpwd () => a function which is executed whenever the directory is changed
1453
1454 # preexec() => a function running before every command
1455 is4 && [[ -z $NOPRECMD ]] && \
1456 preexec () {
1457     [[ -n $NOPRECMD ]] && return 0
1458 # set hostname if not running on host with name 'grml'
1459     if [[ -n "$HOSTNAME" ]] && [[ "$HOSTNAME" != $(hostname) ]] ; then
1460        NAME="@$HOSTNAME"
1461     fi
1462 # get the name of the program currently running and hostname of local machine
1463 # set screen window title if running in a screen
1464     if [[ "$TERM" == screen* ]] ; then
1465         # local CMD=${1[(wr)^(*=*|sudo|ssh|-*)]}       # don't use hostname
1466         local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME" # use hostname
1467         echo -ne "\ek$CMD\e\\"
1468     fi
1469 # set the screen title to "zsh" when sitting at the command prompt:
1470     if [[ "$TERM" == screen* ]] ; then
1471         SCREENTITLE=$'%{\ekzsh\e\\%}'
1472     else
1473         SCREENTITLE=''
1474     fi
1475 # adjust title of xterm
1476     case $TERM in
1477         (xterm*|rxvt)
1478             print -Pn "\e]0;%n@%m: $1\a"
1479             ;;
1480     esac
1481 }
1482
1483 EXITCODE="%(?..%?%1v )"
1484 PS2='`%_> '       # secondary prompt, printed when the shell needs more information to complete a command.
1485 PS3='?# '         # selection prompt used within a select loop.
1486 PS4='+%N:%i:%_> ' # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
1487
1488 # set variable debian_chroot if running in a chroot with /etc/debian_chroot
1489 if [[ -z "$debian_chroot" ]] && [[ -r /etc/debian_chroot ]] ; then
1490     debian_chroot=$(cat /etc/debian_chroot)
1491 fi
1492
1493 # don't use colors on dumb terminals (like emacs):
1494 if [[ "$TERM" == dumb ]] ; then
1495     PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< "'$(vcs_info)'"%# "
1496 else
1497     # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended prompt
1498     # set variable identifying the chroot you work in (used in the prompt below)
1499     if [[ -n $GRMLPROMPT ]] ; then
1500         PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
1501 ${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# "
1502     else
1503         # This assembles the primary prompt string
1504         if (( EUID != 0 )); then
1505             PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "'$(vcs_info)'"%# "
1506         else
1507             PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "'$(vcs_info)'"%# "
1508         fi
1509     fi
1510 fi
1511
1512 # if we are inside a grml-chroot set a specific prompt theme
1513 if [[ -n "$GRML_CHROOT" ]] ; then
1514     PROMPT="%{$fg[red]%}(CHROOT) %{$fg_bold[red]%}%n%{$fg_no_bold[white]%}@%m %40<...<%B%~%b%<< %\# "
1515 fi
1516 # }}}
1517
1518 # {{{ 'hash' some often used directories
1519 #d# start
1520 hash -d deb=/var/cache/apt/archives
1521 hash -d doc=/usr/share/doc
1522 hash -d linux=/lib/modules/$(command uname -r)/build/
1523 hash -d log=/var/log
1524 hash -d slog=/var/log/syslog
1525 hash -d src=/usr/src
1526 hash -d templ=/usr/share/doc/grml-templates
1527 hash -d tt=/usr/share/doc/texttools-doc
1528 hash -d www=/var/www
1529 #d# end
1530 # }}}
1531
1532 # {{{ some aliases
1533 if [[ $UID -eq 0 ]] ; then
1534     [[ -r /etc/grml/screenrc ]] && alias screen='/usr/bin/screen -c /etc/grml/screenrc'
1535 elif [[ -r $HOME/.screenrc ]] ; then
1536     alias screen="/usr/bin/screen -c $HOME/.screenrc"
1537 else
1538     [[ -r /etc/grml/screenrc_grml ]] && alias screen='/usr/bin/screen -c /etc/grml/screenrc_grml'
1539 fi
1540
1541 # do we have GNU ls with color-support?
1542 if ls --help 2>/dev/null | grep -- --color= >/dev/null && [[ "$TERM" != dumb ]] ; then
1543     #a1# execute \kbd{@a@}:\quad ls with colors
1544     alias ls='ls -b -CF --color=auto'
1545     #a1# execute \kbd{@a@}:\quad list all files, with colors
1546     alias la='ls -la --color=auto'
1547     #a1# long colored list, without dotfiles (@a@)
1548     alias ll='ls -l --color=auto'
1549     #a1# long colored list, human readable sizes (@a@)
1550     alias lh='ls -hAl --color=auto'
1551     #a1# List files, append qualifier to filenames \\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
1552     alias l='ls -lF --color=auto'
1553 else
1554     alias ls='ls -b -CF'
1555     alias la='ls -la'
1556     alias ll='ls -l'
1557     alias lh='ls -hAl'
1558     alias l='ls -lF'
1559 fi
1560
1561 alias mdstat='cat /proc/mdstat'
1562 alias ...='cd ../../'
1563
1564 # generate alias named "$KERNELVERSION-reboot" so you can use boot with kexec:
1565 if [[ -x /sbin/kexec ]] && [[ -r /proc/cmdline ]] ; then
1566     alias "$(uname -r)-reboot"="kexec -l --initrd=/boot/initrd.img-"$(uname -r)" --command-line=\"$(cat /proc/cmdline)\" /boot/vmlinuz-"$(uname -r)""
1567 fi
1568
1569 alias cp='nocorrect cp'         # no spelling correction on cp
1570 alias mkdir='nocorrect mkdir'   # no spelling correction on mkdir
1571 alias mv='nocorrect mv'         # no spelling correction on mv
1572 alias rm='nocorrect rm'         # no spelling correction on rm
1573
1574 #a1# Execute \kbd{rmdir}
1575 alias rd='rmdir'
1576 #a1# Execute \kbd{rmdir}
1577 alias md='mkdir'
1578
1579 # see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
1580 alias term2iso="echo 'Setting terminal to iso mode' ; print -n '\e%@'"
1581 alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
1582
1583 # make sure it is not assigned yet
1584 [[ $(whence -w utf2iso &>/dev/null) == 'utf2iso: alias' ]] && unalias utf2iso
1585
1586 utf2iso() {
1587     if isutfenv ; then
1588         for ENV in $(env | command grep -i '.utf') ; do
1589             eval export "$(echo $ENV | sed 's/UTF-8/iso885915/ ; s/utf8/iso885915/')"
1590         done
1591     fi
1592 }
1593
1594 # make sure it is not assigned yet
1595 [[ $(whence -w iso2utf &>/dev/null) == 'iso2utf: alias' ]] && unalias iso2utf
1596 iso2utf() {
1597     if ! isutfenv ; then
1598         for ENV in $(env | command grep -i '\.iso') ; do
1599             eval export "$(echo $ENV | sed 's/iso.*/UTF-8/ ; s/ISO.*/UTF-8/')"
1600         done
1601     fi
1602 }
1603
1604 # set up software synthesizer via speakup
1605 swspeak() {
1606     aumix -w 90 -v 90 -p 90 -m 90
1607     if ! [[ -r /dev/softsynth ]] ; then
1608         flite -o play -t "Sorry, software synthesizer not available. Did you boot with swspeak bootoption?"
1609         return 1
1610     else
1611         setopt singlelinezle
1612         unsetopt prompt_cr
1613         export PS1="%m%# "
1614         nice -n -20 speechd-up
1615         sleep 2
1616         flite -o play -t "Finished setting up software synthesizer"
1617     fi
1618 }
1619
1620 # I like clean prompt, so provide simple way to get that
1621 check_com 0 || alias 0='return 0'
1622
1623 # for really lazy people like mika:
1624 check_com S &>/dev/null || alias S='screen'
1625 check_com s &>/dev/null || alias s='ssh'
1626
1627 # get top 10 shell commands:
1628 alias top10='print -l ? ${(o)history%% *} | uniq -c | sort -nr | head -n 10'
1629
1630 # truecrypt; use e.g. via 'truec /dev/ice /mnt/ice' or 'truec -i'
1631 if check_com -c truecrypt ; then
1632     if isutfenv ; then
1633         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077,utf8" '
1634     else
1635         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077" '
1636     fi
1637 fi
1638
1639 #f1# Hints for the use of zsh on grml
1640 zsh-help() {
1641     print "$bg[white]$fg[black]
1642 zsh-help - hints for use of zsh on grml
1643 =======================================$reset_color"
1644
1645     print '
1646 Main configuration of zsh happens in /etc/zsh/zshrc (global)
1647 and /etc/skel/.zshrc which is copied to $HOME/.zshrc once.
1648 The files are part of the package grml-etc-core, if you want to
1649 use them on a non-grml-system just get the tar.gz from
1650 http://deb.grml.org/ or get the files from the mercurial
1651 repository:
1652
1653   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
1654   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
1655
1656 If you want to stay in sync with zsh configuration of grml
1657 run '\''ln -sf /etc/skel/.zshrc $HOME/.zshrc'\'' and configure
1658 your own stuff in $HOME/.zshrc.local. System wide configuration
1659 without touching configuration files of grml can take place
1660 in /etc/zsh/zshrc.local.
1661
1662 If you want to use the configuration of user grml also when
1663 running as user root just run '\''zshskel'\'' which will source
1664 the file /etc/skel/.zshrc.
1665
1666 For information regarding zsh start at http://grml.org/zsh/
1667
1668 Take a look at grml'\''s zsh refcard:
1669 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
1670
1671 Check out the main zsh refcard:
1672 % '$BROWSER' http://www.bash2zsh.com/zsh_refcard/refcard.pdf
1673
1674 And of course visit the zsh-lovers:
1675 % man zsh-lovers
1676
1677 You can adjust some options through environment variables when
1678 invoking zsh without having to edit configuration files.
1679 Basically meant for bash users who are not used to the power of
1680 the zsh yet. :)
1681
1682   "NOCOR=1    zsh" => deactivate automatic correction
1683   "NOMENU=1   zsh" => do not use menu completion (note: use strg-d for completion instead!)
1684   "NOPRECMD=1 zsh" => disable the precmd + preexec commands (set GNU screen title)
1685   "BATTERY=1  zsh" => activate battery status (via acpi) on right side of prompt'
1686
1687     print "
1688 $bg[white]$fg[black]
1689 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
1690 Enjoy your grml system with the zsh!$reset_color"
1691 }
1692
1693 # debian stuff
1694 if [[ -r /etc/debian_version ]] ; then
1695     #a3# Execute \kbd{apt-cache search}
1696     alias acs='apt-cache search'
1697     #a3# Execute \kbd{apt-cache show}
1698     alias acsh='apt-cache show'
1699     #a3# Execute \kbd{apt-cache policy}
1700     alias acp='apt-cache policy'
1701     #a3# Execute \kbd{apt-get dist-upgrade}
1702     salias adg="apt-get dist-upgrade"
1703     #a3# Execute \kbd{apt-get install}
1704     salias agi="apt-get install"
1705     #a3# Execute \kbd{aptitude install}
1706     salias ati="aptitude install"
1707     #a3# Execute \kbd{apt-get upgrade}
1708     salias ag="apt-get upgrade"
1709     #a3# Execute \kbd{apt-get update}
1710     salias au="apt-get update"
1711     #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
1712     salias -a up="aptitude update ; aptitude safe-upgrade"
1713     #a3# Execute \kbd{dpkg-buildpackage}
1714     alias dbp='dpkg-buildpackage'
1715     #a3# Execute \kbd{grep-excuses}
1716     alias ge='grep-excuses'
1717
1718     # debian upgrade
1719     #f3# Execute \kbd{apt-get update \&\& }\\&\quad \kbd{apt-get dist-upgrade}
1720     upgrade() {
1721         if [[ -z "$1" ]] ; then
1722             $SUDO apt-get update
1723             $SUDO apt-get -u upgrade
1724         else
1725             ssh $1 $SUDO apt-get update
1726             # ask before the upgrade
1727             local dummy
1728             ssh $1 $SUDO apt-get --no-act upgrade
1729             echo -n 'Process the upgrade?'
1730             read -q dummy
1731             if [[ $dummy == "y" ]] ; then
1732                 ssh $1 $SUDO apt-get -u upgrade --yes
1733             fi
1734         fi
1735     }
1736
1737     # get a root shell as normal user in live-cd mode:
1738     if isgrmlcd && [[ $UID -ne 0 ]] ; then
1739        alias su="sudo su"
1740      fi
1741
1742     #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
1743     alias llog="$PAGER /var/log/syslog"     # take a look at the syslog
1744     #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
1745     alias tlog="tail -f /var/log/syslog"    # follow the syslog
1746     #a1# (Re)-source \kbd{/etc/skel/.zshrc}
1747     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
1748 fi
1749
1750 # sort installed Debian-packages by size
1751 if check_com -c grep-status ; then
1752     #a3# List installed Debian-packages sorted by size
1753     alias debs-by-size='grep-status -FStatus -sInstalled-Size,Package -n "install ok installed" | paste -sd "  \n" | sort -rn'
1754 fi
1755
1756 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
1757 if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord ; then
1758     if check_com -c wodim ; then
1759         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
1760 See #377109 in the BTS of Debian for more details.
1761
1762 Please use the wodim binary instead' ; return 1"
1763     fi
1764 fi
1765
1766 # get_tw_cli has been renamed into get_3ware
1767 if check_com -c get_3ware ; then
1768     get_tw_cli() {
1769         echo 'Warning: get_tw_cli has been renamed into get_3ware. Invoking get_3ware for you.'>&2
1770         get_3ware
1771     }
1772 fi
1773
1774 # I hate lacking backward compatibility, so provide an alternative therefore
1775 if ! check_com -c apache2-ssl-certificate ; then
1776
1777     apache2-ssl-certificate() {
1778
1779     print 'Debian does not ship apache2-ssl-certificate anymore (see #398520). :('
1780     print 'You might want to take a look at Debian the package ssl-cert as well.'
1781     print 'To generate a certificate for use with apache2 follow the instructions:'
1782
1783     echo '
1784
1785 export RANDFILE=/dev/random
1786 mkdir /etc/apache2/ssl/
1787 openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
1788 chmod 600 /etc/apache2/ssl/apache.pem
1789
1790 Run "grml-tips ssl-certificate" if you need further instructions.
1791 '
1792     }
1793 fi
1794 # }}}
1795
1796 # {{{ Use hard limits, except for a smaller stack and no core dumps
1797 unlimit
1798 is4 && limit stack 8192
1799 isgrmlcd && limit core 0 # important for a live-cd-system
1800 limit -s
1801 # }}}
1802
1803 # {{{ completion system
1804
1805 # called later (via is4 && grmlcomp)
1806 # notice: use 'zstyle' for getting current settings
1807 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
1808 grmlcomp() {
1809     # TODO: This could use some additional information
1810
1811     # allow one error for every three characters typed in approximate completer
1812     zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )'
1813
1814     # don't complete backup files as executables
1815     zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)'
1816
1817     # start menu completion only if it could find no unambiguous initial string
1818     zstyle ':completion:*:correct:*'       insert-unambiguous true
1819     zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}'
1820     zstyle ':completion:*:correct:*'       original true
1821
1822     # activate color-completion
1823     zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}
1824
1825     # format on completion
1826     zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'
1827
1828     # complete 'cd -<tab>' with menu
1829     zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
1830
1831     # insert all expansions for expand completer
1832     zstyle ':completion:*:expand:*'        tag-order all-expansions
1833     zstyle ':completion:*:history-words'   list false
1834
1835     # activate menu
1836     zstyle ':completion:*:history-words'   menu yes
1837
1838     # ignore duplicate entries
1839     zstyle ':completion:*:history-words'   remove-all-dups yes
1840     zstyle ':completion:*:history-words'   stop yes
1841
1842     # match uppercase from lowercase
1843     zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'
1844
1845     # separate matches into groups
1846     zstyle ':completion:*:matches'         group 'yes'
1847     zstyle ':completion:*'                 group-name ''
1848
1849     if [[ -z "$NOMENU" ]] ; then
1850         # if there are more than 5 options allow selecting from a menu
1851         zstyle ':completion:*'               menu select=5
1852     else
1853         # don't use any menus at all
1854         setopt no_auto_menu
1855     fi
1856
1857     zstyle ':completion:*:messages'        format '%d'
1858     zstyle ':completion:*:options'         auto-description '%d'
1859
1860     # describe options in full
1861     zstyle ':completion:*:options'         description 'yes'
1862
1863     # on processes completion complete all user processes
1864     zstyle ':completion:*:processes'       command 'ps -au$USER'
1865
1866     # offer indexes before parameters in subscripts
1867     zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
1868
1869     # provide verbose completion information
1870     zstyle ':completion:*'                 verbose true
1871
1872     # recent (as of Dec 2007) zsh versions are able to provide descriptions
1873     # for commands (read: 1st word in the line) that it will list for the user
1874     # to choose from. The following disables that, because it's not exactly fast.
1875     zstyle ':completion:*:-command-:*:'    verbose false
1876
1877     # set format for warnings
1878     zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d'
1879
1880     # define files to ignore for zcompile
1881     zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'
1882     zstyle ':completion:correct:'          prompt 'correct to: %e'
1883
1884     # Ignore completion functions for commands you don't have:
1885     zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'
1886
1887     # Provide more processes in completion of programs like killall:
1888     zstyle ':completion:*:processes-names' command 'ps c -u ${USER} -o command | uniq'
1889
1890     # complete manual by their section
1891     zstyle ':completion:*:manuals'    separate-sections true
1892     zstyle ':completion:*:manuals.*'  insert-sections   true
1893     zstyle ':completion:*:man:*'      menu yes select
1894
1895     # run rehash on completion so new installed program are found automatically:
1896     _force_rehash() {
1897         (( CURRENT == 1 )) && rehash
1898         return 1
1899     }
1900
1901     ## correction
1902     # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
1903     if [[ -n "$NOCOR" ]] ; then
1904         zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
1905         setopt nocorrect
1906     else
1907         # try to be smart about when to use what completer...
1908         setopt correct
1909         zstyle -e ':completion:*' completer '
1910             if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then
1911                 _last_try="$HISTNO$BUFFER$CURSOR"
1912                 reply=(_complete _match _ignored _prefix _files)
1913             else
1914                 if [[ $words[1] == (rm|mv) ]] ; then
1915                     reply=(_complete _files)
1916                 else
1917                     reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files)
1918                 fi
1919             fi'
1920     fi
1921
1922     # zstyle ':completion:*' completer _complete _correct _approximate
1923     # zstyle ':completion:*' expand prefix suffix
1924
1925     # complete shell aliases
1926     # zstyle ':completion:*' completer _expand_alias _complete _approximate
1927
1928     # command for process lists, the local web server details and host completion
1929     zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
1930
1931     # caching
1932     [[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \
1933                             zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
1934
1935     # host completion /* add brackets as vim can't parse zsh's complex cmdlines 8-) {{{ */
1936     if is42 ; then
1937         [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
1938         [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
1939     else
1940         _ssh_hosts=()
1941         _etc_hosts=()
1942     fi
1943     hosts=(
1944         $(hostname)
1945         "$_ssh_hosts[@]"
1946         "$_etc_hosts[@]"
1947         grml.org
1948         localhost
1949     )
1950     zstyle ':completion:*:hosts' hosts $hosts
1951     #  zstyle '*' hosts $hosts
1952
1953     # specify your logins:
1954     # my_accounts=(
1955     #  {grml,grml1}@foo.invalid
1956     #  grml-devel@bar.invalid
1957     # )
1958     # other_accounts=(
1959     #  {fred,root}@foo.invalid
1960     #  vera@bar.invalid
1961     # )
1962     # zstyle ':completion:*:my-accounts' users-hosts $my_accounts
1963     # zstyle ':completion:*:other-accounts' users-hosts $other_accounts
1964
1965     # specify specific port/service settings:
1966     #  telnet_users_hosts_ports=(
1967     #    user1@host1:
1968     #    user2@host2:
1969     #    @mail-server:{smtp,pop3}
1970     #    @news-server:nntp
1971     #    @proxy-server:8000
1972     #  )
1973     # zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
1974
1975     # use generic completion system for programs not yet defined; (_gnu_generic works
1976     # with commands that provide a --help option with "standard" gnu-like output.)
1977     compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
1978
1979     # see upgrade function in this file
1980     compdef _hosts upgrade
1981 }
1982 # }}}
1983
1984 # {{{ grmlstuff
1985 grmlstuff() {
1986 # people should use 'grml-x'!
1987     startx() {
1988         if [[ -e /etc/X11/xorg.conf ]] ; then
1989             [[ -x /usr/bin/startx ]] && /usr/bin/startx "$@" || /usr/X11R6/bin/startx "$@"
1990         else
1991             echo "Please use the script \"grml-x\" for starting the X Window System
1992 because there does not exist /etc/X11/xorg.conf yet.
1993 If you want to use startx anyway please call \"/usr/bin/startx\"."
1994             return -1
1995         fi
1996     }
1997
1998     xinit() {
1999         if [[ -e /etc/X11/xorg.conf ]] ; then
2000             [[ -x /usr/bin/xinit ]] && /usr/bin/xinit || /usr/X11R6/bin/xinit
2001         else
2002             echo "Please use the script \"grml-x\" for starting the X Window System.
2003 because there does not exist /etc/X11/xorg.conf yet.
2004 If you want to use xinit anyway please call \"/usr/bin/xinit\"."
2005             return -1
2006         fi
2007     }
2008
2009     if check_com -c 915resolution ; then
2010         alias 855resolution='echo -e "Please use 915resolution as resolution modify tool for Intel graphic chipset."; return -1'
2011     fi
2012
2013     #a1# Output version of running grml
2014     alias grml-version='cat /etc/grml_version'
2015
2016     if check_com -c rebuildfstab ; then
2017         #a1# Rebuild /etc/fstab
2018         alias grml-rebuildfstab='rebuildfstab -v -r -config'
2019     fi
2020
2021     if check_com -c grml-debootstrap ; then
2022         alias debian2hd='print "Installing debian to harddisk is possible via using grml-debootstrap." ; return 1'
2023     fi
2024 }
2025 # }}}
2026
2027 # {{{ now run the functions
2028 isgrml && checkhome
2029 is4    && isgrml    && grmlstuff
2030 is4    && grmlcomp
2031 # }}}
2032
2033 # {{{ keephack
2034 is4 && xsource "/etc/zsh/keephack"
2035 # }}}
2036
2037 # {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson
2038 # You use it as follows:
2039 # $ NTREF=/reference/file
2040 # $ ls -l *(e:nt:)
2041 # This lists all the files in the current directory newer than the reference file.
2042 # You can also specify the reference file inline; note quotes:
2043 # $ ls -l *(e:'nt ~/.zshenv':)
2044 is4 && nt() {
2045     if [[ -n $1 ]] ; then
2046         local NTREF=${~1}
2047     fi
2048     [[ $REPLY -nt $NTREF ]]
2049 }
2050 # }}}
2051
2052 # shell functions {{{
2053
2054 #f1# Provide csh compatibility
2055 setenv()  { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }  # csh compatibility
2056
2057 #f1# Reload an autoloadable function
2058 freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
2059
2060 #f1# Reload zsh setup
2061 reload() {
2062     if [[ "$#*" -eq 0 ]] ; then
2063         [[ -r ~/.zshrc ]] && . ~/.zshrc
2064     else
2065         local fn
2066         for fn in "$@"; do
2067             unfunction $fn
2068             autoload -U $fn
2069         done
2070     fi
2071 }
2072 compdef _functions reload freload
2073
2074 #f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
2075 sll() {
2076     [[ -z "$1" ]] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
2077     for i in "$@" ; do
2078         file=$i
2079         while [[ -h "$file" ]] ; do
2080             ls -l $file
2081             file=$(readlink "$file")
2082         done
2083     done
2084 }
2085
2086 # fast manual access
2087 if check_com qma ; then
2088     #f1# View the zsh manual
2089     manzsh()  { qma zshall "$1" }
2090     compdef _man qma
2091 else
2092     manzsh()  { /usr/bin/man zshall |  vim -c "se ft=man| se hlsearch" +/"$1" - ; }
2093     # manzsh()  { /usr/bin/man zshall |  most +/"$1" ; }
2094     # [[ -f ~/.terminfo/m/mostlike ]] && MYLESS='LESS=C TERMINFO=~/.terminfo TERM=mostlike less' || MYLESS='less'
2095     # manzsh()  { man zshall | $MYLESS -p $1 ; }
2096 fi
2097
2098 if check_com -c $PAGER ; then
2099     #f1# View Debian's changelog of a given package
2100     dchange() {
2101         if [[ -r /usr/share/doc/${1}/changelog.Debian.gz ]] ; then
2102             $PAGER /usr/share/doc/${1}/changelog.Debian.gz
2103         elif [[ -r /usr/share/doc/${1}/changelog.gz ]] ; then
2104             $PAGER /usr/share/doc/${1}/changelog.gz
2105         else
2106             if check_com -c aptitude ; then
2107                 echo "No changelog for package $1 found, using aptitude to retrieve it."
2108                 if isgrml ; then
2109                     aptitude -t unstable changelog ${1}
2110                 else
2111                     aptitude changelog ${1}
2112                 fi
2113             else
2114                 echo "No changelog for package $1 found, sorry."
2115                 return 1
2116             fi
2117         fi
2118     }
2119     _dchange() { _files -W /usr/share/doc -/ }
2120     compdef _dchange dchange
2121
2122     #f1# View Debian's NEWS of a given package
2123     dnews() {
2124         if [[ -r /usr/share/doc/${1}/NEWS.Debian.gz ]] ; then
2125             $PAGER /usr/share/doc/${1}/NEWS.Debian.gz
2126         else
2127             if [[ -r /usr/share/doc/${1}/NEWS.gz ]] ; then
2128                 $PAGER /usr/share/doc/${1}/NEWS.gz
2129             else
2130                 echo "No NEWS file for package $1 found, sorry."
2131                 return 1
2132             fi
2133         fi
2134     }
2135     _dnews() { _files -W /usr/share/doc -/ }
2136     compdef _dnews dnews
2137
2138     #f1# View upstream's changelog of a given package
2139     uchange() {
2140         if [[ -r /usr/share/doc/${1}/changelog.gz ]] ; then
2141             $PAGER /usr/share/doc/${1}/changelog.gz
2142         else
2143             echo "No changelog for package $1 found, sorry."
2144             return 1
2145         fi
2146     }
2147     _uchange() { _files -W /usr/share/doc -/ }
2148     compdef _uchange uchange
2149 fi
2150
2151 # zsh profiling
2152 profile() {
2153     ZSH_PROFILE_RC=1 $SHELL "$@"
2154 }
2155
2156 #f1# Edit an alias via zle
2157 edalias() {
2158     [[ -z "$1" ]] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
2159 }
2160 compdef _aliases edalias
2161
2162 #f1# Edit a function via zle
2163 edfunc() {
2164     [[ -z "$1" ]] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
2165 }
2166 compdef _functions edfunc
2167
2168 # use it e.g. via 'Restart apache2'
2169 #m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
2170 #m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
2171 #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
2172 #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
2173 #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
2174 if [[ -d /etc/init.d || -d /etc/service ]] ; then
2175     __start_stop() {
2176         local action_="${1:l}"  # e.g Start/Stop/Restart
2177         local service_="$2"
2178         local param_="$3"
2179
2180         local service_target_="$(readlink /etc/init.d/$service_)"
2181         if [[ $service_target_ == "/usr/bin/sv" ]]; then
2182             # runit
2183             case "${action_}" in
2184                 start) if [[ ! -e /etc/service/$service_ ]]; then
2185                            $SUDO ln -s "/etc/sv/$service_" "/etc/service/"
2186                        else
2187                            $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
2188                        fi ;;
2189                 # there is no reload in runits sysv emulation
2190                 reload) $SUDO "/etc/init.d/$service_" "force-reload" "$param_" ;;
2191                 *) $SUDO "/etc/init.d/$service_" "${action_}" "$param_" ;;
2192             esac
2193         else
2194             # sysvinit
2195             $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
2196         fi
2197     }
2198
2199     for i in Start Restart Stop Force-Reload Reload ; do
2200         eval "$i() { __start_stop $i \"\$1\" \"\$2\" ; }"
2201     done
2202 fi
2203
2204 #f1# Provides useful information on globbing
2205 H-Glob() {
2206     echo -e "
2207     /      directories
2208     .      plain files
2209     @      symbolic links
2210     =      sockets
2211     p      named pipes (FIFOs)
2212     *      executable plain files (0100)
2213     %      device files (character or block special)
2214     %b     block special files
2215     %c     character special files
2216     r      owner-readable files (0400)
2217     w      owner-writable files (0200)
2218     x      owner-executable files (0100)
2219     A      group-readable files (0040)
2220     I      group-writable files (0020)
2221     E      group-executable files (0010)
2222     R      world-readable files (0004)
2223     W      world-writable files (0002)
2224     X      world-executable files (0001)
2225     s      setuid files (04000)
2226     S      setgid files (02000)
2227     t      files with the sticky bit (01000)
2228
2229   print *(m-1)          # Files modified up to a day ago
2230   print *(a1)           # Files accessed a day ago
2231   print *(@)            # Just symlinks
2232   print *(Lk+50)        # Files bigger than 50 kilobytes
2233   print *(Lk-50)        # Files smaller than 50 kilobytes
2234   print **/*.c          # All *.c files recursively starting in \$PWD
2235   print **/*.c~file.c   # Same as above, but excluding 'file.c'
2236   print (foo|bar).*     # Files starting with 'foo' or 'bar'
2237   print *~*.*           # All Files that do not contain a dot
2238   chmod 644 *(.^x)      # make all plain non-executable files publically readable
2239   print -l *(.c|.h)     # Lists *.c and *.h
2240   print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
2241   echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
2242 }
2243 alias help-zshglob=H-Glob
2244
2245 check_com -c qma && alias ?='qma zshall'
2246
2247 # grep for running process, like: 'any vim'
2248 any() {
2249     if [[ -z "$1" ]] ; then
2250         echo "any - grep for process(es) by keyword" >&2
2251         echo "Usage: any <keyword>" >&2 ; return 1
2252     else
2253         local STRING=$1
2254         local LENGTH=$(expr length $STRING)
2255         local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
2256         local REST=$(echo $(expr substr $STRING 2 $LENGTH))
2257         ps xauwww| grep "[$FIRSCHAR]$REST"
2258     fi
2259 }
2260
2261 # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
2262 # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
2263 [[ -r /proc/1/maps ]] && \
2264 deswap() {
2265     print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
2266     cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
2267     print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
2268 }
2269
2270 # print hex value of a number
2271 hex() {
2272     [[ -n "$1" ]] && printf "%x\n" $1 || { print 'Usage: hex <number-to-convert>' ; return 1 }
2273 }
2274
2275 # calculate (or eval at all ;-)) with perl => p[erl-]eval
2276 # hint: also take a look at zcalc -> 'autoload zcalc' -> 'man zshmodules | less -p MATHFUNC'
2277 peval() {
2278     [[ -n "$1" ]] && CALC="$*" || print "Usage: calc [expression]"
2279     perl -e "print eval($CALC),\"\n\";"
2280 }
2281 functions peval &>/dev/null && alias calc=peval
2282
2283 # brltty seems to have problems with utf8 environment and/or font Uni3-Terminus16 under
2284 # certain circumstances, so work around it, no matter which environment we have
2285 brltty() {
2286     if [[ -z "$DISPLAY" ]] ; then
2287         consolechars -f /usr/share/consolefonts/default8x16.psf.gz
2288         command brltty "$@"
2289     else
2290         command brltty "$@"
2291     fi
2292 }
2293
2294 # just press 'asdf' keys to toggle between dvorak and us keyboard layout
2295 aoeu() {
2296     echo -n 'Switching to us keyboard layout: '
2297     [[ -z "$DISPLAY" ]] && $SUDO loadkeys us &>/dev/null || setxkbmap us &>/dev/null
2298     echo 'Done'
2299 }
2300 asdf() {
2301     echo -n 'Switching to dvorak keyboard layout: '
2302     [[ -z "$DISPLAY" ]] && $SUDO loadkeys dvorak &>/dev/null || setxkbmap dvorak &>/dev/null
2303     echo 'Done'
2304 }
2305 # just press 'asdf' key to toggle from neon layout to us keyboard layout
2306 uiae() {
2307     echo -n 'Switching to us keyboard layout: '
2308     setxkbmap us && echo 'Done' || echo 'Failed'
2309 }
2310
2311 # set up an ipv6 tunnel
2312 ipv6-tunnel() {
2313     case $1 in
2314         start)
2315             if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
2316                 print 'ipv6 tunnel already set up, nothing to be done.'
2317                 print 'execute: "ifconfig sit1 down ; ifconfig sit0 down" to remove ipv6-tunnel.' ; return 1
2318             else
2319                 [[ -n "$PUBLIC_IP" ]] || \
2320                     local PUBLIC_IP=$(ifconfig $(route -n | awk '/^0\.0\.0\.0/{print $8; exit}') | \
2321                                       awk '/inet addr:/ {print $2}' | tr -d 'addr:')
2322
2323                 [[ -n "$PUBLIC_IP" ]] || { print 'No $PUBLIC_IP set and could not determine default one.' ; return 1 }
2324                 local IPV6ADDR=$(printf "2002:%02x%02x:%02x%02x:1::1" $(print ${PUBLIC_IP//./ }))
2325                 print -n "Setting up ipv6 tunnel $IPV6ADDR via ${PUBLIC_IP}: "
2326                 ifconfig sit0 tunnel ::192.88.99.1 up
2327                 ifconfig sit1 add "$IPV6ADDR" && print done || print failed
2328             fi
2329             ;;
2330         status)
2331             if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
2332                 print 'ipv6 tunnel available' ; return 0
2333             else
2334                 print 'ipv6 tunnel not available' ; return 1
2335             fi
2336             ;;
2337         stop)
2338             if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
2339                 print -n 'Stopping ipv6 tunnel (sit0 + sit1): '
2340                 ifconfig sit1 down ; ifconfig sit0 down && print done || print failed
2341             else
2342                 print 'No ipv6 tunnel found, nothing to be done.' ; return 1
2343             fi
2344             ;;
2345         *)
2346             print "Usage: ipv6-tunnel [start|stop|status]">&2 ; return 1
2347             ;;
2348     esac
2349 }
2350
2351 # run dhclient for wireless device
2352 iwclient() {
2353     salias dhclient "$(wavemon -d | awk '/device/{print $2}')"
2354 }
2355
2356 # spawn a minimally set up ksh - useful if you want to umount /usr/.
2357 minimal-shell() {
2358     exec env -i ENV="/etc/minimal-shellrc" HOME="$HOME" TERM="$TERM" ksh
2359 }
2360
2361 # make a backup of a file
2362 bk() {
2363     cp -a "$1" "${1}_$(date --iso-8601=seconds)"
2364 }
2365
2366 # Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
2367 # bash() {
2368 #  NO_SWITCH="yes" command bash "$@"
2369 # }
2370 # restart () {
2371 #  exec $SHELL $SHELL_ARGS "$@"
2372 # }
2373
2374 # }}}
2375
2376 # log out? set timeout in seconds {{{
2377 # TMOUT=1800
2378 # do not log out in some specific terminals:
2379 #  if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]] ; then
2380 #    unset TMOUT
2381 #  fi
2382 # }}}
2383
2384 # {{{ make sure our environment is clean regarding colors
2385 for color in BLUE RED GREEN CYAN YELLOW MAGENTA WHITE ; unset $color
2386 # }}}
2387
2388 # source another config file if present {{{
2389 xsource "/etc/zsh/zshrc.local"
2390 xsource "${HOME}/.zshenv"
2391 # }}}
2392
2393 # "persistent history" {{{
2394 # just write important commands you always need to ~/.important_commands
2395 if [[ -r ~/.important_commands ]] ; then
2396     fc -R ~/.important_commands
2397 fi
2398 # }}}
2399
2400 ## genrefcard.pl settings {{{
2401 ### example: split functions-search 8,16,24,32
2402 #@# split functions-search 8
2403 ## }}}
2404
2405 # add variable to be able to check whether the file has been read {{{
2406 ZSHRC_GLOBAL_HAS_BEEN_READ=1
2407 # }}}
2408
2409 ## END OF FILE #################################################################
2410 # vim:filetype=zsh foldmethod=marker autoindent expandtab shiftwidth=4