several tuning tweaks like host completion in /etc/zsh/zshrc
[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: Fre Jän 05 00:00:23 CET 2007 [mika]
7 ################################################################################
8 # This file is sourced only for interactive shells. It
9 # should contain commands to set up aliases, functions,
10 # options, key bindings, etc.
11 #
12 # Global Order: zshenv, zprofile, zshrc, zlogin
13 ################################################################################
14
15 # {{{ 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   chpwd() {
383     builtin dirs -pl >! ~/.zdirs
384   }
385 # }}}
386
387 # {{{ display battery status on right side of prompt via running 'BATTERY=1 zsh'
388   if [ -n "$BATTERY" ] ; then
389      if [ -x =acpi ] ; then
390         PERCENT="${(C)${(s| |)$(acpi 2>/dev/null)}[4]}"
391         [ -z "$PERCENT" ] && PERCENT='acpi not present'
392         if [ "${PERCENT%%%}" -lt 20 ] ; then
393            PERCENT="warning: ${PERCENT}%"
394         fi
395      fi
396   fi
397 # }}}
398
399 # {{{ set prompt
400   if [ -f "/usr/share/zsh/$ZSH_VERSION/functions/Prompts/promptinit" ] && autoload promptinit && promptinit 2>/dev/null ; then
401      promptinit # people should be able to use their favourite prompt
402   else
403      print 'Notice: no promptinit available :('
404   fi
405
406 # precmd() => a function which is executed just before each prompt
407 # use 'NOPRECMD=1' to disable the precmd + preexec commands
408
409   # precmd () { setopt promptsubst; [[ -o interactive ]] && jobs -l;
410
411   is4 && [[ -z $NOPRECMD ]] && precmd () {
412       [[ -n $NOPRECMD ]] && return 0
413       # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
414       if [[ -z ${DONTSETRPROMPT} ]] ; then
415         if [ -n "$BATTERY" ] ; then
416           # RPROMPT="%(?..:()% ${PERCENT}${SCREENTITLE}"
417           RPROMPT="${PERCENT}${SCREENTITLE}"
418         else
419           # RPROMPT="%(?..:()% ${SCREENTITLE}"
420           RPROMPT="${SCREENTITLE}"
421         fi
422       fi
423       # adjust title of xterm
424       # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
425       case $TERM in (xterm*|rxvt)
426         print -Pn "\e]0;%n@%m: %~\a"
427         ;;
428       esac
429   }
430
431 # chpwd () => a function which is executed whenever the directory is changed
432
433 # preexec() => a function running before every command
434   is4 && [[ -z $NOPRECMD ]] && preexec () {
435       [[ -n $NOPRECMD ]] && return 0
436   # set hostname if not running on host with name 'grml'
437       local HOSTNAME=$(hostname)
438       if [[ "$HOSTNAME" != grml ]] ; then
439          NAME="@$HOSTNAME"
440       fi
441   # get the name of the program currently running and hostname of local machine
442   # set screen window title if running in a screen
443       if [[ "$TERM" == screen* ]]; then
444           # local CMD=${1[(wr)^(*=*|sudo|ssh|-*)]}       # dont't use hostname
445           local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME" # use hostname
446           echo -ne "\ek$CMD\e\\"
447       fi
448   # set the screen title to "zsh" when sitting at the command prompt:
449       if [[ "$TERM" == screen* ]]; then
450            SCREENTITLE=$'%{\ekzsh\e\\%}'
451       else
452            SCREENTITLE=''
453       fi
454   # adjust title of xterm
455       case $TERM in (xterm*|rxvt)
456         print -Pn "\e]0;%n@%m: $1\a"
457         ;;
458       esac
459   }
460
461 # set colors
462   if autoload colors && colors 2>/dev/null ; then
463      BLUE="%{${fg[blue]}%}"
464      RED="%{${fg_bold[red]}%}"
465      GREEN="%{${fg[green]}%}"
466      CYAN="%{${fg[cyan]}%}"
467      WHITE="%{${fg[white]}%}"
468      NO_COLOUR="%{${reset_color}%}"
469   else
470      BLUE="%{\e[1;34m%}"
471      RED="%{\e[1;31m%}"
472      GREEN="%{\e[1;32m%}"
473      CYAN="%{\e[1;36m%}"
474      WHITE="%{\e[1;37m%}"
475      NO_COLOUR="%{\e[0m%}"
476   fi
477
478   EXITCODE="%(?..%?%1v )"
479   PS2='`%_> '       # secondary prompt, printed when the shell needs more information to complete a command.
480   PS3='?# '         # selection prompt used within a select loop.
481   PS4='+%N:%i:%_> ' # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
482
483   # set variable debian_chroot if running in a chroot with /etc/debian_chroot
484   if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
485     debian_chroot=$(cat /etc/debian_chroot)
486   fi
487
488   # don't use colors on dumb terminals (like emacs):
489   if [[ "$TERM" == dumb ]] ; then
490     PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< %# "
491   else
492     # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended prompt
493     # set variable identifying the chroot you work in (used in the prompt below)
494     if [[ -n "$GRMLPROMPT" ]]; then
495       PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
496 ${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# "
497     else
498       if (( EUID != 0 )); then
499         PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
500       else
501         PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
502       fi
503     fi
504   fi
505
506   # if we are inside a grml-chroot set a specific prompt theme
507   if [ -n "$GRML_CHROOT" ] ; then
508      PROMPT="%{$fg[red]%}(CHROOT) %{$fg_bold[red]%}%n%{$fg_no_bold[white]%}@%m %40<...<%B%~%b%<< %\# "
509   fi
510 # }}}
511
512 # {{{ 'hash' some often used directories
513   hash -d deb=/var/cache/apt/archives
514   hash -d doc=/usr/share/doc
515   hash -d linux=/lib/modules/$(command uname -r)/build/
516   hash -d log=/var/log
517   hash -d slog=/var/log/syslog
518   hash -d src=/usr/src
519   hash -d templ=/usr/share/doc/grml-templates
520   hash -d tt=/usr/share/doc/texttools-doc
521   hash -d www=/var/www
522 # }}}
523
524 # {{{ some aliases
525   if [ $UID = 0 ] ; then
526      [ -r /etc/grml/screenrc ] && alias screen='/usr/bin/screen -c /etc/grml/screenrc'
527   elif [ -r $HOME/.screenrc ] ; then
528      alias screen="/usr/bin/screen -c $HOME/.screenrc"
529   else
530      [ -r /etc/grml/screenrc_grml ] && alias screen='/usr/bin/screen -c /etc/grml/screenrc_grml'
531   fi
532
533   if ls --help 2>/dev/null |grep -- --color= >/dev/null && [ "$TERM" != dumb ] ; then
534      alias ls='ls -b -CF --color=auto' # do we have GNU ls with color-support?
535      alias la='ls -la --color=auto'
536      alias ll='ls -l --color=auto'
537      alias lh='ls -hAl --color=auto'
538      alias l='ls -lF --color=auto'
539   else
540      alias ls='ls -b -CF'
541      alias la='ls -la'
542      alias ll='ls -l'
543      alias lh='ls -hAl'
544      alias l='ls -lF'
545   fi
546
547   alias cp='nocorrect cp'         # no spelling correction on cp
548   alias mkdir='nocorrect mkdir'   # no spelling correction on mkdir
549   alias mv='nocorrect mv'         # no spelling correction on mv
550   alias rm='nocorrect rm'         # no spelling correction on rm
551
552   alias rd='rmdir'
553   alias md='mkdir'
554
555   alias swspeak="setopt singlelinezle ; unsetopt prompt_cr ; export PS1='%m%# ' ; speechd-up" # set up software synth.
556
557   # I like clean prompt, so provide simple way to get that
558   alias 0 &>/dev/null || functions 0 &>/dev/null || alias 0='return 0'
559
560 # truecrypt; use e.g. via 'truec /dev/ice' /mnt/ice' or 'truec -i'
561   if [ -x /usr/sbin/truecrypt ] ; then
562      if isutfenv ; then
563         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077,utf8" '
564      else
565         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077" '
566      fi
567   fi
568
569   zsh-help(){print "$bg[white]$fg[black]
570 zsh-help - hints for use of zsh on grml
571 =======================================$reset_color
572
573 Main configuration of zsh happens in /etc/zsh/zshrc (global)
574 and /etc/skel/.zshrc which is copied to \$HOME/.zshrc once.
575 The files are part of the package grml-etc-core, if you want to
576 use them on a non-grml-system just get the tar.gz from
577 http://deb.grml.org/ or get the files from the mercurial
578 repository:
579
580   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
581   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
582
583 If you want to stay in sync with zsh configuration of grml
584 run 'ln -sf /etc/skel/.zshrc \$HOME/.zshrc' and configure
585 your own stuff in \$HOME/.zshrc.local. System wide configuration
586 without touching configuration files of grml can take place
587 in /etc/zsh/zshrc.local.
588
589 If you want to use the configuration of user grml also when
590 running as user root just run 'zshskel' which will source
591 the file /etc/skel/.zshrc.
592
593 For information regarding zsh start at http://grml.org/zsh/
594
595 Take a look at grml's zsh refcard:
596 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
597
598 Check out the main zsh refcard:
599 % $BROWSER http://www.bash2zsh.com/zsh_refcard/refcard.pdf
600
601 And of course visit the zsh-lovers:
602 % man zsh-lovers
603
604 You can adjust some options through environment variables when
605 invoking zsh without having to edit configuration files.
606 Basically meant for bash users who are not used to the power of
607 the zsh yet. :)
608
609   \"NOCOR=1    zsh\" => deactivate automatic correction
610   \"NOMENU=1   zsh\" => do not use menu completion (note: use strg-d for completion instead!)
611   \"NOPRECMD=1 zsh\" => disable the precmd + preexec commands (set GNU screen title)
612   \"BATTERY=1  zsh\" => activate battery status (via acpi) on right side of prompt
613 $bg[white]$fg[black]
614 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
615 Enjoy your grml system with the zsh!$reset_color"
616 }
617
618 # debian stuff
619   if [ -r /etc/debian_version ] ; then
620     alias acs='apt-cache search'
621     alias acsh='apt-cache show'
622     alias acp='apt-cache policy'
623     alias adg="$SUDO apt-get dist-upgrade"
624     alias agi="$SUDO apt-get install"
625     alias ag="$SUDO apt-get upgrade"
626     alias au="$SUDO apt-get update"
627     alias dbp='dpkg-buildpackage'
628     alias ge='grep-excuses'
629
630     # debian upgrade
631     upgrade () {
632       if [ -z "$1" ] ; then
633           $SUDO apt-get update
634           $SUDO apt-get -u upgrade
635       else
636           ssh $1 $SUDO apt-get update
637           # ask before the upgrade
638           local dummy
639           ssh $1 $SUDO apt-get --no-act upgrade
640           echo -n 'Process the upgrade?'
641           read -q dummy
642           if [[ $dummy == "y" ]] ; then
643               ssh $1 $SUDO apt-get -u upgrade --yes
644           fi
645       fi
646     }
647
648     isgrmlcd && alias su="sudo su"          # change to user root
649     alias tlog="tail -f /var/log/syslog"    # take a look at the syslog
650     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
651   fi
652
653 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
654   if [ -L /usr/bin/cdrecord -o ! -x =cdrecord ] ; then
655      if [ -x =wodim ] ; then
656         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
657 See #377109 in the BTS of Debian for more details.
658
659 Please use the wodim binary instead' ; return 1"
660      fi
661   fi
662
663 # I hate lacking backward compability, so provide an alternative therefore
664   if ! [ -x /usr/sbin/apache2-ssl-certificate ] ; then
665    function apache2-ssl-certificate(){
666
667      print 'Debian does not ship apache2-ssl-certificate anymore (see #398520). :('
668      print 'You might want to take a look at Debian the package ssl-cert as well.'
669      print 'To generate a certificate for use with apache2 follow the instructions:'
670
671      echo '
672
673 export RANDFILE=/dev/random
674 mkdir /etc/apache2/ssl/
675 openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
676 chmod 600 /etc/apache2/ssl/apache.pem
677
678 Run "grml-tips ssl-certificate" if you need further instructions.
679 '
680    }
681   fi
682 # }}}
683
684 # {{{ Use hard limits, except for a smaller stack and no core dumps
685   unlimit
686   limit stack 8192
687   isgrmlcd && limit core 0 # important for a live-cd-system
688   limit -s
689 # }}}
690
691 # {{{ completion stuff
692
693 # Where to look for autoloaded function definitions
694   if [ -d /etc/zsh/completion.d ] ; then
695     local comp=/etc/zsh/completion.d
696     for func in $comp/*(N-.:t); . ${comp}/${func}
697   fi
698
699 # called later (via is4 && grmlcomp)
700 # notice: use 'zstyle' for getting current settings
701 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
702 grmlcomp() {
703 ## completion system
704   zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )' # allow one error for every three characters typed in approximate completer
705   zstyle ':completion:*:complete:-command-::commands' ignored-patterns '*\~' # don't complete backup files as executables
706   zstyle ':completion:*:correct:*'       insert-unambiguous true             # start menu completion only if it could find no unambiguous initial string
707   zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}' #
708   zstyle ':completion:*:correct:*'       original true                       #
709   zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}      # activate color-completion(!)
710   zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'  # format on completion
711   zstyle ':completion:*:*:cd:*:directory-stack' menu yes select              # complete 'cd -<tab>' with menu
712   zstyle ':completion:*:expand:*'        tag-order all-expansions            # insert all expansions for expand completer
713   zstyle ':completion:*:history-words'   list false                          #
714   zstyle ':completion:*:history-words'   menu yes                            # activate menu
715   zstyle ':completion:*:history-words'   remove-all-dups yes                 # ignore duplicate entries
716   zstyle ':completion:*:history-words'   stop yes                            #
717   zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'        # match uppercase from lowercase
718   zstyle ':completion:*:matches'         group 'yes'                         # separate matches into groups
719   zstyle ':completion:*'                 group-name ''
720   if [[ -z "$NOMENU" ]] ; then
721     zstyle ':completion:*'               menu select=5                       # if there are more than 5 options allow selecting from a menu
722   else
723     setopt no_auto_menu # don't use any menus at all
724   fi
725   zstyle ':completion:*:messages'        format '%d'                         #
726   zstyle ':completion:*:options'         auto-description '%d'               #
727   zstyle ':completion:*:options'         description 'yes'                   # describe options in full
728   zstyle ':completion:*:processes'       command 'ps -au$USER'               # on processes completion complete all user processes
729   zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters        # offer indexes before parameters in subscripts
730   zstyle ':completion:*'                 verbose true                        # provide verbose completion information
731   zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' # set format for warnings
732   zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'       # define files to ignore for zcompile
733   zstyle ':completion:correct:'          prompt 'correct to: %e'             #
734   zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'    # Ignore completion functions for commands you don't have:
735
736 # complete manual by their section
737   zstyle ':completion:*:manuals'    separate-sections true
738   zstyle ':completion:*:manuals.*'  insert-sections   true
739   zstyle ':completion:*:man:*'      menu yes select
740
741 ## correction
742 # run rehash on completion so new installed program are found automatically:
743   _force_rehash() {
744       (( CURRENT == 1 )) && rehash
745          return 1 # Because we didn't really complete anything
746     }
747 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
748   if [[ -n "$NOCOR" ]] ; then
749     zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete
750     setopt nocorrect # do not try to correct the spelling if possible
751   else
752 #    zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _correct _approximate
753     setopt correct  # try to correct the spelling if possible
754     zstyle -e ':completion:*' completer '
755         if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]]; then
756           _last_try="$HISTNO$BUFFER$CURSOR"
757           reply=(_complete _match _prefix)
758         else
759           if [[ $words[1] = (rm|mv) ]]; then
760             reply=(_complete)
761           else
762             reply=(_oldlist _expand _force_rehash _complete _correct _approximate)
763           fi
764         fi'
765   fi
766 # zstyle ':completion:*' completer _complete _correct _approximate
767 # zstyle ':completion:*' expand prefix suffix
768
769 # automatic rehash? Credits go to Frank Terbeck
770 # function my_accept () {
771 #   local buf
772 #   [[ -z ${BUFFER} ]] && zle accept-line && return
773 #   buf=( ${(z)BUFFER}  )
774 #   [[ -z ${commands[${buf[1]}]} ]] && rehash
775 #   zle accept-line
776 # }
777 # zle -N my_accept
778 # bindkey "^M" my_accept
779
780 # command for process lists, the local web server details and host completion
781   zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
782
783 # caching
784   [ -d $ZSHDIR/cache ] && zstyle ':completion:*' use-cache yes && \
785                           zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
786
787 # host completion
788   if is42 ; then
789     [ -r ~/.ssh/known_hosts ] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
790     [ -r /etc/hosts ] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
791   else
792     _ssh_hosts=()
793     _etc_hosts=()
794   fi
795   hosts=(
796       `hostname`
797       "$_ssh_hosts[@]"
798       "$_etc_hosts[@]"
799       grml.org
800       localhost
801   )
802   zstyle ':completion:*:hosts' hosts $hosts
803 #  zstyle '*' hosts $hosts
804
805 # specify your logins:
806 # my_accounts=(
807 #  {grml,grml1}@foo.invalid
808 #  grml-devel@bar.invalid
809 # )
810 # other_accounts=(
811 #  {fred,root}@foo.invalid
812 #  vera@bar.invalid
813 # )
814 # zstyle ':completion:*:my-accounts' users-hosts $my_accounts
815 # zstyle ':completion:*:other-accounts' users-hosts $other_accounts
816
817 # specify specific port/service settings:
818 #  telnet_users_hosts_ports=(
819 #    user1@host1:
820 #    user2@host2:
821 #    @mail-server:{smtp,pop3}
822 #    @news-server:nntp
823 #    @proxy-server:8000
824 #  )
825 # zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
826
827 # use generic completion system for programs not yet defined:
828   compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
829
830 # see upgrade function in this file
831   compdef _hosts upgrade
832 }
833 # }}}
834
835 # {{{ grmlstuff
836 grmlstuff() {
837 # people should use 'grml-x'!
838   function startx() {
839     if [ -e /etc/X11/xorg.conf ] ; then
840        [ -x /usr/bin/startx ] && /usr/bin/startx || /usr/X11R6/bin/startx
841     else
842       echo "Please use the script \"grml-x\" for starting the X Window System
843 because there does not exist /etc/X11/xorg.conf yet.
844 If you want to use startx anyway please call \"/usr/bin/startx\"."
845       return -1
846     fi
847   }
848
849   function xinit() {
850     if [ -e /etc/X11/xorg.conf ] ; then
851        [ -x /usr/bin/xinit ] && /usr/bin/xinit || /usr/X11R6/bin/xinit
852     else
853       echo "Please use the script \"grml-x\" for starting the X Window System.
854 because there does not exist /etc/X11/xorg.conf yet.
855 If you want to use xinit anyway please call \"/usr/bin/xinit\"."
856       return -1
857     fi
858   }
859
860   if [ -x /usr/sbin/915resolution ] ; then
861      alias 855resolution='echo -e "Please use 915resolution as resolution modify tool for Intel graphic chipset."; return -1'
862   fi
863
864   alias grml-version='cat /etc/grml_version'
865
866   if [ -x /usr/sbin/rebuildfstab ] ; then
867      alias grml-rebuildfstab='rebuildfstab -v -r -config'
868   fi
869 }
870 # }}}
871
872 # {{{ now run the functions
873   isgrml && checkhome
874   is4    && isgrml    && grmlstuff
875   is4    && grmlcomp
876 # }}}
877
878 # {{{ keephack
879   [ -r /etc/zsh/keephack ] && is4 && source /etc/zsh/keephack
880 # }}}
881
882 # {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson
883 # You use it as follows:
884 # $ NTREF=/reference/file
885 # $ ls -l *(e:nt:)
886 # This lists all the files in the current directory newer than the reference file.
887 # You can also specify the reference file inline; note quotes:
888 # $ ls -l *(e:'nt ~/.zshenv':)
889   is4 && nt() {
890     if [[ -n $1 ]]; then
891       local NTREF=${~1}
892     fi
893     [[ $REPLY -nt $NTREF ]]
894   }
895 # }}}
896
897 # shell functions {{{
898   setenv()  { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }  # csh compatibility
899   freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
900   reload () {
901    if [[ "$#*" -eq 0 ]]; then
902       [ -r ~/.zshrc ] && . ~/.zshrc
903    else
904       local fn
905       for fn in "$@"; do
906           unfunction $fn
907           autoload -U $fn
908       done
909    fi
910   }
911   compdef _functions reload freload
912
913   # fast manual access
914   if type -p qma &>/dev/null ; then
915      manzsh()  { qma zshall "$1" }
916   else
917      manzsh()  { /usr/bin/man zshall |  vim -c "se ft=man| se hlsearch" +/"$1" - ; }
918      # manzsh()  { /usr/bin/man zshall |  most +/"$1" ; }
919      # manzsh()  { man zshall | $MYLESS -p $1 ; }
920   fi
921
922 # use "dchange <package-name>" to view Debian's changelog of the package:
923   dchange() {
924     if [ -r /usr/share/doc/${1}/changelog.Debian.gz ] ; then
925        most /usr/share/doc/${1}/changelog.Debian.gz
926     else
927        if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
928           most /usr/share/doc/${1}/changelog.gz
929        else
930           echo "No changelog for package $1 found, sorry."
931           return 1
932        fi
933     fi
934   }
935   _dchange() { _files -W /usr/share/doc -/ }
936   compdef _dchange dchange
937
938 # use "uchange <package-name>" to view upstream's changelog of the package:
939   uchange() {
940     if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
941        most /usr/share/doc/${1}/changelog.gz
942     else
943        echo "No changelog for package $1 found, sorry."
944        return 1
945     fi
946   }
947   _uchange() { _files -W /usr/share/doc -/ }
948   compdef _uchange uchange
949
950 # edit alias via zle:
951   edalias() {
952     [ -z "$1" ] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
953   }
954   compdef _aliases edalias
955
956 # edit function via zle:
957   edfunc() {
958     [ -z "$1" ] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
959   }
960   compdef _functions edfunc
961
962 # use it e.g. via 'Restart apache2'
963  if [ -d /etc/init.d ] ; then
964   for i in Start Restart Stop Force-Reload Reload ; do
965     eval "$i() { $SUDO /etc/init.d/\$1 ${i:l} \$2 ; }"
966   done
967   # now the completion for this:
968   compctl -g "$(echo /etc/init.d/*(:t))" Start Restart Stop Force-Reload Reload
969  fi
970
971 # provide useful information on globbing
972   H-Glob() {
973   echo -e "
974       /      directories
975       .      plain files
976       @      symbolic links
977       =      sockets
978       p      named pipes (FIFOs)
979       *      executable plain files (0100)
980       %      device files (character or block special)
981       %b     block special files
982       %c     character special files
983       r      owner-readable files (0400)
984       w      owner-writable files (0200)
985       x      owner-executable files (0100)
986       A      group-readable files (0040)
987       I      group-writable files (0020)
988       E      group-executable files (0010)
989       R      world-readable files (0004)
990       W      world-writable files (0002)
991       X      world-executable files (0001)
992       s      setuid files (04000)
993       S      setgid files (02000)
994       t      files with the sticky bit (01000)
995
996    print *(m-1)          # Files modified up to a day ago
997    print *(a1)           # Files accessed a day ago
998    print *(@)            # Just symlinks
999    print *(Lk+50)        # Files bigger than 50 kilobytes
1000    print *(Lk-50)        # Files smaller than 50 kilobytes
1001    print **/*.c          # All *.c files recursively starting in \$PWD
1002    print **/*.c~file.c   # Same as above, but excluding 'file.c'
1003    print (foo|bar).*     # Files starting with 'foo' or 'bar'
1004    print *~*.*           # All Files that do not contain a dot
1005    chmod 644 *(.^x)      # make all plain non-executable files publically readable
1006    print -l *(.c|.h)     # Lists *.c and *.h
1007    print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
1008    echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
1009   }
1010   alias help-zshglob=H-Glob
1011
1012   type -p qma &>/dev/null && alias ?='qma zshall'
1013
1014   # grep for running process, like: 'any vim'
1015   any() {
1016   if [ -z "$1" ] ; then
1017      echo "any - grep for process(es) by keyword" >&2
1018      echo "Usage: any <keyword>" >&2 ; return 1
1019   else
1020      local STRING=$1
1021      local LENGTH=$(expr length $STRING)
1022      local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
1023      local REST=$(echo $(expr substr $STRING 2 $LENGTH))
1024      ps xauwww| grep "[$FIRSCHAR]$REST"
1025   fi
1026   }
1027
1028   # Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
1029   # bash() {
1030   #  NO_SWITCH="yes" command bash "$@"
1031   # }
1032   # restart () {
1033   #  exec $SHELL $SHELL_ARGS "$@"
1034   # }
1035
1036 # }}}
1037
1038 # log out? set timeout in seconds {{{
1039 # TMOUT=1800
1040 # do not log out in some specific terminals:
1041 #  if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]]; then
1042 #    unset TMOUT
1043 #  fi
1044 # }}}
1045
1046 # {{{ make sure our environment is clean regarding colors
1047   for color in BLUE RED GREEN CYAN WHITE ; unset $color
1048 # }}}
1049
1050 # source another config file if present {{{
1051   if [ -r /etc/zsh/zshrc.local ]; then
1052    source /etc/zsh/zshrc.local
1053   fi
1054 # }}}
1055
1056 # "persistent history" {{{
1057 # just write important commands you always need to ~/.important_commands
1058   if [ -r ~/.important_commands ] ; then
1059      fc -R ~/.important_commands
1060   fi
1061 # }}}
1062
1063 ## END OF FILE #################################################################
1064 # vim:foldmethod=marker expandtab