move environment stuff from /etc/zsh/zshenv; added function minimal-shell; added...
[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: Mit Jun 20 10:28:28 CEST 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 profiling {{{
16 # just execute 'ZSH_PROFILE_RC=1 zsh' and run 'zprof' to get the details
17   if [[ -n $ZSH_PROFILE_RC ]] ; then
18      zmodload zsh/zprof
19   fi
20 # }}}
21
22 # locale setup {{{
23   if [ -n "$LANG" ]  ; then
24      export LANG
25   else
26      [ -r /etc/default/locale ] && source /etc/default/locale
27   fi
28   [ -n "$LANG" ]          && export LANG || export LANG="en_US.iso885915"
29   [ -n "$LC_ALL" ]        && export LC_ALL
30   [ -n "$LC_MESSAGES" ]   && export LC_MESSAGES
31
32   [ -r /etc/sysconfig/keyboard ] && source /etc/sysconfig/keyboard
33   [ -r /etc/timezone ] && TZ=$(cat /etc/timezone)
34 # }}}
35
36 # check for potentially old files in 'completion.d' {{{
37   setopt extendedglob
38   xof=(/etc/zsh/completion.d/*~/etc/zsh/completion.d/_*(N))
39   if (( ${#xof} > 0 )) ; then
40     printf '\n -!- INFORMATION\n\n'
41     printf ' -!- %s file(s) not starting with an underscore (_) found in\n' ${#xof}
42     printf ' -!- /etc/zsh/completion.d/.\n\n'
43     printf ' -!- While this has been the case in old versions of grml-etc-core,\n'
44     printf ' -!- recent versions of the grml-zsh-setup have all these files rewritten\n'
45     printf ' -!- and renamed. Furthermore, the grml-zsh-setup will *only* add files\n'
46     printf ' -!- named _* to that directory.\n\n'
47     printf ' -!- If you added functions to completion.d yourself, please consider\n'
48     printf ' -!- moving them to /etc/zsh/functions.d/. Files in that directory, not\n'
49     printf ' -!- starting with an underscore are marked for automatic loading\n'
50     printf ' -!- by default (so that is quite convenient).\n\n'
51     printf ' -!- If there are files *not* starting with an underscore from an older\n'
52     printf ' -!- grml-etc-core in completion.d, you may safely remove them.\n\n'
53     printf ' -!- Delete the files for example via running:\n\n'
54     printf "      rm ${xof}\n\n"
55     printf ' -!- Note, that this message will *not* go away, unless you yourself\n'
56     printf ' -!- resolve the situation manually.\n\n'
57     BROKEN_COMPLETION_DIR=1
58   fi
59   unset xof
60 # }}}
61
62 # {{{ check for version/system
63 # check for versions (compatibility reasons)
64   if autoload is-at-least && is-at-least 2>/dev/null ; then
65      is4() { is-at-least 4 }
66      is42() { is-at-least 4.2 }
67   else
68     is4(){
69       [[ $ZSH_VERSION == 4.* ]] && return 0
70       return 1
71     }
72     is42(){
73       [[ $ZSH_VERSION == 4.<2->* ]] && return 0
74       return 1
75     }
76   fi
77
78 # grml specific stuff
79   isgrml(){
80     [ -f /etc/grml_version ] && return 0
81     return 1
82   }
83
84   isgrmlcd(){
85     [ -f /etc/grml_cd ] && return 0
86     return 1
87   }
88
89   if isgrml ; then
90     isgrmlsmall() {
91     [[ ${${${(f)"$(</etc/grml_version)"}%% *}##*-} == 'small' ]] && return 0 ; return 1
92   }
93   else
94     isgrmlsmall() { return 1 }
95   fi
96
97   # are we running within an utf environment?
98   isutfenv() {
99     case "$LANG $CHARSET $LANGUAGE" in
100       *utf*) return 0 ;;
101       *UTF*) return 0 ;;
102       *)     return 1 ;;
103     esac
104   }
105
106 # check for user, if not running as root set $SUDO to sudo
107  (( EUID != 0 )) && SUDO='sudo' || SUDO=''
108
109   salias() {
110     # creates an alias and precedes the command with
111     # sudo if $EUID is not zero.
112     local only=0 ; local multi=0
113     while [[ ${1} == -* ]] ; do
114       case ${1} in
115         (-o) only=1 ;;
116         (-a) multi=1 ;;
117         (--) shift ; break ;;
118         (-h)
119           printf 'usage: salias [-h|-o|-a] <alias-expression>\n'
120           printf '  -h      shows this help text.\n'
121           printf '  -a      replace '\'' ; '\'' sequences with '\'' ; sudo '\''.\n'
122           printf '          be careful using this option.\n'
123           printf '  -o      only sets an alias if a preceding sudo would be needed.\n'
124           return 0
125           ;;
126         (*) printf "unkown option: '%s'\n" "${1}" ; return 1 ;;
127       esac
128       shift
129     done
130     if (( ${#argv} > 1 )) ; then
131       printf 'Too many arguments %s\n' "${#argv}"
132       return 1
133     fi
134     key="${1%%\=*}" ;  val="${1#*\=}"
135     if (( EUID == 0 )) && (( only == 0 )); then
136       alias -- "${key}=${val}"
137     elif (( EUID > 0 )) ; then
138       (( multi > 0 )) && val="${val// ; / ; sudo }"
139       alias -- "${key}=sudo ${val}"
140     fi
141     return 0
142   }
143
144 # change directory to home on first invocation of zsh
145 # important for rungetty -> autologin
146 # Thanks go to Bart Schaefer!
147   isgrml && checkhome() {
148   if [[ -z "$ALREADY_DID_CD_HOME" ]]; then
149      export ALREADY_DID_CD_HOME=$HOME
150      cd
151   fi
152   }
153 # }}}
154
155 # {{{ set some variables
156   export EDITOR=${EDITOR:-vim}
157   export MAIL=${MAIL:-/var/mail/$USER}
158   # if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/
159   export SHELL='/bin/zsh'
160   [[ -f ~/.terminfo/m/mostlike ]] && MYLESS='LESS=C TERMINFO=~/.terminfo TERM=mostlike less' || MYLESS='less'
161   [ -x $(which dircolors) ] && eval `dircolors -b`
162
163 # Search path for the cd comman
164 #  cdpath=(.. ~)
165
166 # completion functions go to /etc/zsh/completion.d
167 # function files may be put into /etc/zsh/functions.d, from where they
168 # will be automatically autoloaded.
169   if [ -n "$BROKEN_COMPLETION_DIR" ] ; then
170      print 'Warning: not setting completion directories because broken files have been found.'>&2
171   else
172      [[ -d /etc/zsh/completion.d ]] && fpath+=( /etc/zsh/completion.d )
173      if [[ -d /etc/zsh/functions.d ]] ; then
174        fpath+=( /etc/zsh/functions.d )
175        for func in /etc/zsh/functions.d/[^_]*[^~] ; do
176          autoload -U ${func:t}
177        done
178      fi
179   fi
180
181 # automatically remove duplicates from these arrays
182   typeset -U path cdpath fpath manpath
183 # }}}
184
185 # {{{ keybindings
186  if [[ "$TERM" != emacs ]]; then
187   [[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
188   [[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
189   [[ -z "$terminfo[kend]"  ]] || bindkey -M emacs "$terminfo[kend]"  end-of-line
190   [[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
191   [[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
192   [[ -z "$terminfo[kend]"  ]] || bindkey -M vicmd "$terminfo[kend]"  vi-end-of-line
193   [[ -z "$terminfo[cuu1]"  ]] || bindkey -M viins "$terminfo[cuu1]"  vi-up-line-or-history
194   [[ -z "$terminfo[cuf1]"  ]] || bindkey -M viins "$terminfo[cuf1]"  vi-forward-char
195   [[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
196   [[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
197   [[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
198   [[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char
199   # ncurses stuff:
200   [[ "$terminfo[kcuu1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history
201   [[ "$terminfo[kcud1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history
202   [[ "$terminfo[kcuf1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char
203   [[ "$terminfo[kcub1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char
204   [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line
205   [[ "$terminfo[kend]"  == $'\eO'* ]] && bindkey -M viins "${terminfo[kend]/O/[}"  end-of-line
206   [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line
207   [[ "$terminfo[kend]"  == $'\eO'* ]] && bindkey -M emacs "${terminfo[kend]/O/[}"  end-of-line
208 fi
209
210 ## keybindings (run 'bindkeys' for details, more details via man zshzle)
211 # use emacs style per default:
212   bindkey -e
213 # use vi style:
214 # bindkey -v
215
216 #if [[ "$TERM" == screen ]]; then
217   bindkey '\e[1~' beginning-of-line       # home
218   bindkey '\e[4~' end-of-line             # end
219   bindkey '\e[A'  up-line-or-search       # cursor up
220   bindkey '\e[B'  down-line-or-search     # <ESC>-
221   bindkey '^x'    history-beginning-search-backward # alternative ways of searching the shell history
222 # bindkey -s '^L' "|less\n"             # ctrl-L pipes to less
223 # bindkey -s '^B' " &\n"                # ctrl-B runs it in the background
224 # if terminal type is set to 'rxvt':
225   bindkey '\e[7~' beginning-of-line       # home
226   bindkey '\e[8~' end-of-line             # end
227 #fi
228
229 # insert unicode character
230 # usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an Â§
231 # See for example http://unicode.org/charts/ for unicode characters code
232   autoload insert-unicode-char
233   zle -N insert-unicode-char
234   bindkey '^Xi' insert-unicode-char
235
236 # just type 'cd ...' to get 'cd ../..'
237 #  rationalise-dot() {
238 #  if [[ $LBUFFER = *.. ]]; then
239 #    LBUFFER+=/..
240 #  else
241 #    LBUFFER+=.
242 #  fi
243 #  }
244 #  zle -N rationalise-dot
245 #  bindkey . rationalise-dot
246
247 #  bindkey '\eq' push-line-or-edit
248 # }}}
249
250 # power completion - abbreviation expansion {{{
251 # power completion / abbreviation expansion / buffer expansion
252 # see http://zshwiki.org/home/examples/zleiab for details
253 # less risky than the global aliases but powerful as well
254 # just type the abbreviation key and afterwards ',.' to expand it
255   declare -A abk
256   setopt extendedglob
257   setopt interactivecomments
258   abk=(
259    # key  # value
260    'C'    '| wc -l'
261    '...' '../..'
262    '....' '../../..'
263    'BG' '& exit'
264    'C' '| wc -l'
265    'G' '|& grep --color=auto'
266    'H' '| head'
267    'Hl' ' --help |& less -r'
268    'L' '| less'
269    'LL' '|& less -r'
270    'M' '| most'
271    'N' '&>/dev/null'
272    'R' '| tr A-z N-za-m'
273    'SL' '| sort | less'
274    'S' '| sort -u'
275    'T' '| tail'
276    'V' '|& vim -'
277    'hide' "echo -en '\033]50;nil2\007'"
278    'tiny' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-80-*-*-c-*-iso8859-15\007"'
279    'small' 'echo -en "\033]50;6x10\007"'
280    'medium' 'echo -en "\033]50;-misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-15\007"'
281    'default' 'echo -e "\033]50;-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-15\007"'
282    'large' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-150-*-*-c-*-iso8859-15\007"'
283    'huge' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-210-*-*-c-*-iso8859-15\007"'
284    'smartfont' 'echo -en "\033]50;-artwiz-smoothansi-*-*-*-*-*-*-*-*-*-*-*-*\007"'
285    'semifont' 'echo -en "\033]50;-misc-fixed-medium-r-semicondensed-*-*-120-*-*-*-*-iso8859-15\007"'
286    'da' 'du -sch'
287    'j' 'jobs -l'
288    'u' 'translate -i'
289    'co' "./configure && make && sudo make install"
290    'CH' "./configure --help"
291    'conkeror' 'firefox -chrome chrome://conkeror/content'
292    'dir' 'ls -lSrah'
293    'lad' $'ls -d .*(/)\n# only show dot-directories'
294    'lsa' $'ls -a .*(.)\n# only show dot-files'
295    'lss' $'ls -l *(s,S,t)\n# only files with setgid/setuid/sticky flag'
296    'lsl' $'ls -l *(@[1,10])\n# only symlinks'
297    'lsx' $'ls -l *(*[1,10])\n# only executables'
298    'lsw' $'ls -ld *(R,W,X.^ND/)\n# world-{readable,writable,executable} files'
299    'lsbig' $'ls -flh *(.OL[1,10])\n# display the biggest files'
300    'lsd' $'ls -d *(/)\n# only show directories'
301    'lse' $'ls -d *(/^F)\n# only show empty directories'
302    'lsnew' $'ls -rl *(D.om[1,10])\n# display the newest files'
303    'lsold' $'ls -rtlh *(D.om[-11,-1])\n # display the oldest files'
304    'lssmall' $'ls -Srl *(.oL[1,10])\n# display the smallest files'
305    'rw-' 'chmod 600'
306    '600' 'chmod u+rw-x,g-rwx,o-rwx'
307    'rwx' 'chmod u+rwx'
308    '700' 'chmod u+rwx,g-rwx,o-rwx'
309    'r--' 'chmod u+r-wx,g-rwx,o-rwx'
310    '644' $'chmod u+rw-x,g+r-wx,o+r-wx\n # 4=r,2=w,1=x'
311    '755' 'chmod u+rwx,g+r-w+x,o+r-w+x'
312    'md' 'mkdir -p '
313    'cmplayer' 'mplayer -vo -fs -zoom fbdev'
314    'fbmplayer' 'mplayer -vo -fs -zoom fbdev'
315    'fblinks' 'links2 -driver fb'
316    'insecssh' 'ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
317    'insecscp' 'scp -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
318    'fori' 'for i ({..}) { }'
319    'cx' 'chmod +x'
320    'e'  'print -l'
321    'se' 'setopt interactivecomments'
322    'va' 'valac --vapidir=../vapi/ --pkg=gtk+-2.0 gtktest.vala'
323    'fb2' '=mplayer -vo fbdev -fs -zoom 1>/dev/null -xy 2'
324    'fb3' '=mplayer -vo fbdev -fs  -zoom 1>/dev/null -xy 3'
325    'ci' 'centericq'
326    'D'  'export DISPLAY=:0.0'
327    'mp' 'mplayer -vo xv -fs -zoom'
328   )
329
330   globalias () {
331         local MATCH
332         matched_chars='[.-|_a-zA-Z0-9]#'
333         LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
334         LBUFFER+=${abk[$MATCH]:-$MATCH}
335   }
336
337   zle -N globalias
338   bindkey ",." globalias
339 # }}}
340
341 # {{{ autoloading
342   autoload -U zmv    # who needs mmv or rename?
343   autoload history-search-end
344
345   # we don't want to quote/espace URLs on our own...
346   # if autoload -U url-quote-magic ; then
347   #    zle -N self-insert url-quote-magic
348   #    zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}='
349   # else
350   #    print 'Notice: no url-quote-magic available :('
351   # fi
352   alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic'
353
354   alias run-help >&/dev/null && unalias run-help
355   autoload run-help # use via 'esc-h'
356
357 # completion system
358   if autoload -U compinit && compinit 2>/dev/null ; then
359      compinit 2>/dev/null || print 'Notice: no compinit available :('
360    else
361      print 'Notice: no compinit available :('
362      function zstyle { }
363      function compdef { }
364   fi
365
366   is4 && autoload -U zed # use ZLE editor to edit a file or function
367
368   is4 && for mod in complist deltochar mathfunc ; do
369              zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :("
370          done
371
372 # autoload zsh modules when they are referenced
373   is4 && for opt mod in a  stat    \
374                         a  zpty    \
375                         ap zprof   \
376                         ap mapfile ; do
377              zmodload -${opt} zsh/${mod} ${mod}
378          done ; unset opt mod
379
380   is4 && autoload -U insert-files && \
381   zle -N insert-files && \
382   bindkey "^Xf" insert-files # C-x-f
383
384   bindkey ' '   magic-space    # also do history expansion on space
385   bindkey '\ei' menu-complete  # menu completion via esc-i
386
387 # press esc-e for editing command line in $EDITOR or $VISUAL
388   is4 && autoload -U edit-command-line && \
389   zle -N edit-command-line && \
390   bindkey '\ee' edit-command-line
391
392 # menu selection: pick item but stay in the menu (press esc-return)
393   is4 && bindkey -M menuselect '\e^M' accept-and-menu-complete
394
395 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
396   _bkdate() { BUFFER="$BUFFER$(date '+%F')"; CURSOR=$#BUFFER; }
397   bindkey '\C-ed' _bkdate
398   zle -N _bkdate
399
400 # press esc-m for inserting last typed word again (thanks to caphuso!)
401   insert-last-typed-word() { zle insert-last-word -- 0 -1 }; \
402   zle -N insert-last-typed-word; bindkey "\em" insert-last-typed-word
403
404 # set command prediction from history, see 'man 1 zshcontrib'
405 #  is4 && autoload -U predict-on && \
406 #  zle -N predict-on         && \
407 #  zle -N predict-off        && \
408 #  bindkey "^X^Z" predict-on && \
409 #  bindkey "^Z" predict-off
410
411 # put job into foreground via ctrl-z:
412   bindkey -s '^z' "fg\n"
413
414 # press ctrl-q to quote line:
415 #  mquote () {
416 #        zle beginning-of-line
417 #        zle forward-word
418 #        # RBUFFER="'$RBUFFER'"
419 #        RBUFFER=${(q)RBUFFER}
420 #        zle end-of-line
421 #  }
422 #  zle -N mquote && bindkey '^q' mquote
423
424 # run command line as user root via sudo:
425   _sudo-command-line() {
426     [[ $BUFFER != sudo\ * ]] && LBUFFER="sudo $LBUFFER"
427   }
428   zle -N sudo-command-line _sudo-command-line
429   bindkey "^Os" sudo-command-line
430
431 ### jump behind the first word on the cmdline.
432 ### useful to add options.
433   function jump_after_first_word() {
434     local words
435     words=(${(z)BUFFER})
436     if (( ${#words} <= 1 )) ; then
437       CURSOR=${#BUFFER}
438     else
439       CURSOR=${#${words[1]}}
440     fi
441   }
442   zle -N jump_after_first_word
443   bindkey '^x1' jump_after_first_word
444
445 # }}}
446
447 # {{{ set some important options
448   (( EUID != 0 )) && umask 002 || umask 022
449
450 # history:
451   setopt append_history       # append history list to the history file (important for multiple parallel zsh sessions!)
452   is4 && setopt SHARE_HISTORY # import new commands from the history file also in other zsh-session
453   setopt extended_history     # save each command's beginning timestamp and the duration to the history file
454   is4 && setopt histignorealldups # If  a  new  command  line being added to the history
455                               # list duplicates an older one, the older command is removed from the list
456   setopt histignorespace      # remove command lines from the history list when
457                               # the first character on the line is a space
458 #  setopt histallowclobber    # add `|' to output redirections in the history
459 #  setopt NO_clobber          # warning if file exists ('cat /dev/null > ~/.zshrc')
460   setopt auto_cd              # if a command is issued that can't be executed as a normal command,
461                               # and the command is the name of a directory, perform the cd command to that directory
462   setopt extended_glob        # in order to use #, ~ and ^ for filename generation
463                               # grep word *~(*.gz|*.bz|*.bz2|*.zip|*.Z) ->
464                               # -> searches for word not in compressed files
465                               # don't forget to quote '^', '~' and '#'!
466   setopt notify               # report the status of backgrounds jobs immediately
467   setopt hash_list_all        # Whenever a command completion is attempted, make sure \
468                               # the entire command path is hashed first.
469   setopt completeinword       # not just at the end
470 # setopt nocheckjobs          # don't warn me about bg processes when exiting
471   setopt nohup                # and don't kill them, either
472 # setopt printexitvalue       # alert me if something failed
473 # setopt dvorak               # with spelling correction, assume dvorak kb
474   setopt auto_pushd           # make cd push the old directory onto the directory stack.
475   setopt nonomatch            # try to avoid the 'zsh: no matches found...'
476   setopt nobeep               # avoid "beep"ing
477
478   MAILCHECK=30       # mailchecks
479   REPORTTIME=5       # report about cpu-/system-/user-time of command if running longer than 5 secondes
480   watch=(notme root) # watch for everyone but me and root
481
482 # define word separators (for stuff like backward-word, forward-word, backward-kill-word,..)
483 #  WORDCHARS='*?_-.[]~=/&;!#$%^(){}<>' # the default
484 #  WORDCHARS=.
485 #  WORDCHARS='*?_[]~=&;!#$%^(){}'
486 #  WORDCHARS='${WORDCHARS:s@/@}'
487
488 # only slash should be considered as a word separator:
489   slash-backward-kill-word() {
490     local WORDCHARS="${WORDCHARS:s@/@}"
491     # zle backward-word
492     zle backward-kill-word
493   }
494   zle -N slash-backward-kill-word
495   bindkey '\ev' slash-backward-kill-word # press esc-v to delete a word until its last '/' (not the same as ctrl-w!)
496 # }}}
497
498 # {{{ history
499   export ZSHDIR=$HOME/.zsh
500   HISTFILE=$HOME/.zsh_history
501   isgrmlcd && HISTSIZE=500  || HISTSIZE=5000
502   isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
503 # }}}
504
505 # dirstack handling {{{
506   DIRSTACKSIZE=20
507   if [[ -f ~/.zdirs ]] && [[ ${#dirstack[*]} -eq 0 ]]; then
508      dirstack=( ${(uf)"$(< ~/.zdirs)"} )
509      # "cd -" won't work after login by just setting $OLDPWD, so
510      [[ -d $dirstack[0] ]] && cd $dirstack[0] && cd $OLDPWD
511   fi
512   chpwd() {
513     builtin dirs -pl >! ~/.zdirs
514   }
515 # }}}
516
517 # {{{ display battery status on right side of prompt via running 'BATTERY=1 zsh'
518   if [ -n "$BATTERY" ] ; then
519      if [ -x $(which acpi) ] ; then
520         PERCENT="${(C)${(s| |)$(acpi 2>/dev/null)}[4]}"
521         [ -z "$PERCENT" ] && PERCENT='acpi not present'
522         if [ "${PERCENT%%%}" -lt 20 ] ; then
523            PERCENT="warning: ${PERCENT}%"
524         fi
525      fi
526   fi
527 # }}}
528
529 # {{{ set prompt
530   if autoload promptinit && promptinit 2>/dev/null ; then
531      promptinit # people should be able to use their favourite prompt
532   else
533      print 'Notice: no promptinit available :('
534   fi
535
536 # precmd() => a function which is executed just before each prompt
537 # use 'NOPRECMD=1' to disable the precmd + preexec commands
538
539   # precmd () { setopt promptsubst; [[ -o interactive ]] && jobs -l;
540
541   # make sure to use right prompt only when not running a command
542   is4 && setopt transient_rprompt
543
544   is4 && [[ -z $NOPRECMD ]] && precmd () {
545       [[ -n $NOPRECMD ]] && return 0
546       # allow manual overwriting of RPROMPT
547       if [[ -n $RPROMPT ]] ; then
548          [[ $TERM == screen* ]] && echo -n $'\ekzsh\e\\'
549          return 0
550       fi
551       # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
552       if [[ -z $DONTSETRPROMPT ]] ; then
553          if [[ -n $BATTERY ]] ; then
554             RPROMPT="%(?..:()% ${PERCENT}${SCREENTITLE}"
555             # RPROMPT="${PERCENT}${SCREENTITLE}"
556          else
557             RPROMPT="%(?..:()% ${SCREENTITLE}"
558             # RPROMPT="${SCREENTITLE}"
559          fi
560       fi
561       # adjust title of xterm
562       # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
563       case $TERM in (xterm*|rxvt)
564         print -Pn "\e]0;%n@%m: %~\a"
565         ;;
566       esac
567   }
568
569 # chpwd () => a function which is executed whenever the directory is changed
570
571 # preexec() => a function running before every command
572   is4 && [[ -z $NOPRECMD ]] && preexec () {
573       [[ -n $NOPRECMD ]] && return 0
574   # set hostname if not running on host with name 'grml'
575       local HOSTNAME=$(hostname)
576       if [[ "$HOSTNAME" != grml ]] ; then
577          NAME="@$HOSTNAME"
578       fi
579   # get the name of the program currently running and hostname of local machine
580   # set screen window title if running in a screen
581       if [[ "$TERM" == screen* ]]; then
582          # local CMD=${1[(wr)^(*=*|sudo|ssh|-*)]}       # dont't use hostname
583          local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME" # use hostname
584          echo -ne "\ek$CMD\e\\"
585       fi
586   # set the screen title to "zsh" when sitting at the command prompt:
587       if [[ "$TERM" == screen* ]]; then
588          SCREENTITLE=$'%{\ekzsh\e\\%}'
589       else
590          SCREENTITLE=''
591       fi
592   # adjust title of xterm
593       case $TERM in (xterm*|rxvt)
594         print -Pn "\e]0;%n@%m: $1\a"
595         ;;
596       esac
597   }
598
599 # set colors
600   if autoload colors && colors 2>/dev/null ; then
601      BLUE="%{${fg[blue]}%}"
602      RED="%{${fg_bold[red]}%}"
603      GREEN="%{${fg[green]}%}"
604      CYAN="%{${fg[cyan]}%}"
605      WHITE="%{${fg[white]}%}"
606      NO_COLOUR="%{${reset_color}%}"
607   else
608      BLUE=$'%{\e[1;34m%}'
609      RED=$'%{\e[1;31m%}'
610      GREEN=$'%{\e[1;32m%}'
611      CYAN=$'%{\e[1;36m%}'
612      WHITE=$'%{\e[1;37m%}'
613      NO_COLOUR=$'%{\e[0m%}'
614   fi
615
616   EXITCODE="%(?..%?%1v )"
617   PS2='`%_> '       # secondary prompt, printed when the shell needs more information to complete a command.
618   PS3='?# '         # selection prompt used within a select loop.
619   PS4='+%N:%i:%_> ' # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
620
621   # set variable debian_chroot if running in a chroot with /etc/debian_chroot
622   if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
623     debian_chroot=$(cat /etc/debian_chroot)
624   fi
625
626   # don't use colors on dumb terminals (like emacs):
627   if [[ "$TERM" == dumb ]] ; then
628      PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< %# "
629   else
630     # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended prompt
631     # set variable identifying the chroot you work in (used in the prompt below)
632     if [[ -n $GRMLPROMPT ]]; then
633       PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
634 ${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# "
635     else
636       if (( EUID != 0 )); then
637         PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
638       else
639         PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
640       fi
641     fi
642   fi
643
644   # if we are inside a grml-chroot set a specific prompt theme
645   if [ -n "$GRML_CHROOT" ] ; then
646      PROMPT="%{$fg[red]%}(CHROOT) %{$fg_bold[red]%}%n%{$fg_no_bold[white]%}@%m %40<...<%B%~%b%<< %\# "
647   fi
648 # }}}
649
650 # {{{ 'hash' some often used directories
651   hash -d deb=/var/cache/apt/archives
652   hash -d doc=/usr/share/doc
653   hash -d linux=/lib/modules/$(command uname -r)/build/
654   hash -d log=/var/log
655   hash -d slog=/var/log/syslog
656   hash -d src=/usr/src
657   hash -d templ=/usr/share/doc/grml-templates
658   hash -d tt=/usr/share/doc/texttools-doc
659   hash -d www=/var/www
660 # }}}
661
662 # {{{ some aliases
663   if [ $UID = 0 ] ; then
664      [ -r /etc/grml/screenrc ] && alias screen='/usr/bin/screen -c /etc/grml/screenrc'
665   elif [ -r $HOME/.screenrc ] ; then
666      alias screen="/usr/bin/screen -c $HOME/.screenrc"
667   else
668      [ -r /etc/grml/screenrc_grml ] && alias screen='/usr/bin/screen -c /etc/grml/screenrc_grml'
669   fi
670
671   if ls --help 2>/dev/null |grep -- --color= >/dev/null && [ "$TERM" != dumb ] ; then
672      alias ls='ls -b -CF --color=auto' # do we have GNU ls with color-support?
673      alias la='ls -la --color=auto'
674      alias ll='ls -l --color=auto'
675      alias lh='ls -hAl --color=auto'
676      alias l='ls -lF --color=auto'
677   else
678      alias ls='ls -b -CF'
679      alias la='ls -la'
680      alias ll='ls -l'
681      alias lh='ls -hAl'
682      alias l='ls -lF'
683   fi
684
685   alias mdstat='cat /proc/mdstat'
686   alias ...='cd ../../'
687
688   alias cp='nocorrect cp'         # no spelling correction on cp
689   alias mkdir='nocorrect mkdir'   # no spelling correction on mkdir
690   alias mv='nocorrect mv'         # no spelling correction on mv
691   alias rm='nocorrect rm'         # no spelling correction on rm
692
693   alias rd='rmdir'
694   alias md='mkdir'
695
696   # see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
697   alias term2iso="echo 'Setting terminal to iso mode' ; print -n '\e%@'"
698   alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
699
700   alias utf2iso='if isutfenv ; then
701    for ENV in `env | grep UTF` ; do
702        eval export "$(echo $ENV | sed 's/UTF-8/iso885915/')"
703    done
704    fi'
705   alias iso2utf='if isutfenv ; then
706    for ENV in `env | grep '\.iso'` ; do
707        eval export "$(echo $ENV | sed 's/iso.*/UTF-8/')"
708    done
709    fi'
710
711 # set up software synthesizer via speakup
712   alias swspeak='
713     aumix -w 90 -v 90 -p 90 -m 90
714     if ! [ -r /dev/softsynth ] ; then
715        flite -o play -t "Sorry, software synthesizer not available. Did you boot with swspeak bootoption?"
716        return 1
717     else
718        setopt singlelinezle
719        unsetopt prompt_cr
720        export PS1="%m%# "
721        nice -n -20 speechd-up
722        sleep 2
723        flite -o play -t "Finished setting up software synthesizer"
724     fi
725   '
726
727 # I like clean prompt, so provide simple way to get that
728   alias 0 &>/dev/null || functions 0 &>/dev/null || alias 0='return 0'
729
730 # truecrypt; use e.g. via 'truec /dev/ice /mnt/ice' or 'truec -i'
731   if [ -x $(which truecrypt) ] ; then
732      if isutfenv ; then
733         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077,utf8" '
734      else
735         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077" '
736      fi
737   fi
738
739   zsh-help(){print "$bg[white]$fg[black]
740 zsh-help - hints for use of zsh on grml
741 =======================================$reset_color
742
743 Main configuration of zsh happens in /etc/zsh/zshrc (global)
744 and /etc/skel/.zshrc which is copied to \$HOME/.zshrc once.
745 The files are part of the package grml-etc-core, if you want to
746 use them on a non-grml-system just get the tar.gz from
747 http://deb.grml.org/ or get the files from the mercurial
748 repository:
749
750   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
751   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
752
753 If you want to stay in sync with zsh configuration of grml
754 run 'ln -sf /etc/skel/.zshrc \$HOME/.zshrc' and configure
755 your own stuff in \$HOME/.zshrc.local. System wide configuration
756 without touching configuration files of grml can take place
757 in /etc/zsh/zshrc.local.
758
759 If you want to use the configuration of user grml also when
760 running as user root just run 'zshskel' which will source
761 the file /etc/skel/.zshrc.
762
763 For information regarding zsh start at http://grml.org/zsh/
764
765 Take a look at grml's zsh refcard:
766 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
767
768 Check out the main zsh refcard:
769 % $BROWSER http://www.bash2zsh.com/zsh_refcard/refcard.pdf
770
771 And of course visit the zsh-lovers:
772 % man zsh-lovers
773
774 You can adjust some options through environment variables when
775 invoking zsh without having to edit configuration files.
776 Basically meant for bash users who are not used to the power of
777 the zsh yet. :)
778
779   \"NOCOR=1    zsh\" => deactivate automatic correction
780   \"NOMENU=1   zsh\" => do not use menu completion (note: use strg-d for completion instead!)
781   \"NOPRECMD=1 zsh\" => disable the precmd + preexec commands (set GNU screen title)
782   \"BATTERY=1  zsh\" => activate battery status (via acpi) on right side of prompt
783 $bg[white]$fg[black]
784 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
785 Enjoy your grml system with the zsh!$reset_color"
786 }
787
788 # debian stuff
789   if [ -r /etc/debian_version ] ; then
790     alias acs='apt-cache search'
791     alias acsh='apt-cache show'
792     alias acp='apt-cache policy'
793     salias adg="apt-get dist-upgrade"
794     salias agi="apt-get install"
795     salias ati="aptitude install"
796     salias ag="apt-get upgrade"
797     salias au="apt-get update"
798     salias -a up="aptitude update ; aptitude upgrade"
799     alias dbp='dpkg-buildpackage'
800     alias ge='grep-excuses'
801
802     # debian upgrade
803     upgrade () {
804       if [ -z "$1" ] ; then
805           $SUDO apt-get update
806           $SUDO apt-get -u upgrade
807       else
808           ssh $1 $SUDO apt-get update
809           # ask before the upgrade
810           local dummy
811           ssh $1 $SUDO apt-get --no-act upgrade
812           echo -n 'Process the upgrade?'
813           read -q dummy
814           if [[ $dummy == "y" ]] ; then
815               ssh $1 $SUDO apt-get -u upgrade --yes
816           fi
817       fi
818     }
819
820     isgrmlcd && alias su="sudo -s"          # get a root shell
821     alias llog="$PAGER /var/log/syslog"     # take a look at the syslog
822     alias tlog="tail -f /var/log/syslog"    # follow the syslog
823     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
824   fi
825
826 # sort installed Debian-packages by size
827   if [ -x $(which grep-status) ] ; then
828      alias debs-by-size='grep-status -FStatus -sInstalled-Size,Package \
829                 -n "install ok installed" | paste -sd "  \n" | sort -rn'
830   fi
831
832 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
833   if [ -L /usr/bin/cdrecord -o ! -x $(which cdrecord) ] ; then
834      if [ -x $(which wodim) ] ; then
835         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
836 See #377109 in the BTS of Debian for more details.
837
838 Please use the wodim binary instead' ; return 1"
839      fi
840   fi
841
842 # get_tw_cli has been renamed into get_3ware
843   if [ -x $(which get_3ware) ] ; then
844      get_tw_cli() {
845        echo 'Warning: get_tw_cli has been renamed into get_3ware. Invoking get_3ware for you.'>&2
846        get_3ware
847      }
848   fi
849
850 # I hate lacking backward compability, so provide an alternative therefore
851   if ! [ -x $(which apache2-ssl-certificate) ] ; then
852      apache2-ssl-certificate(){
853
854      print 'Debian does not ship apache2-ssl-certificate anymore (see #398520). :('
855      print 'You might want to take a look at Debian the package ssl-cert as well.'
856      print 'To generate a certificate for use with apache2 follow the instructions:'
857
858      echo '
859
860 export RANDFILE=/dev/random
861 mkdir /etc/apache2/ssl/
862 openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
863 chmod 600 /etc/apache2/ssl/apache.pem
864
865 Run "grml-tips ssl-certificate" if you need further instructions.
866 '
867    }
868   fi
869 # }}}
870
871 # {{{ Use hard limits, except for a smaller stack and no core dumps
872   unlimit
873   limit stack 8192
874   isgrmlcd && limit core 0 # important for a live-cd-system
875   limit -s
876 # }}}
877
878 # {{{ completion stuff
879
880 # called later (via is4 && grmlcomp)
881 # notice: use 'zstyle' for getting current settings
882 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
883 grmlcomp() {
884 ## completion system
885   zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )' # allow one error for every three characters typed in approximate completer
886   zstyle ':completion:*:complete:-command-::commands' ignored-patterns '*\~' # don't complete backup files as executables
887   zstyle ':completion:*:correct:*'       insert-unambiguous true             # start menu completion only if it could find no unambiguous initial string
888   zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}' #
889   zstyle ':completion:*:correct:*'       original true                       #
890   zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}      # activate color-completion(!)
891   zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'  # format on completion
892   zstyle ':completion:*:*:cd:*:directory-stack' menu yes select              # complete 'cd -<tab>' with menu
893   zstyle ':completion:*:expand:*'        tag-order all-expansions            # insert all expansions for expand completer
894   zstyle ':completion:*:history-words'   list false                          #
895   zstyle ':completion:*:history-words'   menu yes                            # activate menu
896   zstyle ':completion:*:history-words'   remove-all-dups yes                 # ignore duplicate entries
897   zstyle ':completion:*:history-words'   stop yes                            #
898   zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'        # match uppercase from lowercase
899   zstyle ':completion:*:matches'         group 'yes'                         # separate matches into groups
900   zstyle ':completion:*'                 group-name ''
901   if [[ -z "$NOMENU" ]] ; then
902     zstyle ':completion:*'               menu select=5                       # if there are more than 5 options allow selecting from a menu
903   else
904     setopt no_auto_menu # don't use any menus at all
905   fi
906   zstyle ':completion:*:messages'        format '%d'                         #
907   zstyle ':completion:*:options'         auto-description '%d'               #
908   zstyle ':completion:*:options'         description 'yes'                   # describe options in full
909   zstyle ':completion:*:processes'       command 'ps -au$USER'               # on processes completion complete all user processes
910   zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters        # offer indexes before parameters in subscripts
911   zstyle ':completion:*'                 verbose true                        # provide verbose completion information
912   zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' # set format for warnings
913   zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'       # define files to ignore for zcompile
914   zstyle ':completion:correct:'          prompt 'correct to: %e'             #
915   zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'    # Ignore completion functions for commands you don't have:
916
917 # complete manual by their section
918   zstyle ':completion:*:manuals'    separate-sections true
919   zstyle ':completion:*:manuals.*'  insert-sections   true
920   zstyle ':completion:*:man:*'      menu yes select
921
922 ## correction
923 # run rehash on completion so new installed program are found automatically:
924   _force_rehash() {
925       (( CURRENT == 1 )) && rehash
926          return 1 # Because we didn't really complete anything
927     }
928 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
929   if [[ -n "$NOCOR" ]] ; then
930     zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files
931     setopt nocorrect # do not try to correct the spelling if possible
932   else
933 #    zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _correct _approximate _files
934     setopt correct  # try to correct the spelling if possible
935     zstyle -e ':completion:*' completer '
936         if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]]; then
937           _last_try="$HISTNO$BUFFER$CURSOR"
938           reply=(_complete _match _prefix _files)
939         else
940           if [[ $words[1] = (rm|mv) ]]; then
941             reply=(_complete _files)
942           else
943             reply=(_oldlist _expand _force_rehash _complete _correct _approximate _files)
944           fi
945         fi'
946   fi
947 # zstyle ':completion:*' completer _complete _correct _approximate
948 # zstyle ':completion:*' expand prefix suffix
949
950 # automatic rehash? Credits go to Frank Terbeck
951 # my_accept() {
952 #   local buf
953 #   [[ -z ${BUFFER} ]] && zle accept-line && return
954 #   buf=( ${(z)BUFFER}  )
955 #   [[ -z ${commands[${buf[1]}]} ]] && rehash
956 #   zle accept-line
957 # }
958 # zle -N my_accept
959 # bindkey "^M" my_accept
960
961 # command for process lists, the local web server details and host completion
962   zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
963
964 # caching
965   [ -d $ZSHDIR/cache ] && zstyle ':completion:*' use-cache yes && \
966                           zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
967
968 # host completion /* add brackets as vim can't parse zsh's complex cmdlines 8-) {{{ */
969   if is42 ; then
970     [ -r ~/.ssh/known_hosts ] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
971     [ -r /etc/hosts ] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
972   else
973     _ssh_hosts=()
974     _etc_hosts=()
975   fi
976   hosts=(
977       `hostname`
978       "$_ssh_hosts[@]"
979       "$_etc_hosts[@]"
980       grml.org
981       localhost
982   )
983   zstyle ':completion:*:hosts' hosts $hosts
984 #  zstyle '*' hosts $hosts
985
986 # specify your logins:
987 # my_accounts=(
988 #  {grml,grml1}@foo.invalid
989 #  grml-devel@bar.invalid
990 # )
991 # other_accounts=(
992 #  {fred,root}@foo.invalid
993 #  vera@bar.invalid
994 # )
995 # zstyle ':completion:*:my-accounts' users-hosts $my_accounts
996 # zstyle ':completion:*:other-accounts' users-hosts $other_accounts
997
998 # specify specific port/service settings:
999 #  telnet_users_hosts_ports=(
1000 #    user1@host1:
1001 #    user2@host2:
1002 #    @mail-server:{smtp,pop3}
1003 #    @news-server:nntp
1004 #    @proxy-server:8000
1005 #  )
1006 # zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
1007
1008 # use generic completion system for programs not yet defined:
1009   compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
1010
1011 # see upgrade function in this file
1012   compdef _hosts upgrade
1013 }
1014 # }}}
1015
1016 # {{{ grmlstuff
1017 grmlstuff() {
1018 # people should use 'grml-x'!
1019   startx() {
1020     if [ -e /etc/X11/xorg.conf ] ; then
1021        [ -x /usr/bin/startx ] && /usr/bin/startx || /usr/X11R6/bin/startx
1022     else
1023       echo "Please use the script \"grml-x\" for starting the X Window System
1024 because there does not exist /etc/X11/xorg.conf yet.
1025 If you want to use startx anyway please call \"/usr/bin/startx\"."
1026       return -1
1027     fi
1028   }
1029
1030   xinit() {
1031     if [ -e /etc/X11/xorg.conf ] ; then
1032        [ -x /usr/bin/xinit ] && /usr/bin/xinit || /usr/X11R6/bin/xinit
1033     else
1034       echo "Please use the script \"grml-x\" for starting the X Window System.
1035 because there does not exist /etc/X11/xorg.conf yet.
1036 If you want to use xinit anyway please call \"/usr/bin/xinit\"."
1037       return -1
1038     fi
1039   }
1040
1041   if [ -x $(which 915resolution) ] ; then
1042      alias 855resolution='echo -e "Please use 915resolution as resolution modify tool for Intel graphic chipset."; return -1'
1043   fi
1044
1045   alias grml-version='cat /etc/grml_version'
1046
1047   if [ -x $(which rebuildfstab) ] ; then
1048      alias grml-rebuildfstab='rebuildfstab -v -r -config'
1049   fi
1050
1051   if [ -x $(which grml-debootstrap) ] ; then
1052      alias debian2hd='print "Installing debian to harddisk is possible via using grml-debootstrap." ; return 1'
1053   fi
1054 }
1055 # }}}
1056
1057 # {{{ now run the functions
1058   isgrml && checkhome
1059   is4    && isgrml    && grmlstuff
1060   is4    && grmlcomp
1061 # }}}
1062
1063 # {{{ keephack
1064   [ -r /etc/zsh/keephack ] && is4 && source /etc/zsh/keephack
1065 # }}}
1066
1067 # {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson
1068 # You use it as follows:
1069 # $ NTREF=/reference/file
1070 # $ ls -l *(e:nt:)
1071 # This lists all the files in the current directory newer than the reference file.
1072 # You can also specify the reference file inline; note quotes:
1073 # $ ls -l *(e:'nt ~/.zshenv':)
1074   is4 && nt() {
1075     if [[ -n $1 ]]; then
1076       local NTREF=${~1}
1077     fi
1078     [[ $REPLY -nt $NTREF ]]
1079   }
1080 # }}}
1081
1082 # shell functions {{{
1083   setenv()  { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }  # csh compatibility
1084   freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
1085   reload () {
1086    if [[ "$#*" -eq 0 ]]; then
1087       [ -r ~/.zshrc ] && . ~/.zshrc
1088    else
1089       local fn
1090       for fn in "$@"; do
1091           unfunction $fn
1092           autoload -U $fn
1093       done
1094    fi
1095   }
1096   compdef _functions reload freload
1097
1098   # list symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
1099   sll() {
1100     [ -z "$1" ] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
1101     for i in "$@" ; do
1102       file=$i
1103       while [ -h "$file" ] ; do
1104         ls -l $file
1105         file=$(readlink "$file")
1106       done
1107     done
1108   }
1109
1110   # fast manual access
1111   if type -p qma &>/dev/null ; then
1112      manzsh()  { qma zshall "$1" }
1113      compdef _man qma
1114   else
1115      manzsh()  { /usr/bin/man zshall |  vim -c "se ft=man| se hlsearch" +/"$1" - ; }
1116      # manzsh()  { /usr/bin/man zshall |  most +/"$1" ; }
1117      # manzsh()  { man zshall | $MYLESS -p $1 ; }
1118   fi
1119
1120   if [ -x $(which most) ] ; then
1121   # use "dchange <package-name>" to view Debian's changelog of the package:
1122     dchange() {
1123       if [ -r /usr/share/doc/${1}/changelog.Debian.gz ] ; then
1124          most /usr/share/doc/${1}/changelog.Debian.gz
1125       else
1126          if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1127             most /usr/share/doc/${1}/changelog.gz
1128          else
1129             echo "No changelog for package $1 found, sorry."
1130             return 1
1131          fi
1132       fi
1133     }
1134     _dchange() { _files -W /usr/share/doc -/ }
1135     compdef _dchange dchange
1136
1137   # use "dnews <package-name>" to view Debian's NEWS file of the package:
1138     dnews() {
1139       if [ -r /usr/share/doc/${1}/NEWS.Debian.gz ] ; then
1140          most /usr/share/doc/${1}/NEWS.Debian.gz
1141       else
1142          if [ -r /usr/share/doc/${1}/NEWS.gz ] ; then
1143             most /usr/share/doc/${1}/NEWS.gz
1144          else
1145             echo "No NEWS file for package $1 found, sorry."
1146             return 1
1147          fi
1148       fi
1149     }
1150     _dnews() { _files -W /usr/share/doc -/ }
1151     compdef _dnews dnews
1152
1153   # use "uchange <package-name>" to view upstream's changelog of the package:
1154     uchange() {
1155       if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1156          most /usr/share/doc/${1}/changelog.gz
1157       else
1158          echo "No changelog for package $1 found, sorry."
1159          return 1
1160       fi
1161     }
1162     _uchange() { _files -W /usr/share/doc -/ }
1163     compdef _uchange uchange
1164   fi
1165
1166 # zsh profiling
1167   profile () {
1168       ZSH_PROFILE_RC=1 $SHELL "$@"
1169   }
1170
1171 # edit alias via zle:
1172   edalias() {
1173     [ -z "$1" ] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
1174   }
1175   compdef _aliases edalias
1176
1177 # edit function via zle:
1178   edfunc() {
1179     [ -z "$1" ] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
1180   }
1181   compdef _functions edfunc
1182
1183 # use it e.g. via 'Restart apache2'
1184  if [ -d /etc/init.d ] ; then
1185   for i in Start Restart Stop Force-Reload Reload ; do
1186     eval "$i() { $SUDO /etc/init.d/\$1 ${i:l} \$2 ; }"
1187   done
1188   # now the completion for this:
1189   compctl -g "$(echo /etc/init.d/*(:t))" Start Restart Stop Force-Reload Reload
1190  fi
1191
1192 # provide useful information on globbing
1193   H-Glob() {
1194   echo -e "
1195       /      directories
1196       .      plain files
1197       @      symbolic links
1198       =      sockets
1199       p      named pipes (FIFOs)
1200       *      executable plain files (0100)
1201       %      device files (character or block special)
1202       %b     block special files
1203       %c     character special files
1204       r      owner-readable files (0400)
1205       w      owner-writable files (0200)
1206       x      owner-executable files (0100)
1207       A      group-readable files (0040)
1208       I      group-writable files (0020)
1209       E      group-executable files (0010)
1210       R      world-readable files (0004)
1211       W      world-writable files (0002)
1212       X      world-executable files (0001)
1213       s      setuid files (04000)
1214       S      setgid files (02000)
1215       t      files with the sticky bit (01000)
1216
1217    print *(m-1)          # Files modified up to a day ago
1218    print *(a1)           # Files accessed a day ago
1219    print *(@)            # Just symlinks
1220    print *(Lk+50)        # Files bigger than 50 kilobytes
1221    print *(Lk-50)        # Files smaller than 50 kilobytes
1222    print **/*.c          # All *.c files recursively starting in \$PWD
1223    print **/*.c~file.c   # Same as above, but excluding 'file.c'
1224    print (foo|bar).*     # Files starting with 'foo' or 'bar'
1225    print *~*.*           # All Files that do not contain a dot
1226    chmod 644 *(.^x)      # make all plain non-executable files publically readable
1227    print -l *(.c|.h)     # Lists *.c and *.h
1228    print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
1229    echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
1230   }
1231   alias help-zshglob=H-Glob
1232
1233   type -p qma &>/dev/null && alias ?='qma zshall'
1234
1235   # grep for running process, like: 'any vim'
1236   any() {
1237   if [ -z "$1" ] ; then
1238      echo "any - grep for process(es) by keyword" >&2
1239      echo "Usage: any <keyword>" >&2 ; return 1
1240   else
1241      local STRING=$1
1242      local LENGTH=$(expr length $STRING)
1243      local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
1244      local REST=$(echo $(expr substr $STRING 2 $LENGTH))
1245      ps xauwww| grep "[$FIRSCHAR]$REST"
1246   fi
1247   }
1248
1249   # After resuming from suspend, system is paging heavilly, leading to very bad interactivity.
1250   # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
1251   [ -r /proc/1/maps ] && deswap() {
1252      print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
1253      cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
1254      print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
1255   }
1256
1257   # print hex value of a number
1258   hex() {
1259     [ -n "$1" ] && printf "%x\n" $1 || { print 'Usage: hex <number-to-convert>' ; return 1 }
1260   }
1261
1262   # calculate (or eval at all ;-)) with perl => p[erl-]eval
1263   # hint: also take a look at zcalc -> 'autoload zcalc' -> 'man zshmodules | less -p MATHFUNC'
1264   peval() {
1265     [ -n "$1" ] && CALC="$*" || print "Usage: calc [expression]"
1266     perl -e "print eval($CALC),\"\n\";"
1267   }
1268   functions peval &>/dev/null && alias calc=peval
1269
1270   # brltty seems to have problems with utf8 environment and/or font Uni3-Terminus16 under
1271   # certain circumstances, so work around it, no matter which environment we have
1272   brltty() {
1273     if [ -z "$DISPLAY" ] ; then
1274        consolechars -f /usr/share/consolefonts/default8x16.psf.gz
1275        command brltty "$@"
1276     else
1277        command brltty "$@"
1278     fi
1279   }
1280
1281   # just press 'asdf' keys to toggle between dvorak and us keyboard layout
1282   aoeu() {
1283      if [ -n "$XKEYBOARD" -a -n "$KEYTABLE" ] ; then
1284         echo -n "Switching to $KEYTABLE keyboard layout: "
1285         [ -z "$DISPLAY" ] && $SUDO loadkeys $KEYTABLE &>/dev/null || setxkbmap $XKEYBOARD &>/dev/null
1286      else
1287         echo -n 'Switching to us keyboard layout: '
1288         [ -z "$DISPLAY" ] && $SUDO loadkeys us &>/dev/null || setxkbmap us &>/dev/null
1289      fi
1290      echo 'Done'
1291   }
1292   asdf() {
1293      echo -n 'Switching to dvorak keyboard layout: '
1294      [ -z "$DISPLAY" ] && $SUDO loadkeys dvorak &>/dev/null || setxkbmap dvorak &>/dev/null
1295      echo 'Done'
1296   }
1297   # just press 'asdf' key to toggle from neon layout to us keyboard layout
1298   uiae() {
1299      echo -n 'Switching to us keyboard layout: '
1300      setxkbmap us && echo 'Done' || echo 'Failed'
1301   }
1302
1303   # set up an ipv6 tunnel
1304   ipv6-tunnel() {
1305     case $1 in
1306       start)
1307        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1308           print 'ipv6 tunnel already set up, nothing to be done.'
1309           print 'execute: "ifconfig sit1 down ; ifconfig sit0 down" to remove ipv6-tunnel.' ; return 1
1310        else
1311           [ -n "$PUBLIC_IP" ] || local PUBLIC_IP=$(ifconfig $(route -n | awk '/^0\.0\.0\.0/{print $8; exit}') | \
1312                                              awk '/inet addr:/ {print $2}' | tr -d 'addr:')
1313           [ -n "$PUBLIC_IP" ] || { print 'No $PUBLIC_IP set and could not determine default one.' ; return 1 }
1314           local IPV6ADDR=$(printf "2002:%02x%02x:%02x%02x:1::1" $(print ${PUBLIC_IP//./ }))
1315           print -n "Setting up ipv6 tunnel $IPV6ADDR via ${PUBLIC_IP}: "
1316           ifconfig sit0 tunnel ::192.88.99.1 up
1317           ifconfig sit1 add "$IPV6ADDR" && print done || print failed
1318        fi
1319        ;;
1320       status)
1321        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1322           print 'ipv6 tunnel available' ; return 0
1323        else
1324           print 'ipv6 tunnel not available' ; return 1
1325        fi
1326        ;;
1327       stop)
1328        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1329           print -n 'Stopping ipv6 tunnel (sit0 + sit1): '
1330           ifconfig sit1 down ; ifconfig sit0 down && print done || print failed
1331        else
1332           print 'No ipv6 tunnel found, nothing to be done.' ; return 1
1333        fi
1334        ;;
1335       *)
1336        print "Usage: ipv6-tunnel [start|stop|status]">&2 ; return 1
1337        ;;
1338     esac
1339   }
1340
1341   # run dhclient for wireless device
1342   iwclient() {
1343     salias dhclient "$(wavemon -d | awk '/device/{print $2}')"
1344   }
1345
1346   # spawn a minimally set up ksh - useful if you want to umount /usr/.
1347   minimal-shell() {
1348     exec env -i ENV="/etc/minimal-shellrc" HOME="$HOME" TERM="$TERM" ksh
1349   }
1350
1351   # Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
1352   # bash() {
1353   #  NO_SWITCH="yes" command bash "$@"
1354   # }
1355   # restart () {
1356   #  exec $SHELL $SHELL_ARGS "$@"
1357   # }
1358
1359 # }}}
1360
1361 # log out? set timeout in seconds {{{
1362 # TMOUT=1800
1363 # do not log out in some specific terminals:
1364 #  if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]]; then
1365 #    unset TMOUT
1366 #  fi
1367 # }}}
1368
1369 # {{{ make sure our environment is clean regarding colors
1370   for color in BLUE RED GREEN CYAN WHITE ; unset $color
1371 # }}}
1372
1373 # source another config file if present {{{
1374   if [ -r /etc/zsh/zshrc.local ]; then
1375    source /etc/zsh/zshrc.local
1376   fi
1377 # }}}
1378
1379 # "persistent history" {{{
1380 # just write important commands you always need to ~/.important_commands
1381   if [ -r ~/.important_commands ] ; then
1382      fc -R ~/.important_commands
1383   fi
1384 # }}}
1385
1386 # add variable to be able to check whether the file has been read {{{
1387   ZSHRC_GLOBAL_HAS_BEEN_READ=1
1388 # }}}
1389
1390 ## END OF FILE #################################################################
1391 # vim:foldmethod=marker expandtab