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