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