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