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