added function iwclient
[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: Sam Jun 09 18:44:38 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   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 '\e[A'  up-line-or-search       # cursor up
206   bindkey '\e[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' ; print -n '\e%@'"
669   alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\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 -s"          # get a root shell
792     alias llog="$PAGER /var/log/syslog"     # take a look at the syslog
793     alias tlog="tail -f /var/log/syslog"    # follow the syslog
794     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
795   fi
796
797 # sort installed Debian-packages by size
798   if [ -x $(which grep-status) ] ; then
799      alias debs-by-size='grep-status -FStatus -sInstalled-Size,Package \
800                 -n "install ok installed" | paste -sd "  \n" | sort -rn'
801   fi
802
803 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
804   if [ -L /usr/bin/cdrecord -o ! -x $(which cdrecord) ] ; then
805      if [ -x $(which wodim) ] ; then
806         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
807 See #377109 in the BTS of Debian for more details.
808
809 Please use the wodim binary instead' ; return 1"
810      fi
811   fi
812
813 # get_tw_cli has been renamed into get_3ware
814   if [ -x $(which get_3ware) ] ; then
815      get_tw_cli() {
816        echo 'Warning: get_tw_cli has been renamed into get_3ware. Invoking get_3ware for you.'>&2
817        get_3ware
818      }
819   fi
820
821 # I hate lacking backward compability, so provide an alternative therefore
822   if ! [ -x $(which apache2-ssl-certificate) ] ; then
823      apache2-ssl-certificate(){
824
825      print 'Debian does not ship apache2-ssl-certificate anymore (see #398520). :('
826      print 'You might want to take a look at Debian the package ssl-cert as well.'
827      print 'To generate a certificate for use with apache2 follow the instructions:'
828
829      echo '
830
831 export RANDFILE=/dev/random
832 mkdir /etc/apache2/ssl/
833 openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
834 chmod 600 /etc/apache2/ssl/apache.pem
835
836 Run "grml-tips ssl-certificate" if you need further instructions.
837 '
838    }
839   fi
840 # }}}
841
842 # {{{ Use hard limits, except for a smaller stack and no core dumps
843   unlimit
844   limit stack 8192
845   isgrmlcd && limit core 0 # important for a live-cd-system
846   limit -s
847 # }}}
848
849 # {{{ completion stuff
850
851 # called later (via is4 && grmlcomp)
852 # notice: use 'zstyle' for getting current settings
853 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
854 grmlcomp() {
855 ## completion system
856   zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )' # allow one error for every three characters typed in approximate completer
857   zstyle ':completion:*:complete:-command-::commands' ignored-patterns '*\~' # don't complete backup files as executables
858   zstyle ':completion:*:correct:*'       insert-unambiguous true             # start menu completion only if it could find no unambiguous initial string
859   zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}' #
860   zstyle ':completion:*:correct:*'       original true                       #
861   zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}      # activate color-completion(!)
862   zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'  # format on completion
863   zstyle ':completion:*:*:cd:*:directory-stack' menu yes select              # complete 'cd -<tab>' with menu
864   zstyle ':completion:*:expand:*'        tag-order all-expansions            # insert all expansions for expand completer
865   zstyle ':completion:*:history-words'   list false                          #
866   zstyle ':completion:*:history-words'   menu yes                            # activate menu
867   zstyle ':completion:*:history-words'   remove-all-dups yes                 # ignore duplicate entries
868   zstyle ':completion:*:history-words'   stop yes                            #
869   zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'        # match uppercase from lowercase
870   zstyle ':completion:*:matches'         group 'yes'                         # separate matches into groups
871   zstyle ':completion:*'                 group-name ''
872   if [[ -z "$NOMENU" ]] ; then
873     zstyle ':completion:*'               menu select=5                       # if there are more than 5 options allow selecting from a menu
874   else
875     setopt no_auto_menu # don't use any menus at all
876   fi
877   zstyle ':completion:*:messages'        format '%d'                         #
878   zstyle ':completion:*:options'         auto-description '%d'               #
879   zstyle ':completion:*:options'         description 'yes'                   # describe options in full
880   zstyle ':completion:*:processes'       command 'ps -au$USER'               # on processes completion complete all user processes
881   zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters        # offer indexes before parameters in subscripts
882   zstyle ':completion:*'                 verbose true                        # provide verbose completion information
883   zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' # set format for warnings
884   zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'       # define files to ignore for zcompile
885   zstyle ':completion:correct:'          prompt 'correct to: %e'             #
886   zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'    # Ignore completion functions for commands you don't have:
887
888 # complete manual by their section
889   zstyle ':completion:*:manuals'    separate-sections true
890   zstyle ':completion:*:manuals.*'  insert-sections   true
891   zstyle ':completion:*:man:*'      menu yes select
892
893 ## correction
894 # run rehash on completion so new installed program are found automatically:
895   _force_rehash() {
896       (( CURRENT == 1 )) && rehash
897          return 1 # Because we didn't really complete anything
898     }
899 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
900   if [[ -n "$NOCOR" ]] ; then
901     zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files
902     setopt nocorrect # do not try to correct the spelling if possible
903   else
904 #    zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _correct _approximate _files
905     setopt correct  # try to correct the spelling if possible
906     zstyle -e ':completion:*' completer '
907         if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]]; then
908           _last_try="$HISTNO$BUFFER$CURSOR"
909           reply=(_complete _match _prefix _files)
910         else
911           if [[ $words[1] = (rm|mv) ]]; then
912             reply=(_complete _files)
913           else
914             reply=(_oldlist _expand _force_rehash _complete _correct _approximate _files)
915           fi
916         fi'
917   fi
918 # zstyle ':completion:*' completer _complete _correct _approximate
919 # zstyle ':completion:*' expand prefix suffix
920
921 # automatic rehash? Credits go to Frank Terbeck
922 # my_accept() {
923 #   local buf
924 #   [[ -z ${BUFFER} ]] && zle accept-line && return
925 #   buf=( ${(z)BUFFER}  )
926 #   [[ -z ${commands[${buf[1]}]} ]] && rehash
927 #   zle accept-line
928 # }
929 # zle -N my_accept
930 # bindkey "^M" my_accept
931
932 # command for process lists, the local web server details and host completion
933   zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
934
935 # caching
936   [ -d $ZSHDIR/cache ] && zstyle ':completion:*' use-cache yes && \
937                           zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
938
939 # host completion /* add brackets as vim can't parse zsh's complex cmdlines 8-) {{{ */
940   if is42 ; then
941     [ -r ~/.ssh/known_hosts ] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
942     [ -r /etc/hosts ] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
943   else
944     _ssh_hosts=()
945     _etc_hosts=()
946   fi
947   hosts=(
948       `hostname`
949       "$_ssh_hosts[@]"
950       "$_etc_hosts[@]"
951       grml.org
952       localhost
953   )
954   zstyle ':completion:*:hosts' hosts $hosts
955 #  zstyle '*' hosts $hosts
956
957 # specify your logins:
958 # my_accounts=(
959 #  {grml,grml1}@foo.invalid
960 #  grml-devel@bar.invalid
961 # )
962 # other_accounts=(
963 #  {fred,root}@foo.invalid
964 #  vera@bar.invalid
965 # )
966 # zstyle ':completion:*:my-accounts' users-hosts $my_accounts
967 # zstyle ':completion:*:other-accounts' users-hosts $other_accounts
968
969 # specify specific port/service settings:
970 #  telnet_users_hosts_ports=(
971 #    user1@host1:
972 #    user2@host2:
973 #    @mail-server:{smtp,pop3}
974 #    @news-server:nntp
975 #    @proxy-server:8000
976 #  )
977 # zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
978
979 # use generic completion system for programs not yet defined:
980   compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
981
982 # see upgrade function in this file
983   compdef _hosts upgrade
984 }
985 # }}}
986
987 # {{{ grmlstuff
988 grmlstuff() {
989 # people should use 'grml-x'!
990   startx() {
991     if [ -e /etc/X11/xorg.conf ] ; then
992        [ -x /usr/bin/startx ] && /usr/bin/startx || /usr/X11R6/bin/startx
993     else
994       echo "Please use the script \"grml-x\" for starting the X Window System
995 because there does not exist /etc/X11/xorg.conf yet.
996 If you want to use startx anyway please call \"/usr/bin/startx\"."
997       return -1
998     fi
999   }
1000
1001   xinit() {
1002     if [ -e /etc/X11/xorg.conf ] ; then
1003        [ -x /usr/bin/xinit ] && /usr/bin/xinit || /usr/X11R6/bin/xinit
1004     else
1005       echo "Please use the script \"grml-x\" for starting the X Window System.
1006 because there does not exist /etc/X11/xorg.conf yet.
1007 If you want to use xinit anyway please call \"/usr/bin/xinit\"."
1008       return -1
1009     fi
1010   }
1011
1012   if [ -x $(which 915resolution) ] ; then
1013      alias 855resolution='echo -e "Please use 915resolution as resolution modify tool for Intel graphic chipset."; return -1'
1014   fi
1015
1016   alias grml-version='cat /etc/grml_version'
1017
1018   if [ -x $(which rebuildfstab) ] ; then
1019      alias grml-rebuildfstab='rebuildfstab -v -r -config'
1020   fi
1021
1022   if [ -x $(which grml-debootstrap) ] ; then
1023      alias debian2hd='print "Installing debian to harddisk is possible via using grml-debootstrap." ; return 1'
1024   fi
1025 }
1026 # }}}
1027
1028 # {{{ now run the functions
1029   isgrml && checkhome
1030   is4    && isgrml    && grmlstuff
1031   is4    && grmlcomp
1032 # }}}
1033
1034 # {{{ keephack
1035   [ -r /etc/zsh/keephack ] && is4 && source /etc/zsh/keephack
1036 # }}}
1037
1038 # {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson
1039 # You use it as follows:
1040 # $ NTREF=/reference/file
1041 # $ ls -l *(e:nt:)
1042 # This lists all the files in the current directory newer than the reference file.
1043 # You can also specify the reference file inline; note quotes:
1044 # $ ls -l *(e:'nt ~/.zshenv':)
1045   is4 && nt() {
1046     if [[ -n $1 ]]; then
1047       local NTREF=${~1}
1048     fi
1049     [[ $REPLY -nt $NTREF ]]
1050   }
1051 # }}}
1052
1053 # shell functions {{{
1054   setenv()  { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }  # csh compatibility
1055   freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
1056   reload () {
1057    if [[ "$#*" -eq 0 ]]; then
1058       [ -r ~/.zshrc ] && . ~/.zshrc
1059    else
1060       local fn
1061       for fn in "$@"; do
1062           unfunction $fn
1063           autoload -U $fn
1064       done
1065    fi
1066   }
1067   compdef _functions reload freload
1068
1069   # list symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
1070   sll() {
1071     [ -z "$1" ] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
1072     for i in "$@" ; do
1073       file=$i
1074       while [ -h "$file" ] ; do
1075         ls -l $file
1076         file=$(readlink "$file")
1077       done
1078     done
1079   }
1080
1081   # fast manual access
1082   if type -p qma &>/dev/null ; then
1083      manzsh()  { qma zshall "$1" }
1084      compdef _man qma
1085   else
1086      manzsh()  { /usr/bin/man zshall |  vim -c "se ft=man| se hlsearch" +/"$1" - ; }
1087      # manzsh()  { /usr/bin/man zshall |  most +/"$1" ; }
1088      # manzsh()  { man zshall | $MYLESS -p $1 ; }
1089   fi
1090
1091   if [ -x $(which most) ] ; then
1092   # use "dchange <package-name>" to view Debian's changelog of the package:
1093     dchange() {
1094       if [ -r /usr/share/doc/${1}/changelog.Debian.gz ] ; then
1095          most /usr/share/doc/${1}/changelog.Debian.gz
1096       else
1097          if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1098             most /usr/share/doc/${1}/changelog.gz
1099          else
1100             echo "No changelog for package $1 found, sorry."
1101             return 1
1102          fi
1103       fi
1104     }
1105     _dchange() { _files -W /usr/share/doc -/ }
1106     compdef _dchange dchange
1107
1108   # use "uchange <package-name>" to view upstream's changelog of the package:
1109     uchange() {
1110       if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1111          most /usr/share/doc/${1}/changelog.gz
1112       else
1113          echo "No changelog for package $1 found, sorry."
1114          return 1
1115       fi
1116     }
1117     _uchange() { _files -W /usr/share/doc -/ }
1118     compdef _uchange uchange
1119   fi
1120
1121 # zsh profiling
1122   profile () {
1123       ZSH_PROFILE_RC=1 $SHELL "$@"
1124   }
1125
1126 # edit alias via zle:
1127   edalias() {
1128     [ -z "$1" ] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
1129   }
1130   compdef _aliases edalias
1131
1132 # edit function via zle:
1133   edfunc() {
1134     [ -z "$1" ] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
1135   }
1136   compdef _functions edfunc
1137
1138 # use it e.g. via 'Restart apache2'
1139  if [ -d /etc/init.d ] ; then
1140   for i in Start Restart Stop Force-Reload Reload ; do
1141     eval "$i() { $SUDO /etc/init.d/\$1 ${i:l} \$2 ; }"
1142   done
1143   # now the completion for this:
1144   compctl -g "$(echo /etc/init.d/*(:t))" Start Restart Stop Force-Reload Reload
1145  fi
1146
1147 # provide useful information on globbing
1148   H-Glob() {
1149   echo -e "
1150       /      directories
1151       .      plain files
1152       @      symbolic links
1153       =      sockets
1154       p      named pipes (FIFOs)
1155       *      executable plain files (0100)
1156       %      device files (character or block special)
1157       %b     block special files
1158       %c     character special files
1159       r      owner-readable files (0400)
1160       w      owner-writable files (0200)
1161       x      owner-executable files (0100)
1162       A      group-readable files (0040)
1163       I      group-writable files (0020)
1164       E      group-executable files (0010)
1165       R      world-readable files (0004)
1166       W      world-writable files (0002)
1167       X      world-executable files (0001)
1168       s      setuid files (04000)
1169       S      setgid files (02000)
1170       t      files with the sticky bit (01000)
1171
1172    print *(m-1)          # Files modified up to a day ago
1173    print *(a1)           # Files accessed a day ago
1174    print *(@)            # Just symlinks
1175    print *(Lk+50)        # Files bigger than 50 kilobytes
1176    print *(Lk-50)        # Files smaller than 50 kilobytes
1177    print **/*.c          # All *.c files recursively starting in \$PWD
1178    print **/*.c~file.c   # Same as above, but excluding 'file.c'
1179    print (foo|bar).*     # Files starting with 'foo' or 'bar'
1180    print *~*.*           # All Files that do not contain a dot
1181    chmod 644 *(.^x)      # make all plain non-executable files publically readable
1182    print -l *(.c|.h)     # Lists *.c and *.h
1183    print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
1184    echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
1185   }
1186   alias help-zshglob=H-Glob
1187
1188   type -p qma &>/dev/null && alias ?='qma zshall'
1189
1190   # grep for running process, like: 'any vim'
1191   any() {
1192   if [ -z "$1" ] ; then
1193      echo "any - grep for process(es) by keyword" >&2
1194      echo "Usage: any <keyword>" >&2 ; return 1
1195   else
1196      local STRING=$1
1197      local LENGTH=$(expr length $STRING)
1198      local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
1199      local REST=$(echo $(expr substr $STRING 2 $LENGTH))
1200      ps xauwww| grep "[$FIRSCHAR]$REST"
1201   fi
1202   }
1203
1204   # After resuming from suspend, system is paging heavilly, leading to very bad interactivity.
1205   # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
1206   [ -r /proc/1/maps ] && deswap() {
1207      print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
1208      cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
1209      print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
1210   }
1211
1212   # print hex value of a number
1213   hex() {
1214     [ -n "$1" ] && printf "%x\n" $1 || { print 'Usage: hex <number-to-convert>' ; return 1 }
1215   }
1216
1217   # calculate (or eval at all ;-)) with perl => p[erl-]eval
1218   # hint: also take a look at zcalc -> 'autoload zcalc' -> 'man zshmodules | less -p MATHFUNC'
1219   peval() {
1220     [ -n "$1" ] && CALC="$*" || print "Usage: calc [expression]"
1221     perl -e "print eval($CALC),\"\n\";"
1222   }
1223   functions peval &>/dev/null && alias calc=peval
1224
1225   # brltty seems to have problems with utf8 environment and/or font Uni3-Terminus16 under
1226   # certain circumstances, so work around it, no matter which environment we have
1227   brltty() {
1228     if [ -z "$DISPLAY" ] ; then
1229        consolechars -f /usr/share/consolefonts/default8x16.psf.gz
1230        command brltty "$@"
1231     else
1232        command brltty "$@"
1233     fi
1234   }
1235
1236   # just press 'asdf' keys to toggle between dvorak and us keyboard layout
1237   aoeu() {
1238      if [ -n "$XKEYBOARD" -a -n "$KEYTABLE" ] ; then
1239         echo -n "Switching to $KEYTABLE keyboard layout: "
1240         [ -z "$DISPLAY" ] && $SUDO loadkeys $KEYTABLE &>/dev/null || setxkbmap $XKEYBOARD &>/dev/null
1241      else
1242         echo -n 'Switching to us keyboard layout: '
1243         [ -z "$DISPLAY" ] && $SUDO loadkeys us &>/dev/null || setxkbmap us &>/dev/null
1244      fi
1245      echo 'Done'
1246   }
1247   asdf() {
1248      echo -n 'Switching to dvorak keyboard layout: '
1249      [ -z "$DISPLAY" ] && $SUDO loadkeys dvorak &>/dev/null || setxkbmap dvorak &>/dev/null
1250      echo 'Done'
1251   }
1252   # just press 'asdf' key to toggle from neon layout to us keyboard layout
1253   uiae() {
1254      echo -n 'Switching to us keyboard layout: '
1255      setxkbmap us && echo 'Done' || echo 'Failed'
1256   }
1257
1258   # set up an ipv6 tunnel
1259   ipv6-tunnel() {
1260     case $1 in
1261       start)
1262        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1263           print 'ipv6 tunnel already set up, nothing to be done.'
1264           print 'execute: "ifconfig sit1 down ; ifconfig sit0 down" to remove ipv6-tunnel.' ; return 1
1265        else
1266           [ -n "$PUBLIC_IP" ] || local PUBLIC_IP=$(ifconfig $(route -n | awk '/^0\.0\.0\.0/{print $8; exit}') | \
1267                                              awk '/inet addr:/ {print $2}' | tr -d 'addr:')
1268           [ -n "$PUBLIC_IP" ] || { print 'No $PUBLIC_IP set and could not determine default one.' ; return 1 }
1269           local IPV6ADDR=$(printf "2002:%02x%02x:%02x%02x:1::1" $(print ${PUBLIC_IP//./ }))
1270           print -n "Setting up ipv6 tunnel $IPV6ADDR via ${PUBLIC_IP}: "
1271           ifconfig sit0 tunnel ::192.88.99.1 up
1272           ifconfig sit1 add "$IPV6ADDR" && print done || print failed
1273        fi
1274        ;;
1275       status)
1276        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1277           print 'ipv6 tunnel available' ; return 0
1278        else
1279           print 'ipv6 tunnel not available' ; return 1
1280        fi
1281        ;;
1282       stop)
1283        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1284           print -n 'Stopping ipv6 tunnel (sit0 + sit1): '
1285           ifconfig sit1 down ; ifconfig sit0 down && print done || print failed
1286        else
1287           print 'No ipv6 tunnel found, nothing to be done.' ; return 1
1288        fi
1289        ;;
1290       *)
1291        print "Usage: ipv6-tunnel [start|stop|status]">&2 ; return 1
1292        ;;
1293     esac
1294   }
1295
1296   # run dhclient for wireless device
1297   iwclient() {
1298     salias dhclient "$(wavemon -d | awk '/device/{print $2}')"
1299   }
1300
1301   # Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
1302   # bash() {
1303   #  NO_SWITCH="yes" command bash "$@"
1304   # }
1305   # restart () {
1306   #  exec $SHELL $SHELL_ARGS "$@"
1307   # }
1308
1309 # }}}
1310
1311 # log out? set timeout in seconds {{{
1312 # TMOUT=1800
1313 # do not log out in some specific terminals:
1314 #  if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]]; then
1315 #    unset TMOUT
1316 #  fi
1317 # }}}
1318
1319 # {{{ make sure our environment is clean regarding colors
1320   for color in BLUE RED GREEN CYAN WHITE ; unset $color
1321 # }}}
1322
1323 # source another config file if present {{{
1324   if [ -r /etc/zsh/zshrc.local ]; then
1325    source /etc/zsh/zshrc.local
1326   fi
1327 # }}}
1328
1329 # "persistent history" {{{
1330 # just write important commands you always need to ~/.important_commands
1331   if [ -r ~/.important_commands ] ; then
1332      fc -R ~/.important_commands
1333   fi
1334 # }}}
1335
1336 # add variable to be able to check whether the file has been read {{{
1337   ZSHRC_GLOBAL_HAS_BEEN_READ=1
1338 # }}}
1339
1340 ## END OF FILE #################################################################
1341 # vim:foldmethod=marker expandtab