zshrc: Adding support for cvs 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, mtn, svn, cvs 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_mtn_get_data () { # {{{
1246     local msg mtnbranch mtnbase
1247
1248     mtnbase=${vcs_comm[basedir]}
1249     mtnbranch=$(mtn status | awk '/Current branch:/{ sub("Current branch: ", ""); print }')
1250     msg=$(VCS_INFO_format)
1251     zformat -f msg "${msg}" "a:" "b:${mtnbranch}" "s:${vcs}" "r:${mtnbase:t}" "R:${mtnbase}"
1252     printf '%s' ${msg}
1253 }
1254 # }}}
1255 VCS_INFO_svk_get_data () { # {{{
1256     local msg svkbranch svkbase
1257
1258     svkbase=${vcs_comm[basedir]}
1259     svkbranch=${svkbase##*
1260   }
1261     svkbase=${svkbase%%
1262   *}
1263
1264     msg=$(VCS_INFO_format)
1265     zformat -f msg "${msg}" "a:" "b:${svkbranch}" "s:${vcs}" "r:${svkbase:t}" "R:${svkbase}"
1266     printf '%s' ${msg}
1267 }
1268 # }}}
1269 VCS_INFO_svn_get_data () { # {{{
1270     local msg svnbranch svnbase
1271
1272     svnbase="."
1273     while [[ -d "${svnbase}/../.svn" ]]; do
1274         svnbase="${svnbase}/.."
1275     done
1276     svnbase=$(VCS_INFO_realpath ${svnbase})
1277     svnbranch=$(svn info "$base_dir" | awk '/^URL/ { sub(".*/","",$0); r=$0 } /^Revision/ { sub("[^0-9]*","",$0); print r":"$0 }')
1278
1279     msg=$(VCS_INFO_format)
1280     zformat -f msg "${msg}" "a:" "b:${svnbranch}" "s:${vcs}" "r:${svnbase:t}" "R:${svnbase}"
1281     printf '%s' ${msg}
1282 }
1283 # }}}
1284 VCS_INFO_bzr_get_data () { # {{{
1285     local msg bzrbranch bzrbase bzrrevno i j
1286
1287     bzrbase=$(bzr info 2>/dev/null | sed -rne 's, *branch root: ,,p')
1288     bzrbase=$(VCS_INFO_realpath ${bzrbase})
1289
1290     bzr version-info 2> /dev/null | while read i j; do
1291         case "${i}" in
1292             revno:)
1293                 bzrrevno=${j} ;;
1294             branch-nick:)
1295                 bzrbranch=${j} ;;
1296         esac
1297     done
1298
1299     msg=$(VCS_INFO_format)
1300     zformat -f msg "${msg}" "a:" "b:${bzrbranch}:${bzrrevno}" "s:${vcs}" "r:${bzrbase:t}" "R:${bzrbase}"
1301     printf '%s' ${msg}
1302 }
1303 # }}}
1304 VCS_INFO_cvs_get_data () { # {{{
1305     local msg cvsbranch cvsbase basename
1306
1307     cvsbase="."
1308     while [[ -d "${cvsbase}/../CVS" ]]; do
1309         cvsbase="${cvsbase}/.."
1310     done
1311     cvsbase=$(VCS_INFO_realpath ${cvsbase})
1312     cvsbranch=$(< ./CVS/Repository)
1313     basename=${cvsbase:t}
1314     cvsbranch=${cvsbranch##${basename}/}
1315     [[ -z ${cvsbranch} ]] && cvsbranch=${basename}
1316
1317     msg=$(VCS_INFO_format)
1318     zformat -f msg "${msg}" "a:" "b:${cvsbranch}" "s:${vcs}" "r:${basename}" "R:${cvsbase}"
1319     printf '%s' ${msg}
1320 }
1321 # }}}
1322 # VCS_INFO_*_detect () {{{
1323
1324 VCS_INFO_detect_by_dir() {
1325     local dirname=${1}
1326     local basedir="." realbasedir
1327
1328     realbasedir=$(VCS_INFO_realpath ${basedir})
1329     while [[ ${realbasedir} != '/' ]]; do
1330         if [[ -n ${vcs_comm[detect_need_file]} ]] ; then
1331             [[ -d ${basedir}/${dirname} ]] && \
1332             [[ -f ${basedir}/${dirname}/${vcs_comm[detect_need_file]} ]] && \
1333                 break
1334         else
1335             [[ -d ${basedir}/${dirname} ]] && break
1336         fi
1337
1338         basedir=${basedir}/..
1339         realbasedir=$(VCS_INFO_realpath ${basedir})
1340     done
1341
1342     [[ ${realbasedir} == "/" ]] && return 1
1343     vcs_comm[basedir]=${realbasedir}
1344     return 0
1345 }
1346
1347 VCS_INFO_bzr_detect() {
1348     check_com -c bzr || return 1
1349     vcs_comm[detect_need_file]=branch/format
1350     VCS_INFO_detect_by_dir '.bzr'
1351     return $?
1352 }
1353
1354 VCS_INFO_cvs_detect() {
1355     check_com -c svn || return 1
1356     [[ -d "CVS" ]] && return 0
1357     return 1
1358 }
1359
1360 VCS_INFO_darcs_detect() {
1361     check_com -c darcs || return 1
1362     vcs_comm[detect_need_file]=format
1363     VCS_INFO_detect_by_dir '_darcs'
1364     return $?
1365 }
1366
1367 VCS_INFO_git_detect() {
1368     if check_com -c git && git rev-parse --is-inside-work-tree &> /dev/null ; then
1369         vcs_comm[gitdir]="$(git rev-parse --git-dir 2> /dev/null)" || return 1
1370         [[ -d ${vcs_comm[gitdir]}/svn ]] && vcs_comm[overwrite_name]='git-svn'
1371         return 0
1372     fi
1373     return 1
1374 }
1375
1376 VCS_INFO_hg_detect() {
1377     check_com -c hg || return 1
1378     vcs_comm[detect_need_file]=branch
1379     VCS_INFO_detect_by_dir '.hg'
1380     return $?
1381 }
1382
1383 VCS_INFO_mtn_detect() {
1384     check_com -c mtn || return 1
1385     vcs_comm[detect_need_file]=revision
1386     VCS_INFO_detect_by_dir '_MTN'
1387     return $?
1388 }
1389
1390 VCS_INFO_svk_detect() {
1391     local basedir
1392
1393     check_com -c svk || return 1
1394     [[ -f ~/.svk/config ]] || return 1
1395
1396     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
1397
1398     vcs_comm[basedir]=${basedir}
1399     return 0
1400 }
1401
1402 VCS_INFO_svn_detect() {
1403     check_com -c svn || return 1
1404     [[ -d ".svn" ]] && return 0
1405     return 1
1406 }
1407
1408 # }}}
1409 vcs_info () { # {{{
1410     local string
1411     local -i found
1412     local -a VCSs disabled
1413     local -x vcs
1414     local -Ax vcs_comm
1415
1416     vcs="init"
1417     zstyle -T ":vcs_info:${vcs}" "enable" || return 0
1418     zstyle -a ":vcs_info:${vcs}" "disable" disabled
1419
1420     VCSs=(git hg bzr darcs mtn svn cvs svk)
1421
1422     (( found = 0 ))
1423     for vcs in ${VCSs} ; do
1424         [[ -n ${(M)disabled:#${vcs}} ]] && continue
1425         vcs_comm=()
1426         VCS_INFO_${vcs}_detect && (( found = 1 )) && break
1427     done
1428
1429     (( found == 0 )) && return 0
1430
1431     string=$(VCS_INFO_${vcs}_get_data) || return 1
1432     printf '%s' ${string}
1433     return 0
1434 }
1435 # }}}
1436
1437 # change vcs_info formats for the grml prompt
1438 if [[ "$TERM" == dumb ]] ; then
1439     zstyle ':vcs_info:*' promptactionformat "(%s%)-[%b|%a] "
1440     zstyle ':vcs_info:*' promptformat       "(%s%)-[%b] "
1441 else
1442     # these are the same, just with a lot of colours:
1443     zstyle ':vcs_info:*' promptactionformat "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOUR} "
1444     zstyle ':vcs_info:*' promptformat       "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOUR}%} "
1445 fi
1446
1447 # }}}
1448
1449 # {{{ set prompt
1450 if zrcautoload promptinit && promptinit 2>/dev/null ; then
1451     promptinit # people should be able to use their favourite prompt
1452 else
1453     print 'Notice: no promptinit available :('
1454 fi
1455
1456 setopt prompt_subst
1457
1458 # precmd() => a function which is executed just before each prompt
1459 # use 'NOPRECMD=1' to disable the precmd + preexec commands
1460
1461 # precmd () { setopt promptsubst; [[ -o interactive ]] && jobs -l;
1462
1463 # make sure to use right prompt only when not running a command
1464 is41 && setopt transient_rprompt
1465
1466 is4 && [[ -z $NOPRECMD ]] && precmd () {
1467     [[ -n $NOPRECMD ]] && return 0
1468     # allow manual overwriting of RPROMPT
1469     if [[ -n $RPROMPT ]] ; then
1470         [[ $TERM == screen* ]] && echo -n $'\ekzsh\e\\'
1471         # return 0
1472     fi
1473     # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
1474     if [[ -z $DONTSETRPROMPT ]] ; then
1475         if [[ -n $BATTERY ]] ; then
1476             RPROMPT="%(?..:()% ${PERCENT}${SCREENTITLE}"
1477             # RPROMPT="${PERCENT}${SCREENTITLE}"
1478         else
1479             RPROMPT="%(?..:()% ${SCREENTITLE}"
1480             # RPROMPT="${SCREENTITLE}"
1481         fi
1482     fi
1483     # adjust title of xterm
1484     # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
1485     case $TERM in
1486         (xterm*|rxvt)
1487             print -Pn "\e]0;%n@%m: %~\a"
1488             ;;
1489     esac
1490 }
1491
1492 # chpwd () => a function which is executed whenever the directory is changed
1493
1494 # preexec() => a function running before every command
1495 is4 && [[ -z $NOPRECMD ]] && \
1496 preexec () {
1497     [[ -n $NOPRECMD ]] && return 0
1498 # set hostname if not running on host with name 'grml'
1499     if [[ -n "$HOSTNAME" ]] && [[ "$HOSTNAME" != $(hostname) ]] ; then
1500        NAME="@$HOSTNAME"
1501     fi
1502 # get the name of the program currently running and hostname of local machine
1503 # set screen window title if running in a screen
1504     if [[ "$TERM" == screen* ]] ; then
1505         # local CMD=${1[(wr)^(*=*|sudo|ssh|-*)]}       # don't use hostname
1506         local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME" # use hostname
1507         echo -ne "\ek$CMD\e\\"
1508     fi
1509 # set the screen title to "zsh" when sitting at the command prompt:
1510     if [[ "$TERM" == screen* ]] ; then
1511         SCREENTITLE=$'%{\ekzsh\e\\%}'
1512     else
1513         SCREENTITLE=''
1514     fi
1515 # adjust title of xterm
1516     case $TERM in
1517         (xterm*|rxvt)
1518             print -Pn "\e]0;%n@%m: $1\a"
1519             ;;
1520     esac
1521 }
1522
1523 EXITCODE="%(?..%?%1v )"
1524 PS2='`%_> '       # secondary prompt, printed when the shell needs more information to complete a command.
1525 PS3='?# '         # selection prompt used within a select loop.
1526 PS4='+%N:%i:%_> ' # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
1527
1528 # set variable debian_chroot if running in a chroot with /etc/debian_chroot
1529 if [[ -z "$debian_chroot" ]] && [[ -r /etc/debian_chroot ]] ; then
1530     debian_chroot=$(cat /etc/debian_chroot)
1531 fi
1532
1533 # don't use colors on dumb terminals (like emacs):
1534 if [[ "$TERM" == dumb ]] ; then
1535     PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< "'$(vcs_info)'"%# "
1536 else
1537     # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended prompt
1538     # set variable identifying the chroot you work in (used in the prompt below)
1539     if [[ -n $GRMLPROMPT ]] ; then
1540         PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
1541 ${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# "
1542     else
1543         # This assembles the primary prompt string
1544         if (( EUID != 0 )); then
1545             PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "'$(vcs_info)'"%# "
1546         else
1547             PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "'$(vcs_info)'"%# "
1548         fi
1549     fi
1550 fi
1551
1552 # if we are inside a grml-chroot set a specific prompt theme
1553 if [[ -n "$GRML_CHROOT" ]] ; then
1554     PROMPT="%{$fg[red]%}(CHROOT) %{$fg_bold[red]%}%n%{$fg_no_bold[white]%}@%m %40<...<%B%~%b%<< %\# "
1555 fi
1556 # }}}
1557
1558 # {{{ 'hash' some often used directories
1559 #d# start
1560 hash -d deb=/var/cache/apt/archives
1561 hash -d doc=/usr/share/doc
1562 hash -d linux=/lib/modules/$(command uname -r)/build/
1563 hash -d log=/var/log
1564 hash -d slog=/var/log/syslog
1565 hash -d src=/usr/src
1566 hash -d templ=/usr/share/doc/grml-templates
1567 hash -d tt=/usr/share/doc/texttools-doc
1568 hash -d www=/var/www
1569 #d# end
1570 # }}}
1571
1572 # {{{ some aliases
1573 if [[ $UID -eq 0 ]] ; then
1574     [[ -r /etc/grml/screenrc ]] && alias screen='/usr/bin/screen -c /etc/grml/screenrc'
1575 elif [[ -r $HOME/.screenrc ]] ; then
1576     alias screen="/usr/bin/screen -c $HOME/.screenrc"
1577 else
1578     [[ -r /etc/grml/screenrc_grml ]] && alias screen='/usr/bin/screen -c /etc/grml/screenrc_grml'
1579 fi
1580
1581 # do we have GNU ls with color-support?
1582 if ls --help 2>/dev/null | grep -- --color= >/dev/null && [[ "$TERM" != dumb ]] ; then
1583     #a1# execute \kbd{@a@}:\quad ls with colors
1584     alias ls='ls -b -CF --color=auto'
1585     #a1# execute \kbd{@a@}:\quad list all files, with colors
1586     alias la='ls -la --color=auto'
1587     #a1# long colored list, without dotfiles (@a@)
1588     alias ll='ls -l --color=auto'
1589     #a1# long colored list, human readable sizes (@a@)
1590     alias lh='ls -hAl --color=auto'
1591     #a1# List files, append qualifier to filenames \\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
1592     alias l='ls -lF --color=auto'
1593 else
1594     alias ls='ls -b -CF'
1595     alias la='ls -la'
1596     alias ll='ls -l'
1597     alias lh='ls -hAl'
1598     alias l='ls -lF'
1599 fi
1600
1601 alias mdstat='cat /proc/mdstat'
1602 alias ...='cd ../../'
1603
1604 # generate alias named "$KERNELVERSION-reboot" so you can use boot with kexec:
1605 if [[ -x /sbin/kexec ]] && [[ -r /proc/cmdline ]] ; then
1606     alias "$(uname -r)-reboot"="kexec -l --initrd=/boot/initrd.img-"$(uname -r)" --command-line=\"$(cat /proc/cmdline)\" /boot/vmlinuz-"$(uname -r)""
1607 fi
1608
1609 alias cp='nocorrect cp'         # no spelling correction on cp
1610 alias mkdir='nocorrect mkdir'   # no spelling correction on mkdir
1611 alias mv='nocorrect mv'         # no spelling correction on mv
1612 alias rm='nocorrect rm'         # no spelling correction on rm
1613
1614 #a1# Execute \kbd{rmdir}
1615 alias rd='rmdir'
1616 #a1# Execute \kbd{rmdir}
1617 alias md='mkdir'
1618
1619 # see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
1620 alias term2iso="echo 'Setting terminal to iso mode' ; print -n '\e%@'"
1621 alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
1622
1623 # make sure it is not assigned yet
1624 [[ $(whence -w utf2iso &>/dev/null) == 'utf2iso: alias' ]] && unalias utf2iso
1625
1626 utf2iso() {
1627     if isutfenv ; then
1628         for ENV in $(env | command grep -i '.utf') ; do
1629             eval export "$(echo $ENV | sed 's/UTF-8/iso885915/ ; s/utf8/iso885915/')"
1630         done
1631     fi
1632 }
1633
1634 # make sure it is not assigned yet
1635 [[ $(whence -w iso2utf &>/dev/null) == 'iso2utf: alias' ]] && unalias iso2utf
1636 iso2utf() {
1637     if ! isutfenv ; then
1638         for ENV in $(env | command grep -i '\.iso') ; do
1639             eval export "$(echo $ENV | sed 's/iso.*/UTF-8/ ; s/ISO.*/UTF-8/')"
1640         done
1641     fi
1642 }
1643
1644 # set up software synthesizer via speakup
1645 swspeak() {
1646     aumix -w 90 -v 90 -p 90 -m 90
1647     if ! [[ -r /dev/softsynth ]] ; then
1648         flite -o play -t "Sorry, software synthesizer not available. Did you boot with swspeak bootoption?"
1649         return 1
1650     else
1651         setopt singlelinezle
1652         unsetopt prompt_cr
1653         export PS1="%m%# "
1654         nice -n -20 speechd-up
1655         sleep 2
1656         flite -o play -t "Finished setting up software synthesizer"
1657     fi
1658 }
1659
1660 # I like clean prompt, so provide simple way to get that
1661 check_com 0 || alias 0='return 0'
1662
1663 # for really lazy people like mika:
1664 check_com S &>/dev/null || alias S='screen'
1665 check_com s &>/dev/null || alias s='ssh'
1666
1667 # get top 10 shell commands:
1668 alias top10='print -l ? ${(o)history%% *} | uniq -c | sort -nr | head -n 10'
1669
1670 # truecrypt; use e.g. via 'truec /dev/ice /mnt/ice' or 'truec -i'
1671 if check_com -c truecrypt ; then
1672     if isutfenv ; then
1673         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077,utf8" '
1674     else
1675         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077" '
1676     fi
1677 fi
1678
1679 #f1# Hints for the use of zsh on grml
1680 zsh-help() {
1681     print "$bg[white]$fg[black]
1682 zsh-help - hints for use of zsh on grml
1683 =======================================$reset_color"
1684
1685     print '
1686 Main configuration of zsh happens in /etc/zsh/zshrc (global)
1687 and /etc/skel/.zshrc which is copied to $HOME/.zshrc once.
1688 The files are part of the package grml-etc-core, if you want to
1689 use them on a non-grml-system just get the tar.gz from
1690 http://deb.grml.org/ or get the files from the mercurial
1691 repository:
1692
1693   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
1694   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
1695
1696 If you want to stay in sync with zsh configuration of grml
1697 run '\''ln -sf /etc/skel/.zshrc $HOME/.zshrc'\'' and configure
1698 your own stuff in $HOME/.zshrc.local. System wide configuration
1699 without touching configuration files of grml can take place
1700 in /etc/zsh/zshrc.local.
1701
1702 If you want to use the configuration of user grml also when
1703 running as user root just run '\''zshskel'\'' which will source
1704 the file /etc/skel/.zshrc.
1705
1706 For information regarding zsh start at http://grml.org/zsh/
1707
1708 Take a look at grml'\''s zsh refcard:
1709 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
1710
1711 Check out the main zsh refcard:
1712 % '$BROWSER' http://www.bash2zsh.com/zsh_refcard/refcard.pdf
1713
1714 And of course visit the zsh-lovers:
1715 % man zsh-lovers
1716
1717 You can adjust some options through environment variables when
1718 invoking zsh without having to edit configuration files.
1719 Basically meant for bash users who are not used to the power of
1720 the zsh yet. :)
1721
1722   "NOCOR=1    zsh" => deactivate automatic correction
1723   "NOMENU=1   zsh" => do not use menu completion (note: use strg-d for completion instead!)
1724   "NOPRECMD=1 zsh" => disable the precmd + preexec commands (set GNU screen title)
1725   "BATTERY=1  zsh" => activate battery status (via acpi) on right side of prompt'
1726
1727     print "
1728 $bg[white]$fg[black]
1729 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
1730 Enjoy your grml system with the zsh!$reset_color"
1731 }
1732
1733 # debian stuff
1734 if [[ -r /etc/debian_version ]] ; then
1735     #a3# Execute \kbd{apt-cache search}
1736     alias acs='apt-cache search'
1737     #a3# Execute \kbd{apt-cache show}
1738     alias acsh='apt-cache show'
1739     #a3# Execute \kbd{apt-cache policy}
1740     alias acp='apt-cache policy'
1741     #a3# Execute \kbd{apt-get dist-upgrade}
1742     salias adg="apt-get dist-upgrade"
1743     #a3# Execute \kbd{apt-get install}
1744     salias agi="apt-get install"
1745     #a3# Execute \kbd{aptitude install}
1746     salias ati="aptitude install"
1747     #a3# Execute \kbd{apt-get upgrade}
1748     salias ag="apt-get upgrade"
1749     #a3# Execute \kbd{apt-get update}
1750     salias au="apt-get update"
1751     #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
1752     salias -a up="aptitude update ; aptitude safe-upgrade"
1753     #a3# Execute \kbd{dpkg-buildpackage}
1754     alias dbp='dpkg-buildpackage'
1755     #a3# Execute \kbd{grep-excuses}
1756     alias ge='grep-excuses'
1757
1758     # debian upgrade
1759     #f3# Execute \kbd{apt-get update \&\& }\\&\quad \kbd{apt-get dist-upgrade}
1760     upgrade() {
1761         if [[ -z "$1" ]] ; then
1762             $SUDO apt-get update
1763             $SUDO apt-get -u upgrade
1764         else
1765             ssh $1 $SUDO apt-get update
1766             # ask before the upgrade
1767             local dummy
1768             ssh $1 $SUDO apt-get --no-act upgrade
1769             echo -n 'Process the upgrade?'
1770             read -q dummy
1771             if [[ $dummy == "y" ]] ; then
1772                 ssh $1 $SUDO apt-get -u upgrade --yes
1773             fi
1774         fi
1775     }
1776
1777     # get a root shell as normal user in live-cd mode:
1778     if isgrmlcd && [[ $UID -ne 0 ]] ; then
1779        alias su="sudo su"
1780      fi
1781
1782     #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
1783     alias llog="$PAGER /var/log/syslog"     # take a look at the syslog
1784     #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
1785     alias tlog="tail -f /var/log/syslog"    # follow the syslog
1786     #a1# (Re)-source \kbd{/etc/skel/.zshrc}
1787     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
1788 fi
1789
1790 # sort installed Debian-packages by size
1791 if check_com -c grep-status ; then
1792     #a3# List installed Debian-packages sorted by size
1793     alias debs-by-size='grep-status -FStatus -sInstalled-Size,Package -n "install ok installed" | paste -sd "  \n" | sort -rn'
1794 fi
1795
1796 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
1797 if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord ; then
1798     if check_com -c wodim ; then
1799         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
1800 See #377109 in the BTS of Debian for more details.
1801
1802 Please use the wodim binary instead' ; return 1"
1803     fi
1804 fi
1805
1806 # get_tw_cli has been renamed into get_3ware
1807 if check_com -c get_3ware ; then
1808     get_tw_cli() {
1809         echo 'Warning: get_tw_cli has been renamed into get_3ware. Invoking get_3ware for you.'>&2
1810         get_3ware
1811     }
1812 fi
1813
1814 # I hate lacking backward compatibility, so provide an alternative therefore
1815 if ! check_com -c apache2-ssl-certificate ; then
1816
1817     apache2-ssl-certificate() {
1818
1819     print 'Debian does not ship apache2-ssl-certificate anymore (see #398520). :('
1820     print 'You might want to take a look at Debian the package ssl-cert as well.'
1821     print 'To generate a certificate for use with apache2 follow the instructions:'
1822
1823     echo '
1824
1825 export RANDFILE=/dev/random
1826 mkdir /etc/apache2/ssl/
1827 openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
1828 chmod 600 /etc/apache2/ssl/apache.pem
1829
1830 Run "grml-tips ssl-certificate" if you need further instructions.
1831 '
1832     }
1833 fi
1834 # }}}
1835
1836 # {{{ Use hard limits, except for a smaller stack and no core dumps
1837 unlimit
1838 is4 && limit stack 8192
1839 isgrmlcd && limit core 0 # important for a live-cd-system
1840 limit -s
1841 # }}}
1842
1843 # {{{ completion system
1844
1845 # called later (via is4 && grmlcomp)
1846 # notice: use 'zstyle' for getting current settings
1847 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
1848 grmlcomp() {
1849     # TODO: This could use some additional information
1850
1851     # allow one error for every three characters typed in approximate completer
1852     zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )'
1853
1854     # don't complete backup files as executables
1855     zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)'
1856
1857     # start menu completion only if it could find no unambiguous initial string
1858     zstyle ':completion:*:correct:*'       insert-unambiguous true
1859     zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}'
1860     zstyle ':completion:*:correct:*'       original true
1861
1862     # activate color-completion
1863     zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}
1864
1865     # format on completion
1866     zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'
1867
1868     # complete 'cd -<tab>' with menu
1869     zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
1870
1871     # insert all expansions for expand completer
1872     zstyle ':completion:*:expand:*'        tag-order all-expansions
1873     zstyle ':completion:*:history-words'   list false
1874
1875     # activate menu
1876     zstyle ':completion:*:history-words'   menu yes
1877
1878     # ignore duplicate entries
1879     zstyle ':completion:*:history-words'   remove-all-dups yes
1880     zstyle ':completion:*:history-words'   stop yes
1881
1882     # match uppercase from lowercase
1883     zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'
1884
1885     # separate matches into groups
1886     zstyle ':completion:*:matches'         group 'yes'
1887     zstyle ':completion:*'                 group-name ''
1888
1889     if [[ -z "$NOMENU" ]] ; then
1890         # if there are more than 5 options allow selecting from a menu
1891         zstyle ':completion:*'               menu select=5
1892     else
1893         # don't use any menus at all
1894         setopt no_auto_menu
1895     fi
1896
1897     zstyle ':completion:*:messages'        format '%d'
1898     zstyle ':completion:*:options'         auto-description '%d'
1899
1900     # describe options in full
1901     zstyle ':completion:*:options'         description 'yes'
1902
1903     # on processes completion complete all user processes
1904     zstyle ':completion:*:processes'       command 'ps -au$USER'
1905
1906     # offer indexes before parameters in subscripts
1907     zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
1908
1909     # provide verbose completion information
1910     zstyle ':completion:*'                 verbose true
1911
1912     # recent (as of Dec 2007) zsh versions are able to provide descriptions
1913     # for commands (read: 1st word in the line) that it will list for the user
1914     # to choose from. The following disables that, because it's not exactly fast.
1915     zstyle ':completion:*:-command-:*:'    verbose false
1916
1917     # set format for warnings
1918     zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d'
1919
1920     # define files to ignore for zcompile
1921     zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'
1922     zstyle ':completion:correct:'          prompt 'correct to: %e'
1923
1924     # Ignore completion functions for commands you don't have:
1925     zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'
1926
1927     # Provide more processes in completion of programs like killall:
1928     zstyle ':completion:*:processes-names' command 'ps c -u ${USER} -o command | uniq'
1929
1930     # complete manual by their section
1931     zstyle ':completion:*:manuals'    separate-sections true
1932     zstyle ':completion:*:manuals.*'  insert-sections   true
1933     zstyle ':completion:*:man:*'      menu yes select
1934
1935     # run rehash on completion so new installed program are found automatically:
1936     _force_rehash() {
1937         (( CURRENT == 1 )) && rehash
1938         return 1
1939     }
1940
1941     ## correction
1942     # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
1943     if [[ -n "$NOCOR" ]] ; then
1944         zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
1945         setopt nocorrect
1946     else
1947         # try to be smart about when to use what completer...
1948         setopt correct
1949         zstyle -e ':completion:*' completer '
1950             if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then
1951                 _last_try="$HISTNO$BUFFER$CURSOR"
1952                 reply=(_complete _match _ignored _prefix _files)
1953             else
1954                 if [[ $words[1] == (rm|mv) ]] ; then
1955                     reply=(_complete _files)
1956                 else
1957                     reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files)
1958                 fi
1959             fi'
1960     fi
1961
1962     # zstyle ':completion:*' completer _complete _correct _approximate
1963     # zstyle ':completion:*' expand prefix suffix
1964
1965     # complete shell aliases
1966     # zstyle ':completion:*' completer _expand_alias _complete _approximate
1967
1968     # command for process lists, the local web server details and host completion
1969     zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
1970
1971     # caching
1972     [[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \
1973                             zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
1974
1975     # host completion /* add brackets as vim can't parse zsh's complex cmdlines 8-) {{{ */
1976     if is42 ; then
1977         [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
1978         [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
1979     else
1980         _ssh_hosts=()
1981         _etc_hosts=()
1982     fi
1983     hosts=(
1984         $(hostname)
1985         "$_ssh_hosts[@]"
1986         "$_etc_hosts[@]"
1987         grml.org
1988         localhost
1989     )
1990     zstyle ':completion:*:hosts' hosts $hosts
1991     #  zstyle '*' hosts $hosts
1992
1993     # specify your logins:
1994     # my_accounts=(
1995     #  {grml,grml1}@foo.invalid
1996     #  grml-devel@bar.invalid
1997     # )
1998     # other_accounts=(
1999     #  {fred,root}@foo.invalid
2000     #  vera@bar.invalid
2001     # )
2002     # zstyle ':completion:*:my-accounts' users-hosts $my_accounts
2003     # zstyle ':completion:*:other-accounts' users-hosts $other_accounts
2004
2005     # specify specific port/service settings:
2006     #  telnet_users_hosts_ports=(
2007     #    user1@host1:
2008     #    user2@host2:
2009     #    @mail-server:{smtp,pop3}
2010     #    @news-server:nntp
2011     #    @proxy-server:8000
2012     #  )
2013     # zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
2014
2015     # use generic completion system for programs not yet defined; (_gnu_generic works
2016     # with commands that provide a --help option with "standard" gnu-like output.)
2017     compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
2018
2019     # see upgrade function in this file
2020     compdef _hosts upgrade
2021 }
2022 # }}}
2023
2024 # {{{ grmlstuff
2025 grmlstuff() {
2026 # people should use 'grml-x'!
2027     startx() {
2028         if [[ -e /etc/X11/xorg.conf ]] ; then
2029             [[ -x /usr/bin/startx ]] && /usr/bin/startx "$@" || /usr/X11R6/bin/startx "$@"
2030         else
2031             echo "Please use the script \"grml-x\" for starting the X Window System
2032 because there does not exist /etc/X11/xorg.conf yet.
2033 If you want to use startx anyway please call \"/usr/bin/startx\"."
2034             return -1
2035         fi
2036     }
2037
2038     xinit() {
2039         if [[ -e /etc/X11/xorg.conf ]] ; then
2040             [[ -x /usr/bin/xinit ]] && /usr/bin/xinit || /usr/X11R6/bin/xinit
2041         else
2042             echo "Please use the script \"grml-x\" for starting the X Window System.
2043 because there does not exist /etc/X11/xorg.conf yet.
2044 If you want to use xinit anyway please call \"/usr/bin/xinit\"."
2045             return -1
2046         fi
2047     }
2048
2049     if check_com -c 915resolution ; then
2050         alias 855resolution='echo -e "Please use 915resolution as resolution modify tool for Intel graphic chipset."; return -1'
2051     fi
2052
2053     #a1# Output version of running grml
2054     alias grml-version='cat /etc/grml_version'
2055
2056     if check_com -c rebuildfstab ; then
2057         #a1# Rebuild /etc/fstab
2058         alias grml-rebuildfstab='rebuildfstab -v -r -config'
2059     fi
2060
2061     if check_com -c grml-debootstrap ; then
2062         alias debian2hd='print "Installing debian to harddisk is possible via using grml-debootstrap." ; return 1'
2063     fi
2064 }
2065 # }}}
2066
2067 # {{{ now run the functions
2068 isgrml && checkhome
2069 is4    && isgrml    && grmlstuff
2070 is4    && grmlcomp
2071 # }}}
2072
2073 # {{{ keephack
2074 is4 && xsource "/etc/zsh/keephack"
2075 # }}}
2076
2077 # {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson
2078 # You use it as follows:
2079 # $ NTREF=/reference/file
2080 # $ ls -l *(e:nt:)
2081 # This lists all the files in the current directory newer than the reference file.
2082 # You can also specify the reference file inline; note quotes:
2083 # $ ls -l *(e:'nt ~/.zshenv':)
2084 is4 && nt() {
2085     if [[ -n $1 ]] ; then
2086         local NTREF=${~1}
2087     fi
2088     [[ $REPLY -nt $NTREF ]]
2089 }
2090 # }}}
2091
2092 # shell functions {{{
2093
2094 #f1# Provide csh compatibility
2095 setenv()  { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }  # csh compatibility
2096
2097 #f1# Reload an autoloadable function
2098 freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
2099
2100 #f1# Reload zsh setup
2101 reload() {
2102     if [[ "$#*" -eq 0 ]] ; then
2103         [[ -r ~/.zshrc ]] && . ~/.zshrc
2104     else
2105         local fn
2106         for fn in "$@"; do
2107             unfunction $fn
2108             autoload -U $fn
2109         done
2110     fi
2111 }
2112 compdef _functions reload freload
2113
2114 #f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
2115 sll() {
2116     [[ -z "$1" ]] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
2117     for i in "$@" ; do
2118         file=$i
2119         while [[ -h "$file" ]] ; do
2120             ls -l $file
2121             file=$(readlink "$file")
2122         done
2123     done
2124 }
2125
2126 # fast manual access
2127 if check_com qma ; then
2128     #f1# View the zsh manual
2129     manzsh()  { qma zshall "$1" }
2130     compdef _man qma
2131 else
2132     manzsh()  { /usr/bin/man zshall |  vim -c "se ft=man| se hlsearch" +/"$1" - ; }
2133     # manzsh()  { /usr/bin/man zshall |  most +/"$1" ; }
2134     # [[ -f ~/.terminfo/m/mostlike ]] && MYLESS='LESS=C TERMINFO=~/.terminfo TERM=mostlike less' || MYLESS='less'
2135     # manzsh()  { man zshall | $MYLESS -p $1 ; }
2136 fi
2137
2138 if check_com -c $PAGER ; then
2139     #f1# View Debian's changelog of a given package
2140     dchange() {
2141         if [[ -r /usr/share/doc/${1}/changelog.Debian.gz ]] ; then
2142             $PAGER /usr/share/doc/${1}/changelog.Debian.gz
2143         elif [[ -r /usr/share/doc/${1}/changelog.gz ]] ; then
2144             $PAGER /usr/share/doc/${1}/changelog.gz
2145         else
2146             if check_com -c aptitude ; then
2147                 echo "No changelog for package $1 found, using aptitude to retrieve it."
2148                 if isgrml ; then
2149                     aptitude -t unstable changelog ${1}
2150                 else
2151                     aptitude changelog ${1}
2152                 fi
2153             else
2154                 echo "No changelog for package $1 found, sorry."
2155                 return 1
2156             fi
2157         fi
2158     }
2159     _dchange() { _files -W /usr/share/doc -/ }
2160     compdef _dchange dchange
2161
2162     #f1# View Debian's NEWS of a given package
2163     dnews() {
2164         if [[ -r /usr/share/doc/${1}/NEWS.Debian.gz ]] ; then
2165             $PAGER /usr/share/doc/${1}/NEWS.Debian.gz
2166         else
2167             if [[ -r /usr/share/doc/${1}/NEWS.gz ]] ; then
2168                 $PAGER /usr/share/doc/${1}/NEWS.gz
2169             else
2170                 echo "No NEWS file for package $1 found, sorry."
2171                 return 1
2172             fi
2173         fi
2174     }
2175     _dnews() { _files -W /usr/share/doc -/ }
2176     compdef _dnews dnews
2177
2178     #f1# View upstream's changelog of a given package
2179     uchange() {
2180         if [[ -r /usr/share/doc/${1}/changelog.gz ]] ; then
2181             $PAGER /usr/share/doc/${1}/changelog.gz
2182         else
2183             echo "No changelog for package $1 found, sorry."
2184             return 1
2185         fi
2186     }
2187     _uchange() { _files -W /usr/share/doc -/ }
2188     compdef _uchange uchange
2189 fi
2190
2191 # zsh profiling
2192 profile() {
2193     ZSH_PROFILE_RC=1 $SHELL "$@"
2194 }
2195
2196 #f1# Edit an alias via zle
2197 edalias() {
2198     [[ -z "$1" ]] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
2199 }
2200 compdef _aliases edalias
2201
2202 #f1# Edit a function via zle
2203 edfunc() {
2204     [[ -z "$1" ]] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
2205 }
2206 compdef _functions edfunc
2207
2208 # use it e.g. via 'Restart apache2'
2209 #m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
2210 #m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
2211 #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
2212 #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
2213 #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
2214 if [[ -d /etc/init.d || -d /etc/service ]] ; then
2215     __start_stop() {
2216         local action_="${1:l}"  # e.g Start/Stop/Restart
2217         local service_="$2"
2218         local param_="$3"
2219
2220         local service_target_="$(readlink /etc/init.d/$service_)"
2221         if [[ $service_target_ == "/usr/bin/sv" ]]; then
2222             # runit
2223             case "${action_}" in
2224                 start) if [[ ! -e /etc/service/$service_ ]]; then
2225                            $SUDO ln -s "/etc/sv/$service_" "/etc/service/"
2226                        else
2227                            $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
2228                        fi ;;
2229                 # there is no reload in runits sysv emulation
2230                 reload) $SUDO "/etc/init.d/$service_" "force-reload" "$param_" ;;
2231                 *) $SUDO "/etc/init.d/$service_" "${action_}" "$param_" ;;
2232             esac
2233         else
2234             # sysvinit
2235             $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
2236         fi
2237     }
2238
2239     for i in Start Restart Stop Force-Reload Reload ; do
2240         eval "$i() { __start_stop $i \"\$1\" \"\$2\" ; }"
2241     done
2242 fi
2243
2244 #f1# Provides useful information on globbing
2245 H-Glob() {
2246     echo -e "
2247     /      directories
2248     .      plain files
2249     @      symbolic links
2250     =      sockets
2251     p      named pipes (FIFOs)
2252     *      executable plain files (0100)
2253     %      device files (character or block special)
2254     %b     block special files
2255     %c     character special files
2256     r      owner-readable files (0400)
2257     w      owner-writable files (0200)
2258     x      owner-executable files (0100)
2259     A      group-readable files (0040)
2260     I      group-writable files (0020)
2261     E      group-executable files (0010)
2262     R      world-readable files (0004)
2263     W      world-writable files (0002)
2264     X      world-executable files (0001)
2265     s      setuid files (04000)
2266     S      setgid files (02000)
2267     t      files with the sticky bit (01000)
2268
2269   print *(m-1)          # Files modified up to a day ago
2270   print *(a1)           # Files accessed a day ago
2271   print *(@)            # Just symlinks
2272   print *(Lk+50)        # Files bigger than 50 kilobytes
2273   print *(Lk-50)        # Files smaller than 50 kilobytes
2274   print **/*.c          # All *.c files recursively starting in \$PWD
2275   print **/*.c~file.c   # Same as above, but excluding 'file.c'
2276   print (foo|bar).*     # Files starting with 'foo' or 'bar'
2277   print *~*.*           # All Files that do not contain a dot
2278   chmod 644 *(.^x)      # make all plain non-executable files publically readable
2279   print -l *(.c|.h)     # Lists *.c and *.h
2280   print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
2281   echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
2282 }
2283 alias help-zshglob=H-Glob
2284
2285 check_com -c qma && alias ?='qma zshall'
2286
2287 # grep for running process, like: 'any vim'
2288 any() {
2289     if [[ -z "$1" ]] ; then
2290         echo "any - grep for process(es) by keyword" >&2
2291         echo "Usage: any <keyword>" >&2 ; return 1
2292     else
2293         local STRING=$1
2294         local LENGTH=$(expr length $STRING)
2295         local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
2296         local REST=$(echo $(expr substr $STRING 2 $LENGTH))
2297         ps xauwww| grep "[$FIRSCHAR]$REST"
2298     fi
2299 }
2300
2301 # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
2302 # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
2303 [[ -r /proc/1/maps ]] && \
2304 deswap() {
2305     print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
2306     cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
2307     print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
2308 }
2309
2310 # print hex value of a number
2311 hex() {
2312     [[ -n "$1" ]] && printf "%x\n" $1 || { print 'Usage: hex <number-to-convert>' ; return 1 }
2313 }
2314
2315 # calculate (or eval at all ;-)) with perl => p[erl-]eval
2316 # hint: also take a look at zcalc -> 'autoload zcalc' -> 'man zshmodules | less -p MATHFUNC'
2317 peval() {
2318     [[ -n "$1" ]] && CALC="$*" || print "Usage: calc [expression]"
2319     perl -e "print eval($CALC),\"\n\";"
2320 }
2321 functions peval &>/dev/null && alias calc=peval
2322
2323 # brltty seems to have problems with utf8 environment and/or font Uni3-Terminus16 under
2324 # certain circumstances, so work around it, no matter which environment we have
2325 brltty() {
2326     if [[ -z "$DISPLAY" ]] ; then
2327         consolechars -f /usr/share/consolefonts/default8x16.psf.gz
2328         command brltty "$@"
2329     else
2330         command brltty "$@"
2331     fi
2332 }
2333
2334 # just press 'asdf' keys to toggle between dvorak and us keyboard layout
2335 aoeu() {
2336     echo -n 'Switching to us keyboard layout: '
2337     [[ -z "$DISPLAY" ]] && $SUDO loadkeys us &>/dev/null || setxkbmap us &>/dev/null
2338     echo 'Done'
2339 }
2340 asdf() {
2341     echo -n 'Switching to dvorak keyboard layout: '
2342     [[ -z "$DISPLAY" ]] && $SUDO loadkeys dvorak &>/dev/null || setxkbmap dvorak &>/dev/null
2343     echo 'Done'
2344 }
2345 # just press 'asdf' key to toggle from neon layout to us keyboard layout
2346 uiae() {
2347     echo -n 'Switching to us keyboard layout: '
2348     setxkbmap us && echo 'Done' || echo 'Failed'
2349 }
2350
2351 # set up an ipv6 tunnel
2352 ipv6-tunnel() {
2353     case $1 in
2354         start)
2355             if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
2356                 print 'ipv6 tunnel already set up, nothing to be done.'
2357                 print 'execute: "ifconfig sit1 down ; ifconfig sit0 down" to remove ipv6-tunnel.' ; return 1
2358             else
2359                 [[ -n "$PUBLIC_IP" ]] || \
2360                     local PUBLIC_IP=$(ifconfig $(route -n | awk '/^0\.0\.0\.0/{print $8; exit}') | \
2361                                       awk '/inet addr:/ {print $2}' | tr -d 'addr:')
2362
2363                 [[ -n "$PUBLIC_IP" ]] || { print 'No $PUBLIC_IP set and could not determine default one.' ; return 1 }
2364                 local IPV6ADDR=$(printf "2002:%02x%02x:%02x%02x:1::1" $(print ${PUBLIC_IP//./ }))
2365                 print -n "Setting up ipv6 tunnel $IPV6ADDR via ${PUBLIC_IP}: "
2366                 ifconfig sit0 tunnel ::192.88.99.1 up
2367                 ifconfig sit1 add "$IPV6ADDR" && print done || print failed
2368             fi
2369             ;;
2370         status)
2371             if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
2372                 print 'ipv6 tunnel available' ; return 0
2373             else
2374                 print 'ipv6 tunnel not available' ; return 1
2375             fi
2376             ;;
2377         stop)
2378             if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
2379                 print -n 'Stopping ipv6 tunnel (sit0 + sit1): '
2380                 ifconfig sit1 down ; ifconfig sit0 down && print done || print failed
2381             else
2382                 print 'No ipv6 tunnel found, nothing to be done.' ; return 1
2383             fi
2384             ;;
2385         *)
2386             print "Usage: ipv6-tunnel [start|stop|status]">&2 ; return 1
2387             ;;
2388     esac
2389 }
2390
2391 # run dhclient for wireless device
2392 iwclient() {
2393     salias dhclient "$(wavemon -d | awk '/device/{print $2}')"
2394 }
2395
2396 # spawn a minimally set up ksh - useful if you want to umount /usr/.
2397 minimal-shell() {
2398     exec env -i ENV="/etc/minimal-shellrc" HOME="$HOME" TERM="$TERM" ksh
2399 }
2400
2401 # make a backup of a file
2402 bk() {
2403     cp -a "$1" "${1}_$(date --iso-8601=seconds)"
2404 }
2405
2406 # Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
2407 # bash() {
2408 #  NO_SWITCH="yes" command bash "$@"
2409 # }
2410 # restart () {
2411 #  exec $SHELL $SHELL_ARGS "$@"
2412 # }
2413
2414 # }}}
2415
2416 # log out? set timeout in seconds {{{
2417 # TMOUT=1800
2418 # do not log out in some specific terminals:
2419 #  if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]] ; then
2420 #    unset TMOUT
2421 #  fi
2422 # }}}
2423
2424 # {{{ make sure our environment is clean regarding colors
2425 for color in BLUE RED GREEN CYAN YELLOW MAGENTA WHITE ; unset $color
2426 # }}}
2427
2428 # source another config file if present {{{
2429 xsource "/etc/zsh/zshrc.local"
2430 xsource "${HOME}/.zshenv"
2431 # }}}
2432
2433 # "persistent history" {{{
2434 # just write important commands you always need to ~/.important_commands
2435 if [[ -r ~/.important_commands ]] ; then
2436     fc -R ~/.important_commands
2437 fi
2438 # }}}
2439
2440 ## genrefcard.pl settings {{{
2441 ### example: split functions-search 8,16,24,32
2442 #@# split functions-search 8
2443 ## }}}
2444
2445 # add variable to be able to check whether the file has been read {{{
2446 ZSHRC_GLOBAL_HAS_BEEN_READ=1
2447 # }}}
2448
2449 ## END OF FILE #################################################################
2450 # vim:filetype=zsh foldmethod=marker autoindent expandtab shiftwidth=4