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