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