1e799c618930436229de9cc6c85bd9e5fc102c75
[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 is4(){
251     [[ $ZSH_VERSION == <4->* ]] && return 0
252     return 1
253 }
254
255 is41(){
256     [[ $ZSH_VERSION == 4.<1->* || $ZSH_VERSION == <5->* ]] && return 0
257     return 1
258 }
259
260 is42(){
261     [[ $ZSH_VERSION == 4.<2->* || $ZSH_VERSION == <5->* ]] && return 0
262     return 1
263 }
264
265 is43(){
266     [[ $ZSH_VERSION == 4.<3->* || $ZSH_VERSION == <5->* ]] && return 0
267     return 1
268 }
269
270 #f1# Checks whether or not you're running grml
271 isgrml(){
272     [[ -f /etc/grml_version ]] && return 0
273     return 1
274 }
275
276 #f1# Checks whether or not you're running a grml cd
277 isgrmlcd(){
278     [[ -f /etc/grml_cd ]] && return 0
279     return 1
280 }
281
282 if isgrml ; then
283 #f1# Checks whether or not you're running grml-small
284     isgrmlsmall() {
285         [[ ${${${(f)"$(</etc/grml_version)"}%% *}##*-} == 'small' ]] && return 0 ; return 1
286     }
287 else
288     isgrmlsmall() { return 1 }
289 fi
290
291 #f1# are we running within an utf environment?
292 isutfenv() {
293     case "$LANG $CHARSET $LANGUAGE" in
294         *utf*) return 0 ;;
295         *UTF*) return 0 ;;
296         *)     return 1 ;;
297     esac
298 }
299
300 # check for user, if not running as root set $SUDO to sudo
301 (( EUID != 0 )) && SUDO='sudo' || SUDO=''
302
303 # change directory to home on first invocation of zsh
304 # important for rungetty -> autologin
305 # Thanks go to Bart Schaefer!
306 isgrml && checkhome() {
307     if [[ -z "$ALREADY_DID_CD_HOME" ]] ; then
308         export ALREADY_DID_CD_HOME=$HOME
309         cd
310     fi
311 }
312 # }}}
313
314 # {{{ set some variables
315 if check_com -c vim ; then
316 #v#
317     export EDITOR=${EDITOR:-vim}
318 else
319     export EDITOR=${EDITOR:-vi}
320 fi
321
322 #v#
323 (( ${+PAGER} )) || export PAGER="less"
324
325 #v#
326 export MAIL=${MAIL:-/var/mail/$USER}
327
328 # if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/
329 export SHELL='/bin/zsh'
330
331 # color setup for ls:
332 check_com -c dircolors && eval $(dircolors -b)
333
334 # set width of man pages to 80 for more convenient reading
335 # (( ${+MANWIDTH} )) || export MANWIDTH=80
336
337 # Search path for the cd command
338 #  cdpath=(.. ~)
339
340 # completion functions go to /etc/zsh/completion.d
341 # function files may be put into /etc/zsh/functions.d, from where they
342 # will be automatically autoloaded.
343 if [[ -n "$BROKEN_COMPLETION_DIR" ]] ; then
344     print 'Warning: not setting completion directories because broken files have been found.' >&2
345 else
346     [[ -d /etc/zsh/completion.d ]] && fpath=( $fpath /etc/zsh/completion.d )
347     if [[ -d /etc/zsh/functions.d ]] ; then
348         fpath+=( /etc/zsh/functions.d )
349         for func in /etc/zsh/functions.d/[^_]*[^~] ; do
350             autoload -U ${func:t}
351         done
352     fi
353 fi
354
355 # automatically remove duplicates from these arrays
356 typeset -U path cdpath fpath manpath
357 # }}}
358
359 # {{{ keybindings
360 if [[ "$TERM" != emacs ]] ; then
361     [[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
362     [[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
363     [[ -z "$terminfo[kend]"  ]] || bindkey -M emacs "$terminfo[kend]"  end-of-line
364     [[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
365     [[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
366     [[ -z "$terminfo[kend]"  ]] || bindkey -M vicmd "$terminfo[kend]"  vi-end-of-line
367     [[ -z "$terminfo[cuu1]"  ]] || bindkey -M viins "$terminfo[cuu1]"  vi-up-line-or-history
368     [[ -z "$terminfo[cuf1]"  ]] || bindkey -M viins "$terminfo[cuf1]"  vi-forward-char
369     [[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
370     [[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
371     [[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
372     [[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char
373     # ncurses stuff:
374     [[ "$terminfo[kcuu1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history
375     [[ "$terminfo[kcud1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history
376     [[ "$terminfo[kcuf1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char
377     [[ "$terminfo[kcub1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char
378     [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line
379     [[ "$terminfo[kend]"  == $'\eO'* ]] && bindkey -M viins "${terminfo[kend]/O/[}"  end-of-line
380     [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line
381     [[ "$terminfo[kend]"  == $'\eO'* ]] && bindkey -M emacs "${terminfo[kend]/O/[}"  end-of-line
382 fi
383
384 ## keybindings (run 'bindkeys' for details, more details via man zshzle)
385 # use emacs style per default:
386 bindkey -e
387 # use vi style:
388 # bindkey -v
389
390 #if [[ "$TERM" == screen ]] ; then
391 bindkey '\e[1~' beginning-of-line       # home
392 bindkey '\e[4~' end-of-line             # end
393 bindkey '\e[A'  up-line-or-search       # cursor up
394 bindkey '\e[B'  down-line-or-search     # <ESC>-
395 bindkey '^x'    history-beginning-search-backward # alternative ways of searching the shell history
396 # bindkey -s '^L' "|less\n"             # ctrl-L pipes to less
397 # bindkey -s '^B' " &\n"                # ctrl-B runs it in the background
398 # if terminal type is set to 'rxvt':
399 bindkey '\e[7~' beginning-of-line       # home
400 bindkey '\e[8~' end-of-line             # end
401 #fi
402
403 # insert unicode character
404 # usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an Â§
405 # See for example http://unicode.org/charts/ for unicode characters code
406 autoload insert-unicode-char
407 zle -N insert-unicode-char
408 #k# Insert Unicode character
409 bindkey '^Xi' insert-unicode-char
410
411 # just type 'cd ...' to get 'cd ../..'
412 #  rationalise-dot() {
413 #  if [[ $LBUFFER == *.. ]] ; then
414 #    LBUFFER+=/..
415 #  else
416 #    LBUFFER+=.
417 #  fi
418 #  }
419 #  zle -N rationalise-dot
420 #  bindkey . rationalise-dot
421
422 #  bindkey '\eq' push-line-or-edit
423 # }}}
424
425 # a generic accept-line wrapper {{{
426
427 # This widget can prevent unwanted autocorrections from command-name
428 # to _command-name, rehash automatically on enter and call any number
429 # of builtin and user-defined widgets in different contexts.
430 #
431 # For a broader description, see:
432 # <http://bewatermyfriend.org/posts/2007/12-26.11-50-38-tooltime.html>
433 #
434 # The code is imported from the file 'zsh/functions/accept-line' from
435 # <http://ft.bewatermyfriend.org/comp/zsh/zsh-dotfiles.tar.bz2>, which
436 # distributed under the same terms as zsh itself.
437
438 # A newly added command will may not be found or will cause false
439 # correction attempts, if you got auto-correction set. By setting the
440 # following style, we force accept-line() to rehash, if it cannot
441 # find the first word on the command line in the $command[] hash.
442 zstyle ':acceptline:*' rehash true
443
444 function Accept-Line() {
445     setopt localoptions noksharrays
446     local -a subs
447     local -xi aldone
448     local sub
449
450     zstyle -a ":acceptline:${alcontext}" actions subs
451
452     (( ${#subs} < 1 )) && return 0
453
454     (( aldone = 0 ))
455     for sub in ${subs} ; do
456         [[ ${sub} == 'accept-line' ]] && sub='.accept-line'
457         zle ${sub}
458
459         (( aldone > 0 )) && break
460     done
461 }
462
463 function Accept-Line-getdefault() {
464     local default_action
465
466     zstyle -s ":acceptline:${alcontext}" default_action default_action
467     case ${default_action} in
468         ((accept-line|))
469             printf ".accept-line"
470             ;;
471         (*)
472             printf ${default_action}
473             ;;
474     esac
475 }
476
477 function accept-line() {
478     setopt localoptions noksharrays
479     local -a cmdline
480     local -x alcontext
481     local buf com fname format msg default_action
482
483     alcontext='default'
484     buf="${BUFFER}"
485     cmdline=(${(z)BUFFER})
486     com="${cmdline[1]}"
487     fname="_${com}"
488
489     zstyle -t ":acceptline:${alcontext}" rehash \
490         && [[ -z ${commands[$com]} ]]           \
491         && rehash
492
493     if    [[ -n ${reswords[(r)$com]} ]] \
494        || [[ -n ${aliases[$com]}     ]] \
495        || [[ -n ${functions[$com]}   ]] \
496        || [[ -n ${builtins[$com]}    ]] \
497        || [[ -n ${commands[$com]}    ]] ; then
498
499         # there is something sensible to execute, just do it.
500         alcontext='normal'
501         zle Accept-Line
502
503         default_action=$(Accept-Line-getdefault)
504         zstyle -T ":acceptline:${alcontext}" call_default \
505             && zle ${default_action}
506         return
507     fi
508
509     if    [[ -o correct              ]] \
510        || [[ -o correctall           ]] \
511        && [[ -n ${functions[$fname]} ]] ; then
512
513         # nothing there to execute but there is a function called
514         # _command_name; a completion widget. Makes no sense to
515         # call it on the commandline, but the correct{,all} options
516         # will ask for it nevertheless, so warn the user.
517         if [[ ${LASTWIDGET} == 'accept-line' ]] ; then
518             # Okay, we warned the user before, he called us again,
519             # so have it his way.
520             alcontext='force'
521             zle Accept-Line
522
523             default_action=$(Accept-Line-getdefault)
524             zstyle -T ":acceptline:${alcontext}" call_default \
525                 && zle ${default_action}
526             return
527         fi
528
529         # prepare warning message for the user, configurable via zstyle.
530         zstyle -s ":acceptline:${alcontext}" compwarnfmt msg
531
532         if [[ -z ${msg} ]] ; then
533             msg="%c will not execute and completion %f exists."
534         fi
535
536         zformat -f msg "${msg}" "c:${com}" "f:${fname}"
537
538         zle -M -- "${msg}"
539         return
540     elif [[ -n ${buf//[$' \t\n']##/} ]] ; then
541         # If we are here, the commandline contains something that is not
542         # executable, which is neither subject to _command_name correction
543         # and is not empty. might be a variable assignment
544         alcontext='misc'
545         zle Accept-Line
546
547         default_action=$(Accept-Line-getdefault)
548         zstyle -T ":acceptline:${alcontext}" call_default \
549             && zle ${default_action}
550         return
551     fi
552
553     # If we got this far, the commandline only contains whitespace, or is empty.
554     alcontext='empty'
555     zle Accept-Line
556
557     default_action=$(Accept-Line-getdefault)
558     zstyle -T ":acceptline:${alcontext}" call_default \
559         && zle ${default_action}
560 }
561
562 zle -N accept-line
563 zle -N Accept-Line
564
565 # }}}
566
567 # power completion - abbreviation expansion {{{
568 # power completion / abbreviation expansion / buffer expansion
569 # see http://zshwiki.org/home/examples/zleiab for details
570 # less risky than the global aliases but powerful as well
571 # just type the abbreviation key and afterwards ',.' to expand it
572 declare -A abk
573 setopt extendedglob
574 setopt interactivecomments
575 abk=(
576 # key  # value                (#d additional doc string)
577 #A# start
578     '...' '../..'
579     '....' '../../..'
580     'BG' '& exit'
581     'C' '| wc -l'
582     'G' '|& grep --color=auto'
583     'H' '| head'
584     'Hl' ' --help |& less -r'      #d (Display help in pager)
585     'L' '| less'
586     'LL' '|& less -r'
587     'M' '| most'
588     'N' '&>/dev/null'              #d (No Output)
589     'R' '| tr A-z N-za-m'          #d (ROT13)
590     'SL' '| sort | less'
591     'S' '| sort -u'
592     'T' '| tail'
593     'V' '|& vim -'
594 #A# end
595     'hide' "echo -en '\033]50;nil2\007'"
596     'tiny' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-80-*-*-c-*-iso8859-15\007"'
597     'small' 'echo -en "\033]50;6x10\007"'
598     'medium' 'echo -en "\033]50;-misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-15\007"'
599     'default' 'echo -e "\033]50;-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-15\007"'
600     'large' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-150-*-*-c-*-iso8859-15\007"'
601     'huge' 'echo -en "\033]50;-misc-fixed-medium-r-normal-*-*-210-*-*-c-*-iso8859-15\007"'
602     'smartfont' 'echo -en "\033]50;-artwiz-smoothansi-*-*-*-*-*-*-*-*-*-*-*-*\007"'
603     'semifont' 'echo -en "\033]50;-misc-fixed-medium-r-semicondensed-*-*-120-*-*-*-*-iso8859-15\007"'
604     'da' 'du -sch'
605     'j' 'jobs -l'
606     'u' 'translate -i'
607     'co' "./configure && make && sudo make install"
608     'CH' "./configure --help"
609     'conkeror' 'firefox -chrome chrome://conkeror/content'
610     'dir' 'ls -lSrah'
611     'lad' $'ls -d .*(/)\n# only show dot-directories'
612     'lsa' $'ls -a .*(.)\n# only show dot-files'
613     'lss' $'ls -l *(s,S,t)\n# only files with setgid/setuid/sticky flag'
614     'lsl' $'ls -l *(@[1,10])\n# only symlinks'
615     'lsx' $'ls -l *(*[1,10])\n# only executables'
616     'lsw' $'ls -ld *(R,W,X.^ND/)\n# world-{readable,writable,executable} files'
617     'lsbig' $'ls -flh *(.OL[1,10])\n# display the biggest files'
618     'lsd' $'ls -d *(/)\n# only show directories'
619     'lse' $'ls -d *(/^F)\n# only show empty directories'
620     'lsnew' $'ls -rl *(D.om[1,10])\n# display the newest files'
621     'lsold' $'ls -rtlh *(D.om[-11,-1])\n # display the oldest files'
622     'lssmall' $'ls -Srl *(.oL[1,10])\n# display the smallest files'
623     'rw-' 'chmod 600'
624     '600' 'chmod u+rw-x,g-rwx,o-rwx'
625     'rwx' 'chmod u+rwx'
626     '700' 'chmod u+rwx,g-rwx,o-rwx'
627     'r--' 'chmod u+r-wx,g-rwx,o-rwx'
628     '644' $'chmod u+rw-x,g+r-wx,o+r-wx\n # 4=r,2=w,1=x'
629     '755' 'chmod u+rwx,g+r-w+x,o+r-w+x'
630     'md' 'mkdir -p '
631     'cmplayer' 'mplayer -vo -fs -zoom fbdev'
632     'fbmplayer' 'mplayer -vo -fs -zoom fbdev'
633     'fblinks' 'links2 -driver fb'
634     'insecssh' 'ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
635     'insecscp' 'scp -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
636     'fori' 'for i ({..}) { }'
637     'cx' 'chmod +x'
638     'e'  'print -l'
639     'se' 'setopt interactivecomments'
640     'va' 'valac --vapidir=../vapi/ --pkg=gtk+-2.0 gtktest.vala'
641     'fb2' '=mplayer -vo fbdev -fs -zoom 1>/dev/null -xy 2'
642     'fb3' '=mplayer -vo fbdev -fs  -zoom 1>/dev/null -xy 3'
643     'ci' 'centericq'
644     'D'  'export DISPLAY=:0.0'
645     'mp' 'mplayer -vo xv -fs -zoom'
646 )
647
648 globalias() {
649     local MATCH
650     matched_chars='[.-|_a-zA-Z0-9]#'
651     LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
652     LBUFFER+=${abk[$MATCH]:-$MATCH}
653 }
654
655 zle -N globalias
656 bindkey ",." globalias
657 # }}}
658
659 # {{{ autoloading
660 autoload -U zmv    # who needs mmv or rename?
661 autoload history-search-end
662
663 # we don't want to quote/espace URLs on our own...
664 # if autoload -U url-quote-magic ; then
665 #    zle -N self-insert url-quote-magic
666 #    zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}='
667 # else
668 #    print 'Notice: no url-quote-magic available :('
669 # fi
670 alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic'
671
672 #m# k ESC-h Call \kbd{run-help} for the 1st word on the command line
673 alias run-help >&/dev/null && unalias run-help
674 autoload run-help # use via 'esc-h'
675
676 # completion system
677 if autoload -U compinit && compinit 2>/dev/null ; then
678     compinit 2>/dev/null || print 'Notice: no compinit available :('
679 else
680     print 'Notice: no compinit available :('
681     function zstyle { }
682     function compdef { }
683 fi
684
685 is4 && autoload -U zed # use ZLE editor to edit a file or function
686
687 is4 && \
688 for mod in complist deltochar mathfunc ; do
689     zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :("
690 done
691
692 # autoload zsh modules when they are referenced
693 if is4 ; then
694     tmpargs=(
695         a   stat
696         a   zpty
697         ap  zprof
698         ap  mapfile
699     )
700
701     while (( ${#tmpargs} > 0 )) ; do
702         zmodload -${tmpargs[1]} zsh/${tmpargs[2]} ${tmpargs[2]}
703         shift 2 tmpargs
704     done
705     unset tmpargs
706 fi
707
708 if is4 && autoload -U insert-files && zle -N insert-files ; then
709     #k# Insert files
710     bindkey "^Xf" insert-files # C-x-f
711 fi
712
713 bindkey ' '   magic-space    # also do history expansion on space
714 #k# Trigger menu-complete
715 bindkey '\ei' menu-complete  # menu completion via esc-i
716
717 # press esc-e for editing command line in $EDITOR or $VISUAL
718 if is4 && autoload -U edit-command-line && zle -N edit-command-line ; then
719     #k# Edit the current line in \kbd{\$EDITOR}
720     bindkey '\ee' edit-command-line
721 fi
722
723 if is4 && [[ -n ${(k)modules[zsh/complist]} ]] ; then
724     #k# menu selection: pick item but stay in the menu
725     bindkey -M menuselect '\e^M' accept-and-menu-complete
726
727     # use the vi navigation keys (hjkl) besides cursor keys in menu completion
728     #bindkey -M menuselect 'h' vi-backward-char        # left
729     #bindkey -M menuselect 'k' vi-up-line-or-history   # up
730     #bindkey -M menuselect 'l' vi-forward-char         # right
731     #bindkey -M menuselect 'j' vi-down-line-or-history # bottom
732
733     # accept a completion and try to complete again by using menu
734     # completion; very useful with completing directories
735     # by using 'undo' one's got a simple file browser
736     bindkey -M menuselect '^o' accept-and-infer-next-history
737 fi
738
739 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
740 _bkdate() { BUFFER="$BUFFER$(date '+%F')"; CURSOR=$#BUFFER; }
741 zle -N _bkdate
742
743 #k# Insert a timestamp on the command line (yyyy-mm-dd)
744 bindkey '^Ed' _bkdate
745
746 # press esc-m for inserting last typed word again (thanks to caphuso!)
747 insert-last-typed-word() { zle insert-last-word -- 0 -1 };
748 zle -N insert-last-typed-word;
749
750 #k# Insert last typed word
751 bindkey "\em" insert-last-typed-word
752
753 # set command prediction from history, see 'man 1 zshcontrib'
754 #  is4 && autoload -U predict-on && \
755 #  zle -N predict-on         && \
756 #  zle -N predict-off        && \
757 #  bindkey "^X^Z" predict-on && \
758 #  bindkey "^Z" predict-off
759
760 #k# Shortcut for \kbd{fg<enter>}
761 bindkey -s '^z' "fg\n"
762
763 # press ctrl-q to quote line:
764 #  mquote () {
765 #        zle beginning-of-line
766 #        zle forward-word
767 #        # RBUFFER="'$RBUFFER'"
768 #        RBUFFER=${(q)RBUFFER}
769 #        zle end-of-line
770 #  }
771 #  zle -N mquote && bindkey '^q' mquote
772
773 # run command line as user root via sudo:
774 sudo-command-line() {
775     [[ -z $BUFFER ]] && zle up-history
776     [[ $BUFFER != sudo\ * ]] && BUFFER="sudo $BUFFER"
777 }
778 zle -N sudo-command-line
779
780 #k# Put the current command line into a \kbd{sudo} call
781 bindkey "^Os" sudo-command-line
782
783 ### jump behind the first word on the cmdline.
784 ### useful to add options.
785 function jump_after_first_word() {
786     local words
787     words=(${(z)BUFFER})
788
789     if (( ${#words} <= 1 )) ; then
790         CURSOR=${#BUFFER}
791     else
792         CURSOR=${#${words[1]}}
793     fi
794 }
795 zle -N jump_after_first_word
796
797 bindkey '^x1' jump_after_first_word
798
799 # }}}
800
801 # {{{ set some important options
802 # Please update these tags, if you change the umask settings below.
803 #o# r_umask     002
804 #o# r_umaskstr  rwxrwxr-x
805 #o# umask       022
806 #o# umaskstr    rwxr-xr-x
807 (( EUID != 0 )) && umask 002 || umask 022
808
809 # history:
810 setopt append_history       # append history list to the history file (important for multiple parallel zsh sessions!)
811 is4 && setopt SHARE_HISTORY # import new commands from the history file also in other zsh-session
812 setopt extended_history     # save each command's beginning timestamp and the duration to the history file
813 is4 && setopt histignorealldups # If  a  new  command  line being added to the history
814                             # list duplicates an older one, the older command is removed from the list
815 setopt histignorespace      # remove command lines from the history list when
816                             # the first character on the line is a space
817 #  setopt histallowclobber    # add `|' to output redirections in the history
818 #  setopt NO_clobber          # warning if file exists ('cat /dev/null > ~/.zshrc')
819 setopt auto_cd              # if a command is issued that can't be executed as a normal command,
820                             # and the command is the name of a directory, perform the cd command to that directory
821 setopt extended_glob        # in order to use #, ~ and ^ for filename generation
822                             # grep word *~(*.gz|*.bz|*.bz2|*.zip|*.Z) ->
823                             # -> searches for word not in compressed files
824                             # don't forget to quote '^', '~' and '#'!
825 setopt notify               # report the status of backgrounds jobs immediately
826 setopt hash_list_all        # Whenever a command completion is attempted, make sure \
827                             # the entire command path is hashed first.
828 setopt completeinword       # not just at the end
829 # setopt nocheckjobs          # don't warn me about bg processes when exiting
830 setopt nohup                # and don't kill them, either
831 # setopt printexitvalue       # alert me if something failed
832 # setopt dvorak               # with spelling correction, assume dvorak kb
833 setopt auto_pushd           # make cd push the old directory onto the directory stack.
834 setopt nonomatch            # try to avoid the 'zsh: no matches found...'
835 setopt nobeep               # avoid "beep"ing
836 setopt pushd_ignore_dups    # don't push the same dir twice.
837
838 MAILCHECK=30       # mailchecks
839 REPORTTIME=5       # report about cpu-/system-/user-time of command if running longer than 5 seconds
840 watch=(notme root) # watch for everyone but me and root
841
842 # define word separators (for stuff like backward-word, forward-word, backward-kill-word,..)
843 #  WORDCHARS='*?_-.[]~=/&;!#$%^(){}<>' # the default
844 #  WORDCHARS=.
845 #  WORDCHARS='*?_[]~=&;!#$%^(){}'
846 #  WORDCHARS='${WORDCHARS:s@/@}'
847
848 # only slash should be considered as a word separator:
849 slash-backward-kill-word() {
850     local WORDCHARS="${WORDCHARS:s@/@}"
851     # zle backward-word
852     zle backward-kill-word
853 }
854 zle -N slash-backward-kill-word
855
856 #k# Kill everything in a word up to its last \kbd{/}
857 bindkey '\ev' slash-backward-kill-word
858
859 # }}}
860
861 # {{{ history
862
863 ZSHDIR=$HOME/.zsh
864
865 #v#
866 HISTFILE=$HOME/.zsh_history
867 isgrmlcd && HISTSIZE=500  || HISTSIZE=5000
868 isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
869
870 # }}}
871
872 # dirstack handling {{{
873
874 DIRSTACKSIZE=20
875 if [[ -f ~/.zdirs ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then
876     dirstack=( ${(f)"$(< ~/.zdirs)"} )
877     # "cd -" won't work after login by just setting $OLDPWD, so
878     [[ -d $dirstack[0] ]] && cd $dirstack[0] && cd $OLDPWD
879 fi
880
881 chpwd() {
882     builtin print -l ${(u)dirstack} >! ~/.zdirs
883 }
884
885 # }}}
886
887 # {{{ display battery status on right side of prompt via running 'BATTERY=1 zsh'
888 if [[ -n "$BATTERY" ]] ; then
889     if check_com -c acpi ; then
890         PERCENT="${(C)${(s| |)$(acpi 2>/dev/null)}[4]}"
891         [[ -z "$PERCENT" ]] && PERCENT='acpi not present'
892
893         if [[ "${PERCENT%%%}" -lt 20 ]] ; then
894             PERCENT="warning: ${PERCENT}%"
895         fi
896     fi
897 fi
898 # }}}
899
900 # display version control information on right side of prompt if $VCS is set {{{
901 # based on Mike Hommey's http://web.glandium.org/blog/?p=170
902 __vcs_dir() {
903     local vcs base_dir sub_dir ref
904
905     sub_dir() {
906       local sub_dir
907       sub_dir=$(readlink -f "${PWD}")
908       sub_dir=${sub_dir#$1}
909       echo ${sub_dir#/}
910     }
911
912     git_dir() {
913       base_dir=$(git-rev-parse --show-cdup 2>/dev/null) || return 1
914       base_dir=$(readlink -f "$base_dir/..")
915       sub_dir=$(git-rev-parse --show-prefix)
916       sub_dir=${sub_dir%/}
917       ref=$(git-symbolic-ref -q HEAD || git-name-rev --name-only HEAD 2>/dev/null)
918       ref=${ref#refs/heads/}
919       vcs="git"
920     }
921
922     svn_dir() {
923       [[ -d ".svn" ]] || return 1
924       base_dir="."
925       while [[ -d "$base_dir/../.svn" ]]; do base_dir="$base_dir/.."; done
926       base_dir=$(readlink -f "$base_dir")
927       sub_dir=$(sub_dir "${base_dir}")
928       ref=$(svn info "$base_dir" | awk '/^URL/ { sub(".*/","",$0); r=$0 } /^Revision/ { sub("[^0-9]*","",$0); print r":"$0 }')
929       vcs="svn"
930     }
931
932     svk_dir() {
933         [[ -f ~/.svk/config ]] || return 1
934         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
935         ref=${base_dir##*
936   }
937         base_dir=${base_dir%%
938   *}
939         sub_dir=$(sub_dir "${base_dir}")
940         vcs="svk"
941     }
942
943     hg_dir() {
944         base_dir="."
945         while [[ ! -d "$base_dir/.hg" ]]; do
946             base_dir="$base_dir/.."
947             [[ $(readlink -f "${base_dir}") = "/" ]] && return 1
948         done
949         base_dir=$(readlink -f "$base_dir")
950         sub_dir=$(sub_dir "${base_dir}")
951         ref=$(< "${base_dir}/.hg/branch")
952         vcs="hg"
953     }
954
955     hg_dir  ||
956     git_dir ||
957     svn_dir ||
958     svk_dir # ||
959   #  base_dir="$PWD"
960   #  echo "${vcs:+($vcs)}${base_dir/$HOME/~}${vcs:+[$ref]${sub_dir}}"
961     echo "${vcs:+($vcs)}${base_dir}${vcs:+[$ref]${sub_dir}}"
962 }
963 # }}}
964
965 # {{{ set prompt
966 if autoload promptinit && promptinit 2>/dev/null ; then
967     promptinit # people should be able to use their favourite prompt
968 else
969     print 'Notice: no promptinit available :('
970 fi
971
972
973 # precmd() => a function which is executed just before each prompt
974 # use 'NOPRECMD=1' to disable the precmd + preexec commands
975
976 # precmd () { setopt promptsubst; [[ -o interactive ]] && jobs -l;
977
978 # make sure to use right prompt only when not running a command
979 is41 && setopt transient_rprompt
980
981 is4 && [[ -z $NOPRECMD ]] && precmd () {
982     [[ -n $NOPRECMD ]] && return 0
983     # allow manual overwriting of RPROMPT
984     if [[ -n $RPROMPT ]] ; then
985         [[ $TERM == screen* ]] && echo -n $'\ekzsh\e\\'
986         # return 0
987     fi
988     # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
989     if [[ -z $DONTSETRPROMPT ]] ; then
990         if [[ -n $BATTERY ]] ; then
991             RPROMPT="%(?..:()% ${PERCENT}${SCREENTITLE}"
992             # RPROMPT="${PERCENT}${SCREENTITLE}"
993         elif [[ -n $VCS ]] ; then
994             RPROMPT="%(?..:()% $(__vcs_dir)${SCREENTITLE}"
995         else
996             RPROMPT="%(?..:()% ${SCREENTITLE}"
997             # RPROMPT="${SCREENTITLE}"
998         fi
999     fi
1000     # adjust title of xterm
1001     # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
1002     case $TERM in
1003         (xterm*|rxvt)
1004             print -Pn "\e]0;%n@%m: %~\a"
1005             ;;
1006     esac
1007 }
1008
1009 # chpwd () => a function which is executed whenever the directory is changed
1010
1011 # preexec() => a function running before every command
1012 is4 && [[ -z $NOPRECMD ]] && \
1013 preexec () {
1014     [[ -n $NOPRECMD ]] && return 0
1015 # set hostname if not running on host with name 'grml'
1016     if [[ -n "$HOSTNAME" ]] && [[ "$HOSTNAME" != $(hostname) ]] ; then
1017        NAME="@$HOSTNAME"
1018     fi
1019 # get the name of the program currently running and hostname of local machine
1020 # set screen window title if running in a screen
1021     if [[ "$TERM" == screen* ]] ; then
1022         # local CMD=${1[(wr)^(*=*|sudo|ssh|-*)]}       # don't use hostname
1023         local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME" # use hostname
1024         echo -ne "\ek$CMD\e\\"
1025     fi
1026 # set the screen title to "zsh" when sitting at the command prompt:
1027     if [[ "$TERM" == screen* ]] ; then
1028         SCREENTITLE=$'%{\ekzsh\e\\%}'
1029     else
1030         SCREENTITLE=''
1031     fi
1032 # adjust title of xterm
1033     case $TERM in
1034         (xterm*|rxvt)
1035             print -Pn "\e]0;%n@%m: $1\a"
1036             ;;
1037     esac
1038 }
1039
1040 # set colors
1041 if autoload colors && colors 2>/dev/null ; then
1042     BLUE="%{${fg[blue]}%}"
1043     RED="%{${fg_bold[red]}%}"
1044     GREEN="%{${fg[green]}%}"
1045     CYAN="%{${fg[cyan]}%}"
1046     WHITE="%{${fg[white]}%}"
1047     NO_COLOUR="%{${reset_color}%}"
1048 else
1049     BLUE=$'%{\e[1;34m%}'
1050     RED=$'%{\e[1;31m%}'
1051     GREEN=$'%{\e[1;32m%}'
1052     CYAN=$'%{\e[1;36m%}'
1053     WHITE=$'%{\e[1;37m%}'
1054     NO_COLOUR=$'%{\e[0m%}'
1055 fi
1056
1057 EXITCODE="%(?..%?%1v )"
1058 PS2='`%_> '       # secondary prompt, printed when the shell needs more information to complete a command.
1059 PS3='?# '         # selection prompt used within a select loop.
1060 PS4='+%N:%i:%_> ' # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
1061
1062 # set variable debian_chroot if running in a chroot with /etc/debian_chroot
1063 if [[ -z "$debian_chroot" ]] && [[ -r /etc/debian_chroot ]] ; then
1064     debian_chroot=$(cat /etc/debian_chroot)
1065 fi
1066
1067 # don't use colors on dumb terminals (like emacs):
1068 if [[ "$TERM" == dumb ]] ; then
1069     PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< %# "
1070 else
1071     # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended prompt
1072     # set variable identifying the chroot you work in (used in the prompt below)
1073     if [[ -n $GRMLPROMPT ]] ; then
1074         PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
1075 ${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# "
1076     else
1077         if (( EUID != 0 )); then
1078             PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
1079         else
1080             PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string
1081         fi
1082     fi
1083 fi
1084
1085 # if we are inside a grml-chroot set a specific prompt theme
1086 if [[ -n "$GRML_CHROOT" ]] ; then
1087     PROMPT="%{$fg[red]%}(CHROOT) %{$fg_bold[red]%}%n%{$fg_no_bold[white]%}@%m %40<...<%B%~%b%<< %\# "
1088 fi
1089 # }}}
1090
1091 # {{{ 'hash' some often used directories
1092 #d# start
1093 hash -d deb=/var/cache/apt/archives
1094 hash -d doc=/usr/share/doc
1095 hash -d linux=/lib/modules/$(command uname -r)/build/
1096 hash -d log=/var/log
1097 hash -d slog=/var/log/syslog
1098 hash -d src=/usr/src
1099 hash -d templ=/usr/share/doc/grml-templates
1100 hash -d tt=/usr/share/doc/texttools-doc
1101 hash -d www=/var/www
1102 #d# end
1103 # }}}
1104
1105 # {{{ some aliases
1106 if [[ $UID -eq 0 ]] ; then
1107     [[ -r /etc/grml/screenrc ]] && alias screen='/usr/bin/screen -c /etc/grml/screenrc'
1108 elif [[ -r $HOME/.screenrc ]] ; then
1109     alias screen="/usr/bin/screen -c $HOME/.screenrc"
1110 else
1111     [[ -r /etc/grml/screenrc_grml ]] && alias screen='/usr/bin/screen -c /etc/grml/screenrc_grml'
1112 fi
1113
1114 # do we have GNU ls with color-support?
1115 if ls --help 2>/dev/null | grep -- --color= >/dev/null && [[ "$TERM" != dumb ]] ; then
1116     #a1# execute \kbd{@a@}:\quad ls with colors
1117     alias ls='ls -b -CF --color=auto'
1118     #a1# execute \kbd{@a@}:\quad list all files, with colors
1119     alias la='ls -la --color=auto'
1120     #a1# long colored list, without dotfiles (@a@)
1121     alias ll='ls -l --color=auto'
1122     #a1# long colored list, human readable sizes (@a@)
1123     alias lh='ls -hAl --color=auto'
1124     #a1# List files, append qualifier to filenames \\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
1125     alias l='ls -lF --color=auto'
1126 else
1127     alias ls='ls -b -CF'
1128     alias la='ls -la'
1129     alias ll='ls -l'
1130     alias lh='ls -hAl'
1131     alias l='ls -lF'
1132 fi
1133
1134 alias mdstat='cat /proc/mdstat'
1135 alias ...='cd ../../'
1136
1137 # generate alias named "$KERNELVERSION-reboot" so you can use boot with kexec:
1138 if [[ -x /sbin/kexec ]] && [[ -r /proc/cmdline ]] ; then
1139     alias "$(uname -r)-reboot"="kexec -l --initrd=/boot/initrd.img-"$(uname -r)" --command-line=\"$(cat /proc/cmdline)\" /boot/vmlinuz-"$(uname -r)""
1140 fi
1141
1142 alias cp='nocorrect cp'         # no spelling correction on cp
1143 alias mkdir='nocorrect mkdir'   # no spelling correction on mkdir
1144 alias mv='nocorrect mv'         # no spelling correction on mv
1145 alias rm='nocorrect rm'         # no spelling correction on rm
1146
1147 #a1# Execute \kbd{rmdir}
1148 alias rd='rmdir'
1149 #a1# Execute \kbd{rmdir}
1150 alias md='mkdir'
1151
1152 # see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
1153 alias term2iso="echo 'Setting terminal to iso mode' ; print -n '\e%@'"
1154 alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
1155
1156 # make sure it is not assigned yet
1157 [[ $(whence -w utf2iso &>/dev/null) == 'utf2iso: alias' ]] && unalias utf2iso
1158
1159 utf2iso() {
1160     if isutfenv ; then
1161         for ENV in $(env | command grep -i '.utf') ; do
1162             eval export "$(echo $ENV | sed 's/UTF-8/iso885915/ ; s/utf8/iso885915/')"
1163         done
1164     fi
1165 }
1166
1167 # make sure it is not assigned yet
1168 [[ $(whence -w iso2utf &>/dev/null) == 'iso2utf: alias' ]] && unalias iso2utf
1169 iso2utf() {
1170     if ! isutfenv ; then
1171         for ENV in $(env | command grep -i '\.iso') ; do
1172             eval export "$(echo $ENV | sed 's/iso.*/UTF-8/ ; s/ISO.*/UTF-8/')"
1173         done
1174     fi
1175 }
1176
1177 # set up software synthesizer via speakup
1178 swspeak() {
1179     aumix -w 90 -v 90 -p 90 -m 90
1180     if ! [[ -r /dev/softsynth ]] ; then
1181         flite -o play -t "Sorry, software synthesizer not available. Did you boot with swspeak bootoption?"
1182         return 1
1183     else
1184         setopt singlelinezle
1185         unsetopt prompt_cr
1186         export PS1="%m%# "
1187         nice -n -20 speechd-up
1188         sleep 2
1189         flite -o play -t "Finished setting up software synthesizer"
1190     fi
1191 }
1192
1193 # I like clean prompt, so provide simple way to get that
1194 check_com 0 || alias 0='return 0'
1195
1196 # for really lazy people like mika:
1197 check_com S &>/dev/null || alias S='screen'
1198 check_com s &>/dev/null || alias s='ssh'
1199
1200 # get top 10 shell commands:
1201 alias top10='print -l ? ${(o)history%% *} | uniq -c | sort -nr | head -n 10'
1202
1203 # truecrypt; use e.g. via 'truec /dev/ice /mnt/ice' or 'truec -i'
1204 if check_com -c truecrypt ; then
1205     if isutfenv ; then
1206         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077,utf8" '
1207     else
1208         alias truec='truecrypt --mount-options "rw,sync,dirsync,users,uid=1000,gid=users,umask=077" '
1209     fi
1210 fi
1211
1212 #f1# Hints for the use of zsh on grml
1213 zsh-help() {
1214     print "$bg[white]$fg[black]
1215 zsh-help - hints for use of zsh on grml
1216 =======================================$reset_color"
1217
1218     print '
1219 Main configuration of zsh happens in /etc/zsh/zshrc (global)
1220 and /etc/skel/.zshrc which is copied to $HOME/.zshrc once.
1221 The files are part of the package grml-etc-core, if you want to
1222 use them on a non-grml-system just get the tar.gz from
1223 http://deb.grml.org/ or get the files from the mercurial
1224 repository:
1225
1226   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
1227   http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
1228
1229 If you want to stay in sync with zsh configuration of grml
1230 run '\''ln -sf /etc/skel/.zshrc $HOME/.zshrc'\'' and configure
1231 your own stuff in $HOME/.zshrc.local. System wide configuration
1232 without touching configuration files of grml can take place
1233 in /etc/zsh/zshrc.local.
1234
1235 If you want to use the configuration of user grml also when
1236 running as user root just run '\''zshskel'\'' which will source
1237 the file /etc/skel/.zshrc.
1238
1239 For information regarding zsh start at http://grml.org/zsh/
1240
1241 Take a look at grml'\''s zsh refcard:
1242 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
1243
1244 Check out the main zsh refcard:
1245 % '$BROWSER' http://www.bash2zsh.com/zsh_refcard/refcard.pdf
1246
1247 And of course visit the zsh-lovers:
1248 % man zsh-lovers
1249
1250 You can adjust some options through environment variables when
1251 invoking zsh without having to edit configuration files.
1252 Basically meant for bash users who are not used to the power of
1253 the zsh yet. :)
1254
1255   "NOCOR=1    zsh" => deactivate automatic correction
1256   "NOMENU=1   zsh" => do not use menu completion (note: use strg-d for completion instead!)
1257   "NOPRECMD=1 zsh" => disable the precmd + preexec commands (set GNU screen title)
1258   "BATTERY=1  zsh" => activate battery status (via acpi) on right side of prompt'
1259
1260     print "
1261 $bg[white]$fg[black]
1262 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
1263 Enjoy your grml system with the zsh!$reset_color"
1264 }
1265
1266 # debian stuff
1267 if [[ -r /etc/debian_version ]] ; then
1268     #a3# Execute \kbd{apt-cache search}
1269     alias acs='apt-cache search'
1270     #a3# Execute \kbd{apt-cache show}
1271     alias acsh='apt-cache show'
1272     #a3# Execute \kbd{apt-cache policy}
1273     alias acp='apt-cache policy'
1274     #a3# Execute \kbd{apt-get dist-upgrade}
1275     salias adg="apt-get dist-upgrade"
1276     #a3# Execute \kbd{apt-get install}
1277     salias agi="apt-get install"
1278     #a3# Execute \kbd{aptitude install}
1279     salias ati="aptitude install"
1280     #a3# Execute \kbd{apt-get upgrade}
1281     salias ag="apt-get upgrade"
1282     #a3# Execute \kbd{apt-get update}
1283     salias au="apt-get update"
1284     #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
1285     salias -a up="aptitude update ; aptitude safe-upgrade"
1286     #a3# Execute \kbd{dpkg-buildpackage}
1287     alias dbp='dpkg-buildpackage'
1288     #a3# Execute \kbd{grep-excuses}
1289     alias ge='grep-excuses'
1290
1291     # debian upgrade
1292     #f3# Execute \kbd{apt-get update \&\& }\\&\quad \kbd{apt-get dist-upgrade}
1293     upgrade() {
1294         if [[ -z "$1" ]] ; then
1295             $SUDO apt-get update
1296             $SUDO apt-get -u upgrade
1297         else
1298             ssh $1 $SUDO apt-get update
1299             # ask before the upgrade
1300             local dummy
1301             ssh $1 $SUDO apt-get --no-act upgrade
1302             echo -n 'Process the upgrade?'
1303             read -q dummy
1304             if [[ $dummy == "y" ]] ; then
1305                 ssh $1 $SUDO apt-get -u upgrade --yes
1306             fi
1307         fi
1308     }
1309
1310     isgrmlcd && alias su="sudo -s"          # get a root shell
1311     #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
1312     alias llog="$PAGER /var/log/syslog"     # take a look at the syslog
1313     #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
1314     alias tlog="tail -f /var/log/syslog"    # follow the syslog
1315     #a1# (Re)-source \kbd{/etc/skel/.zshrc}
1316     alias zshskel="source /etc/skel/.zshrc" # source skeleton zshrc
1317 fi
1318
1319 # sort installed Debian-packages by size
1320 if check_com -c grep-status ; then
1321     #a3# List installed Debian-packages sorted by size
1322     alias debs-by-size='grep-status -FStatus -sInstalled-Size,Package -n "install ok installed" | paste -sd "  \n" | sort -rn'
1323 fi
1324
1325 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
1326 if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord ; then
1327     if check_com -c wodim ; then
1328         alias cdrecord="echo 'cdrecord is not provided under its original name by Debian anymore.
1329 See #377109 in the BTS of Debian for more details.
1330
1331 Please use the wodim binary instead' ; return 1"
1332     fi
1333 fi
1334
1335 # get_tw_cli has been renamed into get_3ware
1336 if check_com -c get_3ware ; then
1337     get_tw_cli() {
1338         echo 'Warning: get_tw_cli has been renamed into get_3ware. Invoking get_3ware for you.'>&2
1339         get_3ware
1340     }
1341 fi
1342
1343 # I hate lacking backward compatibility, so provide an alternative therefore
1344 if ! check_com -c apache2-ssl-certificate ; then
1345
1346     apache2-ssl-certificate() {
1347
1348     print 'Debian does not ship apache2-ssl-certificate anymore (see #398520). :('
1349     print 'You might want to take a look at Debian the package ssl-cert as well.'
1350     print 'To generate a certificate for use with apache2 follow the instructions:'
1351
1352     echo '
1353
1354 export RANDFILE=/dev/random
1355 mkdir /etc/apache2/ssl/
1356 openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
1357 chmod 600 /etc/apache2/ssl/apache.pem
1358
1359 Run "grml-tips ssl-certificate" if you need further instructions.
1360 '
1361     }
1362 fi
1363 # }}}
1364
1365 # {{{ Use hard limits, except for a smaller stack and no core dumps
1366 unlimit
1367 is4 && limit stack 8192
1368 isgrmlcd && limit core 0 # important for a live-cd-system
1369 limit -s
1370 # }}}
1371
1372 # {{{ completion system
1373
1374 # called later (via is4 && grmlcomp)
1375 # notice: use 'zstyle' for getting current settings
1376 #         press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
1377 grmlcomp() {
1378     # TODO: This could use some additional information
1379
1380     # allow one error for every three characters typed in approximate completer
1381     zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )'
1382
1383     # don't complete backup files as executables
1384     zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)'
1385
1386     # start menu completion only if it could find no unambiguous initial string
1387     zstyle ':completion:*:correct:*'       insert-unambiguous true
1388     zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}'
1389     zstyle ':completion:*:correct:*'       original true
1390
1391     # activate color-completion
1392     zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}
1393
1394     # format on completion
1395     zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'
1396
1397     # complete 'cd -<tab>' with menu
1398     zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
1399
1400     # insert all expansions for expand completer
1401     zstyle ':completion:*:expand:*'        tag-order all-expansions
1402     zstyle ':completion:*:history-words'   list false
1403
1404     # activate menu
1405     zstyle ':completion:*:history-words'   menu yes
1406
1407     # ignore duplicate entries
1408     zstyle ':completion:*:history-words'   remove-all-dups yes
1409     zstyle ':completion:*:history-words'   stop yes
1410
1411     # match uppercase from lowercase
1412     zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'
1413
1414     # separate matches into groups
1415     zstyle ':completion:*:matches'         group 'yes'
1416     zstyle ':completion:*'                 group-name ''
1417
1418     if [[ -z "$NOMENU" ]] ; then
1419         # if there are more than 5 options allow selecting from a menu
1420         zstyle ':completion:*'               menu select=5
1421     else
1422         # don't use any menus at all
1423         setopt no_auto_menu
1424     fi
1425
1426     zstyle ':completion:*:messages'        format '%d'
1427     zstyle ':completion:*:options'         auto-description '%d'
1428
1429     # describe options in full
1430     zstyle ':completion:*:options'         description 'yes'
1431
1432     # on processes completion complete all user processes
1433     zstyle ':completion:*:processes'       command 'ps -au$USER'
1434
1435     # offer indexes before parameters in subscripts
1436     zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
1437
1438     # provide verbose completion information
1439     zstyle ':completion:*'                 verbose true
1440
1441     # recent (as of Dec 2007) zsh versions are able to provide descriptions
1442     # for commands (read: 1st word in the line) that it will list for the user
1443     # to choose from. The following disables that, because it's not exactly fast.
1444     zstyle ':completion:*:-command-:*:'    verbose false
1445
1446     # set format for warnings
1447     zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d'
1448
1449     # define files to ignore for zcompile
1450     zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'
1451     zstyle ':completion:correct:'          prompt 'correct to: %e'
1452
1453     # Ignore completion functions for commands you don't have:
1454     zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'
1455
1456     # complete manual by their section
1457     zstyle ':completion:*:manuals'    separate-sections true
1458     zstyle ':completion:*:manuals.*'  insert-sections   true
1459     zstyle ':completion:*:man:*'      menu yes select
1460
1461     # run rehash on completion so new installed program are found automatically:
1462     _force_rehash() {
1463         (( CURRENT == 1 )) && rehash
1464         return 1
1465     }
1466
1467     ## correction
1468     # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
1469     if [[ -n "$NOCOR" ]] ; then
1470         zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
1471         setopt nocorrect
1472     else
1473         # try to be smart about when to use what completer...
1474         setopt correct
1475         zstyle -e ':completion:*' completer '
1476             if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then
1477                 _last_try="$HISTNO$BUFFER$CURSOR"
1478                 reply=(_complete _match _ignored _prefix _files)
1479             else
1480                 if [[ $words[1] == (rm|mv) ]] ; then
1481                     reply=(_complete _files)
1482                 else
1483                     reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files)
1484                 fi
1485             fi'
1486     fi
1487
1488     # zstyle ':completion:*' completer _complete _correct _approximate
1489     # zstyle ':completion:*' expand prefix suffix
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 $PAGER ; 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             $PAGER /usr/share/doc/${1}/changelog.Debian.gz
1666         elif [[ -r /usr/share/doc/${1}/changelog.gz ]] ; then
1667             $PAGER /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             $PAGER /usr/share/doc/${1}/NEWS.Debian.gz
1689         else
1690             if [[ -r /usr/share/doc/${1}/NEWS.gz ]] ; then
1691                 $PAGER /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             $PAGER /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