zshrc: introduce zrcautoload()
[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: Sam Dez 22 19:17:27 CET 2007 [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 # utility functions {{{
96 # this function checks if a command exists and returns either true
97 # or false. This avoids using 'which' and 'whence', which will
98 # avoid problems with aliases for which on certain weird systems. :-)
99 check_com() {
100     local -i comonly
101
102     if [[ ${1} == '-c' ]] ; then
103         (( comonly = 1 ))
104         shift
105     else
106         (( comonly = 0 ))
107     fi
108
109     if (( ${#argv} != 1 )) ; then
110         printf 'usage: check_com [-c] <command>\n' >&2
111         return 1
112     fi
113
114     if (( comonly > 0 )) ; then
115         [[ -n ${commands[$1]}  ]] && return 0
116         return 1
117     fi
118
119     if   [[ -n ${commands[$1]}    ]] \
120       || [[ -n ${functions[$1]}   ]] \
121       || [[ -n ${aliases[$1]}     ]] \
122       || [[ -n ${reswords[(r)$1]} ]] ; then
123
124         return 0
125     fi
126
127     return 1
128 }
129
130 # creates an alias and precedes the command with
131 # sudo if $EUID is not zero.
132 salias() {
133     local only=0 ; local multi=0
134     while [[ ${1} == -* ]] ; do
135         case ${1} in
136             (-o) only=1 ;;
137             (-a) multi=1 ;;
138             (--) shift ; break ;;
139             (-h)
140                 printf 'usage: salias [-h|-o|-a] <alias-expression>\n'
141                 printf '  -h      shows this help text.\n'
142                 printf '  -a      replace '\'' ; '\'' sequences with '\'' ; sudo '\''.\n'
143                 printf '          be careful using this option.\n'
144                 printf '  -o      only sets an alias if a preceding sudo would be needed.\n'
145                 return 0
146                 ;;
147             (*) printf "unkown option: '%s'\n" "${1}" ; return 1 ;;
148         esac
149         shift
150     done
151
152     if (( ${#argv} > 1 )) ; then
153         printf 'Too many arguments %s\n' "${#argv}"
154         return 1
155     fi
156
157     key="${1%%\=*}" ;  val="${1#*\=}"
158     if (( EUID == 0 )) && (( only == 0 )); then
159         alias -- "${key}=${val}"
160     elif (( EUID > 0 )) ; then
161         (( multi > 0 )) && val="${val// ; / ; sudo }"
162         alias -- "${key}=sudo ${val}"
163     fi
164
165     return 0
166 }
167
168 # Check if we can read given files and source those we can.
169 xsource() {
170     if (( ${#argv} < 1 )) ; then
171         printf 'usage: xsource FILE(s)...\n' >&2
172         return 1
173     fi
174
175     while (( ${#argv} > 0 )) ; do
176         [[ -r ${1} ]] && source ${1}
177         shift
178     done
179     return 0
180 }
181
182 # Check if we can read a given file and 'cat(1)' it.
183 xcat() {
184     if (( ${#argv} != 1 )) ; then
185         printf 'usage: xcat FILE\n' >&2
186         return 1
187     fi
188
189     [[ -r ${1} ]] && cat ${1}
190     return 0
191 }
192
193 # Remove these functions again, they are of use only in these
194 # setup files. This should be called at the end of .zshrc.
195 xunfunction() {
196     local -a funcs
197     funcs=(check_com salias xcat xsource xunfunction zrcautoload)
198
199     for func in $funcs ; do
200         [[ -n ${functions[$func]} ]] \
201             && unfunction $func
202     done
203     return 0
204 }
205
206 # autoload wrapper - use this one instead of autoload directly
207 function zrcautoload() {
208     setopt local_options extended_glob
209     local fdir ffile
210     local -i ffound
211
212     ffile=${1}
213     (( found = 0 ))
214     for fdir in ${fpath} ; do
215         [[ -e ${fdir}/${ffile} ]] && (( ffound = 1 ))
216     done
217
218     (( ffound == 0 )) && return 1
219     if [[ $ZSH_VERSION == 3.1.<6-> || $ZSH_VERSION == <4->* ]] ; then
220         autoload -U ${ffile} || return 1
221     else
222         autoload ${ffile} || return 1
223     fi
224     return 0
225 }
226
227 #}}}
228
229 # locale setup {{{
230 if [[ -z "$LANG" ]] ; then
231     xsource "/etc/default/locale"
232 fi
233
234 export LANG=${LANG:-en_US.iso885915}
235 for var in LC_ALL LC_MESSAGES ; do
236     [[ -n ${(P)var} ]] && export $var
237 done
238
239 xsource "/etc/sysconfig/keyboard"
240
241 TZ=$(xcat /etc/timezone)
242 # }}}
243
244 # check for potentially old files in 'completion.d' {{{
245 setopt extendedglob
246 xof=(/etc/zsh/completion.d/*~/etc/zsh/completion.d/_*(N))
247 if (( ${#xof} > 0 )) ; then
248     printf '\n -!- INFORMATION\n\n'
249     printf ' -!- %s file(s) not starting with an underscore (_) found in\n' ${#xof}
250     printf ' -!- /etc/zsh/completion.d/.\n\n'
251     printf ' -!- While this has been the case in old versions of grml-etc-core,\n'
252     printf ' -!- recent versions of the grml-zsh-setup have all these files rewritten\n'
253     printf ' -!- and renamed. Furthermore, the grml-zsh-setup will *only* add files\n'
254     printf ' -!- named _* to that directory.\n\n'
255     printf ' -!- If you added functions to completion.d yourself, please consider\n'
256     printf ' -!- moving them to /etc/zsh/functions.d/. Files in that directory, not\n'
257     printf ' -!- starting with an underscore are marked for automatic loading\n'
258     printf ' -!- by default (so that is quite convenient).\n\n'
259     printf ' -!- If there are files *not* starting with an underscore from an older\n'
260     printf ' -!- grml-etc-core in completion.d, you may safely remove them.\n\n'
261     printf ' -!- Delete the files for example via running:\n\n'
262     printf "      rm ${xof}\n\n"
263     printf ' -!- Note, that this message will *not* go away, unless you yourself\n'
264     printf ' -!- resolve the situation manually.\n\n'
265     BROKEN_COMPLETION_DIR=1
266 fi
267 unset xof
268 # }}}
269
270 # {{{ check for version/system
271 # check for versions (compatibility reasons)
272 is4(){
273     [[ $ZSH_VERSION == <4->* ]] && return 0
274     return 1
275 }
276
277 is41(){
278     [[ $ZSH_VERSION == 4.<1->* || $ZSH_VERSION == <5->* ]] && return 0
279     return 1
280 }
281
282 is42(){
283     [[ $ZSH_VERSION == 4.<2->* || $ZSH_VERSION == <5->* ]] && return 0
284     return 1
285 }
286
287 is43(){
288     [[ $ZSH_VERSION == 4.<3->* || $ZSH_VERSION == <5->* ]] && return 0
289     return 1
290 }
291
292 #f1# Checks whether or not you're running grml
293 isgrml(){
294     [[ -f /etc/grml_version ]] && return 0
295     return 1
296 }
297
298 #f1# Checks whether or not you're running a grml cd
299 isgrmlcd(){
300     [[ -f /etc/grml_cd ]] && return 0
301     return 1
302 }
303
304 if isgrml ; then
305 #f1# Checks whether or not you're running grml-small
306     isgrmlsmall() {
307         [[ ${${${(f)"$(</etc/grml_version)"}%% *}##*-} == 'small' ]] && return 0 ; return 1
308     }
309 else
310     isgrmlsmall() { return 1 }
311 fi
312
313 #f1# are we running within an utf environment?
314 isutfenv() {
315     case "$LANG $CHARSET $LANGUAGE" in
316         *utf*) return 0 ;;
317         *UTF*) return 0 ;;
318         *)     return 1 ;;
319     esac
320 }
321
322 # check for user, if not running as root set $SUDO to sudo
323 (( EUID != 0 )) && SUDO='sudo' || SUDO=''
324
325 # change directory to home on first invocation of zsh
326 # important for rungetty -> autologin
327 # Thanks go to Bart Schaefer!
328 isgrml && checkhome() {
329     if [[ -z "$ALREADY_DID_CD_HOME" ]] ; then
330         export ALREADY_DID_CD_HOME=$HOME
331         cd
332     fi
333 }
334 # }}}
335
336 # {{{ set some variables
337 if check_com -c vim ; then
338 #v#
339     export EDITOR=${EDITOR:-vim}
340 else
341     export EDITOR=${EDITOR:-vi}
342 fi
343
344 #v#
345 (( ${+PAGER} )) || export PAGER="less"
346
347 #v#
348 export MAIL=${MAIL:-/var/mail/$USER}
349
350 # if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/
351 export SHELL='/bin/zsh'
352
353 # color setup for ls:
354 check_com -c dircolors && eval $(dircolors -b)
355
356 # set width of man pages to 80 for more convenient reading
357 # (( ${+MANWIDTH} )) || export MANWIDTH=80
358
359 # Search path for the cd command
360 #  cdpath=(.. ~)
361
362 # completion functions go to /etc/zsh/completion.d
363 # function files may be put into /etc/zsh/functions.d, from where they
364 # will be automatically autoloaded.
365 if [[ -n "$BROKEN_COMPLETION_DIR" ]] ; then
366     print 'Warning: not setting completion directories because broken files have been found.' >&2
367 else
368     [[ -d /etc/zsh/completion.d ]] && fpath=( $fpath /etc/zsh/completion.d )
369     if [[ -d /etc/zsh/functions.d ]] ; then
370         fpath+=( /etc/zsh/functions.d )
371         for func in /etc/zsh/functions.d/[^_]*[^~] ; do
372             zrcautoload -U ${func:t}
373         done
374     fi
375 fi
376
377 # automatically remove duplicates from these arrays
378 typeset -U path cdpath fpath manpath
379 # }}}
380
381 # {{{ keybindings
382 if [[ "$TERM" != emacs ]] ; then
383     [[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
384     [[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
385     [[ -z "$terminfo[kend]"  ]] || bindkey -M emacs "$terminfo[kend]"  end-of-line
386     [[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
387     [[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
388     [[ -z "$terminfo[kend]"  ]] || bindkey -M vicmd "$terminfo[kend]"  vi-end-of-line
389     [[ -z "$terminfo[cuu1]"  ]] || bindkey -M viins "$terminfo[cuu1]"  vi-up-line-or-history
390     [[ -z "$terminfo[cuf1]"  ]] || bindkey -M viins "$terminfo[cuf1]"  vi-forward-char
391     [[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
392     [[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
393     [[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
394     [[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char
395     # ncurses stuff:
396     [[ "$terminfo[kcuu1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history
397     [[ "$terminfo[kcud1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history
398     [[ "$terminfo[kcuf1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char
399     [[ "$terminfo[kcub1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char
400     [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line
401     [[ "$terminfo[kend]"  == $'\eO'* ]] && bindkey -M viins "${terminfo[kend]/O/[}"  end-of-line
402     [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line
403     [[ "$terminfo[kend]"  == $'\eO'* ]] && bindkey -M emacs "${terminfo[kend]/O/[}"  end-of-line
404 fi
405
406 ## keybindings (run 'bindkeys' for details, more details via man zshzle)
407 # use emacs style per default:
408 bindkey -e
409 # use vi style:
410 # bindkey -v
411
412 #if [[ "$TERM" == screen ]] ; then
413 bindkey '\e[1~' beginning-of-line       # home
414 bindkey '\e[4~' end-of-line             # end
415 bindkey '\e[A'  up-line-or-search       # cursor up
416 bindkey '\e[B'  down-line-or-search     # <ESC>-
417 bindkey '^x'    history-beginning-search-backward # alternative ways of searching the shell history
418 # bindkey -s '^L' "|less\n"             # ctrl-L pipes to less
419 # bindkey -s '^B' " &\n"                # ctrl-B runs it in the background
420 # if terminal type is set to 'rxvt':
421 bindkey '\e[7~' beginning-of-line       # home
422 bindkey '\e[8~' end-of-line             # end
423 #fi
424
425 # insert unicode character
426 # usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an Â§
427 # See for example http://unicode.org/charts/ for unicode characters code
428 zrcautoload insert-unicode-char
429 zle -N insert-unicode-char
430 #k# Insert Unicode character
431 bindkey '^Xi' insert-unicode-char
432
433 # just type 'cd ...' to get 'cd ../..'
434 #  rationalise-dot() {
435 #  if [[ $LBUFFER == *.. ]] ; then
436 #    LBUFFER+=/..
437 #  else
438 #    LBUFFER+=.
439 #  fi
440 #  }
441 #  zle -N rationalise-dot
442 #  bindkey . rationalise-dot
443
444 #  bindkey '\eq' push-line-or-edit
445 # }}}
446
447 # a generic accept-line wrapper {{{
448
449 # This widget can prevent unwanted autocorrections from command-name
450 # to _command-name, rehash automatically on enter and call any number
451 # of builtin and user-defined widgets in different contexts.
452 #
453 # For a broader description, see:
454 # <http://bewatermyfriend.org/posts/2007/12-26.11-50-38-tooltime.html>
455 #
456 # The code is imported from the file 'zsh/functions/accept-line' from
457 # <http://ft.bewatermyfriend.org/comp/zsh/zsh-dotfiles.tar.bz2>, which
458 # distributed under the same terms as zsh itself.
459
460 # A newly added command will may not be found or will cause false
461 # correction attempts, if you got auto-correction set. By setting the
462 # following style, we force accept-line() to rehash, if it cannot
463 # find the first word on the command line in the $command[] hash.
464 zstyle ':acceptline:*' rehash true
465
466 function Accept-Line() {
467     setopt localoptions noksharrays
468     local -a subs
469     local -xi aldone
470     local sub
471
472     zstyle -a ":acceptline:${alcontext}" actions subs
473
474     (( ${#subs} < 1 )) && return 0
475
476     (( aldone = 0 ))
477     for sub in ${subs} ; do
478         [[ ${sub} == 'accept-line' ]] && sub='.accept-line'
479         zle ${sub}
480
481         (( aldone > 0 )) && break
482     done
483 }
484
485 function Accept-Line-getdefault() {
486     local default_action
487
488     zstyle -s ":acceptline:${alcontext}" default_action default_action
489     case ${default_action} in
490         ((accept-line|))
491             printf ".accept-line"
492             ;;
493         (*)
494             printf ${default_action}
495             ;;
496     esac
497 }
498
499 function accept-line() {
500     setopt localoptions noksharrays
501     local -a cmdline
502     local -x alcontext
503     local buf com fname format msg default_action
504
505     alcontext='default'
506     buf="${BUFFER}"
507     cmdline=(${(z)BUFFER})
508     com="${cmdline[1]}"
509     fname="_${com}"
510
511     zstyle -t ":acceptline:${alcontext}" rehash \
512         && [[ -z ${commands[$com]} ]]           \
513         && rehash
514
515     if    [[ -n ${reswords[(r)$com]} ]] \
516        || [[ -n ${aliases[$com]}     ]] \
517        || [[ -n ${functions[$com]}   ]] \
518        || [[ -n ${builtins[$com]}    ]] \
519        || [[ -n ${commands[$com]}    ]] ; then
520
521         # there is something sensible to execute, just do it.
522         alcontext='normal'
523         zle Accept-Line
524
525         default_action=$(Accept-Line-getdefault)
526         zstyle -T ":acceptline:${alcontext}" call_default \
527             && zle ${default_action}
528         return
529     fi
530
531     if    [[ -o correct              ]] \
532        || [[ -o correctall           ]] \
533        && [[ -n ${functions[$fname]} ]] ; then
534
535         # nothing there to execute but there is a function called
536         # _command_name; a completion widget. Makes no sense to
537         # call it on the commandline, but the correct{,all} options
538         # will ask for it nevertheless, so warn the user.
539         if [[ ${LASTWIDGET} == 'accept-line' ]] ; then
540             # Okay, we warned the user before, he called us again,
541             # so have it his way.
542             alcontext='force'
543             zle Accept-Line
544
545             default_action=$(Accept-Line-getdefault)
546             zstyle -T ":acceptline:${alcontext}" call_default \
547                 && zle ${default_action}
548             return
549         fi
550
551         # prepare warning message for the user, configurable via zstyle.
552         zstyle -s ":acceptline:${alcontext}" compwarnfmt msg
553
554         if [[ -z ${msg} ]] ; then
555             msg="%c will not execute and completion %f exists."
556         fi
557
558         zformat -f msg "${msg}" "c:${com}" "f:${fname}"
559
560         zle -M -- "${msg}"
561         return
562     elif [[ -n ${buf//[$' \t\n']##/} ]] ; then
563         # If we are here, the commandline contains something that is not
564         # executable, which is neither subject to _command_name correction
565         # and is not empty. might be a variable assignment
566         alcontext='misc'
567         zle Accept-Line
568
569         default_action=$(Accept-Line-getdefault)
570         zstyle -T ":acceptline:${alcontext}" call_default \
571             && zle ${default_action}
572         return
573     fi
574
575     # If we got this far, the commandline only contains whitespace, or is empty.
576     alcontext='empty'
577     zle Accept-Line
578
579     default_action=$(Accept-Line-getdefault)
580     zstyle -T ":acceptline:${alcontext}" call_default \
581         && zle ${default_action}
582 }
583
584 zle -N accept-line
585 zle -N Accept-Line
586
587 # }}}
588
589 # power completion - abbreviation expansion {{{
590 # power completion / abbreviation expansion / buffer expansion
591 # see http://zshwiki.org/home/examples/zleiab for details
592 # less risky than the global aliases but powerful as well
593 # just type the abbreviation key and afterwards ',.' to expand it
594 declare -A abk
595 setopt extendedglob
596 setopt interactivecomments
597 abk=(
598 # key  # value                (#d additional doc string)
599 #A# start
600     '...' '../..'
601     '....' '../../..'
602     'BG' '& exit'
603     'C' '| wc -l'
604     'G' '|& grep --color=auto'
605     'H' '| head'
606     'Hl' ' --help |& less -r'      #d (Display help in pager)
607     'L' '| less'
608     'LL' '|& less -r'
609     'M' '| most'
610     'N' '&>/dev/null'              #d (No Output)
611     'R' '| tr A-z N-za-m'          #d (ROT13)
612     'SL' '| sort | less'
613     'S' '| sort -u'
614     'T' '| tail'
615     'V' '|& vim -'
616 #A# end
617     'hide' "echo -en '\033]50;nil2\007'"
618     'tiny' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-80-*-*-c-*-iso8859-15\007"'
619     'small' 'echo -en "\033]50;6x10\007"'
620     'medium' 'echo -en "\033]50;-misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-15\007"'
621     'default' 'echo -e "\033]50;-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-15\007"'
622     'large' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-150-*-*-c-*-iso8859-15\007"'
623     'huge' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-210-*-*-c-*-iso8859-15\007"'
624     'smartfont' 'echo -en "\033]50;-artwiz-smoothansi-*-*-*-*-*-*-*-*-*-*-*-*\007"'
625     'semifont' 'echo -en "\033]50;-misc-fixed-medium-r-semicondensed-*-*-120-*-*-*-*-iso8859-15\007"'
626     'da' 'du -sch'
627     'j' 'jobs -l'
628     'u' 'translate -i'
629     'co' "./configure && make && sudo make install"
630     'CH' "./configure --help"
631     'conkeror' 'firefox -chrome chrome://conkeror/content'
632     'dir' 'ls -lSrah'
633     'lad' $'ls -d .*(/)\n# only show dot-directories'
634     'lsa' $'ls -a .*(.)\n# only show dot-files'
635     'lss' $'ls -l *(s,S,t)\n# only files with setgid/setuid/sticky flag'
636     'lsl' $'ls -l *(@[1,10])\n# only symlinks'
637     'lsx' $'ls -l *(*[1,10])\n# only executables'
638     'lsw' $'ls -ld *(R,W,X.^ND/)\n# world-{readable,writable,executable} files'
639     'lsbig' $'ls -flh *(.OL[1,10])\n# display the biggest files'
640     'lsd' $'ls -d *(/)\n# only show directories'
641     'lse' $'ls -d *(/^F)\n# only show empty directories'
642     'lsnew' $'ls -rl *(D.om[1,10])\n# display the newest files'
643     'lsold' $'ls -rtlh *(D.om[-11,-1])\n # display the oldest files'
644     'lssmall' $'ls -Srl *(.oL[1,10])\n# display the smallest files'
645     'rw-' 'chmod 600'
646     '600' 'chmod u+rw-x,g-rwx,o-rwx'
647     'rwx' 'chmod u+rwx'
648     '700' 'chmod u+rwx,g-rwx,o-rwx'
649     'r--' 'chmod u+r-wx,g-rwx,o-rwx'
650     '644' $'chmod u+rw-x,g+r-wx,o+r-wx\n # 4=r,2=w,1=x'
651     '755' 'chmod u+rwx,g+r-w+x,o+r-w+x'
652     'md' 'mkdir -p '
653     'cmplayer' 'mplayer -vo -fs -zoom fbdev'
654     'fbmplayer' 'mplayer -vo -fs -zoom fbdev'
655     'fblinks' 'links2 -driver fb'
656     'insecssh' 'ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
657     'insecscp' 'scp -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
658     'fori' 'for i ({..}) { }'
659     'cx' 'chmod +x'
660     'e'  'print -l'
661     'se' 'setopt interactivecomments'
662     'va' 'valac --vapidir=../vapi/ --pkg=gtk+-2.0 gtktest.vala'
663     'fb2' '=mplayer -vo fbdev -fs -zoom 1>/dev/null -xy 2'
664     'fb3' '=mplayer -vo fbdev -fs  -zoom 1>/dev/null -xy 3'
665     'ci' 'centericq'
666     'D'  'export DISPLAY=:0.0'
667     'mp' 'mplayer -vo xv -fs -zoom'
668 )
669
670 globalias() {
671     local MATCH
672     matched_chars='[.-|_a-zA-Z0-9]#'
673     LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
674     LBUFFER+=${abk[$MATCH]:-$MATCH}
675 }
676
677 zle -N globalias
678 bindkey ",." globalias
679 # }}}
680
681 # {{{ autoloading
682 zrcautoload zmv    # who needs mmv or rename?
683 zrcautoload history-search-end
684
685 # we don't want to quote/espace URLs on our own...
686 # if autoload -U url-quote-magic ; then
687 #    zle -N self-insert url-quote-magic
688 #    zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}='
689 # else
690 #    print 'Notice: no url-quote-magic available :('
691 # fi
692 alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic'
693
694 #m# k ESC-h Call \kbd{run-help} for the 1st word on the command line
695 alias run-help >&/dev/null && unalias run-help
696 zrcautoload run-help # use via 'esc-h'
697
698 # completion system
699 if zrcautoload compinit && compinit 2>/dev/null ; then
700     compinit 2>/dev/null || print 'Notice: no compinit available :('
701 else
702     print 'Notice: no compinit available :('
703     function zstyle { }
704     function compdef { }
705 fi
706
707 is4 && zrcautoload zed # use ZLE editor to edit a file or function
708
709 is4 && \
710 for mod in complist deltochar mathfunc ; do
711     zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :("
712 done
713
714 # autoload zsh modules when they are referenced
715 if is4 ; then
716     tmpargs=(
717         a   stat
718         a   zpty
719         ap  zprof
720         ap  mapfile
721     )
722
723     while (( ${#tmpargs} > 0 )) ; do
724         zmodload -${tmpargs[1]} zsh/${tmpargs[2]} ${tmpargs[2]}
725         shift 2 tmpargs
726     done
727     unset tmpargs
728 fi
729
730 if is4 && zrcautoload insert-files && zle -N insert-files ; then
731     #k# Insert files
732     bindkey "^Xf" insert-files # C-x-f
733 fi
734
735 bindkey ' '   magic-space    # also do history expansion on space
736 #k# Trigger menu-complete
737 bindkey '\ei' menu-complete  # menu completion via esc-i
738
739 # press esc-e for editing command line in $EDITOR or $VISUAL
740 if is4 && zrcautoload edit-command-line && zle -N edit-command-line ; then
741     #k# Edit the current line in \kbd{\$EDITOR}
742     bindkey '\ee' edit-command-line
743 fi
744
745 if is4 && [[ -n ${(k)modules[zsh/complist]} ]] ; then
746     #k# menu selection: pick item but stay in the menu
747     bindkey -M menuselect '\e^M' accept-and-menu-complete
748
749     # use the vi navigation keys (hjkl) besides cursor keys in menu completion
750     #bindkey -M menuselect 'h' vi-backward-char        # left
751     #bindkey -M menuselect 'k' vi-up-line-or-history   # up
752     #bindkey -M menuselect 'l' vi-forward-char         # right
753     #bindkey -M menuselect 'j' vi-down-line-or-history # bottom
754
755     # accept a completion and try to complete again by using menu
756     # completion; very useful with completing directories
757     # by using 'undo' one's got a simple file browser
758     bindkey -M menuselect '^o' accept-and-infer-next-history
759 fi
760
761 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
762 _bkdate() { BUFFER="$BUFFER$(date '+%F')"; CURSOR=$#BUFFER; }
763 zle -N _bkdate
764
765 #k# Insert a timestamp on the command line (yyyy-mm-dd)
766 bindkey '^Ed' _bkdate
767
768 # press esc-m for inserting last typed word again (thanks to caphuso!)
769 insert-last-typed-word() { zle insert-last-word -- 0 -1 };
770 zle -N insert-last-typed-word;
771
772 #k# Insert last typed word
773 bindkey "\em" insert-last-typed-word
774
775 # set command prediction from history, see 'man 1 zshcontrib'
776 #  is4 && zrcautoload predict-on && \
777 #  zle -N predict-on         && \
778 #  zle -N predict-off        && \
779 #  bindkey "^X^Z" predict-on && \
780 #  bindkey "^Z" predict-off
781
782 #k# Shortcut for \kbd{fg<enter>}
783 bindkey -s '^z' "fg\n"
784
785 # press ctrl-q to quote line:
786 #  mquote () {
787 #        zle beginning-of-line
788 #        zle forward-word
789 #        # RBUFFER="'$RBUFFER'"
790 #        RBUFFER=${(q)RBUFFER}
791 #        zle end-of-line
792 #  }
793 #  zle -N mquote && bindkey '^q' mquote
794
795 # run command line as user root via sudo:
796 sudo-command-line() {
797     [[ -z $BUFFER ]] && zle up-history
798     [[ $BUFFER != sudo\ * ]] && BUFFER="sudo $BUFFER"
799 }
800 zle -N sudo-command-line
801
802 #k# Put the current command line into a \kbd{sudo} call
803 bindkey "^Os" sudo-command-line
804
805 ### jump behind the first word on the cmdline.
806 ### useful to add options.
807 function jump_after_first_word() {
808     local words
809     words=(${(z)BUFFER})
810
811     if (( ${#words} <= 1 )) ; then
812         CURSOR=${#BUFFER}
813     else
814         CURSOR=${#${words[1]}}
815     fi
816 }
817 zle -N jump_after_first_word
818
819 bindkey '^x1' jump_after_first_word
820
821 # }}}
822
823 # {{{ set some important options
824 # Please update these tags, if you change the umask settings below.
825 #o# r_umask     002
826 #o# r_umaskstr  rwxrwxr-x
827 #o# umask       022
828 #o# umaskstr    rwxr-xr-x
829 (( EUID != 0 )) && umask 002 || umask 022
830
831 # history:
832 setopt append_history       # append history list to the history file (important for multiple parallel zsh sessions!)
833 is4 && setopt SHARE_HISTORY # import new commands from the history file also in other zsh-session
834 setopt extended_history     # save each command's beginning timestamp and the duration to the history file
835 is4 && setopt histignorealldups # If  a  new  command  line being added to the history
836                             # list duplicates an older one, the older command is removed from the list
837 setopt histignorespace      # remove command lines from the history list when
838                             # the first character on the line is a space
839 #  setopt histallowclobber    # add `|' to output redirections in the history
840 #  setopt NO_clobber          # warning if file exists ('cat /dev/null > ~/.zshrc')
841 setopt auto_cd              # if a command is issued that can't be executed as a normal command,
842                             # and the command is the name of a directory, perform the cd command to that directory
843 setopt extended_glob        # in order to use #, ~ and ^ for filename generation
844                             # grep word *~(*.gz|*.bz|*.bz2|*.zip|*.Z) ->
845                             # -> searches for word not in compressed files
846                             # don't forget to quote '^', '~' and '#'!
847 setopt notify               # report the status of backgrounds jobs immediately
848 setopt hash_list_all        # Whenever a command completion is attempted, make sure \
849                             # the entire command path is hashed first.
850 setopt completeinword       # not just at the end
851 # setopt nocheckjobs          # don't warn me about bg processes when exiting
852 setopt nohup                # and don't kill them, either
853 # setopt printexitvalue       # alert me if something failed
854 # setopt dvorak               # with spelling correction, assume dvorak kb
855 setopt auto_pushd           # make cd push the old directory onto the directory stack.
856 setopt nonomatch            # try to avoid the 'zsh: no matches found...'
857 setopt nobeep               # avoid "beep"ing
858 setopt pushd_ignore_dups    # don't push the same dir twice.
859
860 MAILCHECK=30       # mailchecks
861 REPORTTIME=5       # report about cpu-/system-/user-time of command if running longer than 5 seconds
862 watch=(notme root) # watch for everyone but me and root
863
864 # define word separators (for stuff like backward-word, forward-word, backward-kill-word,..)
865 #  WORDCHARS='*?_-.[]~=/&;!#$%^(){}<>' # the default
866 #  WORDCHARS=.
867 #  WORDCHARS='*?_[]~=&;!#$%^(){}'
868 #  WORDCHARS='${WORDCHARS:s@/@}'
869
870 # only slash should be considered as a word separator:
871 slash-backward-kill-word() {
872     local WORDCHARS="${WORDCHARS:s@/@}"
873     # zle backward-word
874     zle backward-kill-word
875 }
876 zle -N slash-backward-kill-word
877
878 #k# Kill everything in a word up to its last \kbd{/}
879 bindkey '\ev' slash-backward-kill-word
880
881 # }}}
882
883 # {{{ history
884
885 ZSHDIR=$HOME/.zsh
886
887 #v#
888 HISTFILE=$HOME/.zsh_history
889 isgrmlcd && HISTSIZE=500  || HISTSIZE=5000
890 isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
891
892 # }}}
893
894 # dirstack handling {{{
895
896 DIRSTACKSIZE=20
897 if [[ -f ~/.zdirs ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then
898     dirstack=( ${(f)"$(< ~/.zdirs)"} )
899     # "cd -" won't work after login by just setting $OLDPWD, so
900     [[ -d $dirstack[0] ]] && cd $dirstack[0] && cd $OLDPWD
901 fi
902
903 chpwd() {
904     builtin print -l ${(u)dirstack} >! ~/.zdirs
905 }
906
907 # }}}
908
909 # {{{ display battery status on right side of prompt via running 'BATTERY=1 zsh'
910 if [[ -n "$BATTERY" ]] ; then
911     if check_com -c acpi ; then
912         PERCENT="${(C)${(s| |)$(acpi 2>/dev/null)}[4]}"
913         [[ -z "$PERCENT" ]] && PERCENT='acpi not present'
914
915         if [[ "${PERCENT%%%}" -lt 20 ]] ; then
916             PERCENT="warning: ${PERCENT}%"
917         fi
918     fi
919 fi
920 # }}}
921
922 # display version control information on right side of prompt if $VCS is set {{{
923 # based on Mike Hommey's http://web.glandium.org/blog/?p=170
924 __vcs_dir() {
925     local vcs base_dir sub_dir ref
926
927     sub_dir() {
928       local sub_dir
929       sub_dir=$(readlink -f "${PWD}")
930       sub_dir=${sub_dir#$1}
931       echo ${sub_dir#/}
932     }
933
934     git_dir() {
935       base_dir=$(git-rev-parse --show-cdup 2>/dev/null) || return 1
936       base_dir=$(readlink -f "$base_dir/..")
937       sub_dir=$(git-rev-parse --show-prefix)
938       sub_dir=${sub_dir%/}
939       ref=$(git-symbolic-ref -q HEAD || git-name-rev --name-only HEAD 2>/dev/null)
940       ref=${ref#refs/heads/}
941       vcs="git"
942     }
943
944     svn_dir() {
945       [[ -d ".svn" ]] || return 1
946       base_dir="."
947       while [[ -d "$base_dir/../.svn" ]]; do base_dir="$base_dir/.."; done
948       base_dir=$(readlink -f "$base_dir")
949       sub_dir=$(sub_dir "${base_dir}")
950       ref=$(svn info "$base_dir" | awk '/^URL/ { sub(".*/","",$0); r=$0 } /^Revision/ { sub("[^0-9]*","",$0); print r":"$0 }')
951       vcs="svn"
952     }
953
954     svk_dir() {
955         [[ -f ~/.svk/config ]] || return 1
956         base_dir=$(awk '/: *$/ { sub(/^ */,"",$0); sub(/: *$/,"",$0); if (match("'${PWD}'", $0"(/|$)")) { print $0; d=1; } } /depotpath/ && d == 1 { sub(".*/","",$0); r=$0 } /revision/ && d == 1 { print r ":" $2; exit 1 }' ~/.svk/config) && return 1
957         ref=${base_dir##*
958   }
959         base_dir=${base_dir%%
960   *}
961         sub_dir=$(sub_dir "${base_dir}")
962         vcs="svk"
963     }
964
965     hg_dir() {
966         base_dir="."
967         while [[ ! -d "$base_dir/.hg" ]]; do
968             base_dir="$base_dir/.."
969             [[ $(readlink -f "${base_dir}") = "/" ]] && return 1
970         done
971         base_dir=$(readlink -f "$base_dir")
972         sub_dir=$(sub_dir "${base_dir}")
973         ref=$(< "${base_dir}/.hg/branch")
974         vcs="hg"
975     }
976
977     hg_dir  ||
978     git_dir ||
979     svn_dir ||
980     svk_dir # ||
981   #  base_dir="$PWD"
982   #  echo "${vcs:+($vcs)}${base_dir/$HOME/~}${vcs:+[$ref]${sub_dir}}"
983     echo "${vcs:+($vcs)}${base_dir}${vcs:+[$ref]${sub_dir}}"
984 }
985 # }}}
986
987 # {{{ set prompt
988 if zrcautoload promptinit && promptinit 2>/dev/null ; then
989     promptinit # people should be able to use their favourite prompt
990 else
991     print 'Notice: no promptinit available :('
992 fi
993
994
995 # precmd() => a function which is executed just before each prompt
996 # use 'NOPRECMD=1' to disable the precmd + preexec commands
997
998 # precmd () { setopt promptsubst; [[ -o interactive ]] && jobs -l;
999
1000 # make sure to use right prompt only when not running a command
1001 is41 && setopt transient_rprompt
1002
1003 is4 && [[ -z $NOPRECMD ]] && precmd () {
1004     [[ -n $NOPRECMD ]] && return 0
1005     # allow manual overwriting of RPROMPT
1006     if [[ -n $RPROMPT ]] ; then
1007         [[ $TERM == screen* ]] && echo -n $'\ekzsh\e\\'
1008         # return 0
1009     fi
1010     # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
1011     if [[ -z $DONTSETRPROMPT ]] ; then
1012         if [[ -n $BATTERY ]] ; then
1013             RPROMPT="%(?..:()% ${PERCENT}${SCREENTITLE}"
1014             # RPROMPT="${PERCENT}${SCREENTITLE}"
1015         elif [[ -n $VCS ]] ; then
1016             RPROMPT="%(?..:()% $(__vcs_dir)${SCREENTITLE}"
1017         else
1018             RPROMPT="%(?..:()% ${SCREENTITLE}"
1019             # RPROMPT="${SCREENTITLE}"
1020         fi
1021     fi
1022     # adjust title of xterm
1023     # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
1024     case $TERM in
1025         (xterm*|rxvt)
1026             print -Pn "\e]0;%n@%m: %~\a"
1027             ;;
1028     esac
1029 }
1030
1031 # chpwd () => a function which is executed whenever the directory is changed
1032
1033 # preexec() => a function running before every command
1034 is4 && [[ -z $NOPRECMD ]] && \
1035 preexec () {
1036     [[ -n $NOPRECMD ]] && return 0
1037 # set hostname if not running on host with name 'grml'
1038     if [[ -n "$HOSTNAME" ]] && [[ "$HOSTNAME" != $(hostname) ]] ; then
1039        NAME="@$HOSTNAME"
1040     fi
1041 # get the name of the program currently running and hostname of local machine
1042 # set screen window title if running in a screen
1043     if [[ "$TERM" == screen* ]] ; then
1044         # local CMD=${1[(wr)^(*=*|sudo|ssh|-*)]}       # don't use hostname
1045         local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME" # use hostname
1046         echo -ne "\ek$CMD\e\\"
1047     fi
1048 # set the screen title to "zsh" when sitting at the command prompt:
1049     if [[ "$TERM" == screen* ]] ; then
1050         SCREENTITLE=$'%{\ekzsh\e\\%}'
1051     else
1052         SCREENTITLE=''
1053     fi
1054 # adjust title of xterm
1055     case $TERM in
1056         (xterm*|rxvt)
1057             print -Pn "\e]0;%n@%m: $1\a"
1058             ;;
1059     esac
1060 }
1061
1062 # set colors
1063 if zrcautoload colors && colors 2>/dev/null ; then
1064     BLUE="%{${fg[blue]}%}"
1065     RED="%{${fg_bold[red]}%}"
1066     GREEN="%{${fg[green]}%}"
1067     CYAN="%{${fg[cyan]}%}"
1068     WHITE="%{${fg[white]}%}"
1069     NO_COLOUR="%{${reset_color}%}"
1070 else
1071     BLUE=$'%{\e[1;34m%}'
1072     RED=$'%{\e[1;31m%}'
1073     GREEN=$'%{\e[1;32m%}'
1074     CYAN=$'%{\e[1;36m%}'
1075     WHITE=$'%{\e[1;37m%}'
1076     NO_COLOUR=$'%{\e[0m%}'
1077 fi
1078
1079 EXITCODE="%(?..%?%1v )"
1080 PS2='`%_> '       # secondary prompt, printed when the shell needs more information to complete a command.
1081 PS3='?# '         # selection prompt used within a select loop.
1082 PS4='+%N:%i:%_> ' # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
1083
1084 # set variable debian_chroot if running in a chroot with /etc/debian_chroot
1085 if [[ -z "$debian_chroot" ]] && [[ -r /etc/debian_chroot ]] ; then
1086     debian_chroot=$(cat /etc/debian_chroot)
1087 fi
1088
1089 # don't use colors on dumb terminals (like emacs):
1090 if [[ "$TERM" == dumb ]] ; then
1091     PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< %# "
1092 else
1093     # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended prompt
1094     # set variable identifying the chroot you work in (used in the prompt below)
1095     if [[ -n $GRMLPROMPT ]] ; then
1096         PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
1097 ${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# "
1098     else
1099         if (( EUID != 0 )); then
1100             PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
1101         else
1102             PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
1103         fi
1104     fi
1105 fi
1106
1107 # if we are inside a grml-chroot set a specific prompt theme
1108 if [[ -n "$GRML_CHROOT" ]] ; then
1109     PROMPT="%{$fg[red]%}(CHROOT) %{$fg_bold[red]%}%n%{$fg_no_bold[white]%}@%m %40<...<%B%~%b%<< %\# "
1110 fi
1111 # }}}
1112
1113 # {{{ 'hash' some often used directories
1114 #d# start
1115 hash -d deb=/var/cache/apt/archives
1116 hash -d doc=/usr/share/doc
1117 hash -d linux=/lib/modules/$(command uname -r)/build/
1118 hash -d log=/var/log
1119 hash -d slog=/var/log/syslog
1120 hash -d src=/usr/src
1121 hash -d templ=/usr/share/doc/grml-templates
1122 hash -d tt=/usr/share/doc/texttools-doc
1123 hash -d www=/var/www
1124 #d# end
1125 # }}}
1126
1127 # {{{ some aliases
1128 if [[ $UID -eq 0 ]] ; then
1129     [[ -r /etc/grml/screenrc ]] && alias screen='/usr/bin/screen -c /etc/grml/screenrc'
1130 elif [[ -r $HOME/.screenrc ]] ; then
1131     alias screen="/usr/bin/screen -c $HOME/.screenrc"
1132 else
1133     [[ -r /etc/grml/screenrc_grml ]] && alias screen='/usr/bin/screen -c /etc/grml/screenrc_grml'
1134 fi
1135
1136 # do we have GNU ls with color-support?
1137 if ls --help 2>/dev/null | grep -- --color= >/dev/null && [[ "$TERM" != dumb ]] ; then
1138     #a1# execute \kbd{@a@}:\quad ls with colors
1139     alias ls='ls -b -CF --color=auto'
1140     #a1# execute \kbd{@a@}:\quad list all files, with colors
1141     alias la='ls -la --color=auto'
1142     #a1# long colored list, without dotfiles (@a@)
1143     alias ll='ls -l --color=auto'
1144     #a1# long colored list, human readable sizes (@a@)
1145     alias lh='ls -hAl --color=auto'
1146     #a1# List files, append qualifier to filenames \\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
1147     alias l='ls -lF --color=auto'
1148 else
1149     alias ls='ls -b -CF'
1150     alias la='ls -la'
1151     alias ll='ls -l'
1152     alias lh='ls -hAl'
1153     alias l='ls -lF'
1154 fi
1155
1156 alias mdstat='cat /proc/mdstat'
1157 alias ...='cd ../../'
1158
1159 # generate alias named "$KERNELVERSION-reboot" so you can use boot with kexec:
1160 if [[ -x /sbin/kexec ]] && [[ -r /proc/cmdline ]] ; then
1161     alias "$(uname -r)-reboot"="kexec -l --initrd=/boot/initrd.img-"$(uname -r)" --command-line=\"$(cat /proc/cmdline)\" /boot/vmlinuz-"$(uname -r)""
1162 fi
1163
1164 alias cp='nocorrect cp'         # no spelling correction on cp
1165 alias mkdir='nocorrect mkdir'   # no spelling correction on mkdir
1166 alias mv='nocorrect mv'         # no spelling correction on mv
1167 alias rm='nocorrect rm'         # no spelling correction on rm
1168
1169 #a1# Execute \kbd{rmdir}
1170 alias rd='rmdir'
1171 #a1# Execute \kbd{rmdir}
1172 alias md='mkdir'
1173
1174 # see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
1175 alias term2iso="echo 'Setting terminal to iso mode' ; print -n '\e%@'"
1176 alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
1177
1178 # make sure it is not assigned yet
1179 [[ $(whence -w utf2iso &>/dev/null) == 'utf2iso: alias' ]] && unalias utf2iso
1180
1181 utf2iso() {
1182     if isutfenv ; then
1183         for ENV in $(env | command grep -i '.utf') ; do
1184             eval export "$(echo $ENV | sed 's/UTF-8/iso885915/ ; s/utf8/iso885915/')"
1185         done
1186     fi
1187 }
1188
1189 # make sure it is not assigned yet
1190 [[ $(whence -w iso2utf &>/dev/null) == 'iso2utf: alias' ]] && unalias iso2utf
1191 iso2utf() {
1192     if ! isutfenv ; then
1193         for ENV in $(env | command grep -i '\.iso') ; do
1194             eval export "$(echo $ENV | sed 's/iso.*/UTF-8/ ; s/ISO.*/UTF-8/')"
1195         done
1196     fi
1197 }
1198
1199 # set up software synthesizer via speakup
1200 swspeak() {
1201     aumix -w 90 -v 90 -p 90 -m 90
1202     if ! [[ -r /dev/softsynth ]] ; then
1203         flite -o play -t "Sorry, software synthesizer not available. Did you boot with swspeak bootoption?"
1204         return 1
1205     else
1206         setopt singlelinezle
1207         unsetopt prompt_cr
1208         export PS1="%m%# "
1209         nice -n -20 speechd-up
1210         sleep 2
1211         flite -o play -t "Finished setting up software synthesizer"
1212     fi
1213 }
1214
1215 # I like clean prompt, so provide simple way to get that
1216 check_com 0 || alias 0='return 0'
1217
1218 # for really lazy people like mika:
1219 check_com S &>/dev/null || alias S='screen'
1220 check_com s &>/dev/null || alias s='ssh'
1221
1222 # get top 10 shell commands:
1223 alias top10='print -l ? ${(o)history%% *} | uniq -c | sort -nr | head -n 10'
1224
1225 # truecrypt; use e.g. via 'truec /dev/ice /mnt/ice' or 'truec -i'
1226 if check_com -c truecrypt ; then
1227     if isutfenv ; then
1228         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077,utf8" '
1229     else
1230         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077" '
1231     fi
1232 fi
1233
1234 #f1# Hints for the use of zsh on grml
1235 zsh-help() {
1236     print "$bg[white]$fg[black]
1237 zsh-help - hints for use of zsh on grml
1238 =======================================$reset_color"
1239
1240     print '
1241 Main configuration of zsh happens in /etc/zsh/zshrc (global)
1242 and /etc/skel/.zshrc which is copied to $HOME/.zshrc once.
1243 The files are part of the package grml-etc-core, if you want to
1244 use them on a non-grml-system just get the tar.gz from
1245 http://deb.grml.org/ or get the files from the mercurial
1246 repository:
1247
1248   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
1249   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
1250
1251 If you want to stay in sync with zsh configuration of grml
1252 run '\''ln -sf /etc/skel/.zshrc $HOME/.zshrc'\'' and configure
1253 your own stuff in $HOME/.zshrc.local. System wide configuration
1254 without touching configuration files of grml can take place
1255 in /etc/zsh/zshrc.local.
1256
1257 If you want to use the configuration of user grml also when
1258 running as user root just run '\''zshskel'\'' which will source
1259 the file /etc/skel/.zshrc.
1260
1261 For information regarding zsh start at http://grml.org/zsh/
1262
1263 Take a look at grml'\''s zsh refcard:
1264 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
1265
1266 Check out the main zsh refcard:
1267 % '$BROWSER' http://www.bash2zsh.com/zsh_refcard/refcard.pdf
1268
1269 And of course visit the zsh-lovers:
1270 % man zsh-lovers
1271
1272 You can adjust some options through environment variables when
1273 invoking zsh without having to edit configuration files.
1274 Basically meant for bash users who are not used to the power of
1275 the zsh yet. :)
1276
1277   "NOCOR=1    zsh" => deactivate automatic correction
1278   "NOMENU=1   zsh" => do not use menu completion (note: use strg-d for completion instead!)
1279   "NOPRECMD=1 zsh" => disable the precmd + preexec commands (set GNU screen title)
1280   "BATTERY=1  zsh" => activate battery status (via acpi) on right side of prompt'
1281
1282     print "
1283 $bg[white]$fg[black]
1284 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
1285 Enjoy your grml system with the zsh!$reset_color"
1286 }
1287
1288 # debian stuff
1289 if [[ -r /etc/debian_version ]] ; then
1290     #a3# Execute \kbd{apt-cache search}
1291     alias acs='apt-cache search'
1292     #a3# Execute \kbd{apt-cache show}
1293     alias acsh='apt-cache show'
1294     #a3# Execute \kbd{apt-cache policy}
1295     alias acp='apt-cache policy'
1296     #a3# Execute \kbd{apt-get dist-upgrade}
1297     salias adg="apt-get dist-upgrade"
1298     #a3# Execute \kbd{apt-get install}
1299     salias agi="apt-get install"
1300     #a3# Execute \kbd{aptitude install}
1301     salias ati="aptitude install"
1302     #a3# Execute \kbd{apt-get upgrade}
1303     salias ag="apt-get upgrade"
1304     #a3# Execute \kbd{apt-get update}
1305     salias au="apt-get update"
1306     #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
1307     salias -a up="aptitude update ; aptitude safe-upgrade"
1308     #a3# Execute \kbd{dpkg-buildpackage}
1309     alias dbp='dpkg-buildpackage'
1310     #a3# Execute \kbd{grep-excuses}
1311     alias ge='grep-excuses'
1312
1313     # debian upgrade
1314     #f3# Execute \kbd{apt-get update \&\& }\\&\quad \kbd{apt-get dist-upgrade}
1315     upgrade() {
1316         if [[ -z "$1" ]] ; then
1317             $SUDO apt-get update
1318             $SUDO apt-get -u upgrade
1319         else
1320             ssh $1 $SUDO apt-get update
1321             # ask before the upgrade
1322             local dummy
1323             ssh $1 $SUDO apt-get --no-act upgrade
1324             echo -n 'Process the upgrade?'
1325             read -q dummy
1326             if [[ $dummy == "y" ]] ; then
1327                 ssh $1 $SUDO apt-get -u upgrade --yes
1328             fi
1329         fi
1330     }
1331
1332     isgrmlcd && alias su="sudo -s"          # get a root shell
1333     #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
1334     alias llog="$PAGER /var/log/syslog"     # take a look at the syslog
1335     #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
1336     alias tlog="tail -f /var/log/syslog"    # follow the syslog
1337     #a1# (Re)-source \kbd{/etc/skel/.zshrc}
1338     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
1339 fi
1340
1341 # sort installed Debian-packages by size
1342 if check_com -c grep-status ; then
1343     #a3# List installed Debian-packages sorted by size
1344     alias debs-by-size='grep-status -FStatus -sInstalled-Size,Package -n "install ok installed" | paste -sd "  \n" | sort -rn'
1345 fi
1346
1347 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
1348 if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord ; then
1349     if check_com -c wodim ; then
1350         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
1351 See #377109 in the BTS of Debian for more details.
1352
1353 Please use the wodim binary instead' ; return 1"
1354     fi
1355 fi
1356
1357 # get_tw_cli has been renamed into get_3ware
1358 if check_com -c get_3ware ; then
1359     get_tw_cli() {
1360         echo 'Warning: get_tw_cli has been renamed into get_3ware. Invoking get_3ware for you.'>&2
1361         get_3ware
1362     }
1363 fi
1364
1365 # I hate lacking backward compatibility, so provide an alternative therefore
1366 if ! check_com -c apache2-ssl-certificate ; then
1367
1368     apache2-ssl-certificate() {
1369
1370     print 'Debian does not ship apache2-ssl-certificate anymore (see #398520). :('
1371     print 'You might want to take a look at Debian the package ssl-cert as well.'
1372     print 'To generate a certificate for use with apache2 follow the instructions:'
1373
1374     echo '
1375
1376 export RANDFILE=/dev/random
1377 mkdir /etc/apache2/ssl/
1378 openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
1379 chmod 600 /etc/apache2/ssl/apache.pem
1380
1381 Run "grml-tips ssl-certificate" if you need further instructions.
1382 '
1383     }
1384 fi
1385 # }}}
1386
1387 # {{{ Use hard limits, except for a smaller stack and no core dumps
1388 unlimit
1389 is4 && limit stack 8192
1390 isgrmlcd && limit core 0 # important for a live-cd-system
1391 limit -s
1392 # }}}
1393
1394 # {{{ completion system
1395
1396 # called later (via is4 && grmlcomp)
1397 # notice: use 'zstyle' for getting current settings
1398 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
1399 grmlcomp() {
1400     # TODO: This could use some additional information
1401
1402     # allow one error for every three characters typed in approximate completer
1403     zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )'
1404
1405     # don't complete backup files as executables
1406     zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)'
1407
1408     # start menu completion only if it could find no unambiguous initial string
1409     zstyle ':completion:*:correct:*'       insert-unambiguous true
1410     zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}'
1411     zstyle ':completion:*:correct:*'       original true
1412
1413     # activate color-completion
1414     zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}
1415
1416     # format on completion
1417     zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'
1418
1419     # complete 'cd -<tab>' with menu
1420     zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
1421
1422     # insert all expansions for expand completer
1423     zstyle ':completion:*:expand:*'        tag-order all-expansions
1424     zstyle ':completion:*:history-words'   list false
1425
1426     # activate menu
1427     zstyle ':completion:*:history-words'   menu yes
1428
1429     # ignore duplicate entries
1430     zstyle ':completion:*:history-words'   remove-all-dups yes
1431     zstyle ':completion:*:history-words'   stop yes
1432
1433     # match uppercase from lowercase
1434     zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'
1435
1436     # separate matches into groups
1437     zstyle ':completion:*:matches'         group 'yes'
1438     zstyle ':completion:*'                 group-name ''
1439
1440     if [[ -z "$NOMENU" ]] ; then
1441         # if there are more than 5 options allow selecting from a menu
1442         zstyle ':completion:*'               menu select=5
1443     else
1444         # don't use any menus at all
1445         setopt no_auto_menu
1446     fi
1447
1448     zstyle ':completion:*:messages'        format '%d'
1449     zstyle ':completion:*:options'         auto-description '%d'
1450
1451     # describe options in full
1452     zstyle ':completion:*:options'         description 'yes'
1453
1454     # on processes completion complete all user processes
1455     zstyle ':completion:*:processes'       command 'ps -au$USER'
1456
1457     # offer indexes before parameters in subscripts
1458     zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
1459
1460     # provide verbose completion information
1461     zstyle ':completion:*'                 verbose true
1462
1463     # recent (as of Dec 2007) zsh versions are able to provide descriptions
1464     # for commands (read: 1st word in the line) that it will list for the user
1465     # to choose from. The following disables that, because it's not exactly fast.
1466     zstyle ':completion:*:-command-:*:'    verbose false
1467
1468     # set format for warnings
1469     zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d'
1470
1471     # define files to ignore for zcompile
1472     zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'
1473     zstyle ':completion:correct:'          prompt 'correct to: %e'
1474
1475     # Ignore completion functions for commands you don't have:
1476     zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'
1477
1478     # complete manual by their section
1479     zstyle ':completion:*:manuals'    separate-sections true
1480     zstyle ':completion:*:manuals.*'  insert-sections   true
1481     zstyle ':completion:*:man:*'      menu yes select
1482
1483     # run rehash on completion so new installed program are found automatically:
1484     _force_rehash() {
1485         (( CURRENT == 1 )) && rehash
1486         return 1
1487     }
1488
1489     ## correction
1490     # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
1491     if [[ -n "$NOCOR" ]] ; then
1492         zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
1493         setopt nocorrect
1494     else
1495         # try to be smart about when to use what completer...
1496         setopt correct
1497         zstyle -e ':completion:*' completer '
1498             if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then
1499                 _last_try="$HISTNO$BUFFER$CURSOR"
1500                 reply=(_complete _match _ignored _prefix _files)
1501             else
1502                 if [[ $words[1] == (rm|mv) ]] ; then
1503                     reply=(_complete _files)
1504                 else
1505                     reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files)
1506                 fi
1507             fi'
1508     fi
1509
1510     # zstyle ':completion:*' completer _complete _correct _approximate
1511     # zstyle ':completion:*' expand prefix suffix
1512
1513     # command for process lists, the local web server details and host completion
1514     zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
1515
1516     # caching
1517     [[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \
1518                             zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
1519
1520     # host completion /* add brackets as vim can't parse zsh's complex cmdlines 8-) {{{ */
1521     if is42 ; then
1522         [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
1523         [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
1524     else
1525         _ssh_hosts=()
1526         _etc_hosts=()
1527     fi
1528     hosts=(
1529         $(hostname)
1530         "$_ssh_hosts[@]"
1531         "$_etc_hosts[@]"
1532         grml.org
1533         localhost
1534     )
1535     zstyle ':completion:*:hosts' hosts $hosts
1536     #  zstyle '*' hosts $hosts
1537
1538     # specify your logins:
1539     # my_accounts=(
1540     #  {grml,grml1}@foo.invalid
1541     #  grml-devel@bar.invalid
1542     # )
1543     # other_accounts=(
1544     #  {fred,root}@foo.invalid
1545     #  vera@bar.invalid
1546     # )
1547     # zstyle ':completion:*:my-accounts' users-hosts $my_accounts
1548     # zstyle ':completion:*:other-accounts' users-hosts $other_accounts
1549
1550     # specify specific port/service settings:
1551     #  telnet_users_hosts_ports=(
1552     #    user1@host1:
1553     #    user2@host2:
1554     #    @mail-server:{smtp,pop3}
1555     #    @news-server:nntp
1556     #    @proxy-server:8000
1557     #  )
1558     # zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
1559
1560     # use generic completion system for programs not yet defined; (_gnu_generic works
1561     # with commands that provide a --help option with "standard" gnu-like output.)
1562     compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
1563
1564     # see upgrade function in this file
1565     compdef _hosts upgrade
1566 }
1567 # }}}
1568
1569 # {{{ grmlstuff
1570 grmlstuff() {
1571 # people should use 'grml-x'!
1572     startx() {
1573         if [[ -e /etc/X11/xorg.conf ]] ; then
1574             [[ -x /usr/bin/startx ]] && /usr/bin/startx "$@" || /usr/X11R6/bin/startx "$@"
1575         else
1576             echo "Please use the script \"grml-x\" for starting the X Window System
1577 because there does not exist /etc/X11/xorg.conf yet.
1578 If you want to use startx anyway please call \"/usr/bin/startx\"."
1579             return -1
1580         fi
1581     }
1582
1583     xinit() {
1584         if [[ -e /etc/X11/xorg.conf ]] ; then
1585             [[ -x /usr/bin/xinit ]] && /usr/bin/xinit || /usr/X11R6/bin/xinit
1586         else
1587             echo "Please use the script \"grml-x\" for starting the X Window System.
1588 because there does not exist /etc/X11/xorg.conf yet.
1589 If you want to use xinit anyway please call \"/usr/bin/xinit\"."
1590             return -1
1591         fi
1592     }
1593
1594     if check_com -c 915resolution ; then
1595         alias 855resolution='echo -e "Please use 915resolution as resolution modify tool for Intel graphic chipset."; return -1'
1596     fi
1597
1598     #a1# Output version of running grml
1599     alias grml-version='cat /etc/grml_version'
1600
1601     if check_com -c rebuildfstab ; then
1602         #a1# Rebuild /etc/fstab
1603         alias grml-rebuildfstab='rebuildfstab -v -r -config'
1604     fi
1605
1606     if check_com -c grml-debootstrap ; then
1607         alias debian2hd='print "Installing debian to harddisk is possible via using grml-debootstrap." ; return 1'
1608     fi
1609 }
1610 # }}}
1611
1612 # {{{ now run the functions
1613 isgrml && checkhome
1614 is4    && isgrml    && grmlstuff
1615 is4    && grmlcomp
1616 # }}}
1617
1618 # {{{ keephack
1619 is4 && xsource "/etc/zsh/keephack"
1620 # }}}
1621
1622 # {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson
1623 # You use it as follows:
1624 # $ NTREF=/reference/file
1625 # $ ls -l *(e:nt:)
1626 # This lists all the files in the current directory newer than the reference file.
1627 # You can also specify the reference file inline; note quotes:
1628 # $ ls -l *(e:'nt ~/.zshenv':)
1629 is4 && nt() {
1630     if [[ -n $1 ]] ; then
1631         local NTREF=${~1}
1632     fi
1633     [[ $REPLY -nt $NTREF ]]
1634 }
1635 # }}}
1636
1637 # shell functions {{{
1638
1639 #f1# Provide csh compatibility
1640 setenv()  { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }  # csh compatibility
1641
1642 #f1# Reload an autoloadable function
1643 freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
1644
1645 #f1# Reload zsh setup
1646 reload() {
1647     if [[ "$#*" -eq 0 ]] ; then
1648         [[ -r ~/.zshrc ]] && . ~/.zshrc
1649     else
1650         local fn
1651         for fn in "$@"; do
1652             unfunction $fn
1653             autoload -U $fn
1654         done
1655     fi
1656 }
1657 compdef _functions reload freload
1658
1659 #f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
1660 sll() {
1661     [[ -z "$1" ]] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
1662     for i in "$@" ; do
1663         file=$i
1664         while [[ -h "$file" ]] ; do
1665             ls -l $file
1666             file=$(readlink "$file")
1667         done
1668     done
1669 }
1670
1671 # fast manual access
1672 if check_com qma ; then
1673     #f1# View the zsh manual
1674     manzsh()  { qma zshall "$1" }
1675     compdef _man qma
1676 else
1677     manzsh()  { /usr/bin/man zshall |  vim -c "se ft=man| se hlsearch" +/"$1" - ; }
1678     # manzsh()  { /usr/bin/man zshall |  most +/"$1" ; }
1679     # [[ -f ~/.terminfo/m/mostlike ]] && MYLESS='LESS=C TERMINFO=~/.terminfo TERM=mostlike less' || MYLESS='less'
1680     # manzsh()  { man zshall | $MYLESS -p $1 ; }
1681 fi
1682
1683 if check_com -c $PAGER ; then
1684     #f1# View Debian's changelog of a given package
1685     dchange() {
1686         if [[ -r /usr/share/doc/${1}/changelog.Debian.gz ]] ; then
1687             $PAGER /usr/share/doc/${1}/changelog.Debian.gz
1688         elif [[ -r /usr/share/doc/${1}/changelog.gz ]] ; then
1689             $PAGER /usr/share/doc/${1}/changelog.gz
1690         else
1691             if check_com -c aptitude ; then
1692                 echo "No changelog for package $1 found, using aptitude to retrieve it."
1693                 if isgrml ; then
1694                     aptitude -t unstable changelog ${1}
1695                 else
1696                     aptitude changelog ${1}
1697                 fi
1698             else
1699                 echo "No changelog for package $1 found, sorry."
1700                 return 1
1701             fi
1702         fi
1703     }
1704     _dchange() { _files -W /usr/share/doc -/ }
1705     compdef _dchange dchange
1706
1707     #f1# View Debian's NEWS of a given package
1708     dnews() {
1709         if [[ -r /usr/share/doc/${1}/NEWS.Debian.gz ]] ; then
1710             $PAGER /usr/share/doc/${1}/NEWS.Debian.gz
1711         else
1712             if [[ -r /usr/share/doc/${1}/NEWS.gz ]] ; then
1713                 $PAGER /usr/share/doc/${1}/NEWS.gz
1714             else
1715                 echo "No NEWS file for package $1 found, sorry."
1716                 return 1
1717             fi
1718         fi
1719     }
1720     _dnews() { _files -W /usr/share/doc -/ }
1721     compdef _dnews dnews
1722
1723     #f1# View upstream's changelog of a given package
1724     uchange() {
1725         if [[ -r /usr/share/doc/${1}/changelog.gz ]] ; then
1726             $PAGER /usr/share/doc/${1}/changelog.gz
1727         else
1728             echo "No changelog for package $1 found, sorry."
1729             return 1
1730         fi
1731     }
1732     _uchange() { _files -W /usr/share/doc -/ }
1733     compdef _uchange uchange
1734 fi
1735
1736 # zsh profiling
1737 profile() {
1738     ZSH_PROFILE_RC=1 $SHELL "$@"
1739 }
1740
1741 #f1# Edit an alias via zle
1742 edalias() {
1743     [[ -z "$1" ]] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
1744 }
1745 compdef _aliases edalias
1746
1747 #f1# Edit a function via zle
1748 edfunc() {
1749     [[ -z "$1" ]] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
1750 }
1751 compdef _functions edfunc
1752
1753 # use it e.g. via 'Restart apache2'
1754 #m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
1755 #m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
1756 #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
1757 #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
1758 #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
1759 if [[ -d /etc/init.d ]] ; then
1760     for i in Start Restart Stop Force-Reload Reload ; do
1761         eval "$i() { $SUDO /etc/init.d/\$1 ${i:l} \$2 ; }"
1762     done
1763 fi
1764
1765 #f1# Provides useful information on globbing
1766 H-Glob() {
1767     echo -e "
1768     /      directories
1769     .      plain files
1770     @      symbolic links
1771     =      sockets
1772     p      named pipes (FIFOs)
1773     *      executable plain files (0100)
1774     %      device files (character or block special)
1775     %b     block special files
1776     %c     character special files
1777     r      owner-readable files (0400)
1778     w      owner-writable files (0200)
1779     x      owner-executable files (0100)
1780     A      group-readable files (0040)
1781     I      group-writable files (0020)
1782     E      group-executable files (0010)
1783     R      world-readable files (0004)
1784     W      world-writable files (0002)
1785     X      world-executable files (0001)
1786     s      setuid files (04000)
1787     S      setgid files (02000)
1788     t      files with the sticky bit (01000)
1789
1790   print *(m-1)          # Files modified up to a day ago
1791   print *(a1)           # Files accessed a day ago
1792   print *(@)            # Just symlinks
1793   print *(Lk+50)        # Files bigger than 50 kilobytes
1794   print *(Lk-50)        # Files smaller than 50 kilobytes
1795   print **/*.c          # All *.c files recursively starting in \$PWD
1796   print **/*.c~file.c   # Same as above, but excluding 'file.c'
1797   print (foo|bar).*     # Files starting with 'foo' or 'bar'
1798   print *~*.*           # All Files that do not contain a dot
1799   chmod 644 *(.^x)      # make all plain non-executable files publically readable
1800   print -l *(.c|.h)     # Lists *.c and *.h
1801   print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
1802   echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
1803 }
1804 alias help-zshglob=H-Glob
1805
1806 check_com -c qma && alias ?='qma zshall'
1807
1808 # grep for running process, like: 'any vim'
1809 any() {
1810     if [[ -z "$1" ]] ; then
1811         echo "any - grep for process(es) by keyword" >&2
1812         echo "Usage: any <keyword>" >&2 ; return 1
1813     else
1814         local STRING=$1
1815         local LENGTH=$(expr length $STRING)
1816         local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
1817         local REST=$(echo $(expr substr $STRING 2 $LENGTH))
1818         ps xauwww| grep "[$FIRSCHAR]$REST"
1819     fi
1820 }
1821
1822 # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
1823 # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
1824 [[ -r /proc/1/maps ]] && \
1825 deswap() {
1826     print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
1827     cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
1828     print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
1829 }
1830
1831 # print hex value of a number
1832 hex() {
1833     [[ -n "$1" ]] && printf "%x\n" $1 || { print 'Usage: hex <number-to-convert>' ; return 1 }
1834 }
1835
1836 # calculate (or eval at all ;-)) with perl => p[erl-]eval
1837 # hint: also take a look at zcalc -> 'autoload zcalc' -> 'man zshmodules | less -p MATHFUNC'
1838 peval() {
1839     [[ -n "$1" ]] && CALC="$*" || print "Usage: calc [expression]"
1840     perl -e "print eval($CALC),\"\n\";"
1841 }
1842 functions peval &>/dev/null && alias calc=peval
1843
1844 # brltty seems to have problems with utf8 environment and/or font Uni3-Terminus16 under
1845 # certain circumstances, so work around it, no matter which environment we have
1846 brltty() {
1847     if [[ -z "$DISPLAY" ]] ; then
1848         consolechars -f /usr/share/consolefonts/default8x16.psf.gz
1849         command brltty "$@"
1850     else
1851         command brltty "$@"
1852     fi
1853 }
1854
1855 # just press 'asdf' keys to toggle between dvorak and us keyboard layout
1856 aoeu() {
1857     echo -n 'Switching to us keyboard layout: '
1858     [[ -z "$DISPLAY" ]] && $SUDO loadkeys us &>/dev/null || setxkbmap us &>/dev/null
1859     echo 'Done'
1860 }
1861 asdf() {
1862     echo -n 'Switching to dvorak keyboard layout: '
1863     [[ -z "$DISPLAY" ]] && $SUDO loadkeys dvorak &>/dev/null || setxkbmap dvorak &>/dev/null
1864     echo 'Done'
1865 }
1866 # just press 'asdf' key to toggle from neon layout to us keyboard layout
1867 uiae() {
1868     echo -n 'Switching to us keyboard layout: '
1869     setxkbmap us && echo 'Done' || echo 'Failed'
1870 }
1871
1872 # set up an ipv6 tunnel
1873 ipv6-tunnel() {
1874     case $1 in
1875         start)
1876             if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1877                 print 'ipv6 tunnel already set up, nothing to be done.'
1878                 print 'execute: "ifconfig sit1 down ; ifconfig sit0 down" to remove ipv6-tunnel.' ; return 1
1879             else
1880                 [[ -n "$PUBLIC_IP" ]] || \
1881                     local PUBLIC_IP=$(ifconfig $(route -n | awk '/^0\.0\.0\.0/{print $8; exit}') | \
1882                                       awk '/inet addr:/ {print $2}' | tr -d 'addr:')
1883
1884                 [[ -n "$PUBLIC_IP" ]] || { print 'No $PUBLIC_IP set and could not determine default one.' ; return 1 }
1885                 local IPV6ADDR=$(printf "2002:%02x%02x:%02x%02x:1::1" $(print ${PUBLIC_IP//./ }))
1886                 print -n "Setting up ipv6 tunnel $IPV6ADDR via ${PUBLIC_IP}: "
1887                 ifconfig sit0 tunnel ::192.88.99.1 up
1888                 ifconfig sit1 add "$IPV6ADDR" && print done || print failed
1889             fi
1890             ;;
1891         status)
1892             if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1893                 print 'ipv6 tunnel available' ; return 0
1894             else
1895                 print 'ipv6 tunnel not available' ; return 1
1896             fi
1897             ;;
1898         stop)
1899             if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1900                 print -n 'Stopping ipv6 tunnel (sit0 + sit1): '
1901                 ifconfig sit1 down ; ifconfig sit0 down && print done || print failed
1902             else
1903                 print 'No ipv6 tunnel found, nothing to be done.' ; return 1
1904             fi
1905             ;;
1906         *)
1907             print "Usage: ipv6-tunnel [start|stop|status]">&2 ; return 1
1908             ;;
1909     esac
1910 }
1911
1912 # run dhclient for wireless device
1913 iwclient() {
1914     salias dhclient "$(wavemon -d | awk '/device/{print $2}')"
1915 }
1916
1917 # spawn a minimally set up ksh - useful if you want to umount /usr/.
1918 minimal-shell() {
1919     exec env -i ENV="/etc/minimal-shellrc" HOME="$HOME" TERM="$TERM" ksh
1920 }
1921
1922 # make a backup of a file
1923 bk() {
1924     cp -a "$1" "${1}_$(date --iso-8601=seconds)"
1925 }
1926
1927 # Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
1928 # bash() {
1929 #  NO_SWITCH="yes" command bash "$@"
1930 # }
1931 # restart () {
1932 #  exec $SHELL $SHELL_ARGS "$@"
1933 # }
1934
1935 # }}}
1936
1937 # log out? set timeout in seconds {{{
1938 # TMOUT=1800
1939 # do not log out in some specific terminals:
1940 #  if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]] ; then
1941 #    unset TMOUT
1942 #  fi
1943 # }}}
1944
1945 # {{{ make sure our environment is clean regarding colors
1946 for color in BLUE RED GREEN CYAN WHITE ; unset $color
1947 # }}}
1948
1949 # source another config file if present {{{
1950 xsource "/etc/zsh/zshrc.local"
1951 # }}}
1952
1953 # "persistent history" {{{
1954 # just write important commands you always need to ~/.important_commands
1955 if [[ -r ~/.important_commands ]] ; then
1956     fc -R ~/.important_commands
1957 fi
1958 # }}}
1959
1960 ## genrefcard.pl settings {{{
1961 ### example: split functions-search 8,16,24,32
1962 #@# split functions-search 8
1963 ## }}}
1964
1965 # add variable to be able to check whether the file has been read {{{
1966 ZSHRC_GLOBAL_HAS_BEEN_READ=1
1967 # }}}
1968
1969 ## END OF FILE #################################################################
1970 # vim:filetype=zsh foldmethod=marker autoindent expandtab shiftwidth=4