1 # Filename: /etc/zsh/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 ################################################################################
7 # This file is sourced only for interactive shells. It
8 # should contain commands to set up aliases, functions,
9 # options, key bindings, etc.
11 # Global Order: zshenv, zprofile, zshrc, zlogin
12 ################################################################################
15 # If you are using this file as your ~/.zshrc file, please use ~/.zshrc.pre
16 # and ~/.zshrc.local for your own customisations. The former file is read
17 # before ~/.zshrc, the latter is read after it. Also, consider reading the
18 # refcard and the reference manual for this setup, both available from:
19 # <http://grml.org/zsh/>
22 # If you want to help to improve grml's zsh setup, clone the grml-etc-core
23 # repository from git.grml.org:
24 # git clone git://git.grml.org/grml-etc-core.git
26 # Make your changes, commit them; use 'git format-patch' to create a series
27 # of patches and send those to the following address via 'git send-email':
28 # grml-etc-core@grml.org
30 # Doing so makes sure the right people get your patches for review and
33 # zsh-refcard-tag documentation:
34 # You may notice strange looking comments in this file.
35 # These are there for a purpose. grml's zsh-refcard can now be
36 # automatically generated from the contents of the actual configuration
37 # file. However, we need a little extra information on which comments
38 # and what lines of code to take into account (and for what purpose).
40 # Here is what they mean:
42 # List of tags (comment types) used:
43 # #a# Next line contains an important alias, that should
44 # be included in the grml-zsh-refcard.
45 # (placement tag: @@INSERT-aliases@@)
46 # #f# Next line contains the beginning of an important function.
47 # (placement tag: @@INSERT-functions@@)
48 # #v# Next line contains an important variable.
49 # (placement tag: @@INSERT-variables@@)
50 # #k# Next line contains an important keybinding.
51 # (placement tag: @@INSERT-keybindings@@)
52 # #d# Hashed directories list generation:
53 # start denotes the start of a list of 'hash -d'
55 # end denotes its end.
56 # (placement tag: @@INSERT-hasheddirs@@)
57 # #A# Abbreviation expansion list generation:
58 # start denotes the beginning of abbreviations.
59 # end denotes their end.
60 # Lines within this section that end in '#d .*' provide
61 # extra documentation to be included in the refcard.
62 # (placement tag: @@INSERT-abbrev@@)
63 # #m# This tag allows you to manually generate refcard entries
64 # for code lines that are hard/impossible to parse.
66 # #m# k ESC-h Call the run-help function
67 # That would add a refcard entry in the keybindings table
68 # for 'ESC-h' with the given comment.
69 # So the syntax is: #m# <section> <argument> <comment>
70 # #o# This tag lets you insert entries to the 'other' hash.
71 # Generally, this should not be used. It is there for
72 # things that cannot be done easily in another way.
73 # (placement tag: @@INSERT-other-foobar@@)
75 # All of these tags (except for m and o) take two arguments, the first
76 # within the tag, the other after the tag:
78 # #<tag><section># <comment>
80 # Where <section> is really just a number, which are defined by the
81 # @secmap array on top of 'genrefcard.pl'. The reason for numbers
82 # instead of names is, that for the reader, the tag should not differ
83 # much from a regular comment. For zsh, it is a regular comment indeed.
84 # The numbers have got the following meanings:
93 # So, the following will add an entry to the 'functions' table in the
94 # 'system' section, with a (hopefully) descriptive comment:
95 # #f1# Edit an alias via zle
98 # It will then show up in the @@INSERT-aliases-system@@ replacement tag
99 # that can be found in 'grml-zsh-refcard.tex.in'.
100 # If the section number is omitted, the 'default' section is assumed.
101 # Furthermore, in 'grml-zsh-refcard.tex.in' @@INSERT-aliases@@ is
102 # exactly the same as @@INSERT-aliases-default@@. If you want a list of
103 # *all* aliases, for example, use @@INSERT-aliases-all@@.
106 # just execute 'ZSH_PROFILE_RC=1 zsh' and run 'zprof' to get the details
107 if [[ $ZSH_PROFILE_RC -gt 0 ]] ; then
111 # load .zshrc.pre to give the user the chance to overwrite the defaults
112 [[ -r ${HOME}/.zshrc.pre ]] && source ${HOME}/.zshrc.pre
114 # check for version/system
115 # check for versions (compatibility reasons)
117 [[ $ZSH_VERSION == <4->* ]] && return 0
122 [[ $ZSH_VERSION == 4.<1->* || $ZSH_VERSION == <5->* ]] && return 0
127 [[ $ZSH_VERSION == 4.<2->* || $ZSH_VERSION == <5->* ]] && return 0
132 [[ $ZSH_VERSION == 4.2.<5->* || $ZSH_VERSION == 4.<3->* || $ZSH_VERSION == <5->* ]] && return 0
137 [[ $ZSH_VERSION == 4.<3->* || $ZSH_VERSION == <5->* ]] && return 0
142 [[ $ZSH_VERSION == 4.3.<3->* || $ZSH_VERSION == 4.<4->* \
143 || $ZSH_VERSION == <5->* ]] && return 0
148 [[ $ZSH_VERSION == 4.3.<9->* || $ZSH_VERSION == 4.<4->* \
149 || $ZSH_VERSION == <5->* ]] && return 0
153 #f1# Checks whether or not you're running grml
155 [[ -f /etc/grml_version ]] && return 0
159 #f1# Checks whether or not you're running a grml cd
161 [[ -f /etc/grml_cd ]] && return 0
166 #f1# Checks whether or not you're running grml-small
168 if [[ ${${${(f)"$(</etc/grml_version)"}%% *}##*-} == 'small' ]]; then
174 isgrmlsmall() { return 1 }
178 [[ $OSTYPE == darwin* ]] && return 0
182 #f1# are we running within an utf environment?
184 case "$LANG $CHARSET $LANGUAGE" in
191 # check for user, if not running as root set $SUDO to sudo
192 (( EUID != 0 )) && SUDO='sudo' || SUDO=''
194 # change directory to home on first invocation of zsh
195 # important for rungetty -> autologin
196 # Thanks go to Bart Schaefer!
197 isgrml && checkhome() {
198 if [[ -z "$ALREADY_DID_CD_HOME" ]] ; then
199 export ALREADY_DID_CD_HOME=$HOME
204 # check for zsh v3.1.7+
206 if ! [[ ${ZSH_VERSION} == 3.1.<7->* \
207 || ${ZSH_VERSION} == 3.<2->.<->* \
208 || ${ZSH_VERSION} == <4->.<->* ]] ; then
211 printf '-!- In this configuration we try to make use of features, that only\n'
212 printf '-!- require version 3.1.7 of the shell; That way this setup can be\n'
213 printf '-!- used with a wide range of zsh versions, while using fairly\n'
214 printf '-!- advanced features in all supported versions.\n'
216 printf '-!- However, you are running zsh version %s.\n' "$ZSH_VERSION"
218 printf '-!- While this *may* work, it might as well fail.\n'
219 printf '-!- Please consider updating to at least version 3.1.7 of zsh.\n'
221 printf '-!- DO NOT EXPECT THIS TO WORK FLAWLESSLY!\n'
222 printf '-!- If it does today, you'\''ve been lucky.\n'
224 printf '-!- Ye been warned!\n'
227 function zstyle() { : }
230 # autoload wrapper - use this one instead of autoload directly
231 # We need to define this function as early as this, because autoloading
232 # 'is-at-least()' needs it.
233 function zrcautoload() {
241 for fdir in ${fpath} ; do
242 [[ -e ${fdir}/${ffile} ]] && (( ffound = 1 ))
245 (( ffound == 0 )) && return 1
246 if [[ $ZSH_VERSION == 3.1.<6-> || $ZSH_VERSION == <4->* ]] ; then
247 autoload -U ${ffile} || return 1
249 autoload ${ffile} || return 1
254 # Load is-at-least() for more precise version checks Note that this test will
255 # *always* fail, if the is-at-least function could not be marked for
257 zrcautoload is-at-least || is-at-least() { return 1 }
259 # set some important options (as early as possible)
261 # append history list to the history file; this is the default but we make sure
262 # because it's required for share_history.
263 setopt append_history
265 # import new commands from the history file also in other zsh-session
266 is4 && setopt share_history
268 # save each command's beginning timestamp and the duration to the history file
269 setopt extended_history
271 # If a new command line being added to the history list duplicates an older
272 # one, the older command is removed from the list
273 is4 && setopt histignorealldups
275 # remove command lines from the history list when the first character on the
277 setopt histignorespace
279 # if a command is issued that can't be executed as a normal command, and the
280 # command is the name of a directory, perform the cd command to that directory.
283 # in order to use #, ~ and ^ for filename generation grep word
284 # *~(*.gz|*.bz|*.bz2|*.zip|*.Z) -> searches for word not in compressed files
285 # don't forget to quote '^', '~' and '#'!
288 # display PID when suspending processes as well
291 # try to avoid the 'zsh: no matches found...'
294 # report the status of backgrounds jobs immediately
297 # whenever a command completion is attempted, make sure the entire command path
301 # not just at the end
302 setopt completeinword
304 # Don't send SIGHUP to background processes when the shell exits.
307 # make cd push the old directory onto the directory stack.
313 # don't push the same dir twice.
314 setopt pushd_ignore_dups
316 # * shouldn't match dotfiles. ever.
319 # use zsh style word splitting
322 # don't error out when unset parameters are used
325 # setting some default values
328 NOPRECMD=${NOPRECMD:-0}
329 COMMAND_NOT_FOUND=${COMMAND_NOT_FOUND:-0}
330 GRML_ZSH_CNF_HANDLER=${GRML_ZSH_CNF_HANDLER:-/usr/share/command-not-found/command-not-found}
331 BATTERY=${BATTERY:-0}
332 GRMLSMALL_SPECIFIC=${GRMLSMALL_SPECIFIC:-1}
333 ZSH_NO_DEFAULT_LOCALE=${ZSH_NO_DEFAULT_LOCALE:-0}
336 # this function checks if a command exists and returns either true
337 # or false. This avoids using 'which' and 'whence', which will
338 # avoid problems with aliases for which on certain weird systems. :-)
339 # Usage: check_com [-c|-g] word
340 # -c only checks for external commands
341 # -g does the usual tests and also checks for global aliases
344 local -i comonly gatoo
346 if [[ $1 == '-c' ]] ; then
349 elif [[ $1 == '-g' ]] ; then
356 if (( ${#argv} != 1 )) ; then
357 printf 'usage: check_com [-c] <command>\n' >&2
361 if (( comonly > 0 )) ; then
362 [[ -n ${commands[$1]} ]] && return 0
366 if [[ -n ${commands[$1]} ]] \
367 || [[ -n ${functions[$1]} ]] \
368 || [[ -n ${aliases[$1]} ]] \
369 || [[ -n ${reswords[(r)$1]} ]] ; then
374 if (( gatoo > 0 )) && [[ -n ${galiases[$1]} ]] ; then
381 # creates an alias and precedes the command with
382 # sudo if $EUID is not zero.
385 local only=0 ; local multi=0
386 while [[ $1 == -* ]] ; do
390 (--) shift ; break ;;
392 printf 'usage: salias [-h|-o|-a] <alias-expression>\n'
393 printf ' -h shows this help text.\n'
394 printf ' -a replace '\'' ; '\'' sequences with '\'' ; sudo '\''.\n'
395 printf ' be careful using this option.\n'
396 printf ' -o only sets an alias if a preceding sudo would be needed.\n'
399 (*) printf "unkown option: '%s'\n" "$1" ; return 1 ;;
404 if (( ${#argv} > 1 )) ; then
405 printf 'Too many arguments %s\n' "${#argv}"
409 key="${1%%\=*}" ; val="${1#*\=}"
410 if (( EUID == 0 )) && (( only == 0 )); then
411 alias -- "${key}=${val}"
412 elif (( EUID > 0 )) ; then
413 (( multi > 0 )) && val="${val// ; / ; sudo }"
414 alias -- "${key}=sudo ${val}"
420 # a "print -l ${(u)foo}"-workaround for pre-4.2.0 shells
422 # Where foo is the *name* of the parameter you want printed.
423 # Note that foo is no typo; $foo would be wrong here!
431 if [[ -z ${parameter} ]] ; then
432 printf 'usage: uprint <parameter>\n'
436 for w in ${(P)parameter} ; do
437 [[ -z ${(M)u:#$w} ]] && u=( $u $w )
444 # Check if we can read given files and source those we can.
446 if (( ${#argv} < 1 )) ; then
447 printf 'usage: xsource FILE(s)...\n' >&2
451 while (( ${#argv} > 0 )) ; do
452 [[ -r "$1" ]] && source "$1"
458 # Check if we can read a given file and 'cat(1)' it.
461 if (( ${#argv} != 1 )) ; then
462 printf 'usage: xcat FILE\n' >&2
466 [[ -r $1 ]] && cat $1
470 # Remove these functions again, they are of use only in these
471 # setup files. This should be called at the end of .zshrc.
475 funcs=(salias xcat xsource xunfunction zrcautoload)
477 for func in $funcs ; do
478 [[ -n ${functions[$func]} ]] \
484 # this allows us to stay in sync with grml's zshrc and put own
485 # modifications in ~/.zshrc.local
487 xsource "/etc/zsh/zshrc.local"
488 xsource "${HOME}/.zshrc.local"
493 if (( ZSH_NO_DEFAULT_LOCALE == 0 )); then
494 xsource "/etc/default/locale"
497 for var in LANG LC_ALL LC_MESSAGES ; do
498 [[ -n ${(P)var} ]] && export $var
501 xsource "/etc/sysconfig/keyboard"
503 TZ=$(xcat /etc/timezone)
506 if check_com -c vim ; then
508 export EDITOR=${EDITOR:-vim}
510 export EDITOR=${EDITOR:-vi}
514 export PAGER=${PAGER:-less}
517 export MAIL=${MAIL:-/var/mail/$USER}
519 # if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/
520 export SHELL='/bin/zsh'
522 # color setup for ls:
523 check_com -c dircolors && eval $(dircolors -b)
524 # color setup for ls on OS X:
525 isdarwin && export CLICOLOR=1
527 # do MacPorts setup on darwin
528 if isdarwin && [[ -d /opt/local ]]; then
529 # Note: PATH gets set in /etc/zprofile on Darwin, so this can't go into
531 PATH="/opt/local/bin:/opt/local/sbin:$PATH"
532 MANPATH="/opt/local/share/man:$MANPATH"
534 # do Fink setup on darwin
535 isdarwin && xsource /sw/bin/init.sh
537 # load our function and completion directories
538 for fdir in /usr/share/grml/zsh/completion /usr/share/grml/zsh/functions; do
539 fpath=( ${fdir} ${fdir}/**/*(/N) ${fpath} )
540 if [[ ${fpath} == '/usr/share/grml/zsh/functions' ]] ; then
541 for func in ${fdir}/**/[^_]*[^~](N.) ; do
542 zrcautoload ${func:t}
548 # support colors in less
549 export LESS_TERMCAP_mb=$'\E[01;31m'
550 export LESS_TERMCAP_md=$'\E[01;31m'
551 export LESS_TERMCAP_me=$'\E[0m'
552 export LESS_TERMCAP_se=$'\E[0m'
553 export LESS_TERMCAP_so=$'\E[01;44;33m'
554 export LESS_TERMCAP_ue=$'\E[0m'
555 export LESS_TERMCAP_us=$'\E[01;32m'
560 # report about cpu-/system-/user-time of command if running longer than
564 # watch for everyone but me and root
567 # automatically remove duplicates from these arrays
568 typeset -U path cdpath fpath manpath
571 if [[ "$TERM" != emacs ]] ; then
572 [[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
573 [[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
574 [[ -z "$terminfo[kend]" ]] || bindkey -M emacs "$terminfo[kend]" end-of-line
575 [[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
576 [[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
577 [[ -z "$terminfo[kend]" ]] || bindkey -M vicmd "$terminfo[kend]" vi-end-of-line
578 [[ -z "$terminfo[cuu1]" ]] || bindkey -M viins "$terminfo[cuu1]" vi-up-line-or-history
579 [[ -z "$terminfo[cuf1]" ]] || bindkey -M viins "$terminfo[cuf1]" vi-forward-char
580 [[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
581 [[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
582 [[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
583 [[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char
585 [[ "$terminfo[kcuu1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history
586 [[ "$terminfo[kcud1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history
587 [[ "$terminfo[kcuf1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char
588 [[ "$terminfo[kcub1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char
589 [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line
590 [[ "$terminfo[kend]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kend]/O/[}" end-of-line
591 [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line
592 [[ "$terminfo[kend]" == $'\eO'* ]] && bindkey -M emacs "${terminfo[kend]/O/[}" end-of-line
595 ## keybindings (run 'bindkeys' for details, more details via man zshzle)
596 # use emacs style per default:
601 ## beginning-of-line OR beginning-of-buffer OR beginning of history
602 ## by: Bart Schaefer <schaefer@brasslantern.com>, Bernhard Tittelbach
603 beginning-or-end-of-somewhere() {
605 if [[ ( "${LBUFFER[-1]}" == $'\n' && "${WIDGET}" == beginning-of* ) || \
606 ( "${RBUFFER[1]}" == $'\n' && "${WIDGET}" == end-of* ) ]]; then
607 zle .${WIDGET:s/somewhere/buffer-or-history/} "$@"
609 zle .${WIDGET:s/somewhere/line-hist/} "$@"
610 if (( HISTNO != hno )); then
611 zle .${WIDGET:s/somewhere/buffer-or-history/} "$@"
615 zle -N beginning-of-somewhere beginning-or-end-of-somewhere
616 zle -N end-of-somewhere beginning-or-end-of-somewhere
619 #if [[ "$TERM" == screen ]] ; then
621 ## with HOME/END, move to beginning/end of line (on multiline) on first keypress
622 ## to beginning/end of buffer on second keypress
623 ## and to beginning/end of history on (at most) the third keypress
624 # terminator & non-debian xterm
625 bindkey '\eOH' beginning-of-somewhere # home
626 bindkey '\eOF' end-of-somewhere # end
628 bindkey '\e[H' beginning-of-somewhere # home
629 bindkey '\e[F' end-of-somewhere # end
630 # xterm,gnome-terminal,quake,etc
631 bindkey '^[[1~' beginning-of-somewhere # home
632 bindkey '^[[4~' end-of-somewhere # end
633 # if terminal type is set to 'rxvt':
634 bindkey '\e[7~' beginning-of-somewhere # home
635 bindkey '\e[8~' end-of-somewhere # end
638 bindkey '\e[A' up-line-or-search # cursor up
639 bindkey '\e[B' down-line-or-search # <ESC>-
641 ## use Ctrl-left-arrow and Ctrl-right-arrow for jumping to word-beginnings on the CL
642 bindkey "\e[5C" forward-word
643 bindkey "\e[5D" backward-word
644 bindkey "\e[1;5C" forward-word
645 bindkey "\e[1;5D" backward-word
646 ## the same for alt-left-arrow and alt-right-arrow
647 bindkey '^[[1;3C' forward-word
648 bindkey '^[[1;3D' backward-word
650 # Search backward in the history for a line beginning with the current
651 # line up to the cursor and move the cursor to the end of the line then
652 zle -N history-beginning-search-backward-end history-search-end
653 zle -N history-beginning-search-forward-end history-search-end
654 #k# search history backward for entry beginning with typed text
655 bindkey '^xp' history-beginning-search-backward-end
656 #k# search history forward for entry beginning with typed text
657 bindkey '^xP' history-beginning-search-forward-end
658 #k# search history backward for entry beginning with typed text
659 bindkey "\e[5~" history-beginning-search-backward-end # PageUp
660 #k# search history forward for entry beginning with typed text
661 bindkey "\e[6~" history-beginning-search-forward-end # PageDown
663 # bindkey -s '^l' "|less\n" # ctrl-L pipes to less
664 # bindkey -s '^b' " &\n" # ctrl-B runs it in the background
666 # insert unicode character
667 # usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an §
668 # See for example http://unicode.org/charts/ for unicode characters code
669 zrcautoload insert-unicode-char
670 zle -N insert-unicode-char
671 #k# Insert Unicode character
672 bindkey '^xi' insert-unicode-char
674 #m# k Shift-tab Perform backwards menu completion
675 if [[ -n "$terminfo[kcbt]" ]]; then
676 bindkey "$terminfo[kcbt]" reverse-menu-complete
677 elif [[ -n "$terminfo[cbt]" ]]; then # required for GNU screen
678 bindkey "$terminfo[cbt]" reverse-menu-complete
681 ## toggle the ,. abbreviation feature on/off
682 # NOABBREVIATION: default abbreviation-state
683 # 0 - enabled (default)
685 NOABBREVIATION=${NOABBREVIATION:-0}
687 grml_toggle_abbrev() {
688 if (( ${NOABBREVIATION} > 0 )) ; then
695 #k# Toggle abbreviation expansion on/off
696 zle -N grml_toggle_abbrev
697 bindkey '^xA' grml_toggle_abbrev
699 # add a command line to the shells history without executing it
700 commit-to-history() {
701 print -s ${(z)BUFFER}
704 zle -N commit-to-history
705 bindkey "^x^h" commit-to-history
707 # only slash should be considered as a word separator:
708 slash-backward-kill-word() {
709 local WORDCHARS="${WORDCHARS:s@/@}"
711 zle backward-kill-word
713 zle -N slash-backward-kill-word
715 #k# Kill left-side word or everything up to next slash
716 bindkey '\ev' slash-backward-kill-word
717 #k# Kill left-side word or everything up to next slash
718 bindkey '\e^h' slash-backward-kill-word
719 #k# Kill left-side word or everything up to next slash
720 bindkey '\e^?' slash-backward-kill-word
722 # use the new *-pattern-* widgets for incremental history search
724 bindkey '^r' history-incremental-pattern-search-backward
725 bindkey '^s' history-incremental-pattern-search-forward
728 # a generic accept-line wrapper
730 # This widget can prevent unwanted autocorrections from command-name
731 # to _command-name, rehash automatically on enter and call any number
732 # of builtin and user-defined widgets in different contexts.
734 # For a broader description, see:
735 # <http://bewatermyfriend.org/posts/2007/12-26.11-50-38-tooltime.html>
737 # The code is imported from the file 'zsh/functions/accept-line' from
738 # <http://ft.bewatermyfriend.org/comp/zsh/zsh-dotfiles.tar.bz2>, which
739 # distributed under the same terms as zsh itself.
741 # A newly added command will may not be found or will cause false
742 # correction attempts, if you got auto-correction set. By setting the
743 # following style, we force accept-line() to rehash, if it cannot
744 # find the first word on the command line in the $command[] hash.
745 zstyle ':acceptline:*' rehash true
747 function Accept-Line() {
748 setopt localoptions noksharrays
752 local alcontext=${1:-$alcontext}
754 zstyle -a ":acceptline:${alcontext}" actions subs
756 (( ${#subs} < 1 )) && return 0
759 for sub in ${subs} ; do
760 [[ ${sub} == 'accept-line' ]] && sub='.accept-line'
763 (( aldone > 0 )) && break
767 function Accept-Line-getdefault() {
771 zstyle -s ":acceptline:${alcontext}" default_action default_action
772 case ${default_action} in
774 printf ".accept-line"
777 printf ${default_action}
782 function Accept-Line-HandleContext() {
785 default_action=$(Accept-Line-getdefault)
786 zstyle -T ":acceptline:${alcontext}" call_default \
787 && zle ${default_action}
790 function accept-line() {
791 setopt localoptions noksharrays
794 local buf com fname format msg default_action
798 cmdline=(${(z)BUFFER})
802 Accept-Line 'preprocess'
804 zstyle -t ":acceptline:${alcontext}" rehash \
805 && [[ -z ${commands[$com]} ]] \
809 && [[ -n ${reswords[(r)$com]} ]] \
810 || [[ -n ${aliases[$com]} ]] \
811 || [[ -n ${functions[$com]} ]] \
812 || [[ -n ${builtins[$com]} ]] \
813 || [[ -n ${commands[$com]} ]] ; then
815 # there is something sensible to execute, just do it.
817 Accept-Line-HandleContext
822 if [[ -o correct ]] \
823 || [[ -o correctall ]] \
824 && [[ -n ${functions[$fname]} ]] ; then
826 # nothing there to execute but there is a function called
827 # _command_name; a completion widget. Makes no sense to
828 # call it on the commandline, but the correct{,all} options
829 # will ask for it nevertheless, so warn the user.
830 if [[ ${LASTWIDGET} == 'accept-line' ]] ; then
831 # Okay, we warned the user before, he called us again,
832 # so have it his way.
834 Accept-Line-HandleContext
839 if zstyle -t ":acceptline:${alcontext}" nocompwarn ; then
841 Accept-Line-HandleContext
843 # prepare warning message for the user, configurable via zstyle.
844 zstyle -s ":acceptline:${alcontext}" compwarnfmt msg
846 if [[ -z ${msg} ]] ; then
847 msg="%c will not execute and completion %f exists."
850 zformat -f msg "${msg}" "c:${com}" "f:${fname}"
855 elif [[ -n ${buf//[$' \t\n']##/} ]] ; then
856 # If we are here, the commandline contains something that is not
857 # executable, which is neither subject to _command_name correction
858 # and is not empty. might be a variable assignment
860 Accept-Line-HandleContext
865 # If we got this far, the commandline only contains whitespace, or is empty.
867 Accept-Line-HandleContext
872 zle -N Accept-Line-HandleContext
874 # power completion - abbreviation expansion
875 # power completion / abbreviation expansion / buffer expansion
876 # see http://zshwiki.org/home/examples/zleiab for details
877 # less risky than the global aliases but powerful as well
878 # just type the abbreviation key and afterwards ',.' to expand it
881 setopt interactivecomments
883 # key # value (#d additional doc string)
889 'G' '|& grep --color=auto '
891 'Hl' ' --help |& less -r' #d (Display help in pager)
895 'N' '&>/dev/null' #d (No Output)
896 'R' '| tr A-z N-za-m' #d (ROT13)
902 'co' './configure && make && sudo make install'
910 if (( NOABBREVIATION > 0 )) ; then
911 LBUFFER="${LBUFFER},."
915 matched_chars='[.-|_a-zA-Z0-9]#'
916 LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
917 LBUFFER+=${abk[$MATCH]:-$MATCH}
920 zle -N zleiab && bindkey ",." zleiab
922 #f# display contents of assoc array $abk
925 zle -M "$(print "Type ,. after these abbreviations to expand them:"; print -a -C 2 ${(kv)abk})"
927 #k# Display list of abbreviations that expand when followed by ,.
928 zle -N help-show-abk && bindkey '^xb' help-show-abk
931 zrcautoload zmv # who needs mmv or rename?
932 zrcautoload history-search-end
934 # we don't want to quote/espace URLs on our own...
935 # if autoload -U url-quote-magic ; then
936 # zle -N self-insert url-quote-magic
937 # zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}='
939 # print 'Notice: no url-quote-magic available :('
941 alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic'
943 #m# k ESC-h Call \kbd{run-help} for the 1st word on the command line
944 alias run-help >&/dev/null && unalias run-help
945 for rh in run-help{,-git,-svk,-svn}; do
950 if zrcautoload compinit ; then
951 compinit || print 'Notice: no compinit available :('
953 print 'Notice: no compinit available :('
958 is4 && zrcautoload zed # use ZLE editor to edit a file or function
961 for mod in complist deltochar mathfunc ; do
962 zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :("
965 # autoload zsh modules when they are referenced
967 zmodload -a zsh/stat zstat
968 zmodload -a zsh/zpty zpty
969 zmodload -ap zsh/mapfile mapfile
972 if is4 && zrcautoload insert-files && zle -N insert-files ; then
973 #k# Insert files and test globbing
974 bindkey "^xf" insert-files # C-x-f
977 bindkey ' ' magic-space # also do history expansion on space
978 #k# Trigger menu-complete
979 bindkey '\ei' menu-complete # menu completion via esc-i
981 # press esc-e for editing command line in $EDITOR or $VISUAL
982 if is4 && zrcautoload edit-command-line && zle -N edit-command-line ; then
983 #k# Edit the current line in \kbd{\$EDITOR}
984 bindkey '\ee' edit-command-line
987 if is4 && [[ -n ${(k)modules[zsh/complist]} ]] ; then
988 #k# menu selection: pick item but stay in the menu
989 bindkey -M menuselect '\e^M' accept-and-menu-complete
990 # also use + and INSERT since it's easier to press repeatedly
991 bindkey -M menuselect "+" accept-and-menu-complete
992 bindkey -M menuselect "^[[2~" accept-and-menu-complete
994 # accept a completion and try to complete again by using menu
995 # completion; very useful with completing directories
996 # by using 'undo' one's got a simple file browser
997 bindkey -M menuselect '^o' accept-and-infer-next-history
1000 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
1001 insert-datestamp() { LBUFFER+=${(%):-'%D{%Y-%m-%d}'}; }
1002 zle -N insert-datestamp
1004 #k# Insert a timestamp on the command line (yyyy-mm-dd)
1005 bindkey '^ed' insert-datestamp
1007 # press esc-m for inserting last typed word again (thanks to caphuso!)
1008 insert-last-typed-word() { zle insert-last-word -- 0 -1 };
1009 zle -N insert-last-typed-word;
1011 #k# Insert last typed word
1012 bindkey "\em" insert-last-typed-word
1014 function grml-zsh-fg() {
1015 if (( ${#jobstates} )); then
1017 [[ -o hist_ignore_space ]] && BUFFER=' ' || BUFFER=''
1018 BUFFER="${BUFFER}fg"
1021 zle -M 'No background jobs. Doing nothing.'
1025 #k# A smart shortcut for \kbd{fg<enter>}
1026 bindkey '^z' grml-zsh-fg
1028 # run command line as user root via sudo:
1029 sudo-command-line() {
1030 [[ -z $BUFFER ]] && zle up-history
1031 if [[ $BUFFER != sudo\ * ]]; then
1032 BUFFER="sudo $BUFFER"
1033 CURSOR=$(( CURSOR+5 ))
1036 zle -N sudo-command-line
1038 #k# prepend the current command with "sudo"
1039 bindkey "^os" sudo-command-line
1041 ### jump behind the first word on the cmdline.
1042 ### useful to add options.
1043 function jump_after_first_word() {
1045 words=(${(z)BUFFER})
1047 if (( ${#words} <= 1 )) ; then
1050 CURSOR=${#${words[1]}}
1053 zle -N jump_after_first_word
1054 #k# jump to after first word (for adding options)
1055 bindkey '^x1' jump_after_first_word
1057 # complete word from history with menu (from Book: ZSH, OpenSource-Press)
1058 zle -C hist-complete complete-word _generic
1059 zstyle ':completion:hist-complete:*' completer _history
1060 #k# complete word from history with menu
1061 bindkey "^x^x" hist-complete
1063 ## complete word from currently visible Screen or Tmux buffer.
1064 if check_com -c screen || check_com -c tmux; then
1065 _complete_screen_display() {
1066 [[ "$TERM" != "screen" ]] && return 1
1068 local TMPFILE=$(mktemp)
1069 local -U -a _screen_display_wordlist
1070 trap "rm -f $TMPFILE" EXIT
1072 # fill array with contents from screen hardcopy
1073 if ((${+TMUX})); then
1074 #works, but crashes tmux below version 1.4
1075 #luckily tmux -V option to ask for version, was also added in 1.4
1076 tmux -V &>/dev/null || return
1077 tmux -q capture-pane \; save-buffer -b 0 $TMPFILE \; delete-buffer -b 0
1079 screen -X hardcopy $TMPFILE
1080 # screen sucks, it dumps in latin1, apparently always. so recode it
1082 check_com recode && recode latin1 $TMPFILE
1084 _screen_display_wordlist=( ${(QQ)$(<$TMPFILE)} )
1085 # remove PREFIX to be completed from that array
1086 _screen_display_wordlist[${_screen_display_wordlist[(i)$PREFIX]}]=""
1087 compadd -a _screen_display_wordlist
1089 #k# complete word from currently visible GNU screen buffer
1091 compdef -k _complete_screen_display complete-word '^xS'
1099 HISTFILE=$HOME/.zsh_history
1100 isgrmlcd && HISTSIZE=500 || HISTSIZE=5000
1101 isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
1105 DIRSTACKSIZE=${DIRSTACKSIZE:-20}
1106 DIRSTACKFILE=${DIRSTACKFILE:-${HOME}/.zdirs}
1108 if [[ -f ${DIRSTACKFILE} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then
1109 dirstack=( ${(f)"$(< $DIRSTACKFILE)"} )
1110 # "cd -" won't work after login by just setting $OLDPWD, so
1111 [[ -d $dirstack[1] ]] && cd $dirstack[1] && cd $OLDPWD
1116 my_stack=( ${PWD} ${dirstack} )
1118 builtin print -l ${(u)my_stack} >! ${DIRSTACKFILE}
1120 uprint my_stack >! ${DIRSTACKFILE}
1124 # directory based profiles
1128 CHPWD_PROFILE='default'
1129 function chpwd_profiles() {
1130 # Say you want certain settings to be active in certain directories.
1131 # This is what you want.
1133 # zstyle ':chpwd:profiles:/usr/src/grml(|/|/*)' profile grml
1134 # zstyle ':chpwd:profiles:/usr/src/debian(|/|/*)' profile debian
1136 # When that's done and you enter a directory that matches the pattern
1137 # in the third part of the context, a function called chpwd_profile_grml,
1138 # for example, is called (if it exists).
1140 # If no pattern matches (read: no profile is detected) the profile is
1141 # set to 'default', which means chpwd_profile_default is attempted to
1144 # A word about the context (the ':chpwd:profiles:*' stuff in the zstyle
1145 # command) which is used: The third part in the context is matched against
1146 # ${PWD}. That's why using a pattern such as /foo/bar(|/|/*) makes sense.
1147 # Because that way the profile is detected for all these values of ${PWD}:
1151 # So, if you want to make double damn sure a profile works in /foo/bar
1152 # and everywhere deeper in that tree, just use (|/|/*) and be happy.
1154 # The name of the detected profile will be available in a variable called
1155 # 'profile' in your functions. You don't need to do anything, it'll just
1158 # Then there is the parameter $CHPWD_PROFILE is set to the profile, that
1159 # was is currently active. That way you can avoid running code for a
1160 # profile that is already active, by running code such as the following
1161 # at the start of your function:
1163 # function chpwd_profile_grml() {
1164 # [[ ${profile} == ${CHPWD_PROFILE} ]] && return 1
1168 # The initial value for $CHPWD_PROFILE is 'default'.
1170 # Version requirement:
1171 # This feature requires zsh 4.3.3 or newer.
1172 # If you use this feature and need to know whether it is active in your
1173 # current shell, there are several ways to do that. Here are two simple
1176 # a) If knowing if the profiles feature is active when zsh starts is
1177 # good enough for you, you can put the following snippet into your
1180 # (( ${+functions[chpwd_profiles]} )) && print "directory profiles active"
1182 # b) If that is not good enough, and you would prefer to be notified
1183 # whenever a profile changes, you can solve that by making sure you
1184 # start *every* profile function you create like this:
1186 # function chpwd_profile_myprofilename() {
1187 # [[ ${profile} == ${CHPWD_PROFILE} ]] && return 1
1188 # print "chpwd(): Switching to profile: $profile"
1192 # That makes sure you only get notified if a profile is *changed*,
1193 # not everytime you change directory, which would probably piss
1194 # you off fairly quickly. :-)
1196 # There you go. Now have fun with that.
1199 zstyle -s ":chpwd:profiles:${PWD}" profile profile || profile='default'
1200 if (( ${+functions[chpwd_profile_$profile]} )) ; then
1201 chpwd_profile_${profile}
1204 CHPWD_PROFILE="${profile}"
1207 chpwd_functions=( ${chpwd_functions} chpwd_profiles )
1211 # display battery status on right side of prompt via running 'BATTERY=1 zsh'
1212 if [[ $BATTERY -gt 0 ]] ; then
1213 if ! check_com -c acpi ; then
1219 if [[ $BATTERY -gt 0 ]] ; then
1220 PERCENT="${${"$(acpi 2>/dev/null)"}/(#b)[[:space:]]#Battery <->: [^0-9]##, (<->)%*/${match[1]}}"
1221 if [[ -z "$PERCENT" ]] ; then
1222 PERCENT='acpi not present'
1224 if [[ "$PERCENT" -lt 20 ]] ; then
1225 PERCENT="warning: ${PERCENT}%%"
1227 PERCENT="${PERCENT}%%"
1232 # set colors for use in prompts
1233 if zrcautoload colors && colors 2>/dev/null ; then
1234 BLUE="%{${fg[blue]}%}"
1235 RED="%{${fg_bold[red]}%}"
1236 GREEN="%{${fg[green]}%}"
1237 CYAN="%{${fg[cyan]}%}"
1238 MAGENTA="%{${fg[magenta]}%}"
1239 YELLOW="%{${fg[yellow]}%}"
1240 WHITE="%{${fg[white]}%}"
1241 NO_COLOUR="%{${reset_color}%}"
1243 BLUE=$'%{\e[1;34m%}'
1245 GREEN=$'%{\e[1;32m%}'
1246 CYAN=$'%{\e[1;36m%}'
1247 WHITE=$'%{\e[1;37m%}'
1248 MAGENTA=$'%{\e[1;35m%}'
1249 YELLOW=$'%{\e[1;33m%}'
1250 NO_COLOUR=$'%{\e[0m%}'
1253 # gather version control information for inclusion in a prompt
1255 if zrcautoload vcs_info; then
1256 # `vcs_info' in zsh versions 4.3.10 and below have a broken `_realpath'
1257 # function, which can cause a lot of trouble with our directory-based
1259 if [[ ${ZSH_VERSION} == 4.3.<-10> ]] ; then
1260 function VCS_INFO_realpath () {
1261 setopt localoptions NO_shwordsplit chaselinks
1262 ( builtin cd -q $1 2> /dev/null && pwd; )
1266 zstyle ':vcs_info:*' max-exports 2
1268 if [[ -o restricted ]]; then
1269 zstyle ':vcs_info:*' enable NONE
1273 # Change vcs_info formats for the grml prompt. The 2nd format sets up
1274 # $vcs_info_msg_1_ to contain "zsh: repo-name" used to set our screen title.
1275 # TODO: The included vcs_info() version still uses $VCS_INFO_message_N_.
1276 # That needs to be the use of $VCS_INFO_message_N_ needs to be changed
1277 # to $vcs_info_msg_N_ as soon as we use the included version.
1278 if [[ "$TERM" == dumb ]] ; then
1279 zstyle ':vcs_info:*' actionformats "(%s%)-[%b|%a] " "zsh: %r"
1280 zstyle ':vcs_info:*' formats "(%s%)-[%b] " "zsh: %r"
1282 # these are the same, just with a lot of colours:
1283 zstyle ':vcs_info:*' actionformats "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOUR} " \
1285 zstyle ':vcs_info:*' formats "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOUR}%} " \
1287 zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat "%b${RED}:${YELLOW}%r"
1290 # command not found handling
1292 (( ${COMMAND_NOT_FOUND} == 1 )) &&
1293 function command_not_found_handler() {
1295 if [[ -x ${GRML_ZSH_CNF_HANDLER} ]] ; then
1296 ${GRML_ZSH_CNF_HANDLER} $1
1302 if zrcautoload promptinit && promptinit 2>/dev/null ; then
1303 promptinit # people should be able to use their favourite prompt
1305 print 'Notice: no promptinit available :('
1310 # make sure to use right prompt only when not running a command
1311 is41 && setopt transient_rprompt
1314 function ESC_print () {
1315 info_print $'\ek' $'\e\\' "$@"
1317 function set_title () {
1318 info_print $'\e]0;' $'\a' "$@"
1321 function info_print () {
1322 local esc_begin esc_end
1326 printf '%s' ${esc_begin}
1328 printf '%s' "${esc_end}"
1331 # TODO: revise all these NO* variables and especially their documentation
1332 # in zsh-help() below.
1333 is4 && [[ $NOPRECMD -eq 0 ]] && precmd () {
1334 [[ $NOPRECMD -gt 0 ]] && return 0
1335 # update VCS information
1336 (( ${+functions[vcs_info]} )) && vcs_info
1338 if [[ $TERM == screen* ]] ; then
1339 if [[ -n ${vcs_info_msg_1_} ]] ; then
1340 ESC_print ${vcs_info_msg_1_}
1345 # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
1346 if [[ ${DONTSETRPROMPT:-} -eq 0 ]] ; then
1347 if [[ $BATTERY -gt 0 ]] ; then
1348 # update battery (dropped into $PERCENT) information
1350 RPROMPT="%(?..:() ${PERCENT}"
1355 # adjust title of xterm
1356 # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
1357 [[ ${NOTITLE:-} -gt 0 ]] && return 0
1360 set_title ${(%):-"%n@%m: %~"}
1365 # preexec() => a function running before every command
1366 is4 && [[ $NOPRECMD -eq 0 ]] && \
1368 [[ $NOPRECMD -gt 0 ]] && return 0
1369 # set hostname if not running on host with name 'grml'
1370 if [[ -n "$HOSTNAME" ]] && [[ "$HOSTNAME" != $(hostname) ]] ; then
1373 # get the name of the program currently running and hostname of local machine
1374 # set screen window title if running in a screen
1375 if [[ "$TERM" == screen* ]] ; then
1376 # local CMD=${1[(wr)^(*=*|sudo|ssh|-*)]} # don't use hostname
1377 local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME" # use hostname
1380 # adjust title of xterm
1381 [[ ${NOTITLE} -gt 0 ]] && return 0
1384 set_title "${(%):-"%n@%m:"}" "$1"
1389 EXITCODE="%(?..%?%1v )"
1390 # secondary prompt, printed when the shell needs more information to complete a
1393 # selection prompt used within a select loop.
1395 # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
1398 # set variable debian_chroot if running in a chroot with /etc/debian_chroot
1399 if [[ -z "$debian_chroot" ]] && [[ -r /etc/debian_chroot ]] ; then
1400 debian_chroot=$(cat /etc/debian_chroot)
1403 # don't use colors on dumb terminals (like emacs):
1404 if [[ "$TERM" == dumb ]] ; then
1405 PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< "
1407 # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended
1408 # prompt set variable identifying the chroot you work in (used in the
1410 if [[ $GRMLPROMPT -gt 0 ]] ; then
1411 PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
1412 ${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "
1414 # This assembles the primary prompt string
1415 if (( EUID != 0 )); then
1416 PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "
1418 PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "
1423 PROMPT="${PROMPT}"'${vcs_info_msg_0_}'"%# "
1425 # if we are inside a grml-chroot set a specific prompt theme
1426 if [[ -n "$GRML_CHROOT" ]] ; then
1427 PROMPT="%{$fg[red]%}(CHROOT) %{$fg_bold[red]%}%n%{$fg_no_bold[white]%}@%m %40<...<%B%~%b%<< %\# "
1430 # 'hash' some often used directories
1432 hash -d deb=/var/cache/apt/archives
1433 hash -d doc=/usr/share/doc
1434 hash -d linux=/lib/modules/$(command uname -r)/build/
1435 hash -d log=/var/log
1436 hash -d slog=/var/log/syslog
1437 hash -d src=/usr/src
1438 hash -d templ=/usr/share/doc/grml-templates
1439 hash -d tt=/usr/share/doc/texttools-doc
1440 hash -d www=/var/www
1444 if check_com -c screen ; then
1445 if [[ $UID -eq 0 ]] ; then
1446 if [[ -r /etc/grml/screenrc ]]; then
1447 alias screen="${commands[screen]} -c /etc/grml/screenrc"
1449 elif [[ -r $HOME/.screenrc ]] ; then
1450 alias screen="${commands[screen]} -c $HOME/.screenrc"
1452 if [[ -r /etc/grml/screenrc_grml ]]; then
1453 alias screen="${commands[screen]} -c /etc/grml/screenrc_grml"
1455 if [[ -r /etc/grml/screenrc ]]; then
1456 alias screen="${commands[screen]} -c /etc/grml/screenrc"
1462 # do we have GNU ls with color-support?
1463 if ls --help 2>/dev/null | grep -- --color= >/dev/null \
1464 && [[ "$TERM" != dumb ]]
1466 #a1# execute \kbd{@a@}:\quad ls with colors
1467 alias ls='ls -b -CF --color=auto'
1468 #a1# execute \kbd{@a@}:\quad list all files, with colors
1469 alias la='ls -la --color=auto'
1470 #a1# long colored list, without dotfiles (@a@)
1471 alias ll='ls -l --color=auto'
1472 #a1# long colored list, human readable sizes (@a@)
1473 alias lh='ls -hAl --color=auto'
1474 #a1# List files, append qualifier to filenames \\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
1475 alias l='ls -lF --color=auto'
1477 alias ls='ls -b -CF'
1484 alias mdstat='cat /proc/mdstat'
1485 alias ...='cd ../../'
1487 # generate alias named "$KERNELVERSION-reboot" so you can use boot with kexec:
1488 if [[ -x /sbin/kexec ]] && [[ -r /proc/cmdline ]] ; then
1489 alias "$(uname -r)-reboot"="kexec -l --initrd=/boot/initrd.img-"$(uname -r)" --command-line=\"$(cat /proc/cmdline)\" /boot/vmlinuz-"$(uname -r)""
1492 # see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
1493 alias term2iso="echo 'Setting terminal to iso mode' ; print -n '\e%@'"
1494 alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
1496 # make sure it is not assigned yet
1497 [[ -n ${aliases[utf2iso]} ]] && unalias utf2iso
1500 for ENV in $(env | command grep -i '.utf') ; do
1501 eval export "$(echo $ENV | sed 's/UTF-8/iso885915/ ; s/utf8/iso885915/')"
1506 # make sure it is not assigned yet
1507 [[ -n ${aliases[iso2utf]} ]] && unalias iso2utf
1509 if ! isutfenv ; then
1510 for ENV in $(env | command grep -i '\.iso') ; do
1511 eval export "$(echo $ENV | sed 's/iso.*/UTF-8/ ; s/ISO.*/UTF-8/')"
1516 # especially for roadwarriors using GNU screen and ssh:
1517 if ! check_com asc &>/dev/null ; then
1518 asc() { autossh -t "$@" 'screen -RdU' }
1522 #f1# Hints for the use of zsh on grml
1524 print "$bg[white]$fg[black]
1525 zsh-help - hints for use of zsh on grml
1526 =======================================$reset_color"
1529 Main configuration of zsh happens in /etc/zsh/zshrc.
1530 That file is part of the package grml-etc-core, if you want to
1531 use them on a non-grml-system just get the tar.gz from
1532 http://deb.grml.org/ or (preferably) get it from the git repository:
1534 http://git.grml.org/f/grml-etc-core/etc/zsh/zshrc
1536 This version of grml'\''s zsh setup does not use skel/.zshrc anymore.
1537 The file is still there, but it is empty for backwards compatibility.
1539 For your own changes use these two files:
1543 The former is sourced very early in our zshrc, the latter is sourced
1546 System wide configuration without touching configuration files of grml
1547 can take place in /etc/zsh/zshrc.local.
1549 For information regarding zsh start at http://grml.org/zsh/
1551 Take a look at grml'\''s zsh refcard:
1552 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
1554 Check out the main zsh refcard:
1555 % '$BROWSER' http://www.bash2zsh.com/zsh_refcard/refcard.pdf
1557 And of course visit the zsh-lovers:
1560 You can adjust some options through environment variables when
1561 invoking zsh without having to edit configuration files.
1562 Basically meant for bash users who are not used to the power of
1565 "NOCOR=1 zsh" => deactivate automatic correction
1566 "NOMENU=1 zsh" => do not use auto menu completion
1567 (note: use ctrl-d for completion instead!)
1568 "NOPRECMD=1 zsh" => disable the precmd + preexec commands (set GNU screen title)
1569 "NOTITLE=1 zsh" => disable setting the title of xterms without disabling
1570 preexec() and precmd() completely
1571 "BATTERY=1 zsh" => activate battery status (via acpi) on right side of prompt
1572 "COMMAND_NOT_FOUND=1 zsh"
1573 => Enable a handler if an external command was not found
1574 The command called in the handler can be altered by setting
1575 the GRML_ZSH_CNF_HANDLER variable, the default is:
1576 "/usr/share/command-not-found/command-not-found"
1578 A value greater than 0 is enables a feature; a value equal to zero
1579 disables it. If you like one or the other of these settings, you can
1580 add them to ~/.zshrc.pre to ensure they are set when sourcing grml'\''s
1584 $bg[white]$fg[black]
1585 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
1586 Enjoy your grml system with the zsh!$reset_color"
1590 if [[ -r /etc/debian_version ]] ; then
1591 #a3# Execute \kbd{apt-cache search}
1592 alias acs='apt-cache search'
1593 #a3# Execute \kbd{apt-cache show}
1594 alias acsh='apt-cache show'
1595 #a3# Execute \kbd{apt-cache policy}
1596 alias acp='apt-cache policy'
1597 #a3# Execute \kbd{apt-get dist-upgrade}
1598 salias adg="apt-get dist-upgrade"
1599 #a3# Execute \kbd{apt-get install}
1600 salias agi="apt-get install"
1601 #a3# Execute \kbd{aptitude install}
1602 salias ati="aptitude install"
1603 #a3# Execute \kbd{apt-get upgrade}
1604 salias ag="apt-get upgrade"
1605 #a3# Execute \kbd{apt-get update}
1606 salias au="apt-get update"
1607 #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
1608 salias -a up="aptitude update ; aptitude safe-upgrade"
1609 #a3# Execute \kbd{dpkg-buildpackage}
1610 alias dbp='dpkg-buildpackage'
1611 #a3# Execute \kbd{grep-excuses}
1612 alias ge='grep-excuses'
1614 # get a root shell as normal user in live-cd mode:
1615 if isgrmlcd && [[ $UID -ne 0 ]] ; then
1619 #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
1620 salias llog="$PAGER /var/log/syslog" # take a look at the syslog
1621 #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
1622 salias tlog="tail -f /var/log/syslog" # follow the syslog
1625 # sort installed Debian-packages by size
1626 if check_com -c dpkg-query ; then
1627 #a3# List installed Debian-packages sorted by size
1628 alias debs-by-size="dpkg-query -Wf 'x \${Installed-Size} \${Package} \${Status}\n' | sed -ne '/^x /d' -e '/^x \(.*\) install ok installed$/s//\1/p' | sort -nr"
1631 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
1632 if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord; then
1633 if check_com -c wodim; then
1636 cdrecord is not provided under its original name by Debian anymore.
1637 See #377109 in the BTS of Debian for more details.
1639 Please use the wodim binary instead
1646 # Use hard limits, except for a smaller stack and no core dumps
1648 is425 && limit stack 8192
1649 isgrmlcd && limit core 0 # important for a live-cd-system
1654 # called later (via is4 && grmlcomp)
1655 # note: use 'zstyle' for getting current settings
1656 # press ^xh (control-x h) for getting tags in context; ^x? (control-x ?) to run complete_debug with trace output
1658 # TODO: This could use some additional information
1660 # allow one error for every three characters typed in approximate completer
1661 zstyle ':completion:*:approximate:' max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )'
1663 # don't complete backup files as executables
1664 zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)'
1666 # start menu completion only if it could find no unambiguous initial string
1667 zstyle ':completion:*:correct:*' insert-unambiguous true
1668 zstyle ':completion:*:corrections' format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}'
1669 zstyle ':completion:*:correct:*' original true
1671 # activate color-completion
1672 zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
1674 # format on completion
1675 zstyle ':completion:*:descriptions' format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'
1677 # automatically complete 'cd -<tab>' and 'cd -<ctrl-d>' with menu
1678 # zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
1680 # insert all expansions for expand completer
1681 zstyle ':completion:*:expand:*' tag-order all-expansions
1682 zstyle ':completion:*:history-words' list false
1685 zstyle ':completion:*:history-words' menu yes
1687 # ignore duplicate entries
1688 zstyle ':completion:*:history-words' remove-all-dups yes
1689 zstyle ':completion:*:history-words' stop yes
1691 # match uppercase from lowercase
1692 zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
1694 # separate matches into groups
1695 zstyle ':completion:*:matches' group 'yes'
1696 zstyle ':completion:*' group-name ''
1698 if [[ "$NOMENU" -eq 0 ]] ; then
1699 # if there are more than 5 options allow selecting from a menu
1700 zstyle ':completion:*' menu select=5
1702 # don't use any menus at all
1706 zstyle ':completion:*:messages' format '%d'
1707 zstyle ':completion:*:options' auto-description '%d'
1709 # describe options in full
1710 zstyle ':completion:*:options' description 'yes'
1712 # on processes completion complete all user processes
1713 zstyle ':completion:*:processes' command 'ps -au$USER'
1715 # offer indexes before parameters in subscripts
1716 zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
1718 # provide verbose completion information
1719 zstyle ':completion:*' verbose true
1721 # recent (as of Dec 2007) zsh versions are able to provide descriptions
1722 # for commands (read: 1st word in the line) that it will list for the user
1723 # to choose from. The following disables that, because it's not exactly fast.
1724 zstyle ':completion:*:-command-:*:' verbose false
1726 # set format for warnings
1727 zstyle ':completion:*:warnings' format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d'
1729 # define files to ignore for zcompile
1730 zstyle ':completion:*:*:zcompile:*' ignored-patterns '(*~|*.zwc)'
1731 zstyle ':completion:correct:' prompt 'correct to: %e'
1733 # Ignore completion functions for commands you don't have:
1734 zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'
1736 # Provide more processes in completion of programs like killall:
1737 zstyle ':completion:*:processes-names' command 'ps c -u ${USER} -o command | uniq'
1739 # complete manual by their section
1740 zstyle ':completion:*:manuals' separate-sections true
1741 zstyle ':completion:*:manuals.*' insert-sections true
1742 zstyle ':completion:*:man:*' menu yes select
1744 # provide .. as a completion
1745 zstyle ':completion:*' special-dirs ..
1747 # run rehash on completion so new installed program are found automatically:
1749 (( CURRENT == 1 )) && rehash
1754 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
1755 if [[ "$NOCOR" -gt 0 ]] ; then
1756 zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
1759 # try to be smart about when to use what completer...
1761 zstyle -e ':completion:*' completer '
1762 if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then
1763 _last_try="$HISTNO$BUFFER$CURSOR"
1764 reply=(_complete _match _ignored _prefix _files)
1766 if [[ $words[1] == (rm|mv) ]] ; then
1767 reply=(_complete _files)
1769 reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files)
1774 # command for process lists, the local web server details and host completion
1775 zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
1778 [[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \
1779 zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
1783 [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
1784 [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
1796 zstyle ':completion:*:hosts' hosts $hosts
1797 # TODO: so, why is this here?
1798 # zstyle '*' hosts $hosts
1800 # use generic completion system for programs not yet defined; (_gnu_generic works
1801 # with commands that provide a --help option with "standard" gnu-like output.)
1802 for compcom in cp deborphan df feh fetchipac head hnb ipacsum mv \
1803 pal stow tail uname ; do
1804 [[ -z ${_comps[$compcom]} ]] && compdef _gnu_generic ${compcom}
1807 # see upgrade function in this file
1808 compdef _hosts upgrade
1813 # people should use 'grml-x'!
1814 if check_com -c 915resolution; then
1816 echo "Please use 915resolution as resolution modifying tool for Intel \
1822 #a1# Output version of running grml
1823 alias grml-version='cat /etc/grml_version'
1825 if check_com -c rebuildfstab ; then
1826 #a1# Rebuild /etc/fstab
1827 alias grml-rebuildfstab='rebuildfstab -v -r -config'
1830 if check_com -c grml-debootstrap ; then
1832 echo "Installing debian to harddisk is possible by using grml-debootstrap."
1838 # now run the functions
1840 is4 && isgrml && grmlstuff
1844 is4 && xsource "/etc/zsh/keephack"
1846 # wonderful idea of using "e" glob qualifier by Peter Stephenson
1847 # You use it as follows:
1848 # $ NTREF=/reference/file
1850 # This lists all the files in the current directory newer than the reference file.
1851 # You can also specify the reference file inline; note quotes:
1852 # $ ls -l *(e:'nt ~/.zshenv':)
1854 if [[ -n $1 ]] ; then
1857 [[ $REPLY -nt $NTREF ]]
1862 #f1# Reload an autoloadable function
1863 freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
1864 compdef _functions freload
1866 #f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
1868 [[ -z "$1" ]] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
1869 for file in "$@" ; do
1870 while [[ -h "$file" ]] ; do
1872 file=$(readlink "$file")
1877 # TODO: Is it supported to use pager settings like this?
1878 # PAGER='less -Mr' - If so, the use of $PAGER here needs fixing
1879 # with respect to wordsplitting. (ie. ${=PAGER})
1880 if check_com -c $PAGER ; then
1881 #f1# View Debian's changelog of a given package
1884 if [[ -r /usr/share/doc/$1/changelog.Debian.gz ]] ; then
1885 $PAGER /usr/share/doc/$1/changelog.Debian.gz
1886 elif [[ -r /usr/share/doc/$1/changelog.gz ]] ; then
1887 $PAGER /usr/share/doc/$1/changelog.gz
1889 if check_com -c aptitude ; then
1890 echo "No changelog for package $1 found, using aptitude to retrieve it."
1892 aptitude -t unstable changelog $1
1894 aptitude changelog $1
1897 echo "No changelog for package $1 found, sorry."
1902 _dchange() { _files -W /usr/share/doc -/ }
1903 compdef _dchange dchange
1905 #f1# View Debian's NEWS of a given package
1908 if [[ -r /usr/share/doc/$1/NEWS.Debian.gz ]] ; then
1909 $PAGER /usr/share/doc/$1/NEWS.Debian.gz
1911 if [[ -r /usr/share/doc/$1/NEWS.gz ]] ; then
1912 $PAGER /usr/share/doc/$1/NEWS.gz
1914 echo "No NEWS file for package $1 found, sorry."
1919 _dnews() { _files -W /usr/share/doc -/ }
1920 compdef _dnews dnews
1922 #f1# View upstream's changelog of a given package
1925 if [[ -r /usr/share/doc/$1/changelog.gz ]] ; then
1926 $PAGER /usr/share/doc/$1/changelog.gz
1928 echo "No changelog for package $1 found, sorry."
1932 _uchange() { _files -W /usr/share/doc -/ }
1933 compdef _uchange uchange
1938 ZSH_PROFILE_RC=1 $SHELL "$@"
1941 #f1# Edit an alias via zle
1943 [[ -z "$1" ]] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
1945 compdef _aliases edalias
1947 #f1# Edit a function via zle
1949 [[ -z "$1" ]] && { echo "Usage: edfunc <function_to_edit>" ; return 1 } || zed -f "$1" ;
1951 compdef _functions edfunc
1953 # use it e.g. via 'Restart apache2'
1954 #m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
1955 #m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
1956 #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
1957 #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
1958 #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
1959 if [[ -d /etc/init.d || -d /etc/service ]] ; then
1961 local action_="${1:l}" # e.g Start/Stop/Restart
1965 local service_target_="$(readlink /etc/init.d/$service_)"
1966 if [[ $service_target_ == "/usr/bin/sv" ]]; then
1968 case "${action_}" in
1969 start) if [[ ! -e /etc/service/$service_ ]]; then
1970 $SUDO ln -s "/etc/sv/$service_" "/etc/service/"
1972 $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
1974 # there is no reload in runits sysv emulation
1975 reload) $SUDO "/etc/init.d/$service_" "force-reload" "$param_" ;;
1976 *) $SUDO "/etc/init.d/$service_" "${action_}" "$param_" ;;
1980 $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
1986 scripts=( /etc/init.d/*(x:t) )
1987 _describe "service startup script" scripts
1990 for i in Start Restart Stop Force-Reload Reload ; do
1991 eval "$i() { __start_stop $i \"\$1\" \"\$2\" ; }"
1992 compdef _grmlinitd $i
1996 #f1# Provides useful information on globbing
2003 p named pipes (FIFOs)
2004 * executable plain files (0100)
2005 % device files (character or block special)
2006 %b block special files
2007 %c character special files
2008 r owner-readable files (0400)
2009 w owner-writable files (0200)
2010 x owner-executable files (0100)
2011 A group-readable files (0040)
2012 I group-writable files (0020)
2013 E group-executable files (0010)
2014 R world-readable files (0004)
2015 W world-writable files (0002)
2016 X world-executable files (0001)
2017 s setuid files (04000)
2018 S setgid files (02000)
2019 t files with the sticky bit (01000)
2021 print *(m-1) # Files modified up to a day ago
2022 print *(a1) # Files accessed a day ago
2023 print *(@) # Just symlinks
2024 print *(Lk+50) # Files bigger than 50 kilobytes
2025 print *(Lk-50) # Files smaller than 50 kilobytes
2026 print **/*.c # All *.c files recursively starting in \$PWD
2027 print **/*.c~file.c # Same as above, but excluding 'file.c'
2028 print (foo|bar).* # Files starting with 'foo' or 'bar'
2029 print *~*.* # All Files that do not contain a dot
2030 chmod 644 *(.^x) # make all plain non-executable files publically readable
2031 print -l *(.c|.h) # Lists *.c and *.h
2032 print **/*(g:users:) # Recursively match all files that are owned by group 'users'
2033 echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
2035 alias help-zshglob=H-Glob
2037 #v1# set number of lines to display per page
2038 HELP_LINES_PER_PAGE=20
2039 #v1# set location of help-zle cache file
2040 HELP_ZLE_CACHE_FILE=~/.cache/zsh_help_zle_lines.zsh
2041 #f1# helper function for help-zle, actually generates the help text
2042 help_zle_parse_keybindings()
2046 unsetopt ksharrays #indexing starts at 1
2048 #v1# choose files that help-zle will parse for keybindings
2049 ((${+HELPZLE_KEYBINDING_FILES})) || HELPZLE_KEYBINDING_FILES=( /etc/zsh/zshrc ~/.zshrc.pre ~/.zshrc ~/.zshrc.local )
2051 if [[ -r $HELP_ZLE_CACHE_FILE ]]; then
2053 for f ($HELPZLE_KEYBINDING_FILES) [[ $f -nt $HELP_ZLE_CACHE_FILE ]] && load_cache=1
2054 [[ $load_cache -eq 0 ]] && . $HELP_ZLE_CACHE_FILE && return
2057 #fill with default keybindings, possibly to be overwriten in a file later
2058 #Note that due to zsh inconsistency on escaping assoc array keys, we encase the key in '' which we will remove later
2059 local -A help_zle_keybindings
2060 help_zle_keybindings['<Ctrl>@']="set MARK"
2061 help_zle_keybindings['<Ctrl>x<Ctrl>j']="vi-join lines"
2062 help_zle_keybindings['<Ctrl>x<Ctrl>b']="jump to matching brace"
2063 help_zle_keybindings['<Ctrl>x<Ctrl>u']="undo"
2064 help_zle_keybindings['<Ctrl>_']="undo"
2065 help_zle_keybindings['<Ctrl>x<Ctrl>f<c>']="find <c> in cmdline"
2066 help_zle_keybindings['<Ctrl>a']="goto beginning of line"
2067 help_zle_keybindings['<Ctrl>e']="goto end of line"
2068 help_zle_keybindings['<Ctrl>t']="transpose charaters"
2069 help_zle_keybindings['<Alt>t']="transpose words"
2070 help_zle_keybindings['<Alt>s']="spellcheck word"
2071 help_zle_keybindings['<Ctrl>k']="backward kill buffer"
2072 help_zle_keybindings['<Ctrl>u']="forward kill buffer"
2073 help_zle_keybindings['<Ctrl>y']="insert previously killed word/string"
2074 help_zle_keybindings["<Alt>'"]="quote line"
2075 help_zle_keybindings['<Alt>"']="quote from mark to cursor"
2076 help_zle_keybindings['<Alt><arg>']="repeat next cmd/char <arg> times (<Alt>-<Alt>1<Alt>0a -> -10 times 'a')"
2077 help_zle_keybindings['<Alt>u']="make next word Uppercase"
2078 help_zle_keybindings['<Alt>l']="make next word lowercase"
2079 help_zle_keybindings['<Ctrl>xd']="preview expansion under cursor"
2080 help_zle_keybindings['<Alt>q']="push current CL into background, freeing it. Restore on next CL"
2081 help_zle_keybindings['<Alt>.']="insert (and interate through) last word from prev CLs"
2082 help_zle_keybindings['<Alt>,']="complete word from newer history (consecutive hits)"
2083 help_zle_keybindings['<Alt>m']="repeat last typed word on current CL"
2084 help_zle_keybindings['<Ctrl>v']="insert next keypress symbol literally (e.g. for bindkey)"
2085 help_zle_keybindings['!!:n*<Tab>']="insert last n arguments of last command"
2086 help_zle_keybindings['!!:n-<Tab>']="insert arguments n..N-2 of last command (e.g. mv s s d)"
2087 help_zle_keybindings['<Alt>h']="show help/manpage for current command"
2089 #init global variables
2090 unset help_zle_lines help_zle_sln
2091 typeset -g -a help_zle_lines
2092 typeset -g help_zle_sln=1
2095 local lastkeybind_desc contents #last description starting with #k# that we found
2096 local num_lines_elapsed=0 #number of lines between last description and keybinding
2097 #search config files in the order they a called (and thus the order in which they overwrite keybindings)
2098 for f in $HELPZLE_KEYBINDING_FILES; do
2099 [[ -r "$f" ]] || continue #not readable ? skip it
2101 for cline in "${(f)contents}"; do
2102 #zsh pattern: matches lines like: #k# ..............
2103 if [[ "$cline" == (#s)[[:space:]]#\#k\#[[:space:]]##(#b)(*)[[:space:]]#(#e) ]]; then
2104 lastkeybind_desc="$match[*]"
2106 #zsh pattern: matches lines that set a keybinding using bindkey or compdef -k
2107 # ignores lines that are commentend out
2108 # grabs first in '' or "" enclosed string with length between 1 and 6 characters
2109 elif [[ "$cline" == [^#]#(bindkey|compdef -k)[[:space:]](*)(#b)(\"((?)(#c1,6))\"|\'((?)(#c1,6))\')(#B)(*) ]]; then
2110 #description prevously found ? description not more than 2 lines away ? keybinding not empty ?
2111 if [[ -n $lastkeybind_desc && $num_lines_elapsed -lt 2 && -n $match[1] ]]; then
2112 #substitute keybinding string with something readable
2113 k=${${${${${${${match[1]/\\e\^h/<Alt><BS>}/\\e\^\?/<Alt><BS>}/\\e\[5~/<PageUp>}/\\e\[6~/<PageDown>}//(\\e|\^\[)/<Alt>}//\^/<Ctrl>}/3~/<Alt><Del>}
2114 #put keybinding in assoc array, possibly overwriting defaults or stuff found in earlier files
2115 #Note that we are extracting the keybinding-string including the quotes (see Note at beginning)
2116 help_zle_keybindings[${k}]=$lastkeybind_desc
2120 ((num_lines_elapsed++))
2125 #calculate length of keybinding column
2127 for k (${(k)help_zle_keybindings[@]}) ((kstrlen < ${#k})) && kstrlen=${#k}
2128 #convert the assoc array into preformated lines, which we are able to sort
2129 for k v in ${(kv)help_zle_keybindings[@]}; do
2130 #pad keybinding-string to kstrlen chars and remove outermost characters (i.e. the quotes)
2131 help_zle_lines+=("${(r:kstrlen:)k[2,-2]}${v}")
2133 #sort lines alphabetically
2134 help_zle_lines=("${(i)help_zle_lines[@]}")
2135 [[ -d ${HELP_ZLE_CACHE_FILE:h} ]] || mkdir -p "${HELP_ZLE_CACHE_FILE:h}"
2136 echo "help_zle_lines=(${(q)help_zle_lines[@]})" >| $HELP_ZLE_CACHE_FILE
2137 zcompile $HELP_ZLE_CACHE_FILE
2139 typeset -g help_zle_sln
2140 typeset -g -a help_zle_lines
2142 #f1# Provides (partially autogenerated) help on keybindings and the zsh line editor
2146 unsetopt ksharrays #indexing starts at 1
2147 #help lines already generated ? no ? then do it
2148 [[ ${+functions[help_zle_parse_keybindings]} -eq 1 ]] && {help_zle_parse_keybindings && unfunction help_zle_parse_keybindings}
2149 #already displayed all lines ? go back to the start
2150 [[ $help_zle_sln -gt ${#help_zle_lines} ]] && help_zle_sln=1
2151 local sln=$help_zle_sln
2152 #note that help_zle_sln is a global var, meaning we remember the last page we viewed
2153 help_zle_sln=$((help_zle_sln + HELP_LINES_PER_PAGE))
2154 zle -M "${(F)help_zle_lines[sln,help_zle_sln-1]}"
2156 #k# display help for keybindings and ZLE (cycle pages with consecutive use)
2157 zle -N help-zle && bindkey '^xz' help-zle
2159 # grep for running process, like: 'any vim'
2163 if [[ -z "$1" ]] ; then
2164 echo "any - grep for process(es) by keyword" >&2
2165 echo "Usage: any <keyword>" >&2 ; return 1
2167 ps xauwww | grep -i --color=auto "[${1[1]}]${1[2,-1]}"
2172 # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
2173 # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
2174 [[ -r /proc/1/maps ]] && \
2176 print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
2177 cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/') > /dev/null
2178 print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
2181 # a wrapper for vim, that deals with title setting
2183 # set this array to a set of options to vim you always want
2184 # to have set when calling vim (in .zshrc.local), like:
2185 # VIM_OPTIONS=( -p )
2186 # This will cause vim to send every file given on the
2187 # commandline to be send to it's own tab (needs vim7).
2189 VIM_PLEASE_SET_TITLE='yes' command vim ${VIM_OPTIONS} "$@"
2192 # make a backup of a file
2194 cp -a "$1" "${1}_$(date --iso-8601=seconds)"
2197 ssl_hashes=( sha512 sha256 sha1 md5 )
2199 for sh in ${ssl_hashes}; do
2200 eval 'ssl-cert-'${sh}'() {
2202 if [[ -z $1 ]] ; then
2203 printf '\''usage: %s <file>\n'\'' "ssh-cert-'${sh}'"
2206 openssl x509 -noout -fingerprint -'${sh}' -in $1
2210 ssl-cert-fingerprints() {
2213 if [[ -z $1 ]] ; then
2214 printf 'usage: ssl-cert-fingerprints <file>\n'
2217 for i in ${ssl_hashes}
2224 if [[ -z $1 ]] ; then
2225 printf 'usage: ssl-cert-info <file>\n'
2228 openssl x509 -noout -text -in $1
2229 ssl-cert-fingerprints $1
2232 # make sure our environment is clean regarding colors
2233 for color in BLUE RED GREEN CYAN YELLOW MAGENTA WHITE ; unset $color
2235 # "persistent history"
2236 # just write important commands you always need to ~/.important_commands
2237 if [[ -r ~/.important_commands ]] ; then
2238 fc -R ~/.important_commands
2241 # load the lookup subsystem if it's available on the system
2242 zrcautoload lookupinit && lookupinit
2246 # set terminal property (used e.g. by msgid-chooser)
2247 export COLORTERM="yes"
2252 #a2# Execute \kbd{du -sch}
2254 #a2# Execute \kbd{jobs -l}
2258 #a2# Execute \kbd{ls -lSrah}
2259 alias dir="ls -lSrah"
2260 #a2# Only show dot-directories
2261 alias lad='ls -d .*(/)' # only show dot-directories
2262 #a2# Only show dot-files
2263 alias lsa='ls -a .*(.)' # only show dot-files
2264 #a2# Only files with setgid/setuid/sticky flag
2265 alias lss='ls -l *(s,S,t)' # only files with setgid/setuid/sticky flag
2266 #a2# Only show 1st ten symlinks
2267 alias lsl='ls -l *(@)' # only symlinks
2268 #a2# Display only executables
2269 alias lsx='ls -l *(*)' # only executables
2270 #a2# Display world-{readable,writable,executable} files
2271 alias lsw='ls -ld *(R,W,X.^ND/)' # world-{readable,writable,executable} files
2272 #a2# Display the ten biggest files
2273 alias lsbig="ls -flh *(.OL[1,10])" # display the biggest files
2274 #a2# Only show directories
2275 alias lsd='ls -d *(/)' # only show directories
2276 #a2# Only show empty directories
2277 alias lse='ls -d *(/^F)' # only show empty directories
2278 #a2# Display the ten newest files
2279 alias lsnew="ls -rtlh *(D.om[1,10])" # display the newest files
2280 #a2# Display the ten oldest files
2281 alias lsold="ls -rtlh *(D.Om[1,10])" # display the oldest files
2282 #a2# Display the ten smallest files
2283 alias lssmall="ls -Srl *(.oL[1,10])" # display the smallest files
2284 #a2# Display the ten newest directories and ten newest .directories
2285 alias lsnewdir="ls -rthdl *(/om[1,10]) .*(D/om[1,10])"
2286 #a2# Display the ten oldest directories and ten oldest .directories
2287 alias lsolddir="ls -rthdl *(/Om[1,10]) .*(D/Om[1,10])"
2289 # some useful aliases
2290 #a2# Remove current empty directory. Execute \kbd{cd ..; rmdir $OLDCWD}
2291 alias rmcdir='cd ..; rmdir $OLDPWD || cd $OLDPWD'
2293 #a2# ssh with StrictHostKeyChecking=no \\&\quad and UserKnownHostsFile unset
2294 alias insecssh='ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
2295 alias insecscp='scp -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
2298 check_com -c python && alias http="python -m SimpleHTTPServer"
2300 # work around non utf8 capable software in utf environment via $LANG and luit
2301 if check_com isutfenv && check_com luit ; then
2302 if check_com -c mrxvt ; then
2303 isutfenv && [[ -n "$LANG" ]] && \
2304 alias mrxvt="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit mrxvt"
2307 if check_com -c aterm ; then
2308 isutfenv && [[ -n "$LANG" ]] && \
2309 alias aterm="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit aterm"
2312 if check_com -c centericq ; then
2313 isutfenv && [[ -n "$LANG" ]] && \
2314 alias centericq="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit centericq"
2320 #f5# Backup \kbd{file {\rm to} file\_timestamp}
2323 cp -b $1 $1_`date --iso-8601=m`
2326 #f5# cd to directoy and list files
2332 # smart cd function, allows switching to /etc when running 'cd /etc/fstab'
2334 if (( ${#argv} == 1 )) && [[ -f ${1} ]]; then
2335 [[ ! -e ${1:h} ]] && return 1
2336 print "Correcting ${1} to ${1:h}"
2343 #f5# Create Directoy and \kbd{cd} to it
2345 mkdir -p "$@" && cd "$@"
2348 #f5# Create temporary directory and \kbd{cd} to it
2356 #f5# Create directory under cursor or the selected area
2357 # Press ctrl-xM to create the directory under the cursor or the selected area.
2358 # To select an area press ctrl-@ or ctrl-space and use the cursor.
2359 # Use case: you type "mv abc ~/testa/testb/testc/" and remember that the
2360 # directory does not exist yet -> press ctrl-XM and problem solved
2363 if ((REGION_ACTIVE==1)); then
2364 local F=$MARK T=$CURSOR
2365 if [[ $F -gt $T ]]; then
2369 # get marked area from buffer and eliminate whitespace
2370 PATHTOMKDIR=${BUFFER[F+1,T]%%[[:space:]]##}
2371 PATHTOMKDIR=${PATHTOMKDIR##[[:space:]]##}
2373 local bufwords iword
2374 bufwords=(${(z)LBUFFER})
2376 bufwords=(${(z)BUFFER})
2377 PATHTOMKDIR="${(Q)bufwords[iword]}"
2379 [[ -z "${PATHTOMKDIR}" ]] && return 1
2380 if [[ -e "${PATHTOMKDIR}" ]]; then
2381 zle -M " path already exists, doing nothing"
2383 zle -M "$(mkdir -p -v "${PATHTOMKDIR}")"
2387 #k# mkdir -p <dir> from string under cursor or marked area
2388 zle -N inplaceMkDirs && bindkey '^xM' inplaceMkDirs
2390 #f5# List files which have been accessed within the last {\it n} days, {\it n} defaults to 1
2393 print -l -- *(a-${1:-1})
2396 #f5# List files which have been changed within the last {\it n} days, {\it n} defaults to 1
2399 print -l -- *(c-${1:-1})
2402 #f5# List files which have been modified within the last {\it n} days, {\it n} defaults to 1
2405 print -l -- *(m-${1:-1})
2407 # modified() was named new() in earlier versions, add an alias for backwards compatibility
2408 check_com new || alias new=modified
2410 # use colors when GNU grep with color-support
2411 #a2# Execute \kbd{grep -{}-color=auto}
2412 (grep --help 2>/dev/null |grep -- --color) >/dev/null && alias grep='grep --color=auto'
2415 # 'translate' looks up fot a word in a file with language-to-language
2416 # translations (field separator should be " : "). A typical wordlist looks
2418 # | english-word : german-transmission
2419 # It's also only possible to translate english to german but not reciprocal.
2420 # Use the following oneliner to turn back the sort order:
2421 # $ awk -F ':' '{ print $2" : "$1" "$3 }' \
2422 # /usr/local/lib/words/en-de.ISO-8859-1.vok > ~/.translate/de-en.ISO-8859-1.vok
2423 #f5# Translates a word
2428 translate -l de-en $2
2431 translate -l en-de $2
2434 echo "Usage: $0 { -D | -E }"
2435 echo " -D == German to English"
2436 echo " -E == English to German"
2440 # Usage: simple-extract <file>
2441 # Using option -d deletes the original archive file.
2442 #f5# Smart archive extractor
2445 setopt extended_glob noclobber
2446 local DELETE_ORIGINAL DECOMP_CMD USES_STDIN USES_STDOUT GZTARGET WGET_CMD
2448 zparseopts -D -E "d=DELETE_ORIGINAL"
2449 for ARCHIVE in "${@}"; do
2451 *.(tar.bz2|tbz2|tbz))
2452 DECOMP_CMD="tar -xvjf -"
2457 DECOMP_CMD="tar -xvzf -"
2461 *.(tar.xz|txz|tar.lzma))
2462 DECOMP_CMD="tar -xvJf -"
2467 DECOMP_CMD="tar -xvf -"
2472 DECOMP_CMD="unrar x"
2497 DECOMP_CMD="bzip2 -d -c -"
2502 DECOMP_CMD="gzip -d -c -"
2507 DECOMP_CMD="xz -d -c -"
2512 print "ERROR: '$ARCHIVE' has unrecognized archive type." >&2
2518 if ! check_com ${DECOMP_CMD[(w)1]}; then
2519 echo "ERROR: ${DECOMP_CMD[(w)1]} not installed." >&2
2524 GZTARGET="${ARCHIVE:t:r}"
2525 if [[ -f $ARCHIVE ]] ; then
2527 print "Extracting '$ARCHIVE' ..."
2528 if $USES_STDIN; then
2529 if $USES_STDOUT; then
2530 ${=DECOMP_CMD} < "$ARCHIVE" > $GZTARGET
2532 ${=DECOMP_CMD} < "$ARCHIVE"
2535 if $USES_STDOUT; then
2536 ${=DECOMP_CMD} "$ARCHIVE" > $GZTARGET
2538 ${=DECOMP_CMD} "$ARCHIVE"
2541 [[ $? -eq 0 && -n "$DELETE_ORIGINAL" ]] && rm -f "$ARCHIVE"
2543 elif [[ "$ARCHIVE" == (#s)(https|http|ftp)://* ]] ; then
2544 if check_com curl; then
2545 WGET_CMD="curl -L -k -s -o -"
2546 elif check_com wget; then
2547 WGET_CMD="wget -q -O - --no-check-certificate"
2549 print "ERROR: neither wget nor curl is installed" >&2
2553 print "Downloading and Extracting '$ARCHIVE' ..."
2554 if $USES_STDIN; then
2555 if $USES_STDOUT; then
2556 ${=WGET_CMD} "$ARCHIVE" | ${=DECOMP_CMD} > $GZTARGET
2559 ${=WGET_CMD} "$ARCHIVE" | ${=DECOMP_CMD}
2563 if $USES_STDOUT; then
2564 ${=DECOMP_CMD} =(${=WGET_CMD} "$ARCHIVE") > $GZTARGET
2566 ${=DECOMP_CMD} =(${=WGET_CMD} "$ARCHIVE")
2571 print "ERROR: '$ARCHIVE' is neither a valid file nor a supported URI." >&2
2581 'files:Archives:_files -g "*.(#l)(tar.bz2|tbz2|tbz|tar.gz|tgz|tar.xz|txz|tar.lzma|tar|rar|lzh|7z|zip|jar|deb|bz2|gz|Z|xz|lzma)"' \
2582 '_urls:Remote Archives:_urls'
2588 '-d[delete original archivefile after extraction]' \
2589 '*:Archive Or Uri:__archive_or_uri'
2591 compdef _simple_extract simple-extract
2592 alias se=simple-extract
2594 #f5# Set all ulimit parameters to \kbd{unlimited}
2605 #f5# Change the xterm title from within GNU-screen
2608 if [[ $1 != "-f" ]] ; then
2609 if [[ -z ${DISPLAY} ]] ; then
2610 printf 'xtrename only makes sense in X11.\n'
2616 if [[ -z $1 ]] ; then
2617 printf 'usage: xtrename [-f] "title for xterm"\n'
2618 printf ' renames the title of xterm from _within_ screen.\n'
2619 printf ' also works without screen.\n'
2620 printf ' will not work if DISPLAY is unset, use -f to override.\n'
2623 print -n "\eP\e]0;${1}\C-G\e\\"
2628 # Rewrite this by either using tinyurl.com's API
2629 # or using another shortening service to comply with
2630 # tinyurl.com's policy.
2632 # Create small urls via http://tinyurl.com using wget(1).
2635 # [[ -z $1 ]] && { print "USAGE: zurl <URL>" ; return 1 }
2637 # local PN url tiny grabber search result preview
2640 ## Check existence of given URL with the help of ping(1).
2641 ## N.B. ping(1) only works without an eventual given protocol.
2642 # ping -c 1 ${${url#(ftp|http)://}%%/*} >& /dev/null || \
2643 # read -q "?Given host ${${url#http://*/}%/*} is not reachable by pinging. Proceed anyway? [y|n] "
2645 # if (( $? == 0 )) ; then
2646 ## Prepend 'http://' to given URL where necessary for later output.
2647 # [[ ${url} != http(s|)://* ]] && url='http://'${url}
2648 # tiny='http://tinyurl.com/create.php?url='
2649 # if check_com -c wget ; then
2650 # grabber='wget -O- -o/dev/null'
2652 # print "wget is not available, but mandatory for ${PN}. Aborting."
2654 ## Looking for i.e.`copy('http://tinyurl.com/7efkze')' in TinyURL's HTML code.
2655 # search='copy\(?http://tinyurl.com/[[:alnum:]]##*'
2656 # result=${(M)${${${(f)"$(${=grabber} ${tiny}${url})"}[(fr)${search}*]}//[()\';]/}%%http:*}
2657 ## TinyURL provides the rather new feature preview for more confidence. <http://tinyurl.com/preview.php>
2658 # preview='http://preview.'${result#http://}
2660 # printf '%s\n\n' "${PN} - Shrinking long URLs via webservice TinyURL <http://tinyurl.com>."
2661 # printf '%s\t%s\n\n' 'Given URL:' ${url}
2662 # printf '%s\t%s\n\t\t%s\n' 'TinyURL:' ${result} ${preview}
2668 #f2# Find history events by search pattern and list them by date.
2671 local usage help ident format_l format_s first_char remain first last
2672 usage='USAGE: whatwhen [options] <searchstring> <search range>'
2673 help='Use `whatwhen -h'\'' for further explanations.'
2674 ident=${(l,${#${:-Usage: }},, ,)}
2675 format_l="${ident}%s\t\t\t%s\n"
2676 format_s="${format_l//(\\t)##/\\t}"
2677 # Make the first char of the word to search for case
2678 # insensitive; e.g. [aA]
2679 first_char=[${(L)1[1]}${(U)1[1]}]
2681 # Default search range is `-100'.
2683 # Optional, just used for `<first> <last>' given.
2687 printf '%s\n\n' 'ERROR: No search string specified. Aborting.'
2688 printf '%s\n%s\n\n' ${usage} ${help} && return 1
2691 printf '%s\n\n' ${usage}
2693 printf $format_l '-h' 'show help text'
2695 print 'SEARCH RANGE:'
2696 printf $format_l "'0'" 'the whole history,'
2697 printf $format_l '-<n>' 'offset to the current history number; (default: -100)'
2698 printf $format_s '<[-]first> [<last>]' 'just searching within a give range'
2699 printf '\n%s\n' 'EXAMPLES:'
2700 printf ${format_l/(\\t)/} 'whatwhen grml' '# Range is set to -100 by default.'
2701 printf $format_l 'whatwhen zsh -250'
2702 printf $format_l 'whatwhen foo 1 99'
2705 printf '%s\n%s\n\n' ${usage} ${help} && return 1
2708 # -l list results on stout rather than invoking $EDITOR.
2709 # -i Print dates as in YYYY-MM-DD.
2710 # -m Search for a - quoted - pattern within the history.
2711 fc -li -m "*${first_char}${remain}*" $first $last
2716 # mercurial related stuff
2717 if check_com -c hg ; then
2718 # gnu like diff for mercurial
2719 # http://www.selenic.com/mercurial/wiki/index.cgi/TipsAndTricks
2720 #f5# GNU like diff for mercurial
2723 for i in $(hg status -marn "$@") ; diff -ubwd <(hg cat "$i") "$i"
2726 # build debian package
2727 #a2# Alias for \kbd{hg-buildpackage}
2728 alias hbp='hg-buildpackage'
2730 # execute commands on the versioned patch-queue from the current repos
2731 alias mq='hg -R $(readlink -f $(hg root)/.hg/patches)'
2733 # diffstat for specific version of a mercurial repository
2734 # hgstat => display diffstat between last revision and tip
2735 # hgstat 1234 => display diffstat between revision 1234 and tip
2736 #f5# Diffstat for specific version of a mercurial repos
2739 [[ -n "$1" ]] && hg diff -r $1 -r tip | diffstat || hg export tip | diffstat
2742 fi # end of check whether we have the 'hg'-executable
2744 # grml-small cleanups
2746 # The following is used to remove zsh-config-items that do not work
2747 # in grml-small by default.
2748 # If you do not want these adjustments (for whatever reason), set
2749 # $GRMLSMALL_SPECIFIC to 0 in your .zshrc.pre file (which this configuration
2750 # sources if it is there).
2752 if (( GRMLSMALL_SPECIFIC > 0 )) && isgrmlsmall ; then
2755 unalias 'V' &> /dev/null
2756 unfunction vman &> /dev/null
2757 unfunction viless &> /dev/null
2758 unfunction 2html &> /dev/null
2760 # manpages are not in grmlsmall
2761 unfunction manzsh &> /dev/null
2762 unfunction man2 &> /dev/null
2768 ## genrefcard.pl settings
2770 ### doc strings for external functions from files
2771 #m# f5 grml-wallpaper() Sets a wallpaper (try completion for possible values)
2773 ### example: split functions-search 8,16,24,32
2774 #@# split functions-search 8
2776 ## END OF FILE #################################################################
2777 # vim:filetype=zsh foldmethod=marker autoindent expandtab shiftwidth=4