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