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