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