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