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