make sure dirs is not an alias or function
[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: Son Dez 17 13:52:04 CET 2006 [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 # {{{ check for version/system
16 # check for versions (compatibility reasons)
17   if autoload is-at-least && is-at-least 2>/dev/null ; then
18      is4() { is-at-least 4 }
19      is42() { is-at-least 4.2 }
20   else
21     is4(){
22       [[ $ZSH_VERSION == 4.* ]] && return 0
23       return 1
24     }
25     is42(){
26       [[ $ZSH_VERSION == 4.<2->* ]] && return 0
27       return 1
28     }
29   fi
30
31 # grml specific stuff
32   isgrml(){
33     [ -f /etc/grml_version ] && return 0
34     return 1
35   }
36
37   isgrmlcd(){
38     [ -f /etc/grml_cd ] && return 0
39     return 1
40   }
41
42   if isgrml ; then
43     isgrmlsmall() {
44     [[ ${${${(f)"$(</etc/grml_version)"}%% *}##*-} == 'small' ]] && return 0 ; return 1
45   }
46   else
47     isgrmlsmall() { return 1 }
48   fi
49
50   # are we running within an utf environment?
51   isutfenv() {
52     case "$LANG $CHARSET $LANGUAGE" in
53       *utf*) return 0 ;;
54       *)     return 1 ;;
55     esac
56   }
57
58 # check for user, if not running as root set $SUDO to sudo
59  (( EUID != 0 )) && SUDO='sudo' || SUDO=''
60
61 # change directory to home on first invocation of zsh
62 # important for rungetty -> autologin
63 # Thanks go to Bart Schaefer!
64   isgrml && checkhome() {
65   if [[ -z "$ALREADY_DID_CD_HOME" ]]; then
66      export ALREADY_DID_CD_HOME=$HOME
67      cd
68   fi
69   }
70 # }}}
71
72 # {{{ set some variables
73   export EDITOR=${EDITOR:-vim}
74   export MAIL=${MAIL:-/var/mail/$USER}
75   [[ -f ~/.terminfo/m/mostlike ]] && MYLESS='LESS=C TERMINFO=~/.terminfo TERM=mostlike less' || MYLESS='less'
76   [[ -x /usr/bin/dircolors ]] && eval `dircolors -b`
77
78 # Search path for the cd comman
79 #  cdpath=(.. ~)
80
81 # Support our own site-functions
82   [ -d /etc/zsh/site-functions ] && FPATH=/etc/zsh/site-functions:$FPATH
83
84 # automatically remove duplicates from these arrays
85   typeset -U path cdpath fpath manpath
86 # }}}
87
88 # {{{ keybindings
89  if [[ "$TERM" != emacs ]]; then
90   [[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
91   [[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
92   [[ -z "$terminfo[kend]"  ]] || bindkey -M emacs "$terminfo[kend]"  end-of-line
93   [[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
94   [[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
95   [[ -z "$terminfo[kend]"  ]] || bindkey -M vicmd "$terminfo[kend]"  vi-end-of-line
96   [[ -z "$terminfo[cuu1]"  ]] || bindkey -M viins "$terminfo[cuu1]"  vi-up-line-or-history
97   [[ -z "$terminfo[cuf1]"  ]] || bindkey -M viins "$terminfo[cuf1]"  vi-forward-char
98   [[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
99   [[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
100   [[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
101   [[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char
102   # ncurses stuff:
103   [[ "$terminfo[kcuu1]" == "\eO"* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history
104   [[ "$terminfo[kcud1]" == "\eO"* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history
105   [[ "$terminfo[kcuf1]" == "\eO"* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char
106   [[ "$terminfo[kcub1]" == "\eO"* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char
107   [[ "$terminfo[khome]" == "\eO"* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line
108   [[ "$terminfo[kend]"  == "\eO"* ]] && bindkey -M viins "${terminfo[kend]/O/[}"  end-of-line
109   [[ "$terminfo[khome]" == "\eO"* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line
110   [[ "$terminfo[kend]"  == "\eO"* ]] && bindkey -M emacs "${terminfo[kend]/O/[}"  end-of-line
111 fi
112
113 ## keybindings (run 'bindkeys' for details, more details via man zshzle)
114 # use emacs style per default:
115   bindkey -e
116 # use vi style:
117 # bindkey -v
118
119 #if [[ "$TERM" == screen ]]; then
120   bindkey '\e[1~' beginning-of-line       # home
121   bindkey '\e[4~' end-of-line             # end
122   bindkey "^[[A"  up-line-or-search       # cursor up
123   bindkey "^[[B"  down-line-or-search     # <ESC>-
124   bindkey '^x'    history-beginning-search-backward # alternative ways of searching the shell history
125 # bindkey -s '^L' "|less\n"             # ctrl-L pipes to less
126 # bindkey -s '^B' " &\n"                # ctrl-B runs it in the background
127 # if terminal type is set to 'rxvt':
128   bindkey '\e[7~' beginning-of-line       # home
129   bindkey '\e[8~' end-of-line             # end
130 #fi
131
132 #  bindkey '\eq' push-line-or-edit
133 # }}}
134
135 # power completion - abbreviation expansion {{{
136 # power completion / abbreviation expansion / buffer expansion
137 # see http://zshwiki.org/home/examples/zleiab for details
138 # less risky than the global aliases but powerful as well
139 # just type the abbreviation key and afterwards ',.' to expand it
140   declare -A abk
141   setopt extendedglob
142   setopt interactivecomments
143   abk=(
144    # key  # value
145    'C'    '| wc -l'
146    '...' '../..'
147    '....' '../../..'
148    'BG' '& exit'
149    'C' '|wc -l'
150    'G' '|& grep --color=auto'
151    'H' '|head'
152    'Hl' ' --help |& less -r'
153    'L' '|less'
154    'LL' '|& less -r'
155    'M' '|most'
156    'N' '&>/dev/null'
157    'R' '| tr A-z N-za-m'
158    'SL' '| sort | less'
159    'S' '| sort -u'
160    'T' '|tail'
161    'V' '|& vim -'
162    'hide' "echo -en '\033]50;nil2\007'"
163    'tiny' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-80-*-*-c-*-iso8859-15\007"'
164    'small' 'echo -en "\033]50;6x10\007"'
165    'medium' 'echo -en "\033]50;-misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-15\007"'
166    'default' 'echo -e "\033]50;-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-15\007"'
167    'large' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-150-*-*-c-*-iso8859-15\007"'
168    'huge' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-210-*-*-c-*-iso8859-15\007"'
169    'smartfont' 'echo -en "\033]50;-artwiz-smoothansi-*-*-*-*-*-*-*-*-*-*-*-*\007"'
170    'semifont' 'echo -en "\033]50;-misc-fixed-medium-r-semicondensed-*-*-120-*-*-*-*-iso8859-15\007"'
171    'da' 'du -sch'
172    'j' 'jobs -l'
173    'u' 'translate -i'
174    'co' "./configure && make && sudo make install"
175    'CH' "./configure --help"
176    'conkeror' 'firefox -chrome chrome://conkeror/content'
177    'dir' 'ls -lSrah'
178    'lad' $'ls -d .*(/)\n# only show dot-directories'
179    'lsa' $'ls -a .*(.)\n# only show dot-files'
180    'lss' $'ls -l *(s,S,t)\n# only files with setgid/setuid/sticky flag'
181    'lsl' $'ls -l *(@[1,10])\n# only symlinks'
182    'lsx' $'ls -l *(*[1,10])\n# only executables'
183    'lsw' $'ls -ld *(R,W,X.^ND/)\n# world-{readable,writable,executable} files'
184    'lsbig' $'ls -flh *(.OL[1,10])\n# display the biggest files'
185    'lsd' $'ls -d *(/)\n# only show directories'
186    'lse' $'ls -d *(/^F)\n# only show empty directories'
187    'lsnew' $'ls -rl *(D.om[1,10])\n# display the newest files'
188    'lsold' $'ls -rtlh *(D.om[-11,-1])\n # display the oldest files'
189    'lssmall' $'ls -Srl *(.oL[1,10])\n# display the smallest files'
190    'rw-' 'chmod 600'
191    '600' 'chmod u+rw-x,g-rwx,o-rwx'
192    'rwx' 'chmod u+rwx'
193    '700' 'chmod u+rwx,g-rwx,o-rwx'
194    'r--' 'chmod u+r-wx,g-rwx,o-rwx'
195    '644' $'chmod u+rw-x,g+r-wx,o+r-wx\n # 4=r,2=w,1=x'
196    '755' 'chmod u+rwx,g+r-w+x,o+r-w+x'
197    'md' 'mkdir -p '
198    'cmplayer' 'mplayer -vo -fs -zoom fbdev'
199    'fbmplayer' 'mplayer -vo -fs -zoom fbdev'
200    'fblinks' 'links2 -driver fb'
201    'insecssh' 'ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
202    'fori' 'for i ({..}) { }'
203    'cx' 'chmod +x'
204    'e'  'print -l'
205    'se' 'setopt interactivecomments'
206    'va' 'valac --vapidir=../vapi/ --pkg=gtk+-2.0 gtktest.vala'
207    'fb2' '=mplayer -vo fbdev -fs -zoom 1>/dev/null -xy 2'
208    'fb3' '=mplayer -vo fbdev -fs  -zoom 1>/dev/null -xy 3'
209    'ci' 'centericq'
210    'D'  'export DISPLAY=:0.0'
211    'mp' 'mplayer -vo xv -fs -zoom'
212   )
213
214   globalias () {
215         local MATCH
216         matched_chars='[.-|_a-zA-Z0-9]#'
217         LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
218         LBUFFER+=${abk[$MATCH]:-$MATCH}
219   }
220
221   zle -N globalias
222   bindkey ",." globalias
223 # }}}
224
225 # {{{ autoloading
226   autoload -U zmv    # who needs mmv or rename?
227   autoload history-search-end
228
229   # we don't want to quote/espace URLs on our own...
230   # avoid 'url-quote-magic: function definition file not found' on some older boxes
231   if [ -f "/usr/share/zsh/$ZSH_VERSION/functions/Zle/url-quote-magic" ] && \
232      autoload -U url-quote-magic && zle -N self-insert url-quote-magic ; then
233      zle -N self-insert url-quote-magic
234   else
235      print 'Notice: no url-quote-magic available :('
236   fi
237
238   alias run-help >&/dev/null && unalias run-help
239   autoload run-help # use via 'esc-h'
240
241 # completion system
242   if autoload -U compinit && compinit 2>/dev/null ; then
243      compinit 2>/dev/null || print 'Notice: no compinit available :('
244    else
245      print 'Notice: no compinit available :('
246      function zstyle { }
247      function compdef { }
248   fi
249
250   is4 && autoload -U zed                  # use ZLE editor to edit a file or function
251
252   is4 && for mod in complist deltochar mathfunc ; do
253              zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :("
254          done
255
256 # autoload zsh modules when they are referenced
257   is4 && for opt mod in a  stat    \
258                         a  zpty    \
259                         a  zprof   \
260                         ap mapfile ; do
261              zmodload -${opt} zsh/${mod} ${mod}
262          done ; unset opt mod
263
264   is4 && autoload -U insert-files && \
265   zle -N insert-files && \
266   bindkey "^Xf" insert-files # C-x-f
267
268   bindkey ' '   magic-space    # also do history expansion on space
269   bindkey '\ei' menu-complete  # menu completion via esc-i
270
271 # press esc-e for editing command line in $EDITOR or $VISUAL
272   is4 && autoload -U edit-command-line && \
273   zle -N edit-command-line && \
274   bindkey '\ee' edit-command-line
275
276 # menu selection: pick item but stay in the menu (press esc-return)
277   is4 && bindkey -M menuselect '\e^M' accept-and-menu-complete
278
279 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
280   _bkdate() { BUFFER="$BUFFER$(date '+%F')"; CURSOR=$#BUFFER; }
281   bindkey '\C-ed' _bkdate
282   zle -N _bkdate
283
284 # press esc-m for inserting last typed word again (thanks to caphuso!)
285   insert-last-typed-word() { zle insert-last-word -- 0 -1 }; \
286   zle -N insert-last-typed-word; bindkey "\em" insert-last-typed-word
287
288 # set command prediction from history, see 'man 1 zshcontrib'
289 #  is4 && autoload -U predict-on && \
290 #  zle -N predict-on         && \
291 #  zle -N predict-off        && \
292 #  bindkey "^X^Z" predict-on && \
293 #  bindkey "^Z" predict-off
294
295 # put job into foreground via ctrl-z:
296   bindkey -s '^z' "fg\n"
297
298 # press ctrl-q to quote line:
299 #  mquote () {
300 #        zle beginning-of-line
301 #        zle forward-word
302 #        # RBUFFER="'$RBUFFER'"
303 #        RBUFFER=${(q)RBUFFER}
304 #        zle end-of-line
305 #  }
306 #  zle -N mquote && bindkey '^q' mquote
307
308 # run command line as user root via sudo:
309   _sudo-command-line() {
310     [[ $BUFFER != sudo\ * ]] && LBUFFER="sudo $LBUFFER"
311   }
312   zle -N sudo-command-line _sudo-command-line
313   bindkey "^Os" sudo-command-line
314 # }}}
315
316 # {{{ set some important options
317   # umask 022
318   umask 002
319
320 # history:
321   setopt append_history       # append history list to the history file (important for multiple parallel zsh sessions!)
322   is4 && setopt SHARE_HISTORY # import new commands from the history file also in other zsh-session
323   setopt extended_history     # save each command's beginning timestamp and the duration to the history file
324   is4 && setopt histignorealldups # If  a  new  command  line being added to the history
325                               # list duplicates an older one, the older command is removed from the list
326   setopt histignorespace      # remove command lines from the history list when
327                               # the first character on the line is a space
328 #  setopt histallowclobber    # add `|' to output redirections in the history
329 #  setopt NO_clobber          # warning if file exists ('cat /dev/null > ~/.zshrc')
330   setopt auto_cd              # if a command is issued that can't be executed as a normal command,
331                               # and the command is the name of a directory, perform the cd command to that directory
332   setopt extended_glob        # in order to use #, ~ and ^ for filename generation
333                               # grep word *~(*.gz|*.bz|*.bz2|*.zip|*.Z) ->
334                               # -> searches for word not in compressed files
335                               # don't forget to quote '^', '~' and '#'!
336   setopt notify               # report the status of backgrounds jobs immediately
337   setopt hash_list_all        # Whenever a command completion is attempted, make sure \
338                               # the entire command path is hashed first.
339   setopt completeinword       # not just at the end
340 # setopt nocheckjobs          # don't warn me about bg processes when exiting
341   setopt nohup                # and don't kill them, either
342 # setopt printexitvalue       # alert me if something failed
343 # setopt dvorak               # with spelling correction, assume dvorak kb
344   setopt auto_pushd           # make cd push the old directory onto the directory stack.
345   setopt nonomatch            # try to avoid the 'zsh: no matches found...'
346   setopt nobeep               # avoid "beep"ing
347
348   MAILCHECK=30       # mailchecks
349   REPORTTIME=5       # report about cpu-/system-/user-time of command if running longer than 5 secondes
350   watch=(notme root) # watch for everyone but me and root
351
352 # define word separators (for stuff like backward-word, forward-word, backward-kill-word,..)
353 #  WORDCHARS='*?_-.[]~=/&;!#$%^(){}<>' # the default
354 #  WORDCHARS=.
355 #  WORDCHARS='*?_[]~=&;!#$%^(){}'
356 #  WORDCHARS='${WORDCHARS:s@/@}'
357
358 # only slash should be considered as a word separator:
359   slash-backward-kill-word() {
360     local WORDCHARS="${WORDCHARS:s@/@}"
361     # zle backward-word
362     zle backward-kill-word
363   }
364   zle -N slash-backward-kill-word
365   bindkey '\ev' slash-backward-kill-word # press esc-v to delete a word until its last '/' (not the same as ctrl-w!)
366 # }}}
367
368 # {{{ history
369   export ZSHDIR=$HOME/.zsh
370   HISTFILE=$HOME/.zsh_history
371   isgrmlcd && HISTSIZE=500  || HISTSIZE=5000
372   isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
373 # }}}
374
375 # dirstack handling {{{
376   DIRSTACKSIZE=20
377   if [[ -f ~/.zdirs ]] && [[ ${#dirstack[*]} -eq 0 ]]; then
378      dirstack=( ${(uf)"$(< ~/.zdirs)"} )
379      # "cd -" won't work after login by just setting $OLDPWD, so
380      cd $dirstack[0] && cd $OLDPWD
381   fi
382   # notice: we have to make sure 'dirs' is not a function/alias, otherwise
383   # zsh might hang of course
384   chpwd() {
385     alias dirs &>/dev/null || functions dirs &>/dev/null || dirs -pl >! ~/.zdirs
386   }
387 # }}}
388
389 # {{{ display battery status on right side of prompt via running 'BATTERY=1 zsh'
390   if [ -n "$BATTERY" ] ; then
391      if [ -x =acpi ] ; then
392         PERCENT="${(C)${(s| |)$(acpi 2>/dev/null)}[4]}"
393         [ -z "$PERCENT" ] && PERCENT='acpi not present'
394         if [ "${PERCENT%%%}" -lt 20 ] ; then
395            PERCENT="warning: ${PERCENT}%"
396         fi
397      fi
398   fi
399 # }}}
400
401 # {{{ set prompt
402   if [ -f "/usr/share/zsh/$ZSH_VERSION/functions/Prompts/promptinit" ] && autoload promptinit && promptinit 2>/dev/null ; then
403      promptinit # people should be able to use their favourite prompt
404   else
405      print 'Notice: no promptinit available :('
406   fi
407
408 # precmd() => a function which is executed just before each prompt
409 # use 'NOPRECMD=1' to disable the precmd + preexec commands
410
411   # precmd () { setopt promptsubst; [[ -o interactive ]] && jobs -l;
412
413   is4 && [[ -z $NOPRECMD ]] && precmd () {
414       [[ -n $NOPRECMD ]] && return 0
415       # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
416       if [[ -z ${DONTSETRPROMPT} ]] ; then
417         if [ -n "$BATTERY" ] ; then
418           # RPROMPT="%(?..:()% ${PERCENT}${SCREENTITLE}"
419           RPROMPT="${PERCENT}${SCREENTITLE}"
420         else
421           # RPROMPT="%(?..:()% ${SCREENTITLE}"
422           RPROMPT="${SCREENTITLE}"
423         fi
424       fi
425       # adjust title of xterm
426       # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
427       case $TERM in (xterm*|rxvt)
428         print -Pn "\e]0;%n@%m: %~\a"
429         ;;
430       esac
431   }
432
433 # chpwd () => a function which is executed whenever the directory is changed
434
435 # preexec() => a function running before every command
436   is4 && [[ -z $NOPRECMD ]] && preexec () {
437       [[ -n $NOPRECMD ]] && return 0
438   # set hostname if not running on host with name 'grml'
439       local HOSTNAME=$(hostname)
440       if [[ "$HOSTNAME" != grml ]] ; then
441          NAME="@$HOSTNAME"
442       fi
443   # get the name of the program currently running and hostname of local machine
444   # set screen window title if running in a screen
445       if [[ "$TERM" == screen* ]]; then
446           # local CMD=${1[(wr)^(*=*|sudo|ssh|-*)]}       # dont't use hostname
447           local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME" # use hostname
448           echo -ne "\ek$CMD\e\\"
449       fi
450   # set the screen title to "zsh" when sitting at the command prompt:
451       if [[ "$TERM" == screen* ]]; then
452            SCREENTITLE=$'%{\ekzsh\e\\%}'
453       else
454            SCREENTITLE=''
455       fi
456   # adjust title of xterm
457       case $TERM in (xterm*|rxvt)
458         print -Pn "\e]0;%n@%m: $1\a"
459         ;;
460       esac
461   }
462
463 # set colors
464   if autoload colors && colors 2>/dev/null ; then
465      BLUE="%{${fg[blue]}%}"
466      RED="%{${fg_bold[red]}%}"
467      GREEN="%{${fg[green]}%}"
468      CYAN="%{${fg[cyan]}%}"
469      WHITE="%{${fg[white]}%}"
470      NO_COLOUR="%{${reset_color}%}"
471   else
472      BLUE="%{\e[1;34m%}"
473      RED="%{\e[1;31m%}"
474      GREEN="%{\e[1;32m%}"
475      CYAN="%{\e[1;36m%}"
476      WHITE="%{\e[1;37m%}"
477      NO_COLOUR="%{\e[0m%}"
478   fi
479
480   EXITCODE="%(?..%?%1v )"
481   PS2='`%_> '       # secondary prompt, printed when the shell needs more information to complete a command.
482   PS3='?# '         # selection prompt used within a select loop.
483   PS4='+%N:%i:%_> ' # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
484
485   # set variable debian_chroot if running in a chroot with /etc/debian_chroot
486   if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
487     debian_chroot=$(cat /etc/debian_chroot)
488   fi
489
490   # don't use colors on dumb terminals (like emacs):
491   if [[ "$TERM" == dumb ]] ; then
492     PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< %# "
493   else
494     # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended prompt
495     # set variable identifying the chroot you work in (used in the prompt below)
496     if [[ -n "$GRMLPROMPT" ]]; then
497       PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
498 ${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# "
499     else
500       if (( EUID != 0 )); then
501         PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
502       else
503         PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
504       fi
505     fi
506   fi
507
508   # if we are inside a grml-chroot set a specific prompt theme
509   if [ -n "$GRML_CHROOT" ] ; then
510      PROMPT="%{$fg[red]%}(CHROOT) %{$fg_bold[red]%}%n%{$fg_no_bold[white]%}@%m %40<...<%B%~%b%<< %\# "
511   fi
512 # }}}
513
514 # {{{ 'hash' some often used directories
515   hash -d deb=/var/cache/apt/archives
516   hash -d doc=/usr/share/doc
517   hash -d linux=/lib/modules/$(command uname -r)/build/
518   hash -d log=/var/log
519   hash -d slog=/var/log/syslog
520   hash -d src=/usr/src
521   hash -d templ=/usr/share/doc/grml-templates
522   hash -d tt=/usr/share/doc/texttools-doc
523   hash -d www=/var/www
524 # }}}
525
526 # {{{ some aliases
527   if [ $UID = 0 ] ; then
528      [ -r /etc/grml/screenrc ] && alias screen='/usr/bin/screen -c /etc/grml/screenrc'
529   elif [ -r $HOME/.screenrc ] ; then
530      alias screen="/usr/bin/screen -c $HOME/.screenrc"
531   else
532      [ -r /etc/grml/screenrc_grml ] && alias screen='/usr/bin/screen -c /etc/grml/screenrc_grml'
533   fi
534
535   if ls --help 2>/dev/null |grep -- --color= >/dev/null && [ "$TERM" != dumb ] ; then
536      alias ls='ls -b -CF --color=auto' # do we have GNU ls with color-support?
537      alias la='ls -la --color=auto'
538      alias ll='ls -l --color=auto'
539      alias lh='ls -hAl --color=auto'
540      alias l='ls -lF --color=auto'
541   else
542      alias ls='ls -b -CF'
543      alias la='ls -la'
544      alias ll='ls -l'
545      alias lh='ls -hAl'
546      alias l='ls -lF'
547   fi
548
549   alias cp='nocorrect cp'         # no spelling correction on cp
550   alias mkdir='nocorrect mkdir'   # no spelling correction on mkdir
551   alias mv='nocorrect mv'         # no spelling correction on mv
552   alias rm='nocorrect rm'         # no spelling correction on rm
553
554   alias rd='rmdir'
555   alias md='mkdir'
556
557   alias swspeak="setopt singlelinezle ; unsetopt prompt_cr ; export PS1='%m%# ' ; speechd-up" # set up software synth.
558
559 # truecrypt; use e.g. via 'truec /dev/ice' /mnt/ice' or 'truec -i'
560   if [ -x /usr/sbin/truecrypt ] ; then
561      if isutfenv ; then
562         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077,utf8" '
563      else
564         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077" '
565      fi
566   fi
567
568   zsh-help(){print "$bg[white]$fg[black]
569 zsh-help - hints for use of zsh on grml
570 =======================================$reset_color
571
572 Main configuration of zsh happens in /etc/zsh/zshrc (global)
573 and /etc/skel/.zshrc which is copied to \$HOME/.zshrc once.
574 The files are part of the package grml-etc-core, if you want to
575 use them on a non-grml-system just get the tar.gz from
576 http://deb.grml.org/ or get the files from the mercurial
577 repository:
578
579   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
580   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
581
582 If you want to stay in sync with zsh configuration of grml
583 run 'ln -sf /etc/skel/.zshrc \$HOME/.zshrc' and configure
584 your own stuff in \$HOME/.zshrc.local. System wide configuration
585 without touching configuration files of grml can take place
586 in /etc/zsh/zshrc.local.
587
588 If you want to use the configuration of user grml also when
589 running as user root just run 'zshskel' which will source
590 the file /etc/skel/.zshrc.
591
592 For information regarding zsh start at http://grml.org/zsh/
593
594 Take a look at grml's zsh refcard:
595 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
596
597 Check out the main zsh refcard:
598 % $BROWSER http://www.bash2zsh.com/zsh_refcard/refcard.pdf
599
600 And of course visit the zsh-lovers:
601 % man zsh-lovers
602
603 You can adjust some options through environment variables when
604 invoking zsh without having to edit configuration files.
605 Basically meant for bash users who are not used to the power of
606 the zsh yet. :)
607
608   \"NOCOR=1    zsh\" => deactivate automatic correction
609   \"NOMENU=1   zsh\" => do not use menu completion (note: use strg-d for completion instead!)
610   \"NOPRECMD=1 zsh\" => disable the precmd + preexec commands (set GNU screen title)
611   \"BATTERY=1  zsh\" => activate battery status (via acpi) on right side of prompt
612 $bg[white]$fg[black]
613 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
614 Enjoy your grml system with the zsh!$reset_color"
615 }
616
617 # debian stuff
618   if [ -r /etc/debian_version ] ; then
619     alias acs='apt-cache search'
620     alias acsh='apt-cache show'
621     alias acp='apt-cache policy'
622     alias adg="$SUDO apt-get dist-upgrade"
623     alias agi="$SUDO apt-get install"
624     alias ag="$SUDO apt-get upgrade"
625     alias au="$SUDO apt-get update"
626     alias dbp='dpkg-buildpackage'
627     alias ge='grep-excuses'
628
629     # debian upgrade
630     upgrade () {
631       if [ -z "$1" ] ; then
632           $SUDO apt-get update
633           $SUDO apt-get -u upgrade
634       else
635           ssh $1 $SUDO apt-get update
636           # ask before the upgrade
637           local dummy
638           ssh $1 $SUDO apt-get --no-act upgrade
639           echo -n 'Process the upgrade?'
640           read -q dummy
641           if [[ $dummy == "y" ]] ; then
642               ssh $1 $SUDO apt-get -u upgrade --yes
643           fi
644       fi
645     }
646
647     isgrmlcd && alias su="sudo su"          # change to user root
648     alias tlog="tail -f /var/log/syslog"    # take a look at the syslog
649     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
650   fi
651
652 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
653   if [ -L /usr/bin/cdrecord -o ! -x =cdrecord ] ; then
654      if [ -x =wodim ] ; then
655         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
656 See #377109 in the BTS of Debian for more details.
657
658 Please use the wodim binary instead' ; return 1"
659      fi
660   fi
661
662 # }}}
663
664 # {{{ Use hard limits, except for a smaller stack and no core dumps
665   unlimit
666   limit stack 8192
667   isgrmlcd && limit core 0 # important for a live-cd-system
668   limit -s
669 # }}}
670
671 # {{{ completion stuff
672
673 # Where to look for autoloaded function definitions
674   if [ -d /etc/zsh/completion.d ] ; then
675     local comp=/etc/zsh/completion.d
676     for func in $comp/*(N-.:t); . ${comp}/${func}
677   fi
678
679 # called later (via is4 && grmlcomp)
680 # notice: use 'zstyle' for getting current settings
681 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
682 grmlcomp() {
683 ## completion system
684   zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )' # allow one error for every three characters typed in approximate completer
685   zstyle ':completion:*:complete:-command-::commands' ignored-patterns '*\~' # don't complete backup files as executables
686   zstyle ':completion:*:correct:*'       insert-unambiguous true             # start menu completion only if it could find no unambiguous initial string
687   zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}' #
688   zstyle ':completion:*:correct:*'       original true                       #
689   zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}      # activate color-completion(!)
690   zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'  # format on completion
691   zstyle ':completion:*:*:cd:*:directory-stack' menu yes select              # complete 'cd -<tab>' with menu
692   zstyle ':completion:*:expand:*'        tag-order all-expansions            # insert all expansions for expand completer
693   zstyle ':completion:*:history-words'   list false                          #
694   zstyle ':completion:*:history-words'   menu yes                            # activate menu
695   zstyle ':completion:*:history-words'   remove-all-dups yes                 # ignore duplicate entries
696   zstyle ':completion:*:history-words'   stop yes                            #
697   zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'        # match uppercase from lowercase
698   zstyle ':completion:*:matches'         group 'yes'                         # separate matches into groups
699   zstyle ':completion:*'                 group-name ''
700   if [[ -z "$NOMENU" ]] ; then
701     zstyle ':completion:*'               menu select=5                       # if there are more than 5 options allow selecting from a menu
702   else
703     setopt no_auto_menu # don't use any menus at all
704   fi
705   zstyle ':completion:*:messages'        format '%d'                         #
706   zstyle ':completion:*:options'         auto-description '%d'               #
707   zstyle ':completion:*:options'         description 'yes'                   # describe options in full
708   zstyle ':completion:*:processes'       command 'ps -au$USER'               # on processes completion complete all user processes
709   zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters        # offer indexes before parameters in subscripts
710   zstyle ':completion:*'                 verbose true                        # provide verbose completion information
711   zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' # set format for warnings
712   zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'       # define files to ignore for zcompile
713   zstyle ':completion:correct:'          prompt 'correct to: %e'             #
714   zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'    # Ignore completion functions for commands you don't have:
715
716 # complete manual by their section
717   zstyle ':completion:*:manuals'    separate-sections true
718   zstyle ':completion:*:manuals.*'  insert-sections   true
719   zstyle ':completion:*:man:*'      menu yes select
720
721 ## correction
722 # run rehash on completion so new installed program are found automatically:
723   _force_rehash() {
724       (( CURRENT == 1 )) && rehash
725          return 1 # Because we didn't really complete anything
726     }
727 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
728   if [[ -n "$NOCOR" ]] ; then
729     zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete
730     setopt nocorrect # do not try to correct the spelling if possible
731   else
732 #    zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _correct _approximate
733     setopt correct  # try to correct the spelling if possible
734     zstyle -e ':completion:*' completer '
735         if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]]; then
736           _last_try="$HISTNO$BUFFER$CURSOR"
737           reply=(_complete _match _prefix)
738         else
739           if [[ $words[1] = (rm|mv) ]]; then
740             reply=(_complete)
741           else
742             reply=(_oldlist _expand _force_rehash _complete _correct _approximate)
743           fi
744         fi'
745   fi
746 # zstyle ':completion:*' completer _complete _correct _approximate
747 # zstyle ':completion:*' expand prefix suffix
748
749 # automatic rehash? Credits go to Frank Terbeck
750 # function my_accept () {
751 #   local buf
752 #   [[ -z ${BUFFER} ]] && zle accept-line && return
753 #   buf=( ${(z)BUFFER}  )
754 #   [[ -z ${commands[${buf[1]}]} ]] && rehash
755 #   zle accept-line
756 # }
757 # zle -N my_accept
758 # bindkey "^M" my_accept
759
760 # command for process lists, the local web server details and host completion
761   hosts=(`hostname` grml.org)
762   zstyle '*' hosts $hosts
763   zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
764
765 # caching
766   [ -d $ZSHDIR/cache ] && zstyle ':completion:*' use-cache yes && \
767                           zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
768
769 # use ~/.ssh/known_hosts for completion [does not work with hashing of new ssh versions anymore]
770   if [ -f "$HOME/.ssh/known_hosts" ] ; then
771     hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*})
772     zstyle ':completion:*:hosts' hosts $hosts
773   fi
774
775 # use generic completion system for programs not yet defined:
776   compdef _gnu_generic tail head feh cp mv gpg df stow uname ipacsum fetchipac
777
778 # see upgrade function in this file
779   compdef _hosts upgrade
780 }
781 # }}}
782
783 # {{{ grmlstuff
784 grmlstuff() {
785 # people should use 'grml-x'!
786   function startx() {
787     if [ -e /etc/X11/xorg.conf ] ; then
788        [ -x /usr/bin/startx ] && /usr/bin/startx || /usr/X11R6/bin/startx
789     else
790       echo "Please use the script \"grml-x\" for starting the X Window System
791 because there does not exist /etc/X11/xorg.conf yet.
792 If you want to use startx anyway please call \"/usr/bin/startx\"."
793       return -1
794     fi
795   }
796
797   function xinit() {
798     if [ -e /etc/X11/xorg.conf ] ; then
799        [ -x /usr/bin/xinit ] && /usr/bin/xinit || /usr/X11R6/bin/xinit
800     else
801       echo "Please use the script \"grml-x\" for starting the X Window System.
802 because there does not exist /etc/X11/xorg.conf yet.
803 If you want to use xinit anyway please call \"/usr/bin/xinit\"."
804       return -1
805     fi
806   }
807
808   if [ -x /usr/sbin/915resolution ] ; then
809      alias 855resolution='echo -e "Please use 915resolution as resolution modify tool for Intel graphic chipset."; return -1'
810   fi
811
812   alias grml-version='cat /etc/grml_version'
813
814   if [ -x /usr/sbin/rebuildfstab ] ; then
815      alias grml-rebuildfstab='rebuildfstab -v -r -config'
816   fi
817 }
818 # }}}
819
820 # {{{ now run the functions
821   isgrml && checkhome
822   is4    && isgrml    && grmlstuff
823   is4    && grmlcomp
824 # }}}
825
826 # {{{ keephack
827   [ -r /etc/zsh/keephack ] && is4 && source /etc/zsh/keephack
828 # }}}
829
830 # {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson
831 # You use it as follows:
832 # $ NTREF=/reference/file
833 # $ ls -l *(e:nt:)
834 # This lists all the files in the current directory newer than the reference file.
835 # You can also specify the reference file inline; note quotes:
836 # $ ls -l *(e:'nt ~/.zshenv':)
837   is4 && nt() {
838     if [[ -n $1 ]]; then
839       local NTREF=${~1}
840     fi
841     [[ $REPLY -nt $NTREF ]]
842   }
843 # }}}
844
845 # shell functions {{{
846   setenv()  { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }  # csh compatibility
847   freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
848
849   # fast manual access
850   if type -p qma &>/dev/null ; then
851      manzsh()  { qma zshall "$1" }
852   else
853      manzsh()  { /usr/bin/man zshall |  vim -c "se ft=man| se hlsearch" +/"$1" - ; }
854      # manzsh()  { /usr/bin/man zshall |  most +/"$1" ; }
855      # manzsh()  { man zshall | $MYLESS -p $1 ; }
856   fi
857
858 # use "dchange <package-name>" to view Debian's changelog of the package:
859   dchange() {
860     if [ -r /usr/share/doc/${1}/changelog.Debian.gz ] ; then
861        most /usr/share/doc/${1}/changelog.Debian.gz
862     else
863        if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
864           most /usr/share/doc/${1}/changelog.gz
865        else
866           echo "No changelog for package $1 found, sorry."
867           return 1
868        fi
869     fi
870   }
871   _dchange() { _files -W /usr/share/doc -/ }
872   compdef _dchange dchange
873
874 # use "uchange <package-name>" to view upstream's changelog of the package:
875   uchange() {
876     if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
877        most /usr/share/doc/${1}/changelog.gz
878     else
879        echo "No changelog for package $1 found, sorry."
880        return 1
881     fi
882   }
883   _uchange() { _files -W /usr/share/doc -/ }
884   compdef _uchange uchange
885
886 # edit alias via zle:
887   edalias() {
888     [ -z "$1" ] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
889   }
890   compdef _aliases edalias
891
892 # edit function via zle:
893   edfun() {
894     [ -z "$1" ] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
895   }
896   compdef _functions edfun
897
898 # use it e.g. via 'Restart apache2'
899  if [ -d /etc/init.d ] ; then
900   for i in Start Restart Stop Force-Reload Reload ; do
901     eval "$i() { $SUDO /etc/init.d/\$1 ${i:l} \$2 ; }"
902   done
903   # now the completion for this:
904   compctl -g "$(echo /etc/init.d/*(:t))" Start Restart Stop Force-Reload Reload
905  fi
906
907 # provide useful information on globbing
908   H-Glob() {
909   echo -e "
910       /      directories
911       .      plain files
912       @      symbolic links
913       =      sockets
914       p      named pipes (FIFOs)
915       *      executable plain files (0100)
916       %      device files (character or block special)
917       %b     block special files
918       %c     character special files
919       r      owner-readable files (0400)
920       w      owner-writable files (0200)
921       x      owner-executable files (0100)
922       A      group-readable files (0040)
923       I      group-writable files (0020)
924       E      group-executable files (0010)
925       R      world-readable files (0004)
926       W      world-writable files (0002)
927       X      world-executable files (0001)
928       s      setuid files (04000)
929       S      setgid files (02000)
930       t      files with the sticky bit (01000)
931
932    print *(m-1)          # Files modified up to a day ago
933    print *(a1)           # Files accessed a day ago
934    print *(@)            # Just symlinks
935    print *(Lk+50)        # Files bigger than 50 kilobytes
936    print *(Lk-50)        # Files smaller than 50 kilobytes
937    print **/*.c          # All *.c files recursively starting in \$PWD
938    print **/*.c~file.c   # Same as above, but excluding 'file.c'
939    print (foo|bar).*     # Files starting with 'foo' or 'bar'
940    print *~*.*           # All Files that do not contain a dot
941    chmod 644 *(.^x)      # make all plain non-executable files publically readable
942    print -l *(.c|.h)     # Lists *.c and *.h
943    print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
944    echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
945   }
946   alias help-zshglob=H-Glob
947
948   type -p qma &>/dev/null && alias ?='qma zshall'
949
950   # grep for running process, like: 'any vim'
951   any() {
952   if [ -z "$1" ] ; then
953      echo "any - grep for process(es) by keyword" >&2
954      echo "Usage: any <keyword>" >&2 ; return 1
955   else
956      local STRING=$1
957      local LENGTH=$(expr length $STRING)
958      local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
959      local REST=$(echo $(expr substr $STRING 2 $LENGTH))
960      ps xauwww| grep [$FIRSCHAR]$REST
961   fi
962   }
963
964 # }}}
965
966 # {{{ make sure our environment is clean regarding colors
967   for color in BLUE RED GREEN CYAN WHITE ; unset $color
968 # }}}
969
970 # source another config file if present {{{
971   if [ -r /etc/zsh/zshrc.local ]; then
972    source /etc/zsh/zshrc.local
973   fi
974 # }}}
975
976 # "persistent history" {{{
977 # just write important commands you always need to ~/.important_commands
978   if [ -r ~/.important_commands ] ; then
979      fc -R ~/.important_commands
980   fi
981 # }}}
982
983 ## END OF FILE #################################################################
984 # vim:foldmethod=marker