Support LESS_TERMCAP_*
[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 Jul 07 10:56:20 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   [ -x $(which dircolors) ] && eval `dircolors -b`
239
240 # Search path for the cd command
241 #  cdpath=(.. ~)
242
243 # completion functions go to /etc/zsh/completion.d
244 # function files may be put into /etc/zsh/functions.d, from where they
245 # will be automatically autoloaded.
246   if [ -n "$BROKEN_COMPLETION_DIR" ] ; then
247      print 'Warning: not setting completion directories because broken files have been found.'>&2
248   else
249      [[ -d /etc/zsh/completion.d ]] && fpath+=( /etc/zsh/completion.d )
250      if [[ -d /etc/zsh/functions.d ]] ; then
251        fpath+=( /etc/zsh/functions.d )
252        for func in /etc/zsh/functions.d/[^_]*[^~] ; do
253          autoload -U ${func:t}
254        done
255      fi
256   fi
257
258 # automatically remove duplicates from these arrays
259   typeset -U path cdpath fpath manpath
260 # }}}
261
262 # {{{ keybindings
263  if [[ "$TERM" != emacs ]]; then
264   [[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
265   [[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
266   [[ -z "$terminfo[kend]"  ]] || bindkey -M emacs "$terminfo[kend]"  end-of-line
267   [[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
268   [[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
269   [[ -z "$terminfo[kend]"  ]] || bindkey -M vicmd "$terminfo[kend]"  vi-end-of-line
270   [[ -z "$terminfo[cuu1]"  ]] || bindkey -M viins "$terminfo[cuu1]"  vi-up-line-or-history
271   [[ -z "$terminfo[cuf1]"  ]] || bindkey -M viins "$terminfo[cuf1]"  vi-forward-char
272   [[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
273   [[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
274   [[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
275   [[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char
276   # ncurses stuff:
277   [[ "$terminfo[kcuu1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history
278   [[ "$terminfo[kcud1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history
279   [[ "$terminfo[kcuf1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char
280   [[ "$terminfo[kcub1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char
281   [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line
282   [[ "$terminfo[kend]"  == $'\eO'* ]] && bindkey -M viins "${terminfo[kend]/O/[}"  end-of-line
283   [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line
284   [[ "$terminfo[kend]"  == $'\eO'* ]] && bindkey -M emacs "${terminfo[kend]/O/[}"  end-of-line
285 fi
286
287 ## keybindings (run 'bindkeys' for details, more details via man zshzle)
288 # use emacs style per default:
289   bindkey -e
290 # use vi style:
291 # bindkey -v
292
293 #if [[ "$TERM" == screen ]]; then
294   bindkey '\e[1~' beginning-of-line       # home
295   bindkey '\e[4~' end-of-line             # end
296   bindkey '\e[A'  up-line-or-search       # cursor up
297   bindkey '\e[B'  down-line-or-search     # <ESC>-
298   bindkey '^x'    history-beginning-search-backward # alternative ways of searching the shell history
299 # bindkey -s '^L' "|less\n"             # ctrl-L pipes to less
300 # bindkey -s '^B' " &\n"                # ctrl-B runs it in the background
301 # if terminal type is set to 'rxvt':
302   bindkey '\e[7~' beginning-of-line       # home
303   bindkey '\e[8~' end-of-line             # end
304 #fi
305
306 # insert unicode character
307 # usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an Â§
308 # See for example http://unicode.org/charts/ for unicode characters code
309   autoload insert-unicode-char
310   zle -N insert-unicode-char
311   #k# Insert Unicode character
312   bindkey '^Xi' insert-unicode-char
313
314 # just type 'cd ...' to get 'cd ../..'
315 #  rationalise-dot() {
316 #  if [[ $LBUFFER = *.. ]]; then
317 #    LBUFFER+=/..
318 #  else
319 #    LBUFFER+=.
320 #  fi
321 #  }
322 #  zle -N rationalise-dot
323 #  bindkey . rationalise-dot
324
325 #  bindkey '\eq' push-line-or-edit
326 # }}}
327
328 # power completion - abbreviation expansion {{{
329 # power completion / abbreviation expansion / buffer expansion
330 # see http://zshwiki.org/home/examples/zleiab for details
331 # less risky than the global aliases but powerful as well
332 # just type the abbreviation key and afterwards ',.' to expand it
333   declare -A abk
334   setopt extendedglob
335   setopt interactivecomments
336   abk=(
337    # key  # value                (#d additional doc string)
338 #A# start
339    '...' '../..'
340    '....' '../../..'
341    'BG' '& exit'
342    'C' '| wc -l'
343    'G' '|& grep --color=auto'
344    'H' '| head'
345    'Hl' ' --help |& less -r'      #d (Display help in pager)
346    'L' '| less'
347    'LL' '|& less -r'
348    'M' '| most'
349    'N' '&>/dev/null'              #d (No Output)
350    'R' '| tr A-z N-za-m'          #d (ROT13)
351    'SL' '| sort | less'
352    'S' '| sort -u'
353    'T' '| tail'
354    'V' '|& vim -'
355 #A# end
356    'hide' "echo -en '\033]50;nil2\007'"
357    'tiny' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-80-*-*-c-*-iso8859-15\007"'
358    'small' 'echo -en "\033]50;6x10\007"'
359    'medium' 'echo -en "\033]50;-misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-15\007"'
360    'default' 'echo -e "\033]50;-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-15\007"'
361    'large' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-150-*-*-c-*-iso8859-15\007"'
362    'huge' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-210-*-*-c-*-iso8859-15\007"'
363    'smartfont' 'echo -en "\033]50;-artwiz-smoothansi-*-*-*-*-*-*-*-*-*-*-*-*\007"'
364    'semifont' 'echo -en "\033]50;-misc-fixed-medium-r-semicondensed-*-*-120-*-*-*-*-iso8859-15\007"'
365    'da' 'du -sch'
366    'j' 'jobs -l'
367    'u' 'translate -i'
368    'co' "./configure && make && sudo make install"
369    'CH' "./configure --help"
370    'conkeror' 'firefox -chrome chrome://conkeror/content'
371    'dir' 'ls -lSrah'
372    'lad' $'ls -d .*(/)\n# only show dot-directories'
373    'lsa' $'ls -a .*(.)\n# only show dot-files'
374    'lss' $'ls -l *(s,S,t)\n# only files with setgid/setuid/sticky flag'
375    'lsl' $'ls -l *(@[1,10])\n# only symlinks'
376    'lsx' $'ls -l *(*[1,10])\n# only executables'
377    'lsw' $'ls -ld *(R,W,X.^ND/)\n# world-{readable,writable,executable} files'
378    'lsbig' $'ls -flh *(.OL[1,10])\n# display the biggest files'
379    'lsd' $'ls -d *(/)\n# only show directories'
380    'lse' $'ls -d *(/^F)\n# only show empty directories'
381    'lsnew' $'ls -rl *(D.om[1,10])\n# display the newest files'
382    'lsold' $'ls -rtlh *(D.om[-11,-1])\n # display the oldest files'
383    'lssmall' $'ls -Srl *(.oL[1,10])\n# display the smallest files'
384    'rw-' 'chmod 600'
385    '600' 'chmod u+rw-x,g-rwx,o-rwx'
386    'rwx' 'chmod u+rwx'
387    '700' 'chmod u+rwx,g-rwx,o-rwx'
388    'r--' 'chmod u+r-wx,g-rwx,o-rwx'
389    '644' $'chmod u+rw-x,g+r-wx,o+r-wx\n # 4=r,2=w,1=x'
390    '755' 'chmod u+rwx,g+r-w+x,o+r-w+x'
391    'md' 'mkdir -p '
392    'cmplayer' 'mplayer -vo -fs -zoom fbdev'
393    'fbmplayer' 'mplayer -vo -fs -zoom fbdev'
394    'fblinks' 'links2 -driver fb'
395    'insecssh' 'ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
396    'insecscp' 'scp -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
397    'fori' 'for i ({..}) { }'
398    'cx' 'chmod +x'
399    'e'  'print -l'
400    'se' 'setopt interactivecomments'
401    'va' 'valac --vapidir=../vapi/ --pkg=gtk+-2.0 gtktest.vala'
402    'fb2' '=mplayer -vo fbdev -fs -zoom 1>/dev/null -xy 2'
403    'fb3' '=mplayer -vo fbdev -fs  -zoom 1>/dev/null -xy 3'
404    'ci' 'centericq'
405    'D'  'export DISPLAY=:0.0'
406    'mp' 'mplayer -vo xv -fs -zoom'
407   )
408
409   globalias () {
410         local MATCH
411         matched_chars='[.-|_a-zA-Z0-9]#'
412         LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
413         LBUFFER+=${abk[$MATCH]:-$MATCH}
414   }
415
416   zle -N globalias
417   bindkey ",." globalias
418 # }}}
419
420 # {{{ autoloading
421   autoload -U zmv    # who needs mmv or rename?
422   autoload history-search-end
423
424   # we don't want to quote/espace URLs on our own...
425   # if autoload -U url-quote-magic ; then
426   #    zle -N self-insert url-quote-magic
427   #    zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}='
428   # else
429   #    print 'Notice: no url-quote-magic available :('
430   # fi
431   alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic'
432
433   #m# k ESC-h Call \kbd{run-help} for the 1st word on the command line
434   alias run-help >&/dev/null && unalias run-help
435   autoload run-help # use via 'esc-h'
436
437 # completion system
438   if autoload -U compinit && compinit 2>/dev/null ; then
439      compinit 2>/dev/null || print 'Notice: no compinit available :('
440    else
441      print 'Notice: no compinit available :('
442      function zstyle { }
443      function compdef { }
444   fi
445
446   is4 && autoload -U zed # use ZLE editor to edit a file or function
447
448   is4 && for mod in complist deltochar mathfunc ; do
449              zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :("
450          done
451
452 # autoload zsh modules when they are referenced
453   is4 && for opt mod in a  stat    \
454                         a  zpty    \
455                         ap zprof   \
456                         ap mapfile ; do
457              zmodload -${opt} zsh/${mod} ${mod}
458          done ; unset opt mod
459
460   is4 && autoload -U insert-files && \
461   zle -N insert-files && \
462   #k# Insert files
463   bindkey "^Xf" insert-files # C-x-f
464
465   bindkey ' '   magic-space    # also do history expansion on space
466   #k# Trigger menu-complete
467   bindkey '\ei' menu-complete  # menu completion via esc-i
468
469 # press esc-e for editing command line in $EDITOR or $VISUAL
470   is4 && autoload -U edit-command-line && \
471   zle -N edit-command-line && \
472   #k# Edit the current line in \kbd{\$EDITOR}
473   bindkey '\ee' edit-command-line
474
475 #k# menu selection: pick item but stay in the menu
476   is4 && bindkey -M menuselect '\e^M' accept-and-menu-complete
477
478 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
479   _bkdate() { BUFFER="$BUFFER$(date '+%F')"; CURSOR=$#BUFFER; }
480   #k# Insert a timestamp on the command line (yyyy-mm-dd)
481   bindkey '^Ed' _bkdate
482   zle -N _bkdate
483
484 # press esc-m for inserting last typed word again (thanks to caphuso!)
485   insert-last-typed-word() { zle insert-last-word -- 0 -1 }; \
486   zle -N insert-last-typed-word;
487   #k# Insert last typed word
488   bindkey "\em" insert-last-typed-word
489
490 # set command prediction from history, see 'man 1 zshcontrib'
491 #  is4 && autoload -U predict-on && \
492 #  zle -N predict-on         && \
493 #  zle -N predict-off        && \
494 #  bindkey "^X^Z" predict-on && \
495 #  bindkey "^Z" predict-off
496
497 #k# Shortcut for \kbd{fg<enter>}
498   bindkey -s '^z' "fg\n"
499
500 # press ctrl-q to quote line:
501 #  mquote () {
502 #        zle beginning-of-line
503 #        zle forward-word
504 #        # RBUFFER="'$RBUFFER'"
505 #        RBUFFER=${(q)RBUFFER}
506 #        zle end-of-line
507 #  }
508 #  zle -N mquote && bindkey '^q' mquote
509
510 # run command line as user root via sudo:
511   _sudo-command-line() {
512     [[ $BUFFER != sudo\ * ]] && LBUFFER="sudo $LBUFFER"
513   }
514   zle -N sudo-command-line _sudo-command-line
515 #k# Put the current command line into a \kbd{sudo} call
516   bindkey "^Os" sudo-command-line
517
518 ### jump behind the first word on the cmdline.
519 ### useful to add options.
520   function jump_after_first_word() {
521     local words
522     words=(${(z)BUFFER})
523     if (( ${#words} <= 1 )) ; then
524       CURSOR=${#BUFFER}
525     else
526       CURSOR=${#${words[1]}}
527     fi
528   }
529   zle -N jump_after_first_word
530   bindkey '^x1' jump_after_first_word
531
532 # }}}
533
534 # {{{ set some important options
535 # Please update these tags, if you change the umask settings below.
536 #o# r_umask     002
537 #o# r_umaskstr  rwxrwxr-x
538 #o# umask       022
539 #o# umaskstr    rwxr-xr-x
540   (( EUID != 0 )) && umask 002 || umask 022
541
542 # history:
543   setopt append_history       # append history list to the history file (important for multiple parallel zsh sessions!)
544   is4 && setopt SHARE_HISTORY # import new commands from the history file also in other zsh-session
545   setopt extended_history     # save each command's beginning timestamp and the duration to the history file
546   is4 && setopt histignorealldups # If  a  new  command  line being added to the history
547                               # list duplicates an older one, the older command is removed from the list
548   setopt histignorespace      # remove command lines from the history list when
549                               # the first character on the line is a space
550 #  setopt histallowclobber    # add `|' to output redirections in the history
551 #  setopt NO_clobber          # warning if file exists ('cat /dev/null > ~/.zshrc')
552   setopt auto_cd              # if a command is issued that can't be executed as a normal command,
553                               # and the command is the name of a directory, perform the cd command to that directory
554   setopt extended_glob        # in order to use #, ~ and ^ for filename generation
555                               # grep word *~(*.gz|*.bz|*.bz2|*.zip|*.Z) ->
556                               # -> searches for word not in compressed files
557                               # don't forget to quote '^', '~' and '#'!
558   setopt notify               # report the status of backgrounds jobs immediately
559   setopt hash_list_all        # Whenever a command completion is attempted, make sure \
560                               # the entire command path is hashed first.
561   setopt completeinword       # not just at the end
562 # setopt nocheckjobs          # don't warn me about bg processes when exiting
563   setopt nohup                # and don't kill them, either
564 # setopt printexitvalue       # alert me if something failed
565 # setopt dvorak               # with spelling correction, assume dvorak kb
566   setopt auto_pushd           # make cd push the old directory onto the directory stack.
567   setopt nonomatch            # try to avoid the 'zsh: no matches found...'
568   setopt nobeep               # avoid "beep"ing
569   setopt pushd_ignore_dups    # don't push the same dir twice.
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=( ${(f)"$(< ~/.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 # for really lazy people like mika:
842   type S &>/dev/null || alias S='screen'
843   type s &>/dev/null || alias s='ssh'
844
845 # get top 10 shell commands:
846   alias top10='print -l ? ${(o)history%% *} | uniq -c | sort -nr | head -n 10'
847
848 # truecrypt; use e.g. via 'truec /dev/ice /mnt/ice' or 'truec -i'
849   if [ -x $(which truecrypt) ] ; then
850      if isutfenv ; then
851         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077,utf8" '
852      else
853         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077" '
854      fi
855   fi
856
857 #f1# Hints for the use of zsh on grml
858   zsh-help(){print "$bg[white]$fg[black]
859 zsh-help - hints for use of zsh on grml
860 =======================================$reset_color
861
862 Main configuration of zsh happens in /etc/zsh/zshrc (global)
863 and /etc/skel/.zshrc which is copied to \$HOME/.zshrc once.
864 The files are part of the package grml-etc-core, if you want to
865 use them on a non-grml-system just get the tar.gz from
866 http://deb.grml.org/ or get the files from the mercurial
867 repository:
868
869   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
870   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
871
872 If you want to stay in sync with zsh configuration of grml
873 run 'ln -sf /etc/skel/.zshrc \$HOME/.zshrc' and configure
874 your own stuff in \$HOME/.zshrc.local. System wide configuration
875 without touching configuration files of grml can take place
876 in /etc/zsh/zshrc.local.
877
878 If you want to use the configuration of user grml also when
879 running as user root just run 'zshskel' which will source
880 the file /etc/skel/.zshrc.
881
882 For information regarding zsh start at http://grml.org/zsh/
883
884 Take a look at grml's zsh refcard:
885 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
886
887 Check out the main zsh refcard:
888 % $BROWSER http://www.bash2zsh.com/zsh_refcard/refcard.pdf
889
890 And of course visit the zsh-lovers:
891 % man zsh-lovers
892
893 You can adjust some options through environment variables when
894 invoking zsh without having to edit configuration files.
895 Basically meant for bash users who are not used to the power of
896 the zsh yet. :)
897
898   \"NOCOR=1    zsh\" => deactivate automatic correction
899   \"NOMENU=1   zsh\" => do not use menu completion (note: use strg-d for completion instead!)
900   \"NOPRECMD=1 zsh\" => disable the precmd + preexec commands (set GNU screen title)
901   \"BATTERY=1  zsh\" => activate battery status (via acpi) on right side of prompt
902 $bg[white]$fg[black]
903 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
904 Enjoy your grml system with the zsh!$reset_color"
905 }
906
907 # debian stuff
908   if [ -r /etc/debian_version ] ; then
909     #a3# Execute \kbd{apt-cache search}
910     alias acs='apt-cache search'
911     #a3# Execute \kbd{apt-cache show}
912     alias acsh='apt-cache show'
913     #a3# Execute \kbd{apt-cache policy}
914     alias acp='apt-cache policy'
915     #a3# Execute \kbd{apt-get dist-upgrade}
916     salias adg="apt-get dist-upgrade"
917     #a3# Execute \kbd{apt-get install}
918     salias agi="apt-get install"
919     #a3# Execute \kbd{aptitude install}
920     salias ati="aptitude install"
921     #a3# Execute \kbd{apt-get upgrade}
922     salias ag="apt-get upgrade"
923     #a3# Execute \kbd{apt-get update}
924     salias au="apt-get update"
925     #a3# Execute \kbd{aptitude update ; aptitude upgrade}
926     salias -a up="aptitude update ; aptitude upgrade"
927     #a3# Execute \kbd{dpkg-buildpackage}
928     alias dbp='dpkg-buildpackage'
929     #a3# Execute \kbd{grep-excuses}
930     alias ge='grep-excuses'
931
932     # debian upgrade
933     #f3# Execute \kbd{apt-get update \&\& }\\&\quad \kbd{apt-get dist-upgrade}
934     upgrade () {
935       if [ -z "$1" ] ; then
936           $SUDO apt-get update
937           $SUDO apt-get -u upgrade
938       else
939           ssh $1 $SUDO apt-get update
940           # ask before the upgrade
941           local dummy
942           ssh $1 $SUDO apt-get --no-act upgrade
943           echo -n 'Process the upgrade?'
944           read -q dummy
945           if [[ $dummy == "y" ]] ; then
946               ssh $1 $SUDO apt-get -u upgrade --yes
947           fi
948       fi
949     }
950
951     isgrmlcd && alias su="sudo -s"          # get a root shell
952     #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
953     alias llog="$PAGER /var/log/syslog"     # take a look at the syslog
954     #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
955     alias tlog="tail -f /var/log/syslog"    # follow the syslog
956     #a1# (Re)-source \kbd{/etc/skel/.zshrc}
957     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
958   fi
959
960 # sort installed Debian-packages by size
961   if [ -x $(which grep-status) ] ; then
962      #a3# List installed Debian-packages sorted by size
963      alias debs-by-size='grep-status -FStatus -sInstalled-Size,Package -n "install ok installed" | paste -sd "  \n" | sort -rn'
964   fi
965
966 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
967   if [ -L /usr/bin/cdrecord -o ! -x $(which cdrecord) ] ; then
968      if [ -x $(which wodim) ] ; then
969         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
970 See #377109 in the BTS of Debian for more details.
971
972 Please use the wodim binary instead' ; return 1"
973      fi
974   fi
975
976 # get_tw_cli has been renamed into get_3ware
977   if [ -x $(which get_3ware) ] ; then
978      get_tw_cli() {
979        echo 'Warning: get_tw_cli has been renamed into get_3ware. Invoking get_3ware for you.'>&2
980        get_3ware
981      }
982   fi
983
984 # I hate lacking backward compatibility, so provide an alternative therefore
985   if ! [ -x $(which apache2-ssl-certificate) ] ; then
986      apache2-ssl-certificate(){
987
988      print 'Debian does not ship apache2-ssl-certificate anymore (see #398520). :('
989      print 'You might want to take a look at Debian the package ssl-cert as well.'
990      print 'To generate a certificate for use with apache2 follow the instructions:'
991
992      echo '
993
994 export RANDFILE=/dev/random
995 mkdir /etc/apache2/ssl/
996 openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
997 chmod 600 /etc/apache2/ssl/apache.pem
998
999 Run "grml-tips ssl-certificate" if you need further instructions.
1000 '
1001    }
1002   fi
1003 # }}}
1004
1005 # {{{ Use hard limits, except for a smaller stack and no core dumps
1006   unlimit
1007   limit stack 8192
1008   isgrmlcd && limit core 0 # important for a live-cd-system
1009   limit -s
1010 # }}}
1011
1012 # {{{ completion stuff
1013
1014 # called later (via is4 && grmlcomp)
1015 # notice: use 'zstyle' for getting current settings
1016 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
1017 grmlcomp() {
1018 ## completion system
1019   zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )' # allow one error for every three characters typed in approximate completer
1020   zstyle ':completion:*:complete:-command-::commands' ignored-patterns '*\~' # don't complete backup files as executables
1021   zstyle ':completion:*:correct:*'       insert-unambiguous true             # start menu completion only if it could find no unambiguous initial string
1022   zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}' #
1023   zstyle ':completion:*:correct:*'       original true                       #
1024   zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}      # activate color-completion(!)
1025   zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'  # format on completion
1026   zstyle ':completion:*:*:cd:*:directory-stack' menu yes select              # complete 'cd -<tab>' with menu
1027   zstyle ':completion:*:expand:*'        tag-order all-expansions            # insert all expansions for expand completer
1028   zstyle ':completion:*:history-words'   list false                          #
1029   zstyle ':completion:*:history-words'   menu yes                            # activate menu
1030   zstyle ':completion:*:history-words'   remove-all-dups yes                 # ignore duplicate entries
1031   zstyle ':completion:*:history-words'   stop yes                            #
1032   zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'        # match uppercase from lowercase
1033   zstyle ':completion:*:matches'         group 'yes'                         # separate matches into groups
1034   zstyle ':completion:*'                 group-name ''
1035   if [[ -z "$NOMENU" ]] ; then
1036     zstyle ':completion:*'               menu select=5                       # if there are more than 5 options allow selecting from a menu
1037   else
1038     setopt no_auto_menu # don't use any menus at all
1039   fi
1040   zstyle ':completion:*:messages'        format '%d'                         #
1041   zstyle ':completion:*:options'         auto-description '%d'               #
1042   zstyle ':completion:*:options'         description 'yes'                   # describe options in full
1043   zstyle ':completion:*:processes'       command 'ps -au$USER'               # on processes completion complete all user processes
1044   zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters        # offer indexes before parameters in subscripts
1045   zstyle ':completion:*'                 verbose true                        # provide verbose completion information
1046   zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' # set format for warnings
1047   zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'       # define files to ignore for zcompile
1048   zstyle ':completion:correct:'          prompt 'correct to: %e'             #
1049   zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'    # Ignore completion functions for commands you don't have:
1050
1051 # complete manual by their section
1052   zstyle ':completion:*:manuals'    separate-sections true
1053   zstyle ':completion:*:manuals.*'  insert-sections   true
1054   zstyle ':completion:*:man:*'      menu yes select
1055
1056 ## correction
1057 # run rehash on completion so new installed program are found automatically:
1058   _force_rehash() {
1059       (( CURRENT == 1 )) && rehash
1060          return 1 # Because we didn't really complete anything
1061     }
1062 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
1063   if [[ -n "$NOCOR" ]] ; then
1064     zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files
1065     setopt nocorrect # do not try to correct the spelling if possible
1066   else
1067 #    zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _correct _approximate _files
1068     setopt correct  # try to correct the spelling if possible
1069     zstyle -e ':completion:*' completer '
1070         if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]]; then
1071           _last_try="$HISTNO$BUFFER$CURSOR"
1072           reply=(_complete _match _prefix _files)
1073         else
1074           if [[ $words[1] = (rm|mv) ]]; then
1075             reply=(_complete _files)
1076           else
1077             reply=(_oldlist _expand _force_rehash _complete _correct _approximate _files)
1078           fi
1079         fi'
1080   fi
1081 # zstyle ':completion:*' completer _complete _correct _approximate
1082 # zstyle ':completion:*' expand prefix suffix
1083
1084 # automatic rehash? Credits go to Frank Terbeck
1085 # my_accept() {
1086 #   local buf
1087 #   [[ -z ${BUFFER} ]] && zle accept-line && return
1088 #   buf=( ${(z)BUFFER}  )
1089 #   [[ -z ${commands[${buf[1]}]} ]] && rehash
1090 #   zle accept-line
1091 # }
1092 # zle -N my_accept
1093 # bindkey "^M" my_accept
1094
1095 # command for process lists, the local web server details and host completion
1096   zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
1097
1098 # caching
1099   [ -d $ZSHDIR/cache ] && zstyle ':completion:*' use-cache yes && \
1100                           zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
1101
1102 # host completion /* add brackets as vim can't parse zsh's complex cmdlines 8-) {{{ */
1103   if is42 ; then
1104     [ -r ~/.ssh/known_hosts ] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
1105     [ -r /etc/hosts ] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
1106   else
1107     _ssh_hosts=()
1108     _etc_hosts=()
1109   fi
1110   hosts=(
1111       `hostname`
1112       "$_ssh_hosts[@]"
1113       "$_etc_hosts[@]"
1114       grml.org
1115       localhost
1116   )
1117   zstyle ':completion:*:hosts' hosts $hosts
1118 #  zstyle '*' hosts $hosts
1119
1120 # specify your logins:
1121 # my_accounts=(
1122 #  {grml,grml1}@foo.invalid
1123 #  grml-devel@bar.invalid
1124 # )
1125 # other_accounts=(
1126 #  {fred,root}@foo.invalid
1127 #  vera@bar.invalid
1128 # )
1129 # zstyle ':completion:*:my-accounts' users-hosts $my_accounts
1130 # zstyle ':completion:*:other-accounts' users-hosts $other_accounts
1131
1132 # specify specific port/service settings:
1133 #  telnet_users_hosts_ports=(
1134 #    user1@host1:
1135 #    user2@host2:
1136 #    @mail-server:{smtp,pop3}
1137 #    @news-server:nntp
1138 #    @proxy-server:8000
1139 #  )
1140 # zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
1141
1142 # use generic completion system for programs not yet defined:
1143   compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
1144
1145 # see upgrade function in this file
1146   compdef _hosts upgrade
1147 }
1148 # }}}
1149
1150 # {{{ grmlstuff
1151 grmlstuff() {
1152 # people should use 'grml-x'!
1153   startx() {
1154     if [ -e /etc/X11/xorg.conf ] ; then
1155        [ -x /usr/bin/startx ] && /usr/bin/startx "$@" || /usr/X11R6/bin/startx "$@"
1156     else
1157       echo "Please use the script \"grml-x\" for starting the X Window System
1158 because there does not exist /etc/X11/xorg.conf yet.
1159 If you want to use startx anyway please call \"/usr/bin/startx\"."
1160       return -1
1161     fi
1162   }
1163
1164   xinit() {
1165     if [ -e /etc/X11/xorg.conf ] ; then
1166        [ -x /usr/bin/xinit ] && /usr/bin/xinit || /usr/X11R6/bin/xinit
1167     else
1168       echo "Please use the script \"grml-x\" for starting the X Window System.
1169 because there does not exist /etc/X11/xorg.conf yet.
1170 If you want to use xinit anyway please call \"/usr/bin/xinit\"."
1171       return -1
1172     fi
1173   }
1174
1175   if [ -x $(which 915resolution) ] ; then
1176      alias 855resolution='echo -e "Please use 915resolution as resolution modify tool for Intel graphic chipset."; return -1'
1177   fi
1178
1179   #a1# Output version of running grml
1180   alias grml-version='cat /etc/grml_version'
1181
1182   if [ -x $(which rebuildfstab) ] ; then
1183      #a1# Rebuild /etc/fstab
1184      alias grml-rebuildfstab='rebuildfstab -v -r -config'
1185   fi
1186
1187   if [ -x $(which grml-debootstrap) ] ; then
1188      alias debian2hd='print "Installing debian to harddisk is possible via using grml-debootstrap." ; return 1'
1189   fi
1190 }
1191 # }}}
1192
1193 # {{{ now run the functions
1194   isgrml && checkhome
1195   is4    && isgrml    && grmlstuff
1196   is4    && grmlcomp
1197 # }}}
1198
1199 # {{{ keephack
1200   [ -r /etc/zsh/keephack ] && is4 && source /etc/zsh/keephack
1201 # }}}
1202
1203 # {{{ wonderful idea of using "e" glob qualifier by Peter Stephenson
1204 # You use it as follows:
1205 # $ NTREF=/reference/file
1206 # $ ls -l *(e:nt:)
1207 # This lists all the files in the current directory newer than the reference file.
1208 # You can also specify the reference file inline; note quotes:
1209 # $ ls -l *(e:'nt ~/.zshenv':)
1210   is4 && nt() {
1211     if [[ -n $1 ]]; then
1212       local NTREF=${~1}
1213     fi
1214     [[ $REPLY -nt $NTREF ]]
1215   }
1216 # }}}
1217
1218 # shell functions {{{
1219   #f1# Provide csh compatibility
1220   setenv()  { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }  # csh compatibility
1221   #f1# Reload an autoloadable function
1222   freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
1223   #f1# Reload zsh setup
1224   reload () {
1225    if [[ "$#*" -eq 0 ]]; then
1226       [ -r ~/.zshrc ] && . ~/.zshrc
1227    else
1228       local fn
1229       for fn in "$@"; do
1230           unfunction $fn
1231           autoload -U $fn
1232       done
1233    fi
1234   }
1235   compdef _functions reload freload
1236
1237   #f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
1238   sll() {
1239     [ -z "$1" ] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
1240     for i in "$@" ; do
1241       file=$i
1242       while [ -h "$file" ] ; do
1243         ls -l $file
1244         file=$(readlink "$file")
1245       done
1246     done
1247   }
1248
1249   # fast manual access
1250   if type -p qma &>/dev/null ; then
1251   #f1# View the zsh manual
1252      manzsh()  { qma zshall "$1" }
1253      compdef _man qma
1254   else
1255      manzsh()  { /usr/bin/man zshall |  vim -c "se ft=man| se hlsearch" +/"$1" - ; }
1256      # manzsh()  { /usr/bin/man zshall |  most +/"$1" ; }
1257      # [[ -f ~/.terminfo/m/mostlike ]] && MYLESS='LESS=C TERMINFO=~/.terminfo TERM=mostlike less' || MYLESS='less'
1258      # manzsh()  { man zshall | $MYLESS -p $1 ; }
1259   fi
1260
1261   if [ -x $(which most) ] ; then
1262   #f1# View Debian's changelog of a given package
1263     dchange() {
1264       if [ -r /usr/share/doc/${1}/changelog.Debian.gz ] ; then
1265          most /usr/share/doc/${1}/changelog.Debian.gz
1266       elif [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1267          most /usr/share/doc/${1}/changelog.gz
1268       else
1269          if type -p aptitude &>/dev/null ; then
1270             echo "No changelog for package $1 found, using aptitude to retrieve it."
1271             if isgrml ; then
1272               aptitude -t unstable changelog ${1}
1273             else
1274               aptitude changelog ${1}
1275             fi
1276          else
1277             echo "No changelog for package $1 found, sorry."
1278             return 1
1279          fi
1280       fi
1281     }
1282     _dchange() { _files -W /usr/share/doc -/ }
1283     compdef _dchange dchange
1284
1285   #f1# View Debian's NEWS of a given package
1286     dnews() {
1287       if [ -r /usr/share/doc/${1}/NEWS.Debian.gz ] ; then
1288          most /usr/share/doc/${1}/NEWS.Debian.gz
1289       else
1290          if [ -r /usr/share/doc/${1}/NEWS.gz ] ; then
1291             most /usr/share/doc/${1}/NEWS.gz
1292          else
1293             echo "No NEWS file for package $1 found, sorry."
1294             return 1
1295          fi
1296       fi
1297     }
1298     _dnews() { _files -W /usr/share/doc -/ }
1299     compdef _dnews dnews
1300
1301   #f1# View upstream's changelog of a given package
1302     uchange() {
1303       if [ -r /usr/share/doc/${1}/changelog.gz ] ; then
1304          most /usr/share/doc/${1}/changelog.gz
1305       else
1306          echo "No changelog for package $1 found, sorry."
1307          return 1
1308       fi
1309     }
1310     _uchange() { _files -W /usr/share/doc -/ }
1311     compdef _uchange uchange
1312   fi
1313
1314 # zsh profiling
1315   profile () {
1316       ZSH_PROFILE_RC=1 $SHELL "$@"
1317   }
1318
1319 #f1# Edit an alias via zle
1320   edalias() {
1321     [ -z "$1" ] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
1322   }
1323   compdef _aliases edalias
1324
1325 #f1# Edit a function via zle
1326   edfunc() {
1327     [ -z "$1" ] && { echo "Usage: edfun <function_to_edit>" ; return 1 } || zed -f "$1" ;
1328   }
1329   compdef _functions edfunc
1330
1331 # use it e.g. via 'Restart apache2'
1332 #m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
1333 #m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
1334 #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
1335 #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
1336 #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
1337  if [ -d /etc/init.d ] ; then
1338   for i in Start Restart Stop Force-Reload Reload ; do
1339     eval "$i() { $SUDO /etc/init.d/\$1 ${i:l} \$2 ; }"
1340   done
1341  fi
1342
1343   #f1# Provides useful information on globbing
1344   H-Glob() {
1345   echo -e "
1346       /      directories
1347       .      plain files
1348       @      symbolic links
1349       =      sockets
1350       p      named pipes (FIFOs)
1351       *      executable plain files (0100)
1352       %      device files (character or block special)
1353       %b     block special files
1354       %c     character special files
1355       r      owner-readable files (0400)
1356       w      owner-writable files (0200)
1357       x      owner-executable files (0100)
1358       A      group-readable files (0040)
1359       I      group-writable files (0020)
1360       E      group-executable files (0010)
1361       R      world-readable files (0004)
1362       W      world-writable files (0002)
1363       X      world-executable files (0001)
1364       s      setuid files (04000)
1365       S      setgid files (02000)
1366       t      files with the sticky bit (01000)
1367
1368    print *(m-1)          # Files modified up to a day ago
1369    print *(a1)           # Files accessed a day ago
1370    print *(@)            # Just symlinks
1371    print *(Lk+50)        # Files bigger than 50 kilobytes
1372    print *(Lk-50)        # Files smaller than 50 kilobytes
1373    print **/*.c          # All *.c files recursively starting in \$PWD
1374    print **/*.c~file.c   # Same as above, but excluding 'file.c'
1375    print (foo|bar).*     # Files starting with 'foo' or 'bar'
1376    print *~*.*           # All Files that do not contain a dot
1377    chmod 644 *(.^x)      # make all plain non-executable files publically readable
1378    print -l *(.c|.h)     # Lists *.c and *.h
1379    print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
1380    echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
1381   }
1382   alias help-zshglob=H-Glob
1383
1384   type -p qma &>/dev/null && alias ?='qma zshall'
1385
1386   # grep for running process, like: 'any vim'
1387   any() {
1388   if [ -z "$1" ] ; then
1389      echo "any - grep for process(es) by keyword" >&2
1390      echo "Usage: any <keyword>" >&2 ; return 1
1391   else
1392      local STRING=$1
1393      local LENGTH=$(expr length $STRING)
1394      local FIRSCHAR=$(echo $(expr substr $STRING 1 1))
1395      local REST=$(echo $(expr substr $STRING 2 $LENGTH))
1396      ps xauwww| grep "[$FIRSCHAR]$REST"
1397   fi
1398   }
1399
1400   # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
1401   # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
1402   [ -r /proc/1/maps ] && deswap() {
1403      print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
1404      cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
1405      print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
1406   }
1407
1408   # print hex value of a number
1409   hex() {
1410     [ -n "$1" ] && printf "%x\n" $1 || { print 'Usage: hex <number-to-convert>' ; return 1 }
1411   }
1412
1413   # calculate (or eval at all ;-)) with perl => p[erl-]eval
1414   # hint: also take a look at zcalc -> 'autoload zcalc' -> 'man zshmodules | less -p MATHFUNC'
1415   peval() {
1416     [ -n "$1" ] && CALC="$*" || print "Usage: calc [expression]"
1417     perl -e "print eval($CALC),\"\n\";"
1418   }
1419   functions peval &>/dev/null && alias calc=peval
1420
1421   # brltty seems to have problems with utf8 environment and/or font Uni3-Terminus16 under
1422   # certain circumstances, so work around it, no matter which environment we have
1423   brltty() {
1424     if [ -z "$DISPLAY" ] ; then
1425        consolechars -f /usr/share/consolefonts/default8x16.psf.gz
1426        command brltty "$@"
1427     else
1428        command brltty "$@"
1429     fi
1430   }
1431
1432   # just press 'asdf' keys to toggle between dvorak and us keyboard layout
1433   aoeu() {
1434      echo -n 'Switching to us keyboard layout: '
1435      [ -z "$DISPLAY" ] && $SUDO loadkeys us &>/dev/null || setxkbmap us &>/dev/null
1436      echo 'Done'
1437   }
1438   asdf() {
1439      echo -n 'Switching to dvorak keyboard layout: '
1440      [ -z "$DISPLAY" ] && $SUDO loadkeys dvorak &>/dev/null || setxkbmap dvorak &>/dev/null
1441      echo 'Done'
1442   }
1443   # just press 'asdf' key to toggle from neon layout to us keyboard layout
1444   uiae() {
1445      echo -n 'Switching to us keyboard layout: '
1446      setxkbmap us && echo 'Done' || echo 'Failed'
1447   }
1448
1449   # set up an ipv6 tunnel
1450   ipv6-tunnel() {
1451     case $1 in
1452       start)
1453        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1454           print 'ipv6 tunnel already set up, nothing to be done.'
1455           print 'execute: "ifconfig sit1 down ; ifconfig sit0 down" to remove ipv6-tunnel.' ; return 1
1456        else
1457           [ -n "$PUBLIC_IP" ] || local PUBLIC_IP=$(ifconfig $(route -n | awk '/^0\.0\.0\.0/{print $8; exit}') | \
1458                                              awk '/inet addr:/ {print $2}' | tr -d 'addr:')
1459           [ -n "$PUBLIC_IP" ] || { print 'No $PUBLIC_IP set and could not determine default one.' ; return 1 }
1460           local IPV6ADDR=$(printf "2002:%02x%02x:%02x%02x:1::1" $(print ${PUBLIC_IP//./ }))
1461           print -n "Setting up ipv6 tunnel $IPV6ADDR via ${PUBLIC_IP}: "
1462           ifconfig sit0 tunnel ::192.88.99.1 up
1463           ifconfig sit1 add "$IPV6ADDR" && print done || print failed
1464        fi
1465        ;;
1466       status)
1467        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1468           print 'ipv6 tunnel available' ; return 0
1469        else
1470           print 'ipv6 tunnel not available' ; return 1
1471        fi
1472        ;;
1473       stop)
1474        if ifconfig sit1 2>/dev/null | grep -q 'inet6 addr: 2002:.*:1::1' ; then
1475           print -n 'Stopping ipv6 tunnel (sit0 + sit1): '
1476           ifconfig sit1 down ; ifconfig sit0 down && print done || print failed
1477        else
1478           print 'No ipv6 tunnel found, nothing to be done.' ; return 1
1479        fi
1480        ;;
1481       *)
1482        print "Usage: ipv6-tunnel [start|stop|status]">&2 ; return 1
1483        ;;
1484     esac
1485   }
1486
1487   # run dhclient for wireless device
1488   iwclient() {
1489     salias dhclient "$(wavemon -d | awk '/device/{print $2}')"
1490   }
1491
1492   # spawn a minimally set up ksh - useful if you want to umount /usr/.
1493   minimal-shell() {
1494     exec env -i ENV="/etc/minimal-shellrc" HOME="$HOME" TERM="$TERM" ksh
1495   }
1496
1497   # Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
1498   # bash() {
1499   #  NO_SWITCH="yes" command bash "$@"
1500   # }
1501   # restart () {
1502   #  exec $SHELL $SHELL_ARGS "$@"
1503   # }
1504
1505 # }}}
1506
1507 # log out? set timeout in seconds {{{
1508 # TMOUT=1800
1509 # do not log out in some specific terminals:
1510 #  if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]]; then
1511 #    unset TMOUT
1512 #  fi
1513 # }}}
1514
1515 # {{{ make sure our environment is clean regarding colors
1516   for color in BLUE RED GREEN CYAN WHITE ; unset $color
1517 # }}}
1518
1519 # source another config file if present {{{
1520   if [ -r /etc/zsh/zshrc.local ]; then
1521    source /etc/zsh/zshrc.local
1522   fi
1523 # }}}
1524
1525 # "persistent history" {{{
1526 # just write important commands you always need to ~/.important_commands
1527   if [ -r ~/.important_commands ] ; then
1528      fc -R ~/.important_commands
1529   fi
1530 # }}}
1531
1532 ## genrefcard.pl settings {{{
1533 ### example: split functions-search 8,16,24,32
1534 #@# split functions-search 8
1535 ## }}}
1536
1537 # add variable to be able to check whether the file has been read {{{
1538   ZSHRC_GLOBAL_HAS_BEEN_READ=1
1539 # }}}
1540
1541 ## END OF FILE #################################################################
1542 # vim:foldmethod=marker expandtab