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 zle -N grml_toggle_abbrev
696 bindkey '^xA' grml_toggle_abbrev
698 # add a command line to the shells history without executing it
699 commit-to-history() {
700 print -s ${(z)BUFFER}
703 zle -N commit-to-history
704 bindkey "^x^h" commit-to-history
706 # only slash should be considered as a word separator:
707 slash-backward-kill-word() {
708 local WORDCHARS="${WORDCHARS:s@/@}"
710 zle backward-kill-word
712 zle -N slash-backward-kill-word
714 #k# Kill left-side word or everything up to next slash
715 bindkey '\ev' slash-backward-kill-word
716 #k# Kill left-side word or everything up to next slash
717 bindkey '\e^h' slash-backward-kill-word
718 #k# Kill left-side word or everything up to next slash
719 bindkey '\e^?' slash-backward-kill-word
721 # use the new *-pattern-* widgets for incremental history search
723 bindkey '^r' history-incremental-pattern-search-backward
724 bindkey '^s' history-incremental-pattern-search-forward
727 # a generic accept-line wrapper
729 # This widget can prevent unwanted autocorrections from command-name
730 # to _command-name, rehash automatically on enter and call any number
731 # of builtin and user-defined widgets in different contexts.
733 # For a broader description, see:
734 # <http://bewatermyfriend.org/posts/2007/12-26.11-50-38-tooltime.html>
736 # The code is imported from the file 'zsh/functions/accept-line' from
737 # <http://ft.bewatermyfriend.org/comp/zsh/zsh-dotfiles.tar.bz2>, which
738 # distributed under the same terms as zsh itself.
740 # A newly added command will may not be found or will cause false
741 # correction attempts, if you got auto-correction set. By setting the
742 # following style, we force accept-line() to rehash, if it cannot
743 # find the first word on the command line in the $command[] hash.
744 zstyle ':acceptline:*' rehash true
746 function Accept-Line() {
747 setopt localoptions noksharrays
751 local alcontext=${1:-$alcontext}
753 zstyle -a ":acceptline:${alcontext}" actions subs
755 (( ${#subs} < 1 )) && return 0
758 for sub in ${subs} ; do
759 [[ ${sub} == 'accept-line' ]] && sub='.accept-line'
762 (( aldone > 0 )) && break
766 function Accept-Line-getdefault() {
770 zstyle -s ":acceptline:${alcontext}" default_action default_action
771 case ${default_action} in
773 printf ".accept-line"
776 printf ${default_action}
781 function Accept-Line-HandleContext() {
784 default_action=$(Accept-Line-getdefault)
785 zstyle -T ":acceptline:${alcontext}" call_default \
786 && zle ${default_action}
789 function accept-line() {
790 setopt localoptions noksharrays
793 local buf com fname format msg default_action
797 cmdline=(${(z)BUFFER})
801 Accept-Line 'preprocess'
803 zstyle -t ":acceptline:${alcontext}" rehash \
804 && [[ -z ${commands[$com]} ]] \
808 && [[ -n ${reswords[(r)$com]} ]] \
809 || [[ -n ${aliases[$com]} ]] \
810 || [[ -n ${functions[$com]} ]] \
811 || [[ -n ${builtins[$com]} ]] \
812 || [[ -n ${commands[$com]} ]] ; then
814 # there is something sensible to execute, just do it.
816 Accept-Line-HandleContext
821 if [[ -o correct ]] \
822 || [[ -o correctall ]] \
823 && [[ -n ${functions[$fname]} ]] ; then
825 # nothing there to execute but there is a function called
826 # _command_name; a completion widget. Makes no sense to
827 # call it on the commandline, but the correct{,all} options
828 # will ask for it nevertheless, so warn the user.
829 if [[ ${LASTWIDGET} == 'accept-line' ]] ; then
830 # Okay, we warned the user before, he called us again,
831 # so have it his way.
833 Accept-Line-HandleContext
838 if zstyle -t ":acceptline:${alcontext}" nocompwarn ; then
840 Accept-Line-HandleContext
842 # prepare warning message for the user, configurable via zstyle.
843 zstyle -s ":acceptline:${alcontext}" compwarnfmt msg
845 if [[ -z ${msg} ]] ; then
846 msg="%c will not execute and completion %f exists."
849 zformat -f msg "${msg}" "c:${com}" "f:${fname}"
854 elif [[ -n ${buf//[$' \t\n']##/} ]] ; then
855 # If we are here, the commandline contains something that is not
856 # executable, which is neither subject to _command_name correction
857 # and is not empty. might be a variable assignment
859 Accept-Line-HandleContext
864 # If we got this far, the commandline only contains whitespace, or is empty.
866 Accept-Line-HandleContext
871 zle -N Accept-Line-HandleContext
873 ## This widget prevents accidental execution of rm -R / or rm -R ~
874 ## It only works if rmstartsilent option (turns of rm /* check) is off
875 ## It won't bother you, unless rm is used with -r or -R option and target is home or root
876 ## In case of abort, the commandline is pushed on the history so it can be corrected
877 zle_confirm_rm_home_or_root () {
878 [[ -o rmstarsilent ]] && return 0
882 cmdline=(${(z)BUFFER})
883 [[ $cmdline[(I)(-[fiIv]#[rR][fiIv]#|--recursive)] -eq 0 ]] && return 0
884 local askindex=$cmdline[(I)(\~|\~/|/|$HOME)]
885 if [[ "${cmdline[1]}" = "rm" && $askindex -ne 0 ]]
887 zle -R "zsh: sure you want to recursively delete: $cmdline[askindex] [yN]?"
889 if [[ $REPLY != [YyJj] ]]
891 fc -R =(<<<"$BUFFER")
896 zle -N zle_confirm_rm_home_or_root
897 ## add as widget to be executed by grmls Accept-Line if it's a valid command
898 zstyle ":acceptline:normal" actions "zle_confirm_rm_home_or_root"
900 # power completion - abbreviation expansion
901 # power completion / abbreviation expansion / buffer expansion
902 # see http://zshwiki.org/home/examples/zleiab for details
903 # less risky than the global aliases but powerful as well
904 # just type the abbreviation key and afterwards ',.' to expand it
907 setopt interactivecomments
909 # key # value (#d additional doc string)
915 'G' '|& grep --color=auto '
917 'Hl' ' --help |& less -r' #d (Display help in pager)
921 'N' '&>/dev/null' #d (No Output)
922 'R' '| tr A-z N-za-m' #d (ROT13)
928 'co' './configure && make && sudo make install'
936 if (( NOABBREVIATION > 0 )) ; then
937 LBUFFER="${LBUFFER},."
941 matched_chars='[.-|_a-zA-Z0-9]#'
942 LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
943 LBUFFER+=${abk[$MATCH]:-$MATCH}
950 zrcautoload zmv # who needs mmv or rename?
951 zrcautoload history-search-end
953 # we don't want to quote/espace URLs on our own...
954 # if autoload -U url-quote-magic ; then
955 # zle -N self-insert url-quote-magic
956 # zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}='
958 # print 'Notice: no url-quote-magic available :('
960 alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic'
962 #m# k ESC-h Call \kbd{run-help} for the 1st word on the command line
963 alias run-help >&/dev/null && unalias run-help
964 for rh in run-help{,-git,-svk,-svn}; do
969 if zrcautoload compinit ; then
970 compinit || print 'Notice: no compinit available :('
972 print 'Notice: no compinit available :('
977 is4 && zrcautoload zed # use ZLE editor to edit a file or function
980 for mod in complist deltochar mathfunc ; do
981 zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :("
984 # autoload zsh modules when they are referenced
986 zmodload -a zsh/stat zstat
987 zmodload -a zsh/zpty zpty
988 zmodload -ap zsh/mapfile mapfile
991 if is4 && zrcautoload insert-files && zle -N insert-files ; then
992 #k# Insert files and test globbing
993 bindkey "^Xf" insert-files # C-x-f
996 bindkey ' ' magic-space # also do history expansion on space
997 #k# Trigger menu-complete
998 bindkey '\ei' menu-complete # menu completion via esc-i
1000 # press esc-e for editing command line in $EDITOR or $VISUAL
1001 if is4 && zrcautoload edit-command-line && zle -N edit-command-line ; then
1002 #k# Edit the current line in \kbd{\$EDITOR}
1003 bindkey '\ee' edit-command-line
1006 if is4 && [[ -n ${(k)modules[zsh/complist]} ]] ; then
1007 #k# menu selection: pick item but stay in the menu
1008 bindkey -M menuselect '\e^M' accept-and-menu-complete
1009 # also use + and INSERT since it's easier to press repeatedly
1010 bindkey -M menuselect "+" accept-and-menu-complete
1011 bindkey -M menuselect "^[[2~" accept-and-menu-complete
1013 # accept a completion and try to complete again by using menu
1014 # completion; very useful with completing directories
1015 # by using 'undo' one's got a simple file browser
1016 bindkey -M menuselect '^o' accept-and-infer-next-history
1019 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
1020 insert-datestamp() { LBUFFER+=${(%):-'%D{%Y-%m-%d}'}; }
1021 zle -N insert-datestamp
1023 #k# Insert a timestamp on the command line (yyyy-mm-dd)
1024 bindkey '^Ed' insert-datestamp
1026 # press esc-m for inserting last typed word again (thanks to caphuso!)
1027 insert-last-typed-word() { zle insert-last-word -- 0 -1 };
1028 zle -N insert-last-typed-word;
1030 #k# Insert last typed word
1031 bindkey "\em" insert-last-typed-word
1033 function grml-zsh-fg() {
1034 if (( ${#jobstates} )); then
1036 [[ -o hist_ignore_space ]] && BUFFER=' ' || BUFFER=''
1037 BUFFER="${BUFFER}fg"
1040 zle -M 'No background jobs. Doing nothing.'
1044 #k# A smart shortcut for \kbd{fg<enter>}
1045 bindkey '^z' grml-zsh-fg
1047 # run command line as user root via sudo:
1048 sudo-command-line() {
1049 [[ -z $BUFFER ]] && zle up-history
1050 if [[ $BUFFER != sudo\ * ]]; then
1051 BUFFER="sudo $BUFFER"
1052 CURSOR=$(( CURSOR+5 ))
1055 zle -N sudo-command-line
1057 #k# prepend the current command with "sudo"
1058 bindkey "^Os" sudo-command-line
1060 ### jump behind the first word on the cmdline.
1061 ### useful to add options.
1062 function jump_after_first_word() {
1064 words=(${(z)BUFFER})
1066 if (( ${#words} <= 1 )) ; then
1069 CURSOR=${#${words[1]}}
1072 zle -N jump_after_first_word
1073 #k# jump to after first word (for adding options)
1074 bindkey '^x1' jump_after_first_word
1076 # complete word from history with menu (from Book: ZSH, OpenSource-Press)
1077 zle -C hist-complete complete-word _generic
1078 zstyle ':completion:hist-complete:*' completer _history
1079 #k# complete word from history with menu
1080 bindkey "^X^X" hist-complete
1082 ## complete word from currently visible Screen or Tmux buffer.
1083 if check_com -c screen || check_com -c tmux; then
1084 _complete_screen_display() {
1085 [[ "$TERM" != "screen" ]] && return 1
1087 local TMPFILE=$(mktemp)
1088 local -U -a _screen_display_wordlist
1089 trap "rm -f $TMPFILE" EXIT
1091 # fill array with contents from screen hardcopy
1092 if ((${+TMUX})); then
1093 #works, but crashes tmux below version 1.4
1094 #luckily tmux -V option to ask for version, was also added in 1.4
1095 tmux -V &>/dev/null || return
1096 tmux -q capture-pane \; save-buffer -b 0 $TMPFILE \; delete-buffer -b 0
1098 screen -X hardcopy $TMPFILE
1099 # screen sucks, it dumps in latin1, apparently always. so recode it
1101 check_com recode && recode latin1 $TMPFILE
1103 _screen_display_wordlist=( ${(QQ)$(<$TMPFILE)} )
1104 # remove PREFIX to be completed from that array
1105 _screen_display_wordlist[${_screen_display_wordlist[(i)$PREFIX]}]=""
1106 compadd -a _screen_display_wordlist
1108 #k# complete word from currently visible GNU screen buffer
1110 compdef -k _complete_screen_display complete-word '^XS'
1118 HISTFILE=$HOME/.zsh_history
1119 isgrmlcd && HISTSIZE=500 || HISTSIZE=5000
1120 isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
1124 DIRSTACKSIZE=${DIRSTACKSIZE:-20}
1125 DIRSTACKFILE=${DIRSTACKFILE:-${HOME}/.zdirs}
1127 if [[ -f ${DIRSTACKFILE} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then
1128 dirstack=( ${(f)"$(< $DIRSTACKFILE)"} )
1129 # "cd -" won't work after login by just setting $OLDPWD, so
1130 [[ -d $dirstack[1] ]] && cd $dirstack[1] && cd $OLDPWD
1135 my_stack=( ${PWD} ${dirstack} )
1137 builtin print -l ${(u)my_stack} >! ${DIRSTACKFILE}
1139 uprint my_stack >! ${DIRSTACKFILE}
1143 # directory based profiles
1147 CHPWD_PROFILE='default'
1148 function chpwd_profiles() {
1149 # Say you want certain settings to be active in certain directories.
1150 # This is what you want.
1152 # zstyle ':chpwd:profiles:/usr/src/grml(|/|/*)' profile grml
1153 # zstyle ':chpwd:profiles:/usr/src/debian(|/|/*)' profile debian
1155 # When that's done and you enter a directory that matches the pattern
1156 # in the third part of the context, a function called chpwd_profile_grml,
1157 # for example, is called (if it exists).
1159 # If no pattern matches (read: no profile is detected) the profile is
1160 # set to 'default', which means chpwd_profile_default is attempted to
1163 # A word about the context (the ':chpwd:profiles:*' stuff in the zstyle
1164 # command) which is used: The third part in the context is matched against
1165 # ${PWD}. That's why using a pattern such as /foo/bar(|/|/*) makes sense.
1166 # Because that way the profile is detected for all these values of ${PWD}:
1170 # So, if you want to make double damn sure a profile works in /foo/bar
1171 # and everywhere deeper in that tree, just use (|/|/*) and be happy.
1173 # The name of the detected profile will be available in a variable called
1174 # 'profile' in your functions. You don't need to do anything, it'll just
1177 # Then there is the parameter $CHPWD_PROFILE is set to the profile, that
1178 # was is currently active. That way you can avoid running code for a
1179 # profile that is already active, by running code such as the following
1180 # at the start of your function:
1182 # function chpwd_profile_grml() {
1183 # [[ ${profile} == ${CHPWD_PROFILE} ]] && return 1
1187 # The initial value for $CHPWD_PROFILE is 'default'.
1189 # Version requirement:
1190 # This feature requires zsh 4.3.3 or newer.
1191 # If you use this feature and need to know whether it is active in your
1192 # current shell, there are several ways to do that. Here are two simple
1195 # a) If knowing if the profiles feature is active when zsh starts is
1196 # good enough for you, you can put the following snippet into your
1199 # (( ${+functions[chpwd_profiles]} )) && print "directory profiles active"
1201 # b) If that is not good enough, and you would prefer to be notified
1202 # whenever a profile changes, you can solve that by making sure you
1203 # start *every* profile function you create like this:
1205 # function chpwd_profile_myprofilename() {
1206 # [[ ${profile} == ${CHPWD_PROFILE} ]] && return 1
1207 # print "chpwd(): Switching to profile: $profile"
1211 # That makes sure you only get notified if a profile is *changed*,
1212 # not everytime you change directory, which would probably piss
1213 # you off fairly quickly. :-)
1215 # There you go. Now have fun with that.
1218 zstyle -s ":chpwd:profiles:${PWD}" profile profile || profile='default'
1219 if (( ${+functions[chpwd_profile_$profile]} )) ; then
1220 chpwd_profile_${profile}
1223 CHPWD_PROFILE="${profile}"
1226 chpwd_functions=( ${chpwd_functions} chpwd_profiles )
1230 # display battery status on right side of prompt via running 'BATTERY=1 zsh'
1231 if [[ $BATTERY -gt 0 ]] ; then
1232 if ! check_com -c acpi ; then
1238 if [[ $BATTERY -gt 0 ]] ; then
1239 PERCENT="${${"$(acpi 2>/dev/null)"}/(#b)[[:space:]]#Battery <->: [^0-9]##, (<->)%*/${match[1]}}"
1240 if [[ -z "$PERCENT" ]] ; then
1241 PERCENT='acpi not present'
1243 if [[ "$PERCENT" -lt 20 ]] ; then
1244 PERCENT="warning: ${PERCENT}%%"
1246 PERCENT="${PERCENT}%%"
1251 # set colors for use in prompts
1252 if zrcautoload colors && colors 2>/dev/null ; then
1253 BLUE="%{${fg[blue]}%}"
1254 RED="%{${fg_bold[red]}%}"
1255 GREEN="%{${fg[green]}%}"
1256 CYAN="%{${fg[cyan]}%}"
1257 MAGENTA="%{${fg[magenta]}%}"
1258 YELLOW="%{${fg[yellow]}%}"
1259 WHITE="%{${fg[white]}%}"
1260 NO_COLOUR="%{${reset_color}%}"
1262 BLUE=$'%{\e[1;34m%}'
1264 GREEN=$'%{\e[1;32m%}'
1265 CYAN=$'%{\e[1;36m%}'
1266 WHITE=$'%{\e[1;37m%}'
1267 MAGENTA=$'%{\e[1;35m%}'
1268 YELLOW=$'%{\e[1;33m%}'
1269 NO_COLOUR=$'%{\e[0m%}'
1272 # gather version control information for inclusion in a prompt
1274 if zrcautoload vcs_info; then
1275 # `vcs_info' in zsh versions 4.3.10 and below have a broken `_realpath'
1276 # function, which can cause a lot of trouble with our directory-based
1278 if [[ ${ZSH_VERSION} == 4.3.<-10> ]] ; then
1279 function VCS_INFO_realpath () {
1280 setopt localoptions NO_shwordsplit chaselinks
1281 ( builtin cd -q $1 2> /dev/null && pwd; )
1285 zstyle ':vcs_info:*' max-exports 2
1287 if [[ -o restricted ]]; then
1288 zstyle ':vcs_info:*' enable NONE
1292 # Change vcs_info formats for the grml prompt. The 2nd format sets up
1293 # $vcs_info_msg_1_ to contain "zsh: repo-name" used to set our screen title.
1294 # TODO: The included vcs_info() version still uses $VCS_INFO_message_N_.
1295 # That needs to be the use of $VCS_INFO_message_N_ needs to be changed
1296 # to $vcs_info_msg_N_ as soon as we use the included version.
1297 if [[ "$TERM" == dumb ]] ; then
1298 zstyle ':vcs_info:*' actionformats "(%s%)-[%b|%a] " "zsh: %r"
1299 zstyle ':vcs_info:*' formats "(%s%)-[%b] " "zsh: %r"
1301 # these are the same, just with a lot of colours:
1302 zstyle ':vcs_info:*' actionformats "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOUR} " \
1304 zstyle ':vcs_info:*' formats "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOUR}%} " \
1306 zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat "%b${RED}:${YELLOW}%r"
1309 # command not found handling
1311 (( ${COMMAND_NOT_FOUND} == 1 )) &&
1312 function command_not_found_handler() {
1314 if [[ -x ${GRML_ZSH_CNF_HANDLER} ]] ; then
1315 ${GRML_ZSH_CNF_HANDLER} $1
1321 if zrcautoload promptinit && promptinit 2>/dev/null ; then
1322 promptinit # people should be able to use their favourite prompt
1324 print 'Notice: no promptinit available :('
1329 # make sure to use right prompt only when not running a command
1330 is41 && setopt transient_rprompt
1333 function ESC_print () {
1334 info_print $'\ek' $'\e\\' "$@"
1336 function set_title () {
1337 info_print $'\e]0;' $'\a' "$@"
1340 function info_print () {
1341 local esc_begin esc_end
1345 printf '%s' ${esc_begin}
1347 printf '%s' "${esc_end}"
1350 # TODO: revise all these NO* variables and especially their documentation
1351 # in zsh-help() below.
1352 is4 && [[ $NOPRECMD -eq 0 ]] && precmd () {
1353 [[ $NOPRECMD -gt 0 ]] && return 0
1354 # update VCS information
1355 (( ${+functions[vcs_info]} )) && vcs_info
1357 if [[ $TERM == screen* ]] ; then
1358 if [[ -n ${vcs_info_msg_1_} ]] ; then
1359 ESC_print ${vcs_info_msg_1_}
1364 # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
1365 if [[ ${DONTSETRPROMPT:-} -eq 0 ]] ; then
1366 if [[ $BATTERY -gt 0 ]] ; then
1367 # update battery (dropped into $PERCENT) information
1369 RPROMPT="%(?..:() ${PERCENT}"
1374 # adjust title of xterm
1375 # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
1376 [[ ${NOTITLE:-} -gt 0 ]] && return 0
1379 set_title ${(%):-"%n@%m: %~"}
1384 # preexec() => a function running before every command
1385 is4 && [[ $NOPRECMD -eq 0 ]] && \
1387 [[ $NOPRECMD -gt 0 ]] && return 0
1388 # set hostname if not running on host with name 'grml'
1389 if [[ -n "$HOSTNAME" ]] && [[ "$HOSTNAME" != $(hostname) ]] ; then
1392 # get the name of the program currently running and hostname of local machine
1393 # set screen window title if running in a screen
1394 if [[ "$TERM" == screen* ]] ; then
1395 # local CMD=${1[(wr)^(*=*|sudo|ssh|-*)]} # don't use hostname
1396 local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME" # use hostname
1399 # adjust title of xterm
1400 [[ ${NOTITLE} -gt 0 ]] && return 0
1403 set_title "${(%):-"%n@%m:"}" "$1"
1408 EXITCODE="%(?..%?%1v )"
1409 # secondary prompt, printed when the shell needs more information to complete a
1412 # selection prompt used within a select loop.
1414 # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
1417 # set variable debian_chroot if running in a chroot with /etc/debian_chroot
1418 if [[ -z "$debian_chroot" ]] && [[ -r /etc/debian_chroot ]] ; then
1419 debian_chroot=$(cat /etc/debian_chroot)
1422 # don't use colors on dumb terminals (like emacs):
1423 if [[ "$TERM" == dumb ]] ; then
1424 PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< "
1426 # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended
1427 # prompt set variable identifying the chroot you work in (used in the
1429 if [[ $GRMLPROMPT -gt 0 ]] ; then
1430 PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
1431 ${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "
1433 # This assembles the primary prompt string
1434 if (( EUID != 0 )); then
1435 PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "
1437 PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "
1442 PROMPT="${PROMPT}"'${vcs_info_msg_0_}'"%# "
1444 # if we are inside a grml-chroot set a specific prompt theme
1445 if [[ -n "$GRML_CHROOT" ]] ; then
1446 PROMPT="%{$fg[red]%}(CHROOT) %{$fg_bold[red]%}%n%{$fg_no_bold[white]%}@%m %40<...<%B%~%b%<< %\# "
1449 # 'hash' some often used directories
1451 hash -d deb=/var/cache/apt/archives
1452 hash -d doc=/usr/share/doc
1453 hash -d linux=/lib/modules/$(command uname -r)/build/
1454 hash -d log=/var/log
1455 hash -d slog=/var/log/syslog
1456 hash -d src=/usr/src
1457 hash -d templ=/usr/share/doc/grml-templates
1458 hash -d tt=/usr/share/doc/texttools-doc
1459 hash -d www=/var/www
1463 if check_com -c screen ; then
1464 if [[ $UID -eq 0 ]] ; then
1465 if [[ -r /etc/grml/screenrc ]]; then
1466 alias screen="${commands[screen]} -c /etc/grml/screenrc"
1468 elif [[ -r $HOME/.screenrc ]] ; then
1469 alias screen="${commands[screen]} -c $HOME/.screenrc"
1471 if [[ -r /etc/grml/screenrc_grml ]]; then
1472 alias screen="${commands[screen]} -c /etc/grml/screenrc_grml"
1474 if [[ -r /etc/grml/screenrc ]]; then
1475 alias screen="${commands[screen]} -c /etc/grml/screenrc"
1481 # do we have GNU ls with color-support?
1482 if ls --help 2>/dev/null | grep -- --color= >/dev/null \
1483 && [[ "$TERM" != dumb ]]
1485 #a1# execute \kbd{@a@}:\quad ls with colors
1486 alias ls='ls -b -CF --color=auto'
1487 #a1# execute \kbd{@a@}:\quad list all files, with colors
1488 alias la='ls -la --color=auto'
1489 #a1# long colored list, without dotfiles (@a@)
1490 alias ll='ls -l --color=auto'
1491 #a1# long colored list, human readable sizes (@a@)
1492 alias lh='ls -hAl --color=auto'
1493 #a1# List files, append qualifier to filenames \\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
1494 alias l='ls -lF --color=auto'
1496 alias ls='ls -b -CF'
1503 alias mdstat='cat /proc/mdstat'
1504 alias ...='cd ../../'
1506 # generate alias named "$KERNELVERSION-reboot" so you can use boot with kexec:
1507 if [[ -x /sbin/kexec ]] && [[ -r /proc/cmdline ]] ; then
1508 alias "$(uname -r)-reboot"="kexec -l --initrd=/boot/initrd.img-"$(uname -r)" --command-line=\"$(cat /proc/cmdline)\" /boot/vmlinuz-"$(uname -r)""
1511 # see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
1512 alias term2iso="echo 'Setting terminal to iso mode' ; print -n '\e%@'"
1513 alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
1515 # make sure it is not assigned yet
1516 [[ -n ${aliases[utf2iso]} ]] && unalias utf2iso
1519 for ENV in $(env | command grep -i '.utf') ; do
1520 eval export "$(echo $ENV | sed 's/UTF-8/iso885915/ ; s/utf8/iso885915/')"
1525 # make sure it is not assigned yet
1526 [[ -n ${aliases[iso2utf]} ]] && unalias iso2utf
1528 if ! isutfenv ; then
1529 for ENV in $(env | command grep -i '\.iso') ; do
1530 eval export "$(echo $ENV | sed 's/iso.*/UTF-8/ ; s/ISO.*/UTF-8/')"
1535 # especially for roadwarriors using GNU screen and ssh:
1536 if ! check_com asc &>/dev/null ; then
1537 asc() { autossh -t "$@" 'screen -RdU' }
1541 #f1# Hints for the use of zsh on grml
1543 print "$bg[white]$fg[black]
1544 zsh-help - hints for use of zsh on grml
1545 =======================================$reset_color"
1548 Main configuration of zsh happens in /etc/zsh/zshrc.
1549 That file is part of the package grml-etc-core, if you want to
1550 use them on a non-grml-system just get the tar.gz from
1551 http://deb.grml.org/ or (preferably) get it from the git repository:
1553 http://git.grml.org/f/grml-etc-core/etc/zsh/zshrc
1555 This version of grml'\''s zsh setup does not use skel/.zshrc anymore.
1556 The file is still there, but it is empty for backwards compatibility.
1558 For your own changes use these two files:
1562 The former is sourced very early in our zshrc, the latter is sourced
1565 System wide configuration without touching configuration files of grml
1566 can take place in /etc/zsh/zshrc.local.
1568 For information regarding zsh start at http://grml.org/zsh/
1570 Take a look at grml'\''s zsh refcard:
1571 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
1573 Check out the main zsh refcard:
1574 % '$BROWSER' http://www.bash2zsh.com/zsh_refcard/refcard.pdf
1576 And of course visit the zsh-lovers:
1579 You can adjust some options through environment variables when
1580 invoking zsh without having to edit configuration files.
1581 Basically meant for bash users who are not used to the power of
1584 "NOCOR=1 zsh" => deactivate automatic correction
1585 "NOMENU=1 zsh" => do not use auto menu completion
1586 (note: use ctrl-d for completion instead!)
1587 "NOPRECMD=1 zsh" => disable the precmd + preexec commands (set GNU screen title)
1588 "NOTITLE=1 zsh" => disable setting the title of xterms without disabling
1589 preexec() and precmd() completely
1590 "BATTERY=1 zsh" => activate battery status (via acpi) on right side of prompt
1591 "COMMAND_NOT_FOUND=1 zsh"
1592 => Enable a handler if an external command was not found
1593 The command called in the handler can be altered by setting
1594 the GRML_ZSH_CNF_HANDLER variable, the default is:
1595 "/usr/share/command-not-found/command-not-found"
1597 A value greater than 0 is enables a feature; a value equal to zero
1598 disables it. If you like one or the other of these settings, you can
1599 add them to ~/.zshrc.pre to ensure they are set when sourcing grml'\''s
1603 $bg[white]$fg[black]
1604 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
1605 Enjoy your grml system with the zsh!$reset_color"
1609 if [[ -r /etc/debian_version ]] ; then
1610 #a3# Execute \kbd{apt-cache search}
1611 alias acs='apt-cache search'
1612 #a3# Execute \kbd{apt-cache show}
1613 alias acsh='apt-cache show'
1614 #a3# Execute \kbd{apt-cache policy}
1615 alias acp='apt-cache policy'
1616 #a3# Execute \kbd{apt-get dist-upgrade}
1617 salias adg="apt-get dist-upgrade"
1618 #a3# Execute \kbd{apt-get install}
1619 salias agi="apt-get install"
1620 #a3# Execute \kbd{aptitude install}
1621 salias ati="aptitude install"
1622 #a3# Execute \kbd{apt-get upgrade}
1623 salias ag="apt-get upgrade"
1624 #a3# Execute \kbd{apt-get update}
1625 salias au="apt-get update"
1626 #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
1627 salias -a up="aptitude update ; aptitude safe-upgrade"
1628 #a3# Execute \kbd{dpkg-buildpackage}
1629 alias dbp='dpkg-buildpackage'
1630 #a3# Execute \kbd{grep-excuses}
1631 alias ge='grep-excuses'
1633 # get a root shell as normal user in live-cd mode:
1634 if isgrmlcd && [[ $UID -ne 0 ]] ; then
1638 #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
1639 salias llog="$PAGER /var/log/syslog" # take a look at the syslog
1640 #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
1641 salias tlog="tail -f /var/log/syslog" # follow the syslog
1644 # sort installed Debian-packages by size
1645 if check_com -c dpkg-query ; then
1646 #a3# List installed Debian-packages sorted by size
1647 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"
1650 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
1651 if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord; then
1652 if check_com -c wodim; then
1655 cdrecord is not provided under its original name by Debian anymore.
1656 See #377109 in the BTS of Debian for more details.
1658 Please use the wodim binary instead
1665 # Use hard limits, except for a smaller stack and no core dumps
1667 is425 && limit stack 8192
1668 isgrmlcd && limit core 0 # important for a live-cd-system
1673 # called later (via is4 && grmlcomp)
1674 # note: use 'zstyle' for getting current settings
1675 # press ^Xh (control-x h) for getting tags in context; ^X? (control-x ?) to run complete_debug with trace output
1677 # TODO: This could use some additional information
1679 # allow one error for every three characters typed in approximate completer
1680 zstyle ':completion:*:approximate:' max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )'
1682 # don't complete backup files as executables
1683 zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)'
1685 # start menu completion only if it could find no unambiguous initial string
1686 zstyle ':completion:*:correct:*' insert-unambiguous true
1687 zstyle ':completion:*:corrections' format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}'
1688 zstyle ':completion:*:correct:*' original true
1690 # activate color-completion
1691 zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
1693 # format on completion
1694 zstyle ':completion:*:descriptions' format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'
1696 # automatically complete 'cd -<tab>' and 'cd -<ctrl-d>' with menu
1697 # zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
1699 # insert all expansions for expand completer
1700 zstyle ':completion:*:expand:*' tag-order all-expansions
1701 zstyle ':completion:*:history-words' list false
1704 zstyle ':completion:*:history-words' menu yes
1706 # ignore duplicate entries
1707 zstyle ':completion:*:history-words' remove-all-dups yes
1708 zstyle ':completion:*:history-words' stop yes
1710 # match uppercase from lowercase
1711 zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
1713 # separate matches into groups
1714 zstyle ':completion:*:matches' group 'yes'
1715 zstyle ':completion:*' group-name ''
1717 if [[ "$NOMENU" -eq 0 ]] ; then
1718 # if there are more than 5 options allow selecting from a menu
1719 zstyle ':completion:*' menu select=5
1721 # don't use any menus at all
1725 zstyle ':completion:*:messages' format '%d'
1726 zstyle ':completion:*:options' auto-description '%d'
1728 # describe options in full
1729 zstyle ':completion:*:options' description 'yes'
1731 # on processes completion complete all user processes
1732 zstyle ':completion:*:processes' command 'ps -au$USER'
1734 # offer indexes before parameters in subscripts
1735 zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
1737 # provide verbose completion information
1738 zstyle ':completion:*' verbose true
1740 # recent (as of Dec 2007) zsh versions are able to provide descriptions
1741 # for commands (read: 1st word in the line) that it will list for the user
1742 # to choose from. The following disables that, because it's not exactly fast.
1743 zstyle ':completion:*:-command-:*:' verbose false
1745 # set format for warnings
1746 zstyle ':completion:*:warnings' format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d'
1748 # define files to ignore for zcompile
1749 zstyle ':completion:*:*:zcompile:*' ignored-patterns '(*~|*.zwc)'
1750 zstyle ':completion:correct:' prompt 'correct to: %e'
1752 # Ignore completion functions for commands you don't have:
1753 zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'
1755 # Provide more processes in completion of programs like killall:
1756 zstyle ':completion:*:processes-names' command 'ps c -u ${USER} -o command | uniq'
1758 # complete manual by their section
1759 zstyle ':completion:*:manuals' separate-sections true
1760 zstyle ':completion:*:manuals.*' insert-sections true
1761 zstyle ':completion:*:man:*' menu yes select
1763 # provide .. as a completion
1764 zstyle ':completion:*' special-dirs ..
1766 # run rehash on completion so new installed program are found automatically:
1768 (( CURRENT == 1 )) && rehash
1773 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
1774 if [[ "$NOCOR" -gt 0 ]] ; then
1775 zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
1778 # try to be smart about when to use what completer...
1780 zstyle -e ':completion:*' completer '
1781 if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then
1782 _last_try="$HISTNO$BUFFER$CURSOR"
1783 reply=(_complete _match _ignored _prefix _files)
1785 if [[ $words[1] == (rm|mv) ]] ; then
1786 reply=(_complete _files)
1788 reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files)
1793 # command for process lists, the local web server details and host completion
1794 zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
1797 [[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \
1798 zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
1802 [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
1803 [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
1815 zstyle ':completion:*:hosts' hosts $hosts
1816 # TODO: so, why is this here?
1817 # zstyle '*' hosts $hosts
1819 # use generic completion system for programs not yet defined; (_gnu_generic works
1820 # with commands that provide a --help option with "standard" gnu-like output.)
1821 for compcom in cp deborphan df feh fetchipac head hnb ipacsum mv \
1822 pal stow tail uname ; do
1823 [[ -z ${_comps[$compcom]} ]] && compdef _gnu_generic ${compcom}
1826 # see upgrade function in this file
1827 compdef _hosts upgrade
1832 # people should use 'grml-x'!
1833 if check_com -c 915resolution; then
1835 echo "Please use 915resolution as resolution modifying tool for Intel \
1841 #a1# Output version of running grml
1842 alias grml-version='cat /etc/grml_version'
1844 if check_com -c rebuildfstab ; then
1845 #a1# Rebuild /etc/fstab
1846 alias grml-rebuildfstab='rebuildfstab -v -r -config'
1849 if check_com -c grml-debootstrap ; then
1851 echo "Installing debian to harddisk is possible by using grml-debootstrap."
1857 # now run the functions
1859 is4 && isgrml && grmlstuff
1863 is4 && xsource "/etc/zsh/keephack"
1865 # wonderful idea of using "e" glob qualifier by Peter Stephenson
1866 # You use it as follows:
1867 # $ NTREF=/reference/file
1869 # This lists all the files in the current directory newer than the reference file.
1870 # You can also specify the reference file inline; note quotes:
1871 # $ ls -l *(e:'nt ~/.zshenv':)
1873 if [[ -n $1 ]] ; then
1876 [[ $REPLY -nt $NTREF ]]
1881 #f1# Reload an autoloadable function
1882 freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
1883 compdef _functions freload
1885 #f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
1887 [[ -z "$1" ]] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
1888 for file in "$@" ; do
1889 while [[ -h "$file" ]] ; do
1891 file=$(readlink "$file")
1896 # TODO: Is it supported to use pager settings like this?
1897 # PAGER='less -Mr' - If so, the use of $PAGER here needs fixing
1898 # with respect to wordsplitting. (ie. ${=PAGER})
1899 if check_com -c $PAGER ; then
1900 #f1# View Debian's changelog of a given package
1903 if [[ -r /usr/share/doc/$1/changelog.Debian.gz ]] ; then
1904 $PAGER /usr/share/doc/$1/changelog.Debian.gz
1905 elif [[ -r /usr/share/doc/$1/changelog.gz ]] ; then
1906 $PAGER /usr/share/doc/$1/changelog.gz
1908 if check_com -c aptitude ; then
1909 echo "No changelog for package $1 found, using aptitude to retrieve it."
1911 aptitude -t unstable changelog $1
1913 aptitude changelog $1
1916 echo "No changelog for package $1 found, sorry."
1921 _dchange() { _files -W /usr/share/doc -/ }
1922 compdef _dchange dchange
1924 #f1# View Debian's NEWS of a given package
1927 if [[ -r /usr/share/doc/$1/NEWS.Debian.gz ]] ; then
1928 $PAGER /usr/share/doc/$1/NEWS.Debian.gz
1930 if [[ -r /usr/share/doc/$1/NEWS.gz ]] ; then
1931 $PAGER /usr/share/doc/$1/NEWS.gz
1933 echo "No NEWS file for package $1 found, sorry."
1938 _dnews() { _files -W /usr/share/doc -/ }
1939 compdef _dnews dnews
1941 #f1# View upstream's changelog of a given package
1944 if [[ -r /usr/share/doc/$1/changelog.gz ]] ; then
1945 $PAGER /usr/share/doc/$1/changelog.gz
1947 echo "No changelog for package $1 found, sorry."
1951 _uchange() { _files -W /usr/share/doc -/ }
1952 compdef _uchange uchange
1957 ZSH_PROFILE_RC=1 $SHELL "$@"
1960 #f1# Edit an alias via zle
1962 [[ -z "$1" ]] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
1964 compdef _aliases edalias
1966 #f1# Edit a function via zle
1968 [[ -z "$1" ]] && { echo "Usage: edfunc <function_to_edit>" ; return 1 } || zed -f "$1" ;
1970 compdef _functions edfunc
1972 # use it e.g. via 'Restart apache2'
1973 #m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
1974 #m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
1975 #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
1976 #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
1977 #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
1978 if [[ -d /etc/init.d || -d /etc/service ]] ; then
1980 local action_="${1:l}" # e.g Start/Stop/Restart
1984 local service_target_="$(readlink /etc/init.d/$service_)"
1985 if [[ $service_target_ == "/usr/bin/sv" ]]; then
1987 case "${action_}" in
1988 start) if [[ ! -e /etc/service/$service_ ]]; then
1989 $SUDO ln -s "/etc/sv/$service_" "/etc/service/"
1991 $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
1993 # there is no reload in runits sysv emulation
1994 reload) $SUDO "/etc/init.d/$service_" "force-reload" "$param_" ;;
1995 *) $SUDO "/etc/init.d/$service_" "${action_}" "$param_" ;;
1999 $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
2005 scripts=( /etc/init.d/*(x:t) )
2006 _describe "service startup script" scripts
2009 for i in Start Restart Stop Force-Reload Reload ; do
2010 eval "$i() { __start_stop $i \"\$1\" \"\$2\" ; }"
2011 compdef _grmlinitd $i
2015 #f1# Provides useful information on globbing
2022 p named pipes (FIFOs)
2023 * executable plain files (0100)
2024 % device files (character or block special)
2025 %b block special files
2026 %c character special files
2027 r owner-readable files (0400)
2028 w owner-writable files (0200)
2029 x owner-executable files (0100)
2030 A group-readable files (0040)
2031 I group-writable files (0020)
2032 E group-executable files (0010)
2033 R world-readable files (0004)
2034 W world-writable files (0002)
2035 X world-executable files (0001)
2036 s setuid files (04000)
2037 S setgid files (02000)
2038 t files with the sticky bit (01000)
2040 print *(m-1) # Files modified up to a day ago
2041 print *(a1) # Files accessed a day ago
2042 print *(@) # Just symlinks
2043 print *(Lk+50) # Files bigger than 50 kilobytes
2044 print *(Lk-50) # Files smaller than 50 kilobytes
2045 print **/*.c # All *.c files recursively starting in \$PWD
2046 print **/*.c~file.c # Same as above, but excluding 'file.c'
2047 print (foo|bar).* # Files starting with 'foo' or 'bar'
2048 print *~*.* # All Files that do not contain a dot
2049 chmod 644 *(.^x) # make all plain non-executable files publically readable
2050 print -l *(.c|.h) # Lists *.c and *.h
2051 print **/*(g:users:) # Recursively match all files that are owned by group 'users'
2052 echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
2054 alias help-zshglob=H-Glob
2056 #v1# set number of lines to display per page
2057 HELP_LINES_PER_PAGE=20
2058 #v1# set location of help-zle cache file
2059 HELP_ZLE_CACHE_FILE=~/.cache/zsh_help_zle_lines.zsh
2060 #f1# helper function for help-zle, actually generates the help text
2061 help_zle_parse_keybindings()
2065 unsetopt ksharrays #indexing starts at 1
2067 #v1# choose files that help-zle will parse for keybindings
2068 ((${+HELPZLE_KEYBINDING_FILES})) || HELPZLE_KEYBINDING_FILES=( /etc/zsh/zshrc ~/.zshrc.pre ~/.zshrc ~/.zshrc.local )
2070 if [[ -r $HELP_ZLE_CACHE_FILE ]]; then
2072 for f ($KEYBINDING_FILES) [[ $f -nt $HELP_ZLE_CACHE_FILE ]] && load_cache=1
2073 [[ $load_cache -eq 0 ]] && . $HELP_ZLE_CACHE_FILE && return
2076 #fill with default keybindings, possibly to be overwriten in a file later
2077 #Note that due to zsh inconsistency on escaping assoc array keys, we encase the key in '' which we will remove later
2078 local -A help_zle_keybindings
2079 help_zle_keybindings['<Ctrl>@']="set MARK"
2080 help_zle_keybindings['<Ctrl>X<Ctrl>J']="vi-join lines"
2081 help_zle_keybindings['<Ctrl>X<Ctrl>B']="jump to matching brace"
2082 help_zle_keybindings['<Ctrl>X<Ctrl>U']="undo"
2083 help_zle_keybindings['<Ctrl>_']="undo"
2084 help_zle_keybindings['<Ctrl>X<Ctrl>F<c>']="find <c> in cmdline"
2085 help_zle_keybindings['<Ctrl>A']="goto beginning of line"
2086 help_zle_keybindings['<Ctrl>E']="goto end of line"
2087 help_zle_keybindings['<Ctrl>t']="transpose charaters"
2088 help_zle_keybindings['<Alt>T']="transpose words"
2089 help_zle_keybindings['<Alt>s']="spellcheck word"
2090 help_zle_keybindings['<Ctrl>K']="backward kill buffer"
2091 help_zle_keybindings['<Ctrl>U']="forward kill buffer"
2092 help_zle_keybindings['<Ctrl>y']="insert previously killed word/string"
2093 help_zle_keybindings["<Alt>'"]="quote line"
2094 help_zle_keybindings['<Alt>"']="quote from mark to cursor"
2095 help_zle_keybindings['<Alt><arg>']="repeat next cmd/char <arg> times (<Alt>-<Alt>1<Alt>0a -> -10 times 'a')"
2096 help_zle_keybindings['<Alt>U']="make next word Uppercase"
2097 help_zle_keybindings['<Alt>l']="make next word lowercase"
2098 help_zle_keybindings['<Ctrl>Xd']="preview expansion under cursor"
2099 help_zle_keybindings['<Alt>q']="push current CL into background, freeing it. Restore on next CL"
2100 help_zle_keybindings['<Alt>.']="insert (and interate through) last word from prev CLs"
2101 help_zle_keybindings['<Alt>,']="complete word from newer history (consecutive hits)"
2102 help_zle_keybindings['<Alt>m']="repeat last typed word on current CL"
2103 help_zle_keybindings['<Ctrl>V']="insert next keypress symbol literally (e.g. for bindkey)"
2104 help_zle_keybindings['!!:n*<Tab>']="insert last n arguments of last command"
2105 help_zle_keybindings['!!:n-<Tab>']="insert arguments n..N-2 of last command (e.g. mv s s d)"
2106 help_zle_keybindings['<Alt>H']="run help on current command"
2108 #init global variables
2109 unset help_zle_lines help_zle_sln
2110 typeset -g -a help_zle_lines
2111 typeset -g help_zle_sln=1
2114 local lastkeybind_desc contents #last description starting with #k# that we found
2115 local num_lines_elapsed=0 #number of lines between last description and keybinding
2116 #search config files in the order they a called (and thus the order in which they overwrite keybindings)
2117 for f in $HELPZLE_KEYBINDING_FILES; do
2118 [[ -r "$f" ]] || continue #not readable ? skip it
2120 for cline in "${(f)contents}"; do
2121 #zsh pattern: matches lines like: #k# ..............
2122 if [[ "$cline" == (#s)[[:space:]]#\#k\#[[:space:]]##(#b)(*)[[:space:]]#(#e) ]]; then
2123 lastkeybind_desc="$match[*]"
2125 #zsh pattern: matches lines that set a keybinding using bindkey or compdef -k
2126 # ignores lines that are commentend out
2127 # grabs first in '' or "" enclosed string with length between 1 and 6 characters
2128 elif [[ "$cline" == [^#]#(bindkey|compdef -k)[[:space:]](*)(#b)(\"((?)(#c1,6))\"|\'((?)(#c1,6))\')(#B)(*) ]]; then
2129 #description prevously found ? description not more than 2 lines away ? keybinding not empty ?
2130 if [[ -n $lastkeybind_desc && $num_lines_elapsed -lt 2 && -n $match[1] ]]; then
2131 #substitute keybinding string with something readable
2132 k=${${${${${${${match[1]/\\e\^h/<Alt><BS>}/\\e\^\?/<Alt><BS>}/\\e\[5~/<PageUp>}/\\e\[6~/<PageDown>}//(\\e|\^\[)/<Alt>}//\^/<Ctrl>}/3~/<Alt><Del>}
2133 #put keybinding in assoc array, possibly overwriting defaults or stuff found in earlier files
2134 #Note that we are extracting the keybinding-string including the quotes (see Note at beginning)
2135 help_zle_keybindings[${k}]=$lastkeybind_desc
2139 ((num_lines_elapsed++))
2144 #calculate length of keybinding column
2146 for k (${(k)help_zle_keybindings[@]}) ((kstrlen < ${#k})) && kstrlen=${#k}
2147 #convert the assoc array into preformated lines, which we are able to sort
2148 for k v in ${(kv)help_zle_keybindings[@]}; do
2149 #pad keybinding-string to kstrlen chars and remove outermost characters (i.e. the quotes)
2150 help_zle_lines+=("${(r:kstrlen:)k[2,-2]}${v}")
2152 #sort lines alphabetically
2153 help_zle_lines=("${(i)help_zle_lines[@]}")
2154 [[ -d ${HELP_ZLE_CACHE_FILE:h} ]] || mkdir -p "${HELP_ZLE_CACHE_FILE:h}"
2155 echo "help_zle_lines=(${(q)help_zle_lines[@]})" >| $HELP_ZLE_CACHE_FILE
2156 zcompile $HELP_ZLE_CACHE_FILE
2158 typeset -g help_zle_sln
2159 typeset -g -a help_zle_lines
2161 #f1# Provides (partially autogenerated) help on keybindings and the zsh line editor
2165 unsetopt ksharrays #indexing starts at 1
2166 #help lines already generated ? no ? then do it
2167 [[ ${+functions[help_zle_parse_keybindings]} -eq 1 ]] && {help_zle_parse_keybindings && unfunction help_zle_parse_keybindings}
2168 #already displayed all lines ? go back to the start
2169 [[ $help_zle_sln -gt ${#help_zle_lines} ]] && help_zle_sln=1
2170 local sln=$help_zle_sln
2171 #note that help_zle_sln is a global var, meaning we remember the last page we viewed
2172 help_zle_sln=$((help_zle_sln + HELP_LINES_PER_PAGE))
2173 zle -M "${(F)help_zle_lines[sln,help_zle_sln-1]}"
2175 #k# display help for keybindings and ZLE (cycle pages with consecutive use)
2176 zle -N help-zle && bindkey '^Xz' help-zle
2178 # grep for running process, like: 'any vim'
2182 if [[ -z "$1" ]] ; then
2183 echo "any - grep for process(es) by keyword" >&2
2184 echo "Usage: any <keyword>" >&2 ; return 1
2186 ps xauwww | grep -i --color=auto "[${1[1]}]${1[2,-1]}"
2191 # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
2192 # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
2193 [[ -r /proc/1/maps ]] && \
2195 print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
2196 cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/') > /dev/null
2197 print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
2200 # a wrapper for vim, that deals with title setting
2202 # set this array to a set of options to vim you always want
2203 # to have set when calling vim (in .zshrc.local), like:
2204 # VIM_OPTIONS=( -p )
2205 # This will cause vim to send every file given on the
2206 # commandline to be send to it's own tab (needs vim7).
2208 VIM_PLEASE_SET_TITLE='yes' command vim ${VIM_OPTIONS} "$@"
2211 # make a backup of a file
2213 cp -a "$1" "${1}_$(date --iso-8601=seconds)"
2216 ssl_hashes=( sha512 sha256 sha1 md5 )
2218 for sh in ${ssl_hashes}; do
2219 eval 'ssl-cert-'${sh}'() {
2221 if [[ -z $1 ]] ; then
2222 printf '\''usage: %s <file>\n'\'' "ssh-cert-'${sh}'"
2225 openssl x509 -noout -fingerprint -'${sh}' -in $1
2229 ssl-cert-fingerprints() {
2232 if [[ -z $1 ]] ; then
2233 printf 'usage: ssl-cert-fingerprints <file>\n'
2236 for i in ${ssl_hashes}
2243 if [[ -z $1 ]] ; then
2244 printf 'usage: ssl-cert-info <file>\n'
2247 openssl x509 -noout -text -in $1
2248 ssl-cert-fingerprints $1
2251 # make sure our environment is clean regarding colors
2252 for color in BLUE RED GREEN CYAN YELLOW MAGENTA WHITE ; unset $color
2254 # "persistent history"
2255 # just write important commands you always need to ~/.important_commands
2256 if [[ -r ~/.important_commands ]] ; then
2257 fc -R ~/.important_commands
2260 # load the lookup subsystem if it's available on the system
2261 zrcautoload lookupinit && lookupinit
2265 # set terminal property (used e.g. by msgid-chooser)
2266 export COLORTERM="yes"
2271 #a2# Execute \kbd{du -sch}
2273 #a2# Execute \kbd{jobs -l}
2277 #a2# Execute \kbd{ls -lSrah}
2278 alias dir="ls -lSrah"
2279 #a2# Only show dot-directories
2280 alias lad='ls -d .*(/)' # only show dot-directories
2281 #a2# Only show dot-files
2282 alias lsa='ls -a .*(.)' # only show dot-files
2283 #a2# Only files with setgid/setuid/sticky flag
2284 alias lss='ls -l *(s,S,t)' # only files with setgid/setuid/sticky flag
2285 #a2# Only show 1st ten symlinks
2286 alias lsl='ls -l *(@)' # only symlinks
2287 #a2# Display only executables
2288 alias lsx='ls -l *(*)' # only executables
2289 #a2# Display world-{readable,writable,executable} files
2290 alias lsw='ls -ld *(R,W,X.^ND/)' # world-{readable,writable,executable} files
2291 #a2# Display the ten biggest files
2292 alias lsbig="ls -flh *(.OL[1,10])" # display the biggest files
2293 #a2# Only show directories
2294 alias lsd='ls -d *(/)' # only show directories
2295 #a2# Only show empty directories
2296 alias lse='ls -d *(/^F)' # only show empty directories
2297 #a2# Display the ten newest files
2298 alias lsnew="ls -rtlh *(D.om[1,10])" # display the newest files
2299 #a2# Display the ten oldest files
2300 alias lsold="ls -rtlh *(D.Om[1,10])" # display the oldest files
2301 #a2# Display the ten smallest files
2302 alias lssmall="ls -Srl *(.oL[1,10])" # display the smallest files
2303 #a2# Display the ten newest directories and ten newest .directories
2304 alias lsnewdir="ls -rthdl *(/om[1,10]) .*(D/om[1,10])"
2305 #a2# Display the ten oldest directories and ten oldest .directories
2306 alias lsolddir="ls -rthdl *(/Om[1,10]) .*(D/Om[1,10])"
2308 # some useful aliases
2309 #a2# Remove current empty directory. Execute \kbd{cd ..; rmdir $OLDCWD}
2310 alias rmcdir='cd ..; rmdir $OLDPWD || cd $OLDPWD'
2312 #a2# ssh with StrictHostKeyChecking=no \\&\quad and UserKnownHostsFile unset
2313 alias insecssh='ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
2314 alias insecscp='scp -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
2317 check_com -c python && alias http="python -m SimpleHTTPServer"
2319 # work around non utf8 capable software in utf environment via $LANG and luit
2320 if check_com isutfenv && check_com luit ; then
2321 if check_com -c mrxvt ; then
2322 isutfenv && [[ -n "$LANG" ]] && \
2323 alias mrxvt="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit mrxvt"
2326 if check_com -c aterm ; then
2327 isutfenv && [[ -n "$LANG" ]] && \
2328 alias aterm="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit aterm"
2331 if check_com -c centericq ; then
2332 isutfenv && [[ -n "$LANG" ]] && \
2333 alias centericq="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit centericq"
2339 #f5# Backup \kbd{file {\rm to} file\_timestamp}
2342 cp -b $1 $1_`date --iso-8601=m`
2345 #f5# cd to directoy and list files
2351 # smart cd function, allows switching to /etc when running 'cd /etc/fstab'
2353 if (( ${#argv} == 1 )) && [[ -f ${1} ]]; then
2354 [[ ! -e ${1:h} ]] && return 1
2355 print "Correcting ${1} to ${1:h}"
2362 #f5# Create Directoy and \kbd{cd} to it
2364 mkdir -p "$@" && cd "$@"
2367 #f5# Create temporary directory and \kbd{cd} to it
2375 #f5# Create directory under cursor or the selected area
2376 # Press ctrl-xM to create the directory under the cursor or the selected area.
2377 # To select an area press ctrl-@ or ctrl-space and use the cursor.
2378 # Use case: you type "mv abc ~/testa/testb/testc/" and remember that the
2379 # directory does not exist yet -> press ctrl-XM and problem solved
2382 if ((REGION_ACTIVE==1)); then
2383 local F=$MARK T=$CURSOR
2384 if [[ $F -gt $T ]]; then
2388 # get marked area from buffer and eliminate whitespace
2389 PATHTOMKDIR=${BUFFER[F+1,T]%%[[:space:]]##}
2390 PATHTOMKDIR=${PATHTOMKDIR##[[:space:]]##}
2392 local bufwords iword
2393 bufwords=(${(z)LBUFFER})
2395 bufwords=(${(z)BUFFER})
2396 PATHTOMKDIR="${(Q)bufwords[iword]}"
2398 [[ -z "${PATHTOMKDIR}" ]] && return 1
2399 if [[ -e "${PATHTOMKDIR}" ]]; then
2400 zle -M " path already exists, doing nothing"
2402 zle -M "$(mkdir -p -v "${PATHTOMKDIR}")"
2406 #k# mkdir -p <dir> from string under cursor or marked area
2407 zle -N inplaceMkDirs && bindkey '^XM' inplaceMkDirs
2409 #f5# List files which have been accessed within the last {\it n} days, {\it n} defaults to 1
2412 print -l -- *(a-${1:-1})
2415 #f5# List files which have been changed within the last {\it n} days, {\it n} defaults to 1
2418 print -l -- *(c-${1:-1})
2421 #f5# List files which have been modified within the last {\it n} days, {\it n} defaults to 1
2424 print -l -- *(m-${1:-1})
2426 # modified() was named new() in earlier versions, add an alias for backwards compatibility
2427 check_com new || alias new=modified
2429 # use colors when GNU grep with color-support
2430 #a2# Execute \kbd{grep -{}-color=auto}
2431 (grep --help 2>/dev/null |grep -- --color) >/dev/null && alias grep='grep --color=auto'
2434 # 'translate' looks up fot a word in a file with language-to-language
2435 # translations (field separator should be " : "). A typical wordlist looks
2437 # | english-word : german-transmission
2438 # It's also only possible to translate english to german but not reciprocal.
2439 # Use the following oneliner to turn back the sort order:
2440 # $ awk -F ':' '{ print $2" : "$1" "$3 }' \
2441 # /usr/local/lib/words/en-de.ISO-8859-1.vok > ~/.translate/de-en.ISO-8859-1.vok
2442 #f5# Translates a word
2447 translate -l de-en $2
2450 translate -l en-de $2
2453 echo "Usage: $0 { -D | -E }"
2454 echo " -D == German to English"
2455 echo " -E == English to German"
2459 # Usage: simple-extract <file>
2460 # Using option -d deletes the original archive file.
2461 #f5# Smart archive extractor
2464 setopt extended_glob noclobber
2465 local DELETE_ORIGINAL DECOMP_CMD USES_STDIN USES_STDOUT GZTARGET WGET_CMD
2467 zparseopts -D -E "d=DELETE_ORIGINAL"
2468 for ARCHIVE in "${@}"; do
2470 *.(tar.bz2|tbz2|tbz))
2471 DECOMP_CMD="tar -xvjf -"
2476 DECOMP_CMD="tar -xvzf -"
2480 *.(tar.xz|txz|tar.lzma))
2481 DECOMP_CMD="tar -xvJf -"
2486 DECOMP_CMD="tar -xvf -"
2491 DECOMP_CMD="unrar x"
2516 DECOMP_CMD="bzip2 -d -c -"
2521 DECOMP_CMD="gzip -d -c -"
2526 DECOMP_CMD="xz -d -c -"
2531 print "ERROR: '$ARCHIVE' has unrecognized archive type." >&2
2537 if ! check_com ${DECOMP_CMD[(w)1]}; then
2538 echo "ERROR: ${DECOMP_CMD[(w)1]} not installed." >&2
2543 GZTARGET="${ARCHIVE:t:r}"
2544 if [[ -f $ARCHIVE ]] ; then
2546 print "Extracting '$ARCHIVE' ..."
2547 if $USES_STDIN; then
2548 if $USES_STDOUT; then
2549 ${=DECOMP_CMD} < "$ARCHIVE" > $GZTARGET
2551 ${=DECOMP_CMD} < "$ARCHIVE"
2554 if $USES_STDOUT; then
2555 ${=DECOMP_CMD} "$ARCHIVE" > $GZTARGET
2557 ${=DECOMP_CMD} "$ARCHIVE"
2560 [[ $? -eq 0 && -n "$DELETE_ORIGINAL" ]] && rm -f "$ARCHIVE"
2562 elif [[ "$ARCHIVE" == (#s)(https|http|ftp)://* ]] ; then
2563 if check_com curl; then
2564 WGET_CMD="curl -L -k -s -o -"
2565 elif check_com wget; then
2566 WGET_CMD="wget -q -O - --no-check-certificate"
2568 print "ERROR: neither wget nor curl is installed" >&2
2572 print "Downloading and Extracting '$ARCHIVE' ..."
2573 if $USES_STDIN; then
2574 if $USES_STDOUT; then
2575 ${=WGET_CMD} "$ARCHIVE" | ${=DECOMP_CMD} > $GZTARGET
2578 ${=WGET_CMD} "$ARCHIVE" | ${=DECOMP_CMD}
2582 if $USES_STDOUT; then
2583 ${=DECOMP_CMD} =(${=WGET_CMD} "$ARCHIVE") > $GZTARGET
2585 ${=DECOMP_CMD} =(${=WGET_CMD} "$ARCHIVE")
2590 print "ERROR: '$ARCHIVE' is neither a valid file nor a supported URI." >&2
2600 '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)"' \
2601 '_urls:Remote Archives:_urls'
2607 '-d[delete original archivefile after extraction]' \
2608 '*:Archive Or Uri:__archive_or_uri'
2610 compdef _simple_extract simple-extract
2611 alias se=simple-extract
2613 #f5# Set all ulimit parameters to \kbd{unlimited}
2624 #f5# Change the xterm title from within GNU-screen
2627 if [[ $1 != "-f" ]] ; then
2628 if [[ -z ${DISPLAY} ]] ; then
2629 printf 'xtrename only makes sense in X11.\n'
2635 if [[ -z $1 ]] ; then
2636 printf 'usage: xtrename [-f] "title for xterm"\n'
2637 printf ' renames the title of xterm from _within_ screen.\n'
2638 printf ' also works without screen.\n'
2639 printf ' will not work if DISPLAY is unset, use -f to override.\n'
2642 print -n "\eP\e]0;${1}\C-G\e\\"
2647 # Rewrite this by either using tinyurl.com's API
2648 # or using another shortening service to comply with
2649 # tinyurl.com's policy.
2651 # Create small urls via http://tinyurl.com using wget(1).
2654 # [[ -z $1 ]] && { print "USAGE: zurl <URL>" ; return 1 }
2656 # local PN url tiny grabber search result preview
2659 ## Check existence of given URL with the help of ping(1).
2660 ## N.B. ping(1) only works without an eventual given protocol.
2661 # ping -c 1 ${${url#(ftp|http)://}%%/*} >& /dev/null || \
2662 # read -q "?Given host ${${url#http://*/}%/*} is not reachable by pinging. Proceed anyway? [y|n] "
2664 # if (( $? == 0 )) ; then
2665 ## Prepend 'http://' to given URL where necessary for later output.
2666 # [[ ${url} != http(s|)://* ]] && url='http://'${url}
2667 # tiny='http://tinyurl.com/create.php?url='
2668 # if check_com -c wget ; then
2669 # grabber='wget -O- -o/dev/null'
2671 # print "wget is not available, but mandatory for ${PN}. Aborting."
2673 ## Looking for i.e.`copy('http://tinyurl.com/7efkze')' in TinyURL's HTML code.
2674 # search='copy\(?http://tinyurl.com/[[:alnum:]]##*'
2675 # result=${(M)${${${(f)"$(${=grabber} ${tiny}${url})"}[(fr)${search}*]}//[()\';]/}%%http:*}
2676 ## TinyURL provides the rather new feature preview for more confidence. <http://tinyurl.com/preview.php>
2677 # preview='http://preview.'${result#http://}
2679 # printf '%s\n\n' "${PN} - Shrinking long URLs via webservice TinyURL <http://tinyurl.com>."
2680 # printf '%s\t%s\n\n' 'Given URL:' ${url}
2681 # printf '%s\t%s\n\t\t%s\n' 'TinyURL:' ${result} ${preview}
2687 #f2# Find history events by search pattern and list them by date.
2690 local usage help ident format_l format_s first_char remain first last
2691 usage='USAGE: whatwhen [options] <searchstring> <search range>'
2692 help='Use `whatwhen -h'\'' for further explanations.'
2693 ident=${(l,${#${:-Usage: }},, ,)}
2694 format_l="${ident}%s\t\t\t%s\n"
2695 format_s="${format_l//(\\t)##/\\t}"
2696 # Make the first char of the word to search for case
2697 # insensitive; e.g. [aA]
2698 first_char=[${(L)1[1]}${(U)1[1]}]
2700 # Default search range is `-100'.
2702 # Optional, just used for `<first> <last>' given.
2706 printf '%s\n\n' 'ERROR: No search string specified. Aborting.'
2707 printf '%s\n%s\n\n' ${usage} ${help} && return 1
2710 printf '%s\n\n' ${usage}
2712 printf $format_l '-h' 'show help text'
2714 print 'SEARCH RANGE:'
2715 printf $format_l "'0'" 'the whole history,'
2716 printf $format_l '-<n>' 'offset to the current history number; (default: -100)'
2717 printf $format_s '<[-]first> [<last>]' 'just searching within a give range'
2718 printf '\n%s\n' 'EXAMPLES:'
2719 printf ${format_l/(\\t)/} 'whatwhen grml' '# Range is set to -100 by default.'
2720 printf $format_l 'whatwhen zsh -250'
2721 printf $format_l 'whatwhen foo 1 99'
2724 printf '%s\n%s\n\n' ${usage} ${help} && return 1
2727 # -l list results on stout rather than invoking $EDITOR.
2728 # -i Print dates as in YYYY-MM-DD.
2729 # -m Search for a - quoted - pattern within the history.
2730 fc -li -m "*${first_char}${remain}*" $first $last
2735 # mercurial related stuff
2736 if check_com -c hg ; then
2737 # gnu like diff for mercurial
2738 # http://www.selenic.com/mercurial/wiki/index.cgi/TipsAndTricks
2739 #f5# GNU like diff for mercurial
2742 for i in $(hg status -marn "$@") ; diff -ubwd <(hg cat "$i") "$i"
2745 # build debian package
2746 #a2# Alias for \kbd{hg-buildpackage}
2747 alias hbp='hg-buildpackage'
2749 # execute commands on the versioned patch-queue from the current repos
2750 alias mq='hg -R $(readlink -f $(hg root)/.hg/patches)'
2752 # diffstat for specific version of a mercurial repository
2753 # hgstat => display diffstat between last revision and tip
2754 # hgstat 1234 => display diffstat between revision 1234 and tip
2755 #f5# Diffstat for specific version of a mercurial repos
2758 [[ -n "$1" ]] && hg diff -r $1 -r tip | diffstat || hg export tip | diffstat
2761 fi # end of check whether we have the 'hg'-executable
2763 # grml-small cleanups
2765 # The following is used to remove zsh-config-items that do not work
2766 # in grml-small by default.
2767 # If you do not want these adjustments (for whatever reason), set
2768 # $GRMLSMALL_SPECIFIC to 0 in your .zshrc.pre file (which this configuration
2769 # sources if it is there).
2771 if (( GRMLSMALL_SPECIFIC > 0 )) && isgrmlsmall ; then
2774 unalias 'V' &> /dev/null
2775 unfunction vman &> /dev/null
2776 unfunction viless &> /dev/null
2777 unfunction 2html &> /dev/null
2779 # manpages are not in grmlsmall
2780 unfunction manzsh &> /dev/null
2781 unfunction man2 &> /dev/null
2787 ## genrefcard.pl settings
2789 ### doc strings for external functions from files
2790 #m# f5 grml-wallpaper() Sets a wallpaper (try completion for possible values)
2792 ### example: split functions-search 8,16,24,32
2793 #@# split functions-search 8
2795 ## END OF FILE #################################################################
2796 # vim:filetype=zsh foldmethod=marker autoindent expandtab shiftwidth=4