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 ${ZDOTDIR:-${HOME}}/.zshrc.pre ]] && source ${ZDOTDIR:-${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.<7->* || $ZSH_VERSION == 4.<4->* \
149 || $ZSH_VERSION == <5->* ]] && return 0
154 [[ $ZSH_VERSION == 4.3.<9->* || $ZSH_VERSION == 4.<4->* \
155 || $ZSH_VERSION == <5->* ]] && return 0
159 #f1# Checks whether or not you're running grml
161 [[ -f /etc/grml_version ]] && return 0
165 #f1# Checks whether or not you're running a grml cd
167 [[ -f /etc/grml_cd ]] && return 0
172 #f1# Checks whether or not you're running grml-small
174 if [[ ${${${(f)"$(</etc/grml_version)"}%% *}##*-} == 'small' ]]; then
180 isgrmlsmall() { return 1 }
183 GRML_OSTYPE=$(uname -s)
186 [[ $GRML_OSTYPE == "Linux" ]]
190 [[ $GRML_OSTYPE == "Darwin" ]]
194 [[ $GRML_OSTYPE == "FreeBSD" ]]
198 [[ $GRML_OSTYPE == "OpenBSD" ]]
202 [[ $GRML_OSTYPE == "SunOS" ]]
205 #f1# are we running within an utf environment?
207 case "$LANG $CHARSET $LANGUAGE" in
214 # check for user, if not running as root set $SUDO to sudo
215 (( EUID != 0 )) && SUDO='sudo' || SUDO=''
217 # change directory to home on first invocation of zsh
218 # important for rungetty -> autologin
219 # Thanks go to Bart Schaefer!
220 isgrml && checkhome() {
221 if [[ -z "$ALREADY_DID_CD_HOME" ]] ; then
222 export ALREADY_DID_CD_HOME=$HOME
227 # check for zsh v3.1.7+
229 if ! [[ ${ZSH_VERSION} == 3.1.<7->* \
230 || ${ZSH_VERSION} == 3.<2->.<->* \
231 || ${ZSH_VERSION} == <4->.<->* ]] ; then
234 printf '-!- In this configuration we try to make use of features, that only\n'
235 printf '-!- require version 3.1.7 of the shell; That way this setup can be\n'
236 printf '-!- used with a wide range of zsh versions, while using fairly\n'
237 printf '-!- advanced features in all supported versions.\n'
239 printf '-!- However, you are running zsh version %s.\n' "$ZSH_VERSION"
241 printf '-!- While this *may* work, it might as well fail.\n'
242 printf '-!- Please consider updating to at least version 3.1.7 of zsh.\n'
244 printf '-!- DO NOT EXPECT THIS TO WORK FLAWLESSLY!\n'
245 printf '-!- If it does today, you'\''ve been lucky.\n'
247 printf '-!- Ye been warned!\n'
250 function zstyle() { : }
253 # autoload wrapper - use this one instead of autoload directly
254 # We need to define this function as early as this, because autoloading
255 # 'is-at-least()' needs it.
256 function zrcautoload() {
264 for fdir in ${fpath} ; do
265 [[ -e ${fdir}/${ffile} ]] && (( ffound = 1 ))
268 (( ffound == 0 )) && return 1
269 if [[ $ZSH_VERSION == 3.1.<6-> || $ZSH_VERSION == <4->* ]] ; then
270 autoload -U ${ffile} || return 1
272 autoload ${ffile} || return 1
277 # Load is-at-least() for more precise version checks Note that this test will
278 # *always* fail, if the is-at-least function could not be marked for
280 zrcautoload is-at-least || is-at-least() { return 1 }
282 # set some important options (as early as possible)
284 # append history list to the history file; this is the default but we make sure
285 # because it's required for share_history.
286 setopt append_history
288 # import new commands from the history file also in other zsh-session
289 is4 && setopt share_history
291 # save each command's beginning timestamp and the duration to the history file
292 setopt extended_history
294 # If a new command line being added to the history list duplicates an older
295 # one, the older command is removed from the list
296 is4 && setopt histignorealldups
298 # remove command lines from the history list when the first character on the
300 setopt histignorespace
302 # if a command is issued that can't be executed as a normal command, and the
303 # command is the name of a directory, perform the cd command to that directory.
306 # in order to use #, ~ and ^ for filename generation grep word
307 # *~(*.gz|*.bz|*.bz2|*.zip|*.Z) -> searches for word not in compressed files
308 # don't forget to quote '^', '~' and '#'!
311 # display PID when suspending processes as well
314 # try to avoid the 'zsh: no matches found...'
317 # report the status of backgrounds jobs immediately
320 # whenever a command completion is attempted, make sure the entire command path
324 # not just at the end
325 setopt completeinword
327 # Don't send SIGHUP to background processes when the shell exits.
330 # make cd push the old directory onto the directory stack.
336 # don't push the same dir twice.
337 setopt pushd_ignore_dups
339 # * shouldn't match dotfiles. ever.
342 # use zsh style word splitting
345 # don't error out when unset parameters are used
348 # setting some default values
351 NOPRECMD=${NOPRECMD:-0}
352 COMMAND_NOT_FOUND=${COMMAND_NOT_FOUND:-0}
353 GRML_ZSH_CNF_HANDLER=${GRML_ZSH_CNF_HANDLER:-/usr/share/command-not-found/command-not-found}
354 GRML_DISPLAY_BATTERY=${GRML_DISPLAY_BATTERY:-${BATTERY:-0}}
355 GRMLSMALL_SPECIFIC=${GRMLSMALL_SPECIFIC:-1}
356 ZSH_NO_DEFAULT_LOCALE=${ZSH_NO_DEFAULT_LOCALE:-0}
358 typeset -ga ls_options
359 typeset -ga grep_options
360 if ls --color=auto / >/dev/null 2>&1; then
361 ls_options+=( --color=auto )
362 elif ls -G / >/dev/null 2>&1; then
365 if grep --color=auto -q "a" <<< "a" >/dev/null 2>&1; then
366 grep_options+=( --color=auto )
370 # this function checks if a command exists and returns either true
371 # or false. This avoids using 'which' and 'whence', which will
372 # avoid problems with aliases for which on certain weird systems. :-)
373 # Usage: check_com [-c|-g] word
374 # -c only checks for external commands
375 # -g does the usual tests and also checks for global aliases
378 local -i comonly gatoo
380 if [[ $1 == '-c' ]] ; then
383 elif [[ $1 == '-g' ]] ; then
390 if (( ${#argv} != 1 )) ; then
391 printf 'usage: check_com [-c] <command>\n' >&2
395 if (( comonly > 0 )) ; then
396 [[ -n ${commands[$1]} ]] && return 0
400 if [[ -n ${commands[$1]} ]] \
401 || [[ -n ${functions[$1]} ]] \
402 || [[ -n ${aliases[$1]} ]] \
403 || [[ -n ${reswords[(r)$1]} ]] ; then
408 if (( gatoo > 0 )) && [[ -n ${galiases[$1]} ]] ; then
415 # creates an alias and precedes the command with
416 # sudo if $EUID is not zero.
419 local only=0 ; local multi=0
421 while [[ $1 == -* ]] ; do
425 (--) shift ; break ;;
427 printf 'usage: salias [-h|-o|-a] <alias-expression>\n'
428 printf ' -h shows this help text.\n'
429 printf ' -a replace '\'' ; '\'' sequences with '\'' ; sudo '\''.\n'
430 printf ' be careful using this option.\n'
431 printf ' -o only sets an alias if a preceding sudo would be needed.\n'
434 (*) printf "unkown option: '%s'\n" "$1" ; return 1 ;;
439 if (( ${#argv} > 1 )) ; then
440 printf 'Too many arguments %s\n' "${#argv}"
444 key="${1%%\=*}" ; val="${1#*\=}"
445 if (( EUID == 0 )) && (( only == 0 )); then
446 alias -- "${key}=${val}"
447 elif (( EUID > 0 )) ; then
448 (( multi > 0 )) && val="${val// ; / ; sudo }"
449 alias -- "${key}=sudo ${val}"
455 # a "print -l ${(u)foo}"-workaround for pre-4.2.0 shells
457 # Where foo is the *name* of the parameter you want printed.
458 # Note that foo is no typo; $foo would be wrong here!
466 if [[ -z ${parameter} ]] ; then
467 printf 'usage: uprint <parameter>\n'
471 for w in ${(P)parameter} ; do
472 [[ -z ${(M)u:#$w} ]] && u=( $u $w )
479 # Check if we can read given files and source those we can.
481 if (( ${#argv} < 1 )) ; then
482 printf 'usage: xsource FILE(s)...\n' >&2
486 while (( ${#argv} > 0 )) ; do
487 [[ -r "$1" ]] && source "$1"
493 # Check if we can read a given file and 'cat(1)' it.
496 if (( ${#argv} != 1 )) ; then
497 printf 'usage: xcat FILE\n' >&2
501 [[ -r $1 ]] && cat $1
505 # Remove these functions again, they are of use only in these
506 # setup files. This should be called at the end of .zshrc.
510 funcs=(salias xcat xsource xunfunction zrcautoload zrcautozle)
511 for func in $funcs ; do
512 [[ -n ${functions[$func]} ]] \
518 # this allows us to stay in sync with grml's zshrc and put own
519 # modifications in ~/.zshrc.local
521 xsource "/etc/zsh/zshrc.local"
522 xsource "${ZDOTDIR:-${HOME}}/.zshrc.local"
527 if (( ZSH_NO_DEFAULT_LOCALE == 0 )); then
528 xsource "/etc/default/locale"
531 for var in LANG LC_ALL LC_MESSAGES ; do
532 [[ -n ${(P)var} ]] && export $var
536 if check_com -c vim ; then
538 export EDITOR=${EDITOR:-vim}
540 export EDITOR=${EDITOR:-vi}
544 export PAGER=${PAGER:-less}
547 export MAIL=${MAIL:-/var/mail/$USER}
549 # if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/
550 if [[ -z "$SHELL" ]] ; then
552 if [[ -x "$SHELL" ]] ; then
557 # color setup for ls:
558 check_com -c dircolors && eval $(dircolors -b)
559 # color setup for ls on OS X / FreeBSD:
560 isdarwin && export CLICOLOR=1
561 isfreebsd && export CLICOLOR=1
563 # do MacPorts setup on darwin
564 if isdarwin && [[ -d /opt/local ]]; then
565 # Note: PATH gets set in /etc/zprofile on Darwin, so this can't go into
567 PATH="/opt/local/bin:/opt/local/sbin:$PATH"
568 MANPATH="/opt/local/share/man:$MANPATH"
570 # do Fink setup on darwin
571 isdarwin && xsource /sw/bin/init.sh
573 # load our function and completion directories
574 for fdir in /usr/share/grml/zsh/completion /usr/share/grml/zsh/functions; do
575 fpath=( ${fdir} ${fdir}/**/*(/N) ${fpath} )
576 if [[ ${fdir} == '/usr/share/grml/zsh/functions' ]] ; then
577 for func in ${fdir}/**/[^_]*[^~](N.) ; do
578 zrcautoload ${func:t}
584 # support colors in less
585 export LESS_TERMCAP_mb=$'\E[01;31m'
586 export LESS_TERMCAP_md=$'\E[01;31m'
587 export LESS_TERMCAP_me=$'\E[0m'
588 export LESS_TERMCAP_se=$'\E[0m'
589 export LESS_TERMCAP_so=$'\E[01;44;33m'
590 export LESS_TERMCAP_ue=$'\E[0m'
591 export LESS_TERMCAP_us=$'\E[01;32m'
596 # report about cpu-/system-/user-time of command if running longer than
600 # watch for everyone but me and root
603 # automatically remove duplicates from these arrays
604 typeset -U path cdpath fpath manpath
608 for mod in parameter complist deltochar mathfunc ; do
609 zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :("
612 # autoload zsh modules when they are referenced
614 zmodload -a zsh/stat zstat
615 zmodload -a zsh/zpty zpty
616 zmodload -ap zsh/mapfile mapfile
620 COMPDUMPFILE=${COMPDUMPFILE:-${ZDOTDIR:-${HOME}}/.zcompdump}
621 if zrcautoload compinit ; then
622 compinit -d ${COMPDUMPFILE} || print 'Notice: no compinit available :('
624 print 'Notice: no compinit available :('
630 # called later (via is4 && grmlcomp)
631 # note: use 'zstyle' for getting current settings
632 # press ^xh (control-x h) for getting tags in context; ^x? (control-x ?) to run complete_debug with trace output
634 # TODO: This could use some additional information
636 # Make sure the completion system is initialised
637 (( ${+_comps} )) || return 1
639 # allow one error for every three characters typed in approximate completer
640 zstyle ':completion:*:approximate:' max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )'
642 # don't complete backup files as executables
643 zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)'
645 # start menu completion only if it could find no unambiguous initial string
646 zstyle ':completion:*:correct:*' insert-unambiguous true
647 zstyle ':completion:*:corrections' format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}'
648 zstyle ':completion:*:correct:*' original true
650 # activate color-completion
651 zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
653 # format on completion
654 zstyle ':completion:*:descriptions' format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'
656 # automatically complete 'cd -<tab>' and 'cd -<ctrl-d>' with menu
657 # zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
659 # insert all expansions for expand completer
660 zstyle ':completion:*:expand:*' tag-order all-expansions
661 zstyle ':completion:*:history-words' list false
664 zstyle ':completion:*:history-words' menu yes
666 # ignore duplicate entries
667 zstyle ':completion:*:history-words' remove-all-dups yes
668 zstyle ':completion:*:history-words' stop yes
670 # match uppercase from lowercase
671 zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
673 # separate matches into groups
674 zstyle ':completion:*:matches' group 'yes'
675 zstyle ':completion:*' group-name ''
677 if [[ "$NOMENU" -eq 0 ]] ; then
678 # if there are more than 5 options allow selecting from a menu
679 zstyle ':completion:*' menu select=5
681 # don't use any menus at all
685 zstyle ':completion:*:messages' format '%d'
686 zstyle ':completion:*:options' auto-description '%d'
688 # describe options in full
689 zstyle ':completion:*:options' description 'yes'
691 # on processes completion complete all user processes
692 zstyle ':completion:*:processes' command 'ps -au$USER'
694 # offer indexes before parameters in subscripts
695 zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
697 # provide verbose completion information
698 zstyle ':completion:*' verbose true
700 # recent (as of Dec 2007) zsh versions are able to provide descriptions
701 # for commands (read: 1st word in the line) that it will list for the user
702 # to choose from. The following disables that, because it's not exactly fast.
703 zstyle ':completion:*:-command-:*:' verbose false
705 # set format for warnings
706 zstyle ':completion:*:warnings' format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d'
708 # define files to ignore for zcompile
709 zstyle ':completion:*:*:zcompile:*' ignored-patterns '(*~|*.zwc)'
710 zstyle ':completion:correct:' prompt 'correct to: %e'
712 # Ignore completion functions for commands you don't have:
713 zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'
715 # Provide more processes in completion of programs like killall:
716 zstyle ':completion:*:processes-names' command 'ps c -u ${USER} -o command | uniq'
718 # complete manual by their section
719 zstyle ':completion:*:manuals' separate-sections true
720 zstyle ':completion:*:manuals.*' insert-sections true
721 zstyle ':completion:*:man:*' menu yes select
723 # Search path for sudo completion
724 zstyle ':completion:*:sudo:*' command-path /usr/local/sbin \
732 # provide .. as a completion
733 zstyle ':completion:*' special-dirs ..
735 # run rehash on completion so new installed program are found automatically:
737 (( CURRENT == 1 )) && rehash
742 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
743 if [[ "$NOCOR" -gt 0 ]] ; then
744 zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
747 # try to be smart about when to use what completer...
749 zstyle -e ':completion:*' completer '
750 if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then
751 _last_try="$HISTNO$BUFFER$CURSOR"
752 reply=(_complete _match _ignored _prefix _files)
754 if [[ $words[1] == (rm|mv) ]] ; then
755 reply=(_complete _files)
757 reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files)
762 # command for process lists, the local web server details and host completion
763 zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
766 [[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \
767 zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
771 [[ -r ~/.ssh/config ]] && _ssh_config_hosts=(${${${(@M)${(f)"$(<$HOME/.ssh/config)"}:#Host *}#Host }:#*[*?]*}) || _ssh_config_hosts=()
772 [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
773 [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
781 "$_ssh_config_hosts[@]"
786 zstyle ':completion:*:hosts' hosts $hosts
787 # TODO: so, why is this here?
788 # zstyle '*' hosts $hosts
790 # use generic completion system for programs not yet defined; (_gnu_generic works
791 # with commands that provide a --help option with "standard" gnu-like output.)
792 for compcom in cp deborphan df feh fetchipac gpasswd head hnb ipacsum mv \
794 [[ -z ${_comps[$compcom]} ]] && compdef _gnu_generic ${compcom}
797 # see upgrade function in this file
798 compdef _hosts upgrade
801 # Keyboard setup: The following is based on the same code, we wrote for
802 # debian's setup. It ensures the terminal is in the right mode, when zle is
803 # active, so the values from $terminfo are valid. Therefore, this setup should
804 # work on all systems, that have support for `terminfo'. It also requires the
805 # zsh in use to have the `zsh/terminfo' module built.
807 # If you are customising your `zle-line-init()' or `zle-line-finish()'
808 # functions, make sure you call the following utility functions in there:
810 # - zle-line-init(): zle-smkx
811 # - zle-line-finish(): zle-rmkx
813 # Use emacs-like key bindings by default:
818 ## beginning-of-line OR beginning-of-buffer OR beginning of history
819 ## by: Bart Schaefer <schaefer@brasslantern.com>, Bernhard Tittelbach
820 beginning-or-end-of-somewhere() {
822 if [[ ( "${LBUFFER[-1]}" == $'\n' && "${WIDGET}" == beginning-of* ) || \
823 ( "${RBUFFER[1]}" == $'\n' && "${WIDGET}" == end-of* ) ]]; then
824 zle .${WIDGET:s/somewhere/buffer-or-history/} "$@"
826 zle .${WIDGET:s/somewhere/line-hist/} "$@"
827 if (( HISTNO != hno )); then
828 zle .${WIDGET:s/somewhere/buffer-or-history/} "$@"
832 zle -N beginning-of-somewhere beginning-or-end-of-somewhere
833 zle -N end-of-somewhere beginning-or-end-of-somewhere
835 # add a command line to the shells history without executing it
836 commit-to-history() {
837 print -s ${(z)BUFFER}
840 zle -N commit-to-history
842 # only slash should be considered as a word separator:
843 slash-backward-kill-word() {
844 local WORDCHARS="${WORDCHARS:s@/@}"
846 zle backward-kill-word
848 zle -N slash-backward-kill-word
850 # a generic accept-line wrapper
852 # This widget can prevent unwanted autocorrections from command-name
853 # to _command-name, rehash automatically on enter and call any number
854 # of builtin and user-defined widgets in different contexts.
856 # For a broader description, see:
857 # <http://bewatermyfriend.org/posts/2007/12-26.11-50-38-tooltime.html>
859 # The code is imported from the file 'zsh/functions/accept-line' from
860 # <http://ft.bewatermyfriend.org/comp/zsh/zsh-dotfiles.tar.bz2>, which
861 # distributed under the same terms as zsh itself.
863 # A newly added command will may not be found or will cause false
864 # correction attempts, if you got auto-correction set. By setting the
865 # following style, we force accept-line() to rehash, if it cannot
866 # find the first word on the command line in the $command[] hash.
867 zstyle ':acceptline:*' rehash true
869 function Accept-Line() {
870 setopt localoptions noksharrays
874 local alcontext=${1:-$alcontext}
876 zstyle -a ":acceptline:${alcontext}" actions subs
878 (( ${#subs} < 1 )) && return 0
881 for sub in ${subs} ; do
882 [[ ${sub} == 'accept-line' ]] && sub='.accept-line'
885 (( aldone > 0 )) && break
889 function Accept-Line-getdefault() {
893 zstyle -s ":acceptline:${alcontext}" default_action default_action
894 case ${default_action} in
896 printf ".accept-line"
899 printf ${default_action}
904 function Accept-Line-HandleContext() {
907 default_action=$(Accept-Line-getdefault)
908 zstyle -T ":acceptline:${alcontext}" call_default \
909 && zle ${default_action}
912 function accept-line() {
913 setopt localoptions noksharrays
916 local buf com fname format msg default_action
920 cmdline=(${(z)BUFFER})
924 Accept-Line 'preprocess'
926 zstyle -t ":acceptline:${alcontext}" rehash \
927 && [[ -z ${commands[$com]} ]] \
931 && [[ -n ${reswords[(r)$com]} ]] \
932 || [[ -n ${aliases[$com]} ]] \
933 || [[ -n ${functions[$com]} ]] \
934 || [[ -n ${builtins[$com]} ]] \
935 || [[ -n ${commands[$com]} ]] ; then
937 # there is something sensible to execute, just do it.
939 Accept-Line-HandleContext
944 if [[ -o correct ]] \
945 || [[ -o correctall ]] \
946 && [[ -n ${functions[$fname]} ]] ; then
948 # nothing there to execute but there is a function called
949 # _command_name; a completion widget. Makes no sense to
950 # call it on the commandline, but the correct{,all} options
951 # will ask for it nevertheless, so warn the user.
952 if [[ ${LASTWIDGET} == 'accept-line' ]] ; then
953 # Okay, we warned the user before, he called us again,
954 # so have it his way.
956 Accept-Line-HandleContext
961 if zstyle -t ":acceptline:${alcontext}" nocompwarn ; then
963 Accept-Line-HandleContext
965 # prepare warning message for the user, configurable via zstyle.
966 zstyle -s ":acceptline:${alcontext}" compwarnfmt msg
968 if [[ -z ${msg} ]] ; then
969 msg="%c will not execute and completion %f exists."
972 zformat -f msg "${msg}" "c:${com}" "f:${fname}"
977 elif [[ -n ${buf//[$' \t\n']##/} ]] ; then
978 # If we are here, the commandline contains something that is not
979 # executable, which is neither subject to _command_name correction
980 # and is not empty. might be a variable assignment
982 Accept-Line-HandleContext
987 # If we got this far, the commandline only contains whitespace, or is empty.
989 Accept-Line-HandleContext
994 zle -N Accept-Line-HandleContext
996 # power completion / abbreviation expansion / buffer expansion
997 # see http://zshwiki.org/home/examples/zleiab for details
998 # less risky than the global aliases but powerful as well
999 # just type the abbreviation key and afterwards 'ctrl-x .' to expand it
1002 setopt interactivecomments
1004 # key # value (#d additional doc string)
1010 'G' '|& grep '${grep_options:+"${grep_options[*]}"}
1012 'Hl' ' --help |& less -r' #d (Display help in pager)
1016 'N' '&>/dev/null' #d (No Output)
1017 'R' '| tr A-z N-za-m' #d (ROT13)
1018 'SL' '| sort | less'
1023 'co' './configure && make && sudo make install'
1031 LBUFFER=${LBUFFER%%(#m)[.\-+:|_a-zA-Z0-9]#}
1032 LBUFFER+=${abk[$MATCH]:-$MATCH}
1039 zle -M "$(print "Available abbreviations for expansion:"; print -a -C 2 ${(kv)abk})"
1042 zle -N help-show-abk
1044 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
1045 insert-datestamp() { LBUFFER+=${(%):-'%D{%Y-%m-%d}'}; }
1046 zle -N insert-datestamp
1048 # press esc-m for inserting last typed word again (thanks to caphuso!)
1049 insert-last-typed-word() { zle insert-last-word -- 0 -1 };
1050 zle -N insert-last-typed-word;
1052 function grml-zsh-fg() {
1053 if (( ${#jobstates} )); then
1055 [[ -o hist_ignore_space ]] && BUFFER=' ' || BUFFER=''
1056 BUFFER="${BUFFER}fg"
1059 zle -M 'No background jobs. Doing nothing.'
1064 # run command line as user root via sudo:
1065 sudo-command-line() {
1066 [[ -z $BUFFER ]] && zle up-history
1067 if [[ $BUFFER != sudo\ * ]]; then
1068 BUFFER="sudo $BUFFER"
1069 CURSOR=$(( CURSOR+5 ))
1072 zle -N sudo-command-line
1074 ### jump behind the first word on the cmdline.
1075 ### useful to add options.
1076 function jump_after_first_word() {
1078 words=(${(z)BUFFER})
1080 if (( ${#words} <= 1 )) ; then
1083 CURSOR=${#${words[1]}}
1086 zle -N jump_after_first_word
1088 #f5# Create directory under cursor or the selected area
1090 # Press ctrl-xM to create the directory under the cursor or the selected area.
1091 # To select an area press ctrl-@ or ctrl-space and use the cursor.
1092 # Use case: you type "mv abc ~/testa/testb/testc/" and remember that the
1093 # directory does not exist yet -> press ctrl-XM and problem solved
1095 if ((REGION_ACTIVE==1)); then
1096 local F=$MARK T=$CURSOR
1097 if [[ $F -gt $T ]]; then
1101 # get marked area from buffer and eliminate whitespace
1102 PATHTOMKDIR=${BUFFER[F+1,T]%%[[:space:]]##}
1103 PATHTOMKDIR=${PATHTOMKDIR##[[:space:]]##}
1105 local bufwords iword
1106 bufwords=(${(z)LBUFFER})
1108 bufwords=(${(z)BUFFER})
1109 PATHTOMKDIR="${(Q)bufwords[iword]}"
1111 [[ -z "${PATHTOMKDIR}" ]] && return 1
1112 PATHTOMKDIR=${~PATHTOMKDIR}
1113 if [[ -e "${PATHTOMKDIR}" ]]; then
1114 zle -M " path already exists, doing nothing"
1116 zle -M "$(mkdir -p -v "${PATHTOMKDIR}")"
1121 zle -N inplaceMkDirs
1123 #v1# set number of lines to display per page
1124 HELP_LINES_PER_PAGE=20
1125 #v1# set location of help-zle cache file
1126 HELP_ZLE_CACHE_FILE=~/.cache/zsh_help_zle_lines.zsh
1127 # helper function for help-zle, actually generates the help text
1128 help_zle_parse_keybindings()
1132 unsetopt ksharrays #indexing starts at 1
1134 #v1# choose files that help-zle will parse for keybindings
1135 ((${+HELPZLE_KEYBINDING_FILES})) || HELPZLE_KEYBINDING_FILES=( /etc/zsh/zshrc ~/.zshrc.pre ~/.zshrc ~/.zshrc.local )
1137 if [[ -r $HELP_ZLE_CACHE_FILE ]]; then
1139 for f ($HELPZLE_KEYBINDING_FILES) [[ $f -nt $HELP_ZLE_CACHE_FILE ]] && load_cache=1
1140 [[ $load_cache -eq 0 ]] && . $HELP_ZLE_CACHE_FILE && return
1143 #fill with default keybindings, possibly to be overwriten in a file later
1144 #Note that due to zsh inconsistency on escaping assoc array keys, we encase the key in '' which we will remove later
1145 local -A help_zle_keybindings
1146 help_zle_keybindings['<Ctrl>@']="set MARK"
1147 help_zle_keybindings['<Ctrl>x<Ctrl>j']="vi-join lines"
1148 help_zle_keybindings['<Ctrl>x<Ctrl>b']="jump to matching brace"
1149 help_zle_keybindings['<Ctrl>x<Ctrl>u']="undo"
1150 help_zle_keybindings['<Ctrl>_']="undo"
1151 help_zle_keybindings['<Ctrl>x<Ctrl>f<c>']="find <c> in cmdline"
1152 help_zle_keybindings['<Ctrl>a']="goto beginning of line"
1153 help_zle_keybindings['<Ctrl>e']="goto end of line"
1154 help_zle_keybindings['<Ctrl>t']="transpose charaters"
1155 help_zle_keybindings['<Alt>t']="transpose words"
1156 help_zle_keybindings['<Alt>s']="spellcheck word"
1157 help_zle_keybindings['<Ctrl>k']="backward kill buffer"
1158 help_zle_keybindings['<Ctrl>u']="forward kill buffer"
1159 help_zle_keybindings['<Ctrl>y']="insert previously killed word/string"
1160 help_zle_keybindings["<Alt>'"]="quote line"
1161 help_zle_keybindings['<Alt>"']="quote from mark to cursor"
1162 help_zle_keybindings['<Alt><arg>']="repeat next cmd/char <arg> times (<Alt>-<Alt>1<Alt>0a -> -10 times 'a')"
1163 help_zle_keybindings['<Alt>u']="make next word Uppercase"
1164 help_zle_keybindings['<Alt>l']="make next word lowercase"
1165 help_zle_keybindings['<Ctrl>xd']="preview expansion under cursor"
1166 help_zle_keybindings['<Alt>q']="push current CL into background, freeing it. Restore on next CL"
1167 help_zle_keybindings['<Alt>.']="insert (and interate through) last word from prev CLs"
1168 help_zle_keybindings['<Alt>,']="complete word from newer history (consecutive hits)"
1169 help_zle_keybindings['<Alt>m']="repeat last typed word on current CL"
1170 help_zle_keybindings['<Ctrl>v']="insert next keypress symbol literally (e.g. for bindkey)"
1171 help_zle_keybindings['!!:n*<Tab>']="insert last n arguments of last command"
1172 help_zle_keybindings['!!:n-<Tab>']="insert arguments n..N-2 of last command (e.g. mv s s d)"
1173 help_zle_keybindings['<Alt>h']="show help/manpage for current command"
1175 #init global variables
1176 unset help_zle_lines help_zle_sln
1177 typeset -g -a help_zle_lines
1178 typeset -g help_zle_sln=1
1181 local lastkeybind_desc contents #last description starting with #k# that we found
1182 local num_lines_elapsed=0 #number of lines between last description and keybinding
1183 #search config files in the order they a called (and thus the order in which they overwrite keybindings)
1184 for f in $HELPZLE_KEYBINDING_FILES; do
1185 [[ -r "$f" ]] || continue #not readable ? skip it
1187 for cline in "${(f)contents}"; do
1188 #zsh pattern: matches lines like: #k# ..............
1189 if [[ "$cline" == (#s)[[:space:]]#\#k\#[[:space:]]##(#b)(*)[[:space:]]#(#e) ]]; then
1190 lastkeybind_desc="$match[*]"
1192 #zsh pattern: matches lines that set a keybinding using bind2map, bindkey or compdef -k
1193 # ignores lines that are commentend out
1194 # grabs first in '' or "" enclosed string with length between 1 and 6 characters
1195 elif [[ "$cline" == [^#]#(bind2maps[[:space:]](*)-s|bindkey|compdef -k)[[:space:]](*)(#b)(\"((?)(#c1,6))\"|\'((?)(#c1,6))\')(#B)(*) ]]; then
1196 #description prevously found ? description not more than 2 lines away ? keybinding not empty ?
1197 if [[ -n $lastkeybind_desc && $num_lines_elapsed -lt 2 && -n $match[1] ]]; then
1198 #substitute keybinding string with something readable
1199 k=${${${${${${${match[1]/\\e\^h/<Alt><BS>}/\\e\^\?/<Alt><BS>}/\\e\[5~/<PageUp>}/\\e\[6~/<PageDown>}//(\\e|\^\[)/<Alt>}//\^/<Ctrl>}/3~/<Alt><Del>}
1200 #put keybinding in assoc array, possibly overwriting defaults or stuff found in earlier files
1201 #Note that we are extracting the keybinding-string including the quotes (see Note at beginning)
1202 help_zle_keybindings[${k}]=$lastkeybind_desc
1206 ((num_lines_elapsed++))
1211 #calculate length of keybinding column
1213 for k (${(k)help_zle_keybindings[@]}) ((kstrlen < ${#k})) && kstrlen=${#k}
1214 #convert the assoc array into preformated lines, which we are able to sort
1215 for k v in ${(kv)help_zle_keybindings[@]}; do
1216 #pad keybinding-string to kstrlen chars and remove outermost characters (i.e. the quotes)
1217 help_zle_lines+=("${(r:kstrlen:)k[2,-2]}${v}")
1219 #sort lines alphabetically
1220 help_zle_lines=("${(i)help_zle_lines[@]}")
1221 [[ -d ${HELP_ZLE_CACHE_FILE:h} ]] || mkdir -p "${HELP_ZLE_CACHE_FILE:h}"
1222 echo "help_zle_lines=(${(q)help_zle_lines[@]})" >| $HELP_ZLE_CACHE_FILE
1223 zcompile $HELP_ZLE_CACHE_FILE
1225 typeset -g help_zle_sln
1226 typeset -g -a help_zle_lines
1228 # Provides (partially autogenerated) help on keybindings and the zsh line editor
1232 unsetopt ksharrays #indexing starts at 1
1233 #help lines already generated ? no ? then do it
1234 [[ ${+functions[help_zle_parse_keybindings]} -eq 1 ]] && {help_zle_parse_keybindings && unfunction help_zle_parse_keybindings}
1235 #already displayed all lines ? go back to the start
1236 [[ $help_zle_sln -gt ${#help_zle_lines} ]] && help_zle_sln=1
1237 local sln=$help_zle_sln
1238 #note that help_zle_sln is a global var, meaning we remember the last page we viewed
1239 help_zle_sln=$((help_zle_sln + HELP_LINES_PER_PAGE))
1240 zle -M "${(F)help_zle_lines[sln,help_zle_sln-1]}"
1244 ## complete word from currently visible Screen or Tmux buffer.
1245 if check_com -c screen || check_com -c tmux; then
1246 _complete_screen_display() {
1247 [[ "$TERM" != "screen" ]] && return 1
1249 local TMPFILE=$(mktemp)
1250 local -U -a _screen_display_wordlist
1251 trap "rm -f $TMPFILE" EXIT
1253 # fill array with contents from screen hardcopy
1254 if ((${+TMUX})); then
1255 #works, but crashes tmux below version 1.4
1256 #luckily tmux -V option to ask for version, was also added in 1.4
1257 tmux -V &>/dev/null || return
1258 tmux -q capture-pane \; save-buffer -b 0 $TMPFILE \; delete-buffer -b 0
1260 screen -X hardcopy $TMPFILE
1261 # screen sucks, it dumps in latin1, apparently always. so recode it
1263 check_com recode && recode latin1 $TMPFILE
1265 _screen_display_wordlist=( ${(QQ)$(<$TMPFILE)} )
1266 # remove PREFIX to be completed from that array
1267 _screen_display_wordlist[${_screen_display_wordlist[(i)$PREFIX]}]=""
1268 compadd -a _screen_display_wordlist
1270 #m# k CTRL-x\,\,\,S Complete word from GNU screen buffer
1272 compdef -k _complete_screen_display complete-word '^xS'
1275 # Load a few more functions and tie them to widgets, so they can be bound:
1277 function zrcautozle() {
1280 zrcautoload $fnc && zle -N $fnc
1283 function zrcgotwidget() {
1284 (( ${+widgets[$1]} ))
1287 function zrcgotkeymap() {
1288 [[ -n ${(M)keymaps:#$1} ]]
1291 zrcautozle insert-files
1292 zrcautozle edit-command-line
1293 zrcautozle insert-unicode-char
1294 if zrcautoload history-search-end; then
1295 zle -N history-beginning-search-backward-end history-search-end
1296 zle -N history-beginning-search-forward-end history-search-end
1298 zle -C hist-complete complete-word _generic
1299 zstyle ':completion:hist-complete:*' completer _history
1301 # The actual terminal setup hooks and bindkey-calls:
1303 # An array to note missing features to ease diagnosis in case of problems.
1304 typeset -ga grml_missing_features
1306 function zrcbindkey() {
1307 if (( ARGC )) && zrcgotwidget ${argv[-1]}; then
1312 function bind2maps () {
1313 local i sequence widget
1316 while [[ "$1" != "--" ]]; do
1322 if [[ "$1" == "-s" ]]; then
1326 sequence="${key[$1]}"
1330 [[ -z "$sequence" ]] && return 1
1332 for i in "${maps[@]}"; do
1333 zrcbindkey -M "$i" "$sequence" "$widget"
1337 if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then
1338 function zle-smkx () {
1340 printf '%s' ${terminfo[smkx]}
1342 function zle-rmkx () {
1344 printf '%s' ${terminfo[rmkx]}
1346 function zle-line-init () {
1349 function zle-line-finish () {
1352 zle -N zle-line-init
1353 zle -N zle-line-finish
1355 for i in {s,r}mkx; do
1356 (( ${+terminfo[$i]} )) || grml_missing_features+=($i)
1363 Home "${terminfo[khome]}"
1364 End "${terminfo[kend]}"
1365 Insert "${terminfo[kich1]}"
1366 Delete "${terminfo[kdch1]}"
1367 Up "${terminfo[kcuu1]}"
1368 Down "${terminfo[kcud1]}"
1369 Left "${terminfo[kcub1]}"
1370 Right "${terminfo[kcuf1]}"
1371 PageUp "${terminfo[kpp]}"
1372 PageDown "${terminfo[knp]}"
1373 BackTab "${terminfo[kcbt]}"
1376 # Guidelines for adding key bindings:
1378 # - Do not add hardcoded escape sequences, to enable non standard key
1379 # combinations such as Ctrl-Meta-Left-Cursor. They are not easily portable.
1381 # - Adding Ctrl characters, such as '^b' is okay; note that '^b' and '^B' are
1384 # - All keys from the $key[] mapping are obviously okay.
1386 # - Most terminals send "ESC x" when Meta-x is pressed. Thus, sequences like
1387 # '\ex' are allowed in here as well.
1389 bind2maps emacs -- Home beginning-of-somewhere
1390 bind2maps viins vicmd -- Home vi-beginning-of-line
1391 bind2maps emacs -- End end-of-somewhere
1392 bind2maps viins vicmd -- End vi-end-of-line
1393 bind2maps emacs viins -- Insert overwrite-mode
1394 bind2maps vicmd -- Insert vi-insert
1395 bind2maps emacs -- Delete delete-char
1396 bind2maps viins vicmd -- Delete vi-delete-char
1397 bind2maps emacs viins vicmd -- Up up-line-or-search
1398 bind2maps emacs viins vicmd -- Down down-line-or-search
1399 bind2maps emacs -- Left backward-char
1400 bind2maps viins vicmd -- Left vi-backward-char
1401 bind2maps emacs -- Right forward-char
1402 bind2maps viins vicmd -- Right vi-forward-char
1403 #k# Perform abbreviation expansion
1404 bind2maps emacs viins -- -s '^x.' zleiab
1405 #k# Display list of abbreviations that would expand
1406 bind2maps emacs viins -- -s '^xb' help-show-abk
1407 #k# mkdir -p <dir> from string under cursor or marked area
1408 bind2maps emacs viins -- -s '^xM' inplaceMkDirs
1409 #k# display help for keybindings and ZLE
1410 bind2maps emacs viins -- -s '^xz' help-zle
1411 #k# Insert files and test globbing
1412 bind2maps emacs viins -- -s "^xf" insert-files
1413 #k# Edit the current line in \kbd{\$EDITOR}
1414 bind2maps emacs viins -- -s '\ee' edit-command-line
1415 #k# search history backward for entry beginning with typed text
1416 bind2maps emacs viins -- -s '^xp' history-beginning-search-backward-end
1417 #k# search history forward for entry beginning with typed text
1418 bind2maps emacs viins -- -s '^xP' history-beginning-search-forward-end
1419 #k# search history backward for entry beginning with typed text
1420 bind2maps emacs viins -- PageUp history-beginning-search-backward-end
1421 #k# search history forward for entry beginning with typed text
1422 bind2maps emacs viins -- PageDown history-beginning-search-forward-end
1423 bind2maps emacs viins -- -s "^x^h" commit-to-history
1424 #k# Kill left-side word or everything up to next slash
1425 bind2maps emacs viins -- -s '\ev' slash-backward-kill-word
1426 #k# Kill left-side word or everything up to next slash
1427 bind2maps emacs viins -- -s '\e^h' slash-backward-kill-word
1428 #k# Kill left-side word or everything up to next slash
1429 bind2maps emacs viins -- -s '\e^?' slash-backward-kill-word
1430 # Do history expansion on space:
1431 bind2maps emacs viins -- -s ' ' magic-space
1432 #k# Trigger menu-complete
1433 bind2maps emacs viins -- -s '\ei' menu-complete # menu completion via esc-i
1434 #k# Insert a timestamp on the command line (yyyy-mm-dd)
1435 bind2maps emacs viins -- -s '^ed' insert-datestamp
1436 #k# Insert last typed word
1437 bind2maps emacs viins -- -s "\em" insert-last-typed-word
1438 #k# A smart shortcut for \kbd{fg<enter>}
1439 bind2maps emacs viins -- -s '^z' grml-zsh-fg
1440 #k# prepend the current command with "sudo"
1441 bind2maps emacs viins -- -s "^os" sudo-command-line
1442 #k# jump to after first word (for adding options)
1443 bind2maps emacs viins -- -s '^x1' jump_after_first_word
1444 #k# complete word from history with menu
1445 bind2maps emacs viins -- -s "^x^x" hist-complete
1447 # insert unicode character
1448 # usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an §
1449 # See for example http://unicode.org/charts/ for unicode characters code
1450 #k# Insert Unicode character
1451 bind2maps emacs viins -- -s '^xi' insert-unicode-char
1453 # use the new *-pattern-* widgets for incremental history search
1454 if zrcgotwidget history-incremental-pattern-search-backward; then
1455 for seq wid in '^r' history-incremental-pattern-search-backward \
1456 '^s' history-incremental-pattern-search-forward
1458 bind2maps emacs viins vicmd -- -s $seq $wid
1462 if zrcgotkeymap menuselect; then
1463 #m# k Shift-tab Perform backwards menu completion
1464 bind2maps menuselect -- BackTab reverse-menu-complete
1466 #k# menu selection: pick item but stay in the menu
1467 bind2maps menuselect -- -s '\e^M' accept-and-menu-complete
1468 # also use + and INSERT since it's easier to press repeatedly
1469 bind2maps menuselect -- -s '+' accept-and-menu-complete
1470 bind2maps menuselect -- Insert accept-and-menu-complete
1472 # accept a completion and try to complete again by using menu
1473 # completion; very useful with completing directories
1474 # by using 'undo' one's got a simple file browser
1475 bind2maps menuselect -- -s '^o' accept-and-infer-next-history
1478 # Finally, here are still a few hardcoded escape sequences; Special sequences
1479 # like Ctrl-<Cursor-key> etc do suck a fair bit, because they are not
1480 # standardised and most of the time are not available in a terminals terminfo
1483 # While we do not encourage adding bindings like these, we will keep these for
1484 # backward compatibility.
1486 ## use Ctrl-left-arrow and Ctrl-right-arrow for jumping to word-beginnings on
1487 ## the command line.
1489 bind2maps emacs viins vicmd -- -s '\eOc' forward-word
1490 bind2maps emacs viins vicmd -- -s '\eOd' backward-word
1491 # These are for xterm:
1492 bind2maps emacs viins vicmd -- -s '\e[1;5C' forward-word
1493 bind2maps emacs viins vicmd -- -s '\e[1;5D' backward-word
1494 ## the same for alt-left-arrow and alt-right-arrow
1496 bind2maps emacs viins vicmd -- -s '\e\e[C' forward-word
1497 bind2maps emacs viins vicmd -- -s '\e\e[D' backward-word
1499 bind2maps emacs viins vicmd -- -s '^[[1;3C' forward-word
1500 bind2maps emacs viins vicmd -- -s '^[[1;3D' backward-word
1501 # Also try ESC Left/Right:
1502 bind2maps emacs viins vicmd -- -s '\e'${key[Right]} forward-word
1503 bind2maps emacs viins vicmd -- -s '\e'${key[Left]} backward-word
1510 # we don't want to quote/espace URLs on our own...
1511 # if autoload -U url-quote-magic ; then
1512 # zle -N self-insert url-quote-magic
1513 # zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}='
1515 # print 'Notice: no url-quote-magic available :('
1517 alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic'
1519 #m# k ESC-h Call \kbd{run-help} for the 1st word on the command line
1520 alias run-help >&/dev/null && unalias run-help
1521 for rh in run-help{,-git,-svk,-svn}; do
1525 # command not found handling
1527 (( ${COMMAND_NOT_FOUND} == 1 )) &&
1528 function command_not_found_handler() {
1530 if [[ -x ${GRML_ZSH_CNF_HANDLER} ]] ; then
1531 ${GRML_ZSH_CNF_HANDLER} $1
1538 ZSHDIR=${ZDOTDIR:-${HOME}/.zsh}
1541 HISTFILE=${ZDOTDIR:-${HOME}}/.zsh_history
1542 isgrmlcd && HISTSIZE=500 || HISTSIZE=5000
1543 isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
1547 DIRSTACKSIZE=${DIRSTACKSIZE:-20}
1548 DIRSTACKFILE=${DIRSTACKFILE:-${ZDOTDIR:-${HOME}}/.zdirs}
1550 if [[ -f ${DIRSTACKFILE} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then
1551 dirstack=( ${(f)"$(< $DIRSTACKFILE)"} )
1552 # "cd -" won't work after login by just setting $OLDPWD, so
1553 [[ -d $dirstack[1] ]] && cd $dirstack[1] && cd $OLDPWD
1557 if (( $DIRSTACKSIZE <= 0 )) || [[ -z $DIRSTACKFILE ]]; then return; fi
1559 my_stack=( ${PWD} ${dirstack} )
1561 builtin print -l ${(u)my_stack} >! ${DIRSTACKFILE}
1563 uprint my_stack >! ${DIRSTACKFILE}
1567 # directory based profiles
1571 # chpwd_profiles(): Directory Profiles, Quickstart:
1575 # zstyle ':chpwd:profiles:/usr/src/grml(|/|/*)' profile grml
1576 # zstyle ':chpwd:profiles:/usr/src/debian(|/|/*)' profile debian
1579 # For details see the `grmlzshrc.5' manual page.
1580 function chpwd_profiles() {
1581 local profile context
1584 context=":chpwd:profiles:$PWD"
1585 zstyle -s "$context" profile profile || profile='default'
1586 zstyle -T "$context" re-execute && reexecute=1 || reexecute=0
1588 if (( ${+parameters[CHPWD_PROFILE]} == 0 )); then
1589 typeset -g CHPWD_PROFILE
1590 local CHPWD_PROFILES_INIT=1
1591 (( ${+functions[chpwd_profiles_init]} )) && chpwd_profiles_init
1592 elif [[ $profile != $CHPWD_PROFILE ]]; then
1593 (( ${+functions[chpwd_leave_profile_$CHPWD_PROFILE]} )) \
1594 && chpwd_leave_profile_${CHPWD_PROFILE}
1596 if (( reexecute )) || [[ $profile != $CHPWD_PROFILE ]]; then
1597 (( ${+functions[chpwd_profile_$profile]} )) && chpwd_profile_${profile}
1600 CHPWD_PROFILE="${profile}"
1604 chpwd_functions=( ${chpwd_functions} chpwd_profiles )
1608 # Prompt setup for grml:
1610 # set colors for use in prompts (modern zshs allow for the use of %F{red}foo%f
1611 # in prompts to get a red "foo" embedded, but it's good to keep these for
1612 # backwards compatibility).
1618 MAGENTA="%F{magenta}"
1622 elif zrcautoload colors && colors 2>/dev/null ; then
1623 BLUE="%{${fg[blue]}%}"
1624 RED="%{${fg_bold[red]}%}"
1625 GREEN="%{${fg[green]}%}"
1626 CYAN="%{${fg[cyan]}%}"
1627 MAGENTA="%{${fg[magenta]}%}"
1628 YELLOW="%{${fg[yellow]}%}"
1629 WHITE="%{${fg[white]}%}"
1630 NO_COLOR="%{${reset_color}%}"
1632 BLUE=$'%{\e[1;34m%}'
1634 GREEN=$'%{\e[1;32m%}'
1635 CYAN=$'%{\e[1;36m%}'
1636 WHITE=$'%{\e[1;37m%}'
1637 MAGENTA=$'%{\e[1;35m%}'
1638 YELLOW=$'%{\e[1;33m%}'
1639 NO_COLOR=$'%{\e[0m%}'
1642 # First, the easy ones: PS2..4:
1644 # secondary prompt, printed when the shell needs more information to complete a
1647 # selection prompt used within a select loop.
1649 # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
1652 # Some additional features to use with our prompt:
1656 # - vcs_info setup and version specific fixes
1658 # display battery status on right side of prompt using 'GRML_DISPLAY_BATTERY=1' in .zshrc.pre
1661 if [[ $GRML_DISPLAY_BATTERY -gt 0 ]] ; then
1664 elif isopenbsd ; then
1666 elif isfreebsd ; then
1668 elif isdarwin ; then
1672 GRML_DISPLAY_BATTERY=0
1678 GRML_BATTERY_LEVEL=''
1679 local batteries bat capacity
1680 batteries=( /sys/class/power_supply/BAT*(N) )
1681 if (( $#batteries > 0 )) ; then
1682 for bat in $batteries ; do
1683 capacity=$(< $bat/capacity)
1684 case $(< $bat/status) in
1686 GRML_BATTERY_LEVEL+=" ^"
1689 if (( capacity < 20 )) ; then
1690 GRML_BATTERY_LEVEL+=" !v"
1692 GRML_BATTERY_LEVEL+=" v"
1696 GRML_BATTERY_LEVEL+=" ="
1699 GRML_BATTERY_LEVEL+="${capacity}%%"
1705 GRML_BATTERY_LEVEL=''
1706 local bat batfull batwarn batnow num
1708 bat=$(sysctl -n hw.sensors.acpibat${num} 2>/dev/null)
1709 if [[ -n $bat ]]; then
1710 batfull=${"$(sysctl -n hw.sensors.acpibat${num}.amphour0)"%% *}
1711 batwarn=${"$(sysctl -n hw.sensors.acpibat${num}.amphour1)"%% *}
1712 batnow=${"$(sysctl -n hw.sensors.acpibat${num}.amphour3)"%% *}
1713 case "$(sysctl -n hw.sensors.acpibat${num}.raw0)" in
1715 if (( batnow < batwarn )) ; then
1716 GRML_BATTERY_LEVEL+=" !v"
1718 GRML_BATTERY_LEVEL+=" v"
1722 GRML_BATTERY_LEVEL+=" ^"
1725 GRML_BATTERY_LEVEL+=" ="
1728 GRML_BATTERY_LEVEL+="${$(( 100 * batnow / batfull ))%%.*}%%"
1734 GRML_BATTERY_LEVEL=''
1738 table=( ${=${${${${${(M)${(f)"$(acpiconf -i $num 2>&1)"}:#(State|Remaining capacity):*}%%( ##|%)}//:[ $'\t']##/@}// /-}//@/ }} )
1739 if [[ -n $table ]] && [[ $table[State] != "not-present" ]] ; then
1740 case $table[State] in
1742 if (( $table[Remaining-capacity] < 20 )) ; then
1743 GRML_BATTERY_LEVEL+=" !v"
1745 GRML_BATTERY_LEVEL+=" v"
1749 GRML_BATTERY_LEVEL+=" ^"
1752 GRML_BATTERY_LEVEL+=" ="
1755 GRML_BATTERY_LEVEL+="$table[Remaining-capacity]%%"
1761 GRML_BATTERY_LEVEL=''
1763 table=( ${$(pmset -g ps)[(w)7,8]%%(\%|);} )
1764 if [[ -n $table[2] ]] ; then
1767 GRML_BATTERY_LEVEL+=" ^"
1770 if (( $table[1] < 20 )) ; then
1771 GRML_BATTERY_LEVEL+=" !v"
1773 GRML_BATTERY_LEVEL+=" v"
1777 GRML_BATTERY_LEVEL+=" ="
1780 GRML_BATTERY_LEVEL+="$table[1]%%"
1784 # set variable debian_chroot if running in a chroot with /etc/debian_chroot
1785 if [[ -z "$debian_chroot" ]] && [[ -r /etc/debian_chroot ]] ; then
1786 debian_chroot=$(</etc/debian_chroot)
1789 # gather version control information for inclusion in a prompt
1791 if zrcautoload vcs_info; then
1792 # `vcs_info' in zsh versions 4.3.10 and below have a broken `_realpath'
1793 # function, which can cause a lot of trouble with our directory-based
1795 if [[ ${ZSH_VERSION} == 4.3.<-10> ]] ; then
1796 function VCS_INFO_realpath () {
1797 setopt localoptions NO_shwordsplit chaselinks
1798 ( builtin cd -q $1 2> /dev/null && pwd; )
1802 zstyle ':vcs_info:*' max-exports 2
1804 if [[ -o restricted ]]; then
1805 zstyle ':vcs_info:*' enable NONE
1809 typeset -A grml_vcs_coloured_formats
1810 typeset -A grml_vcs_plain_formats
1812 grml_vcs_plain_formats=(
1813 format "(%s%)-[%b] " "zsh: %r"
1814 actionformat "(%s%)-[%b|%a] " "zsh: %r"
1815 rev-branchformat "%b:%r"
1818 grml_vcs_coloured_formats=(
1819 format "${MAGENTA}(${NO_COLOR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOR} "
1820 actionformat "${MAGENTA}(${NO_COLOR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOR} "
1821 rev-branchformat "%b${RED}:${YELLOW}%r"
1824 typeset GRML_VCS_COLOUR_MODE=xxx
1826 grml_vcs_info_toggle_colour () {
1828 if [[ $GRML_VCS_COLOUR_MODE == plain ]]; then
1829 grml_vcs_info_set_formats coloured
1831 grml_vcs_info_set_formats plain
1836 grml_vcs_info_set_formats () {
1838 #setopt localoptions xtrace
1839 local mode=$1 AF F BF
1840 if [[ $mode == coloured ]]; then
1841 AF=${grml_vcs_coloured_formats[actionformat]}
1842 F=${grml_vcs_coloured_formats[format]}
1843 BF=${grml_vcs_coloured_formats[rev-branchformat]}
1844 GRML_VCS_COLOUR_MODE=coloured
1846 AF=${grml_vcs_plain_formats[actionformat]}
1847 F=${grml_vcs_plain_formats[format]}
1848 BF=${grml_vcs_plain_formats[rev-branchformat]}
1849 GRML_VCS_COLOUR_MODE=plain
1852 zstyle ':vcs_info:*' actionformats "$AF" "zsh: %r"
1853 zstyle ':vcs_info:*' formats "$F" "zsh: %r"
1854 zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat "$BF"
1858 # Change vcs_info formats for the grml prompt. The 2nd format sets up
1859 # $vcs_info_msg_1_ to contain "zsh: repo-name" used to set our screen title.
1860 if [[ "$TERM" == dumb ]] ; then
1861 grml_vcs_info_set_formats plain
1863 grml_vcs_info_set_formats coloured
1866 # Now for the fun part: The grml prompt themes in `promptsys' mode of operation
1868 # This actually defines three prompts:
1874 # They all share the same code and only differ with respect to which items they
1875 # contain. The main source of documentation is the `prompt_grml_help' function
1876 # below, which gets called when the user does this: prompt -h grml
1878 function prompt_grml_help () {
1882 This is the prompt as used by the grml-live system <http://grml.org>. It is
1883 a rather simple one-line prompt, that by default looks something like this:
1885 <user>@<host> <current-working-directory>[ <vcs_info-data>]%
1887 The prompt itself integrates with zsh's prompt themes system (as you are
1888 witnessing right now) and is configurable to a certain degree. In
1889 particular, these aspects are customisable:
1891 - The items used in the prompt (e.g. you can remove \`user' from
1892 the list of activated items, which will cause the user name to
1893 be omitted from the prompt string).
1895 - The attributes used with the items are customisable via strings
1896 used before and after the actual item.
1898 The available items are: at, battery, change-root, date, grml-chroot,
1899 history, host, jobs, newline, path, percent, rc, rc-always, sad-smiley,
1900 shell-level, time, user, vcs
1902 The actual configuration is done via zsh's \`zstyle' mechanism. The
1903 context, that is used while looking up styles is:
1905 ':prompt:grml:<left-or-right>:<subcontext>'
1907 Here <left-or-right> is either \`left' or \`right', signifying whether the
1908 style should affect the left or the right prompt. <subcontext> is either
1909 \`setup' or 'items:<item>', where \`<item>' is one of the available items.
1913 - use-rprompt (boolean): If \`true' (the default), print a sad smiley
1914 in $RPROMPT if the last command a returned non-successful error code.
1915 (This in only valid if <left-or-right> is "right"; ignored otherwise)
1917 - items (list): The list of items used in the prompt. If \`vcs' is
1918 present in the list, the theme's code invokes \`vcs_info'
1919 accordingly. Default (left): rc change-root user at host path vcs
1920 percent; Default (right): sad-smiley
1922 Available styles in 'items:<item>' are: pre, post. These are strings that
1923 are inserted before (pre) and after (post) the item in question. Thus, the
1924 following would cause the user name to be printed in red instead of the
1927 zstyle ':prompt:grml:*:items:user' pre '%F{red}'
1929 Note, that the \`post' style may remain at its default value, because its
1930 default value is '%f', which turns the foreground text attribute off (which
1931 is exactly, what is still required with the new \`pre' value).
1935 function prompt_grml-chroot_help () {
1939 This is a variation of the grml prompt, see: prompt -h grml
1941 The main difference is the default value of the \`items' style. The rest
1942 behaves exactly the same. Here are the defaults for \`grml-chroot':
1944 - left: grml-chroot user at host path percent
1945 - right: (empty list)
1949 function prompt_grml-large_help () {
1953 This is a variation of the grml prompt, see: prompt -h grml
1955 The main difference is the default value of the \`items' style. In
1956 particular, this theme uses _two_ lines instead of one with the plain
1957 \`grml' theme. The rest behaves exactly the same. Here are the defaults
1960 - left: rc jobs history shell-level change-root time date newline user
1961 at host path vcs percent
1966 function grml_prompt_setup () {
1968 autoload -Uz vcs_info
1969 autoload -Uz add-zsh-hook
1970 add-zsh-hook precmd prompt_$1_precmd
1973 function prompt_grml_setup () {
1974 grml_prompt_setup grml
1977 function prompt_grml-chroot_setup () {
1978 grml_prompt_setup grml-chroot
1981 function prompt_grml-large_setup () {
1982 grml_prompt_setup grml-large
1985 # These maps define default tokens and pre-/post-decoration for items to be
1986 # used within the themes. All defaults may be customised in a context sensitive
1987 # matter by using zsh's `zstyle' mechanism.
1988 typeset -gA grml_prompt_pre_default \
1989 grml_prompt_post_default \
1990 grml_prompt_token_default \
1991 grml_prompt_token_function
1993 grml_prompt_pre_default=(
1998 grml-chroot '%F{red}'
2008 shell-level '%F{red}'
2014 grml_prompt_post_default=(
2035 grml_prompt_token_default=(
2037 battery 'GRML_BATTERY_LEVEL'
2038 change-root 'debian_chroot'
2040 grml-chroot 'GRML_CHROOT'
2041 history '{history#%!} '
2043 jobs '[%j running job(s)] '
2045 path '%40<..<%~%<< '
2049 sad-smiley '%(?..:()'
2050 shell-level '%(3L.+ .)'
2051 time '%D{%H:%M:%S} '
2056 function grml_theme_has_token () {
2057 if (( ARGC != 1 )); then
2058 printf 'usage: grml_theme_has_token <name>\n'
2061 (( ${+grml_prompt_token_default[$1]} ))
2064 function GRML_theme_add_token_usage () {
2066 Usage: grml_theme_add_token <name> [-f|-i] <token/function> [<pre> <post>]
2068 <name> is the name for the newly added token. If the \`-f' or \`-i' options
2069 are used, <token/function> is the name of the function (see below for
2070 details). Otherwise it is the literal token string to be used. <pre> and
2071 <post> are optional.
2075 -f <function> Use a function named \`<function>' each time the token
2078 -i <function> Use a function named \`<function>' to initialise the
2079 value of the token _once_ at runtime.
2081 The functions are called with one argument: the token's new name. The
2082 return value is expected in the \$REPLY parameter. The use of these
2083 options is mutually exclusive.
2085 There is a utility function \`grml_theme_has_token', which you can use
2086 to test if a token exists before trying to add it. This can be a guard
2087 for situations in which a \`grml_theme_add_token' call may happen more
2092 To add a new token \`day' that expands to the current weekday in the
2093 current locale in green foreground colour, use this:
2095 grml_theme_add_token day '%D{%A}' '%F{green}' '%f'
2097 Another example would be support for \$VIRTUAL_ENV:
2099 function virtual_env_prompt () {
2100 REPLY=\${VIRTUAL_ENV+\${VIRTUAL_ENV:t} }
2102 grml_theme_add_token virtual-env -f virtual_env_prompt
2104 After that, you will be able to use a changed \`items' style to
2105 assemble your prompt.
2109 function grml_theme_add_token () {
2111 local name token pre post
2112 local -i init funcall
2114 if (( ARGC == 0 )); then
2115 GRML_theme_add_token_usage
2125 if [[ $1 == '-f' ]]; then
2128 elif [[ $1 == '-i' ]]; then
2133 if (( ARGC == 0 )); then
2135 grml_theme_add_token: No token-string/function-name provided!\n\n'
2136 GRML_theme_add_token_usage
2141 if (( ARGC != 0 && ARGC != 2 )); then
2143 grml_theme_add_token: <pre> and <post> need to by specified _both_!\n\n'
2144 GRML_theme_add_token_usage
2153 if grml_theme_has_token $name; then
2155 grml_theme_add_token: Token `%s'\'' exists! Giving up!\n\n' $name
2156 GRML_theme_add_token_usage
2163 grml_prompt_pre_default[$name]=$pre
2164 grml_prompt_post_default[$name]=$post
2165 if (( funcall )); then
2166 grml_prompt_token_function[$name]=$token
2167 grml_prompt_token_default[$name]=23
2169 grml_prompt_token_default[$name]=$token
2173 function grml_typeset_and_wrap () {
2180 if (( ${+parameters[$new]} )); then
2181 typeset -g "${target}=${(P)target}${left}${(P)new}${right}"
2185 function grml_prompt_addto () {
2188 local lr it apre apost new v
2192 [[ $target == PS1 ]] && lr=left || lr=right
2193 zstyle -a ":prompt:${grmltheme}:${lr}:setup" items items || items=( "$@" )
2194 typeset -g "${target}="
2195 for it in "${items[@]}"; do
2196 zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" pre apre \
2197 || apre=${grml_prompt_pre_default[$it]}
2198 zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" post apost \
2199 || apost=${grml_prompt_post_default[$it]}
2200 zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" token new \
2201 || new=${grml_prompt_token_default[$it]}
2202 typeset -g "${target}=${(P)target}${apre}"
2203 if (( ${+grml_prompt_token_function[$it]} )); then
2204 ${grml_prompt_token_function[$it]} $it
2205 typeset -g "${target}=${(P)target}${REPLY}"
2209 grml_typeset_and_wrap $target $new '' ''
2212 grml_typeset_and_wrap $target $new '(' ')'
2215 if [[ -n ${(P)new} ]]; then
2216 typeset -g "${target}=${(P)target}(CHROOT)"
2220 v="vcs_info_msg_${new}_"
2221 if (( ! vcscalled )); then
2225 if (( ${+parameters[$v]} )) && [[ -n "${(P)v}" ]]; then
2226 typeset -g "${target}=${(P)target}${(P)v}"
2229 *) typeset -g "${target}=${(P)target}${new}" ;;
2232 typeset -g "${target}=${(P)target}${apost}"
2236 function prompt_grml_precmd () {
2238 local grmltheme=grml
2239 local -a left_items right_items
2240 left_items=(rc change-root user at host path vcs percent)
2241 right_items=(sad-smiley)
2243 prompt_grml_precmd_worker
2246 function prompt_grml-chroot_precmd () {
2248 local grmltheme=grml-chroot
2249 local -a left_items right_items
2250 left_items=(grml-chroot user at host path percent)
2253 prompt_grml_precmd_worker
2256 function prompt_grml-large_precmd () {
2258 local grmltheme=grml-large
2259 local -a left_items right_items
2260 left_items=(rc jobs history shell-level change-root time date newline
2261 user at host path vcs percent)
2262 right_items=(sad-smiley)
2264 prompt_grml_precmd_worker
2267 function prompt_grml_precmd_worker () {
2269 local -i vcscalled=0
2271 grml_prompt_addto PS1 "${left_items[@]}"
2272 if zstyle -T ":prompt:${grmltheme}:right:setup" use-rprompt; then
2273 grml_prompt_addto RPS1 "${right_items[@]}"
2277 grml_prompt_fallback() {
2280 (( ${+functions[vcs_info]} )) && vcs_info
2283 p0="${RED}%(?..%? )${WHITE}${debian_chroot:+($debian_chroot)}"
2284 p1="${BLUE}%n${NO_COLOR}@%m %40<...<%B%~%b%<< "'${vcs_info_msg_0_}'"%# "
2285 if (( EUID == 0 )); then
2286 PROMPT="${BLUE}${p0}${RED}${p1}"
2288 PROMPT="${RED}${p0}${BLUE}${p1}"
2293 if zrcautoload promptinit && promptinit 2>/dev/null ; then
2294 # Since we define the required functions in here and not in files in
2295 # $fpath, we need to stick the theme's name into `$prompt_themes'
2296 # ourselves, since promptinit does not pick them up otherwise.
2297 prompt_themes+=( grml grml-chroot grml-large )
2298 # Also, keep the array sorted...
2299 prompt_themes=( "${(@on)prompt_themes}" )
2301 print 'Notice: no promptinit available :('
2302 grml_prompt_fallback
2306 # The prompt themes use modern features of zsh, that require at least
2307 # version 4.3.7 of the shell. Use the fallback otherwise.
2308 if [[ $GRML_DISPLAY_BATTERY -gt 0 ]]; then
2309 zstyle ':prompt:grml:right:setup' items sad-smiley battery
2310 add-zsh-hook precmd battery
2312 if [[ "$TERM" == dumb ]] ; then
2313 zstyle ":prompt:grml(|-large|-chroot):*:items:grml-chroot" pre ''
2314 zstyle ":prompt:grml(|-large|-chroot):*:items:grml-chroot" post ' '
2315 for i in rc user path jobs history date time shell-level; do
2316 zstyle ":prompt:grml(|-large|-chroot):*:items:$i" pre ''
2317 zstyle ":prompt:grml(|-large|-chroot):*:items:$i" post ''
2320 zstyle ':prompt:grml(|-large|-chroot):right:setup' use-rprompt false
2321 elif (( EUID == 0 )); then
2322 zstyle ':prompt:grml(|-large|-chroot):*:items:user' pre '%B%F{red}'
2325 # Finally enable one of the prompts.
2326 if [[ -n $GRML_CHROOT ]]; then
2328 elif [[ $GRMLPROMPT -gt 0 ]]; then
2334 grml_prompt_fallback
2337 # Terminal-title wizardry
2339 function ESC_print () {
2340 info_print $'\ek' $'\e\\' "$@"
2342 function set_title () {
2343 info_print $'\e]0;' $'\a' "$@"
2346 function info_print () {
2347 local esc_begin esc_end
2351 printf '%s' ${esc_begin}
2353 printf '%s' "${esc_end}"
2356 function grml_reset_screen_title () {
2357 # adjust title of xterm
2358 # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
2359 [[ ${NOTITLE:-} -gt 0 ]] && return 0
2362 set_title ${(%):-"%n@%m: %~"}
2367 function grml_vcs_to_screen_title () {
2368 if [[ $TERM == screen* ]] ; then
2369 if [[ -n ${vcs_info_msg_1_} ]] ; then
2370 ESC_print ${vcs_info_msg_1_}
2377 function grml_maintain_name () {
2378 # set hostname if not running on host with name 'grml'
2379 if [[ -n "$HOSTNAME" ]] && [[ "$HOSTNAME" != $(hostname) ]] ; then
2384 function grml_cmd_to_screen_title () {
2385 # get the name of the program currently running and hostname of local
2386 # machine set screen window title if running in a screen
2387 if [[ "$TERM" == screen* ]] ; then
2388 local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME"
2393 function grml_control_xterm_title () {
2396 set_title "${(%):-"%n@%m:"}" "$1"
2401 zrcautoload add-zsh-hook || add-zsh-hook () { :; }
2402 if [[ $NOPRECMD -eq 0 ]]; then
2403 add-zsh-hook precmd grml_reset_screen_title
2404 add-zsh-hook precmd grml_vcs_to_screen_title
2405 add-zsh-hook preexec grml_maintain_name
2406 add-zsh-hook preexec grml_cmd_to_screen_title
2407 if [[ $NOTITLE -eq 0 ]]; then
2408 add-zsh-hook preexec grml_control_xterm_title
2412 # 'hash' some often used directories
2414 hash -d deb=/var/cache/apt/archives
2415 hash -d doc=/usr/share/doc
2416 hash -d linux=/lib/modules/$(command uname -r)/build/
2417 hash -d log=/var/log
2418 hash -d slog=/var/log/syslog
2419 hash -d src=/usr/src
2420 hash -d www=/var/www
2424 if check_com -c screen ; then
2425 if [[ $UID -eq 0 ]] ; then
2426 if [[ -r /etc/grml/screenrc ]]; then
2427 alias screen="${commands[screen]} -c /etc/grml/screenrc"
2429 elif [[ -r $HOME/.screenrc ]] ; then
2430 alias screen="${commands[screen]} -c $HOME/.screenrc"
2432 if [[ -r /etc/grml/screenrc_grml ]]; then
2433 alias screen="${commands[screen]} -c /etc/grml/screenrc_grml"
2435 if [[ -r /etc/grml/screenrc ]]; then
2436 alias screen="${commands[screen]} -c /etc/grml/screenrc"
2442 # do we have GNU ls with color-support?
2443 if [[ "$TERM" != dumb ]]; then
2444 #a1# List files with colors (\kbd{ls \ldots})
2445 alias ls="command ls ${ls_options:+${ls_options[*]}}"
2446 #a1# List all files, with colors (\kbd{ls -la \ldots})
2447 alias la="command ls -la ${ls_options:+${ls_options[*]}}"
2448 #a1# List files with long colored list, without dotfiles (\kbd{ls -l \ldots})
2449 alias ll="command ls -l ${ls_options:+${ls_options[*]}}"
2450 #a1# List files with long colored list, human readable sizes (\kbd{ls -hAl \ldots})
2451 alias lh="command ls -hAl ${ls_options:+${ls_options[*]}}"
2452 #a1# List files with long colored list, append qualifier to filenames (\kbd{ls -l \ldots})\\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
2453 alias l="command ls -l ${ls_options:+${ls_options[*]}}"
2455 alias la='command ls -la'
2456 alias ll='command ls -l'
2457 alias lh='command ls -hAl'
2458 alias l='command ls -l'
2461 alias mdstat='cat /proc/mdstat'
2462 alias ...='cd ../../'
2464 # generate alias named "$KERNELVERSION-reboot" so you can use boot with kexec:
2465 if [[ -x /sbin/kexec ]] && [[ -r /proc/cmdline ]] ; then
2466 alias "$(uname -r)-reboot"="kexec -l --initrd=/boot/initrd.img-"$(uname -r)" --command-line=\"$(cat /proc/cmdline)\" /boot/vmlinuz-"$(uname -r)""
2469 # see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
2470 alias term2iso="echo 'Setting terminal to iso mode' ; print -n '\e%@'"
2471 alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
2473 # make sure it is not assigned yet
2474 [[ -n ${aliases[utf2iso]} ]] && unalias utf2iso
2477 for ENV in $(env | command grep -i '.utf') ; do
2478 eval export "$(echo $ENV | sed 's/UTF-8/iso885915/ ; s/utf8/iso885915/')"
2483 # make sure it is not assigned yet
2484 [[ -n ${aliases[iso2utf]} ]] && unalias iso2utf
2486 if ! isutfenv ; then
2487 for ENV in $(env | command grep -i '\.iso') ; do
2488 eval export "$(echo $ENV | sed 's/iso.*/UTF-8/ ; s/ISO.*/UTF-8/')"
2493 # especially for roadwarriors using GNU screen and ssh:
2494 if ! check_com asc &>/dev/null ; then
2495 asc() { autossh -t "$@" 'screen -RdU' }
2499 #f1# Hints for the use of zsh on grml
2501 print "$bg[white]$fg[black]
2502 zsh-help - hints for use of zsh on grml
2503 =======================================$reset_color"
2506 Main configuration of zsh happens in /etc/zsh/zshrc.
2507 That file is part of the package grml-etc-core, if you want to
2508 use them on a non-grml-system just get the tar.gz from
2509 http://deb.grml.org/ or (preferably) get it from the git repository:
2511 http://git.grml.org/f/grml-etc-core/etc/zsh/zshrc
2513 This version of grml'\''s zsh setup does not use skel/.zshrc anymore.
2514 The file is still there, but it is empty for backwards compatibility.
2516 For your own changes use these two files:
2520 The former is sourced very early in our zshrc, the latter is sourced
2523 System wide configuration without touching configuration files of grml
2524 can take place in /etc/zsh/zshrc.local.
2526 For information regarding zsh start at http://grml.org/zsh/
2528 Take a look at grml'\''s zsh refcard:
2529 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
2531 Check out the main zsh refcard:
2532 % '$BROWSER' http://www.bash2zsh.com/zsh_refcard/refcard.pdf
2534 And of course visit the zsh-lovers:
2537 You can adjust some options through environment variables when
2538 invoking zsh without having to edit configuration files.
2539 Basically meant for bash users who are not used to the power of
2542 "NOCOR=1 zsh" => deactivate automatic correction
2543 "NOMENU=1 zsh" => do not use auto menu completion
2544 (note: use ctrl-d for completion instead!)
2545 "NOPRECMD=1 zsh" => disable the precmd + preexec commands (set GNU screen title)
2546 "NOTITLE=1 zsh" => disable setting the title of xterms without disabling
2547 preexec() and precmd() completely
2548 "GRML_DISPLAY_BATTERY=1 zsh"
2549 => activate battery status on right side of prompt (WIP)
2550 "COMMAND_NOT_FOUND=1 zsh"
2551 => Enable a handler if an external command was not found
2552 The command called in the handler can be altered by setting
2553 the GRML_ZSH_CNF_HANDLER variable, the default is:
2554 "/usr/share/command-not-found/command-not-found"
2556 A value greater than 0 is enables a feature; a value equal to zero
2557 disables it. If you like one or the other of these settings, you can
2558 add them to ~/.zshrc.pre to ensure they are set when sourcing grml'\''s
2562 $bg[white]$fg[black]
2563 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
2564 Enjoy your grml system with the zsh!$reset_color"
2568 if [[ -r /etc/debian_version ]] ; then
2569 #a3# Execute \kbd{apt-cache search}
2570 alias acs='apt-cache search'
2571 #a3# Execute \kbd{apt-cache show}
2572 alias acsh='apt-cache show'
2573 #a3# Execute \kbd{apt-cache policy}
2574 alias acp='apt-cache policy'
2575 #a3# Execute \kbd{apt-get dist-upgrade}
2576 salias adg="apt-get dist-upgrade"
2577 #a3# Execute \kbd{apt-get install}
2578 salias agi="apt-get install"
2579 #a3# Execute \kbd{aptitude install}
2580 salias ati="aptitude install"
2581 #a3# Execute \kbd{apt-get upgrade}
2582 salias ag="apt-get upgrade"
2583 #a3# Execute \kbd{apt-get update}
2584 salias au="apt-get update"
2585 #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
2586 salias -a up="aptitude update ; aptitude safe-upgrade"
2587 #a3# Execute \kbd{dpkg-buildpackage}
2588 alias dbp='dpkg-buildpackage'
2589 #a3# Execute \kbd{grep-excuses}
2590 alias ge='grep-excuses'
2592 # get a root shell as normal user in live-cd mode:
2593 if isgrmlcd && [[ $UID -ne 0 ]] ; then
2597 #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
2598 salias llog="$PAGER /var/log/syslog" # take a look at the syslog
2599 #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
2600 salias tlog="tail -f /var/log/syslog" # follow the syslog
2603 # sort installed Debian-packages by size
2604 if check_com -c dpkg-query ; then
2605 #a3# List installed Debian-packages sorted by size
2606 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"
2609 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
2610 if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord; then
2611 if check_com -c wodim; then
2614 cdrecord is not provided under its original name by Debian anymore.
2615 See #377109 in the BTS of Debian for more details.
2617 Please use the wodim binary instead
2624 # Use hard limits, except for a smaller stack and no core dumps
2626 is425 && limit stack 8192
2627 isgrmlcd && limit core 0 # important for a live-cd-system
2632 # people should use 'grml-x'!
2633 if check_com -c 915resolution; then
2635 echo "Please use 915resolution as resolution modifying tool for Intel \
2641 #a1# Output version of running grml
2642 alias grml-version='cat /etc/grml_version'
2644 if check_com -c grml-debootstrap ; then
2646 echo "Installing debian to harddisk is possible by using grml-debootstrap."
2652 # now run the functions
2654 is4 && isgrml && grmlstuff
2658 is4 && xsource "/etc/zsh/keephack"
2660 # wonderful idea of using "e" glob qualifier by Peter Stephenson
2661 # You use it as follows:
2662 # $ NTREF=/reference/file
2664 # This lists all the files in the current directory newer than the reference file.
2665 # You can also specify the reference file inline; note quotes:
2666 # $ ls -l *(e:'nt ~/.zshenv':)
2668 if [[ -n $1 ]] ; then
2671 [[ $REPLY -nt $NTREF ]]
2676 #f1# Reload an autoloadable function
2677 freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
2678 compdef _functions freload
2680 #f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
2682 [[ -z "$1" ]] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
2684 for file in "$@" ; do
2685 while [[ -h "$file" ]] ; do
2687 file=$(readlink "$file")
2692 # TODO: Is it supported to use pager settings like this?
2693 # PAGER='less -Mr' - If so, the use of $PAGER here needs fixing
2694 # with respect to wordsplitting. (ie. ${=PAGER})
2695 if check_com -c $PAGER ; then
2696 #f3# View Debian's changelog of given package(s)
2699 [[ -z "$1" ]] && printf 'Usage: %s <package_name(s)>\n' "$0" && return 1
2702 for package in "$@" ; do
2703 if [[ -r /usr/share/doc/${package}/changelog.Debian.gz ]] ; then
2704 $PAGER /usr/share/doc/${package}/changelog.Debian.gz
2705 elif [[ -r /usr/share/doc/${package}/changelog.gz ]] ; then
2706 $PAGER /usr/share/doc/${package}/changelog.gz
2707 elif [[ -r /usr/share/doc/${package}/changelog ]] ; then
2708 $PAGER /usr/share/doc/${package}/changelog
2710 if check_com -c aptitude ; then
2711 echo "No changelog for package $package found, using aptitude to retrieve it."
2712 aptitude changelog "$package"
2713 elif check_com -c apt-get ; then
2714 echo "No changelog for package $package found, using apt-get to retrieve it."
2715 apt-get changelog "$package"
2717 echo "No changelog for package $package found, sorry."
2722 _dchange() { _files -W /usr/share/doc -/ }
2723 compdef _dchange dchange
2725 #f3# View Debian's NEWS of a given package
2728 if [[ -r /usr/share/doc/$1/NEWS.Debian.gz ]] ; then
2729 $PAGER /usr/share/doc/$1/NEWS.Debian.gz
2731 if [[ -r /usr/share/doc/$1/NEWS.gz ]] ; then
2732 $PAGER /usr/share/doc/$1/NEWS.gz
2734 echo "No NEWS file for package $1 found, sorry."
2739 _dnews() { _files -W /usr/share/doc -/ }
2740 compdef _dnews dnews
2742 #f3# View Debian's copyright of a given package
2745 if [[ -r /usr/share/doc/$1/copyright ]] ; then
2746 $PAGER /usr/share/doc/$1/copyright
2748 echo "No copyright file for package $1 found, sorry."
2752 _dcopyright() { _files -W /usr/share/doc -/ }
2753 compdef _dcopyright dcopyright
2755 #f3# View upstream's changelog of a given package
2758 if [[ -r /usr/share/doc/$1/changelog.gz ]] ; then
2759 $PAGER /usr/share/doc/$1/changelog.gz
2761 echo "No changelog for package $1 found, sorry."
2765 _uchange() { _files -W /usr/share/doc -/ }
2766 compdef _uchange uchange
2771 ZSH_PROFILE_RC=1 $SHELL "$@"
2774 #f1# Edit an alias via zle
2776 [[ -z "$1" ]] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
2778 compdef _aliases edalias
2780 #f1# Edit a function via zle
2782 [[ -z "$1" ]] && { echo "Usage: edfunc <function_to_edit>" ; return 1 } || zed -f "$1" ;
2784 compdef _functions edfunc
2786 # use it e.g. via 'Restart apache2'
2787 #m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
2788 #m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
2789 #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
2790 #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
2791 #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
2792 #m# f6 Status() \kbd{/etc/init.d/\em{process}}\quad\kbd{status}
2793 if [[ -d /etc/init.d || -d /etc/service ]] ; then
2795 local action_="${1:l}" # e.g Start/Stop/Restart
2799 local service_target_="$(readlink /etc/init.d/$service_)"
2800 if [[ $service_target_ == "/usr/bin/sv" ]]; then
2802 case "${action_}" in
2803 start) if [[ ! -e /etc/service/$service_ ]]; then
2804 $SUDO ln -s "/etc/sv/$service_" "/etc/service/"
2806 $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
2808 # there is no reload in runits sysv emulation
2809 reload) $SUDO "/etc/init.d/$service_" "force-reload" "$param_" ;;
2810 *) $SUDO "/etc/init.d/$service_" "${action_}" "$param_" ;;
2814 $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
2820 scripts=( /etc/init.d/*(x:t) )
2821 _describe "service startup script" scripts
2824 for i in Start Restart Stop Force-Reload Reload Status ; do
2825 eval "$i() { __start_stop $i \"\$1\" \"\$2\" ; }"
2826 compdef _grmlinitd $i
2830 #f1# Provides useful information on globbing
2837 p named pipes (FIFOs)
2838 * executable plain files (0100)
2839 % device files (character or block special)
2840 %b block special files
2841 %c character special files
2842 r owner-readable files (0400)
2843 w owner-writable files (0200)
2844 x owner-executable files (0100)
2845 A group-readable files (0040)
2846 I group-writable files (0020)
2847 E group-executable files (0010)
2848 R world-readable files (0004)
2849 W world-writable files (0002)
2850 X world-executable files (0001)
2851 s setuid files (04000)
2852 S setgid files (02000)
2853 t files with the sticky bit (01000)
2855 print *(m-1) # Files modified up to a day ago
2856 print *(a1) # Files accessed a day ago
2857 print *(@) # Just symlinks
2858 print *(Lk+50) # Files bigger than 50 kilobytes
2859 print *(Lk-50) # Files smaller than 50 kilobytes
2860 print **/*.c # All *.c files recursively starting in \$PWD
2861 print **/*.c~file.c # Same as above, but excluding 'file.c'
2862 print (foo|bar).* # Files starting with 'foo' or 'bar'
2863 print *~*.* # All Files that do not contain a dot
2864 chmod 644 *(.^x) # make all plain non-executable files publically readable
2865 print -l *(.c|.h) # Lists *.c and *.h
2866 print **/*(g:users:) # Recursively match all files that are owned by group 'users'
2867 echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
2869 alias help-zshglob=H-Glob
2871 # grep for running process, like: 'any vim'
2875 if [[ -z "$1" ]] ; then
2876 echo "any - grep for process(es) by keyword" >&2
2877 echo "Usage: any <keyword>" >&2 ; return 1
2879 ps xauwww | grep -i "${grep_options[@]}" "[${1[1]}]${1[2,-1]}"
2884 # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
2885 # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
2886 [[ -r /proc/1/maps ]] && \
2888 print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
2889 cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/') > /dev/null
2890 print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
2893 # a wrapper for vim, that deals with title setting
2895 # set this array to a set of options to vim you always want
2896 # to have set when calling vim (in .zshrc.local), like:
2897 # VIM_OPTIONS=( -p )
2898 # This will cause vim to send every file given on the
2899 # commandline to be send to it's own tab (needs vim7).
2900 if check_com vim; then
2902 VIM_PLEASE_SET_TITLE='yes' command vim ${VIM_OPTIONS} "$@"
2906 ssl_hashes=( sha512 sha256 sha1 md5 )
2908 for sh in ${ssl_hashes}; do
2909 eval 'ssl-cert-'${sh}'() {
2911 if [[ -z $1 ]] ; then
2912 printf '\''usage: %s <file>\n'\'' "ssh-cert-'${sh}'"
2915 openssl x509 -noout -fingerprint -'${sh}' -in $1
2919 ssl-cert-fingerprints() {
2922 if [[ -z $1 ]] ; then
2923 printf 'usage: ssl-cert-fingerprints <file>\n'
2926 for i in ${ssl_hashes}
2933 if [[ -z $1 ]] ; then
2934 printf 'usage: ssl-cert-info <file>\n'
2937 openssl x509 -noout -text -in $1
2938 ssl-cert-fingerprints $1
2941 # make sure our environment is clean regarding colors
2942 for color in BLUE RED GREEN CYAN YELLOW MAGENTA WHITE ; unset $color
2944 # "persistent history"
2945 # just write important commands you always need to ~/.important_commands
2946 if [[ -r ~/.important_commands ]] ; then
2947 fc -R ~/.important_commands
2950 # load the lookup subsystem if it's available on the system
2951 zrcautoload lookupinit && lookupinit
2955 # set terminal property (used e.g. by msgid-chooser)
2956 export COLORTERM="yes"
2961 #a2# Execute \kbd{du -sch}
2965 #a2# Execute \kbd{ls -lSrah}
2966 alias dir="command ls -lSrah"
2967 #a2# Only show dot-directories
2968 alias lad='command ls -d .*(/)'
2969 #a2# Only show dot-files
2970 alias lsa='command ls -a .*(.)'
2971 #a2# Only files with setgid/setuid/sticky flag
2972 alias lss='command ls -l *(s,S,t)'
2973 #a2# Only show symlinks
2974 alias lsl='command ls -l *(@)'
2975 #a2# Display only executables
2976 alias lsx='command ls -l *(*)'
2977 #a2# Display world-{readable,writable,executable} files
2978 alias lsw='command ls -ld *(R,W,X.^ND/)'
2979 #a2# Display the ten biggest files
2980 alias lsbig="command ls -flh *(.OL[1,10])"
2981 #a2# Only show directories
2982 alias lsd='command ls -d *(/)'
2983 #a2# Only show empty directories
2984 alias lse='command ls -d *(/^F)'
2985 #a2# Display the ten newest files
2986 alias lsnew="command ls -rtlh *(D.om[1,10])"
2987 #a2# Display the ten oldest files
2988 alias lsold="command ls -rtlh *(D.Om[1,10])"
2989 #a2# Display the ten smallest files
2990 alias lssmall="command ls -Srl *(.oL[1,10])"
2991 #a2# Display the ten newest directories and ten newest .directories
2992 alias lsnewdir="command ls -rthdl *(/om[1,10]) .*(D/om[1,10])"
2993 #a2# Display the ten oldest directories and ten oldest .directories
2994 alias lsolddir="command ls -rthdl *(/Om[1,10]) .*(D/Om[1,10])"
2996 # some useful aliases
2997 #a2# Remove current empty directory. Execute \kbd{cd ..; rmdir \$OLDCWD}
2998 alias rmcdir='cd ..; rmdir $OLDPWD || cd $OLDPWD'
3000 #a2# ssh with StrictHostKeyChecking=no \\&\quad and UserKnownHostsFile unset
3001 alias insecssh='ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
3002 #a2# scp with StrictHostKeyChecking=no \\&\quad and UserKnownHostsFile unset
3003 alias insecscp='scp -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
3005 # work around non utf8 capable software in utf environment via $LANG and luit
3006 if check_com isutfenv && check_com luit ; then
3007 if check_com -c mrxvt ; then
3008 isutfenv && [[ -n "$LANG" ]] && \
3009 alias mrxvt="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit mrxvt"
3012 if check_com -c aterm ; then
3013 isutfenv && [[ -n "$LANG" ]] && \
3014 alias aterm="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit aterm"
3017 if check_com -c centericq ; then
3018 isutfenv && [[ -n "$LANG" ]] && \
3019 alias centericq="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit centericq"
3025 #f5# Backup \kbd{file_or_folder {\rm to} file_or_folder\_timestamp}
3028 local current_date=$(date -u "+%Y-%m-%dT%H:%M:%SZ")
3029 local clean keep move verbose result all
3030 setopt extended_glob
3033 bk [-hcmv] FILE [FILE ...]
3034 bk -r [-av] [FILE [FILE ...]]
3035 Backup a file or folder in place and append the timestamp
3036 Remove backups of a file or folder, or all backups in the current directory
3039 -h Display this help text
3040 -c Keep the file/folder as is, create a copy backup using cp(1) (default)
3041 -m Move the file/folder, using mv(1)
3042 -r Remove backups of the specified file or directory, using rm(1). If none
3043 is provided, remove all backups in the current directory.
3044 -a Remove all (even hidden) backups.
3047 The -c, -r and -m options are mutually exclusive. If specified at the same time,
3048 the last one is used.
3050 The return code is the sum of all cp/mv/rm return codes.
3054 while getopts ":hacmrv" opt; do
3057 c) unset move clean && (( ++keep ));;
3058 m) unset keep clean && (( ++move ));;
3059 r) unset move keep && (( ++clean ));;
3062 \?) usage >&2; return 1;;
3065 shift "$((OPTIND-1))"
3066 if (( keep > 0 )); then
3067 while (( $# > 0 )); do
3068 if islinux || isfreebsd; then
3069 cp $verbose -a "${1%/}" "${1%/}_$current_date"
3071 cp $verbose -pR "${1%/}" "${1%/}_$current_date"
3076 elif (( move > 0 )); then
3077 while (( $# > 0 )); do
3078 mv $verbose "${1%/}" "${1%/}_$current_date"
3082 elif (( clean > 0 )); then
3083 if (( $# > 0 )); then
3084 while (( $# > 0 )); do
3085 rm $verbose -rf "${1%/}"_[0-9](#c4,)-(0[0-9]|1[0-2])-([0-2][0-9]|3[0-1])T([0-1][0-9]|2[0-3])(:[0-5][0-9])(#c2)Z
3090 if (( all > 0 )); then
3091 rm $verbose -rf *_[0-9](#c4,)-(0[0-9]|1[0-2])-([0-2][0-9]|3[0-1])T([0-1][0-9]|2[0-3])(:[0-5][0-9])(#c2)Z(D)
3093 rm $verbose -rf *_[0-9](#c4,)-(0[0-9]|1[0-2])-([0-2][0-9]|3[0-1])T([0-1][0-9]|2[0-3])(:[0-5][0-9])(#c2)Z
3101 #f5# cd to directoy and list files
3107 # smart cd function, allows switching to /etc when running 'cd /etc/fstab'
3109 if (( ${#argv} == 1 )) && [[ -f ${1} ]]; then
3110 [[ ! -e ${1:h} ]] && return 1
3111 print "Correcting ${1} to ${1:h}"
3118 #f5# Create Directoy and \kbd{cd} to it
3120 if (( ARGC != 1 )); then
3121 printf 'usage: mkcd <new-directory>\n'
3124 if [[ ! -d "$1" ]]; then
3125 command mkdir -p "$1"
3127 printf '`%s'\'' already exists: cd-ing.\n' "$1"
3132 #f5# Create temporary directory and \kbd{cd} to it
3140 #f5# List files which have been accessed within the last {\it n} days, {\it n} defaults to 1
3143 print -l -- *(a-${1:-1})
3146 #f5# List files which have been changed within the last {\it n} days, {\it n} defaults to 1
3149 print -l -- *(c-${1:-1})
3152 #f5# List files which have been modified within the last {\it n} days, {\it n} defaults to 1
3155 print -l -- *(m-${1:-1})
3157 # modified() was named new() in earlier versions, add an alias for backwards compatibility
3158 check_com new || alias new=modified
3160 # use colors when GNU grep with color-support
3161 if (( $#grep_options > 0 )); then
3162 o=${grep_options:+"${grep_options[*]}"}
3163 #a2# Execute \kbd{grep -{}-color=auto}
3164 alias grep='grep '$o
3165 alias egrep='egrep '$o
3170 # 'translate' looks up fot a word in a file with language-to-language
3171 # translations (field separator should be " : "). A typical wordlist looks
3173 # | english-word : german-transmission
3174 # It's also only possible to translate english to german but not reciprocal.
3175 # Use the following oneliner to turn back the sort order:
3176 # $ awk -F ':' '{ print $2" : "$1" "$3 }' \
3177 # /usr/local/lib/words/en-de.ISO-8859-1.vok > ~/.translate/de-en.ISO-8859-1.vok
3178 #f5# Translates a word
3183 translate -l de-en $2
3186 translate -l en-de $2
3189 echo "Usage: $0 { -D | -E }"
3190 echo " -D == German to English"
3191 echo " -E == English to German"
3195 # Usage: simple-extract <file>
3196 # Using option -d deletes the original archive file.
3197 #f5# Smart archive extractor
3200 setopt extended_glob noclobber
3201 local DELETE_ORIGINAL DECOMP_CMD USES_STDIN USES_STDOUT GZTARGET WGET_CMD
3203 zparseopts -D -E "d=DELETE_ORIGINAL"
3204 for ARCHIVE in "${@}"; do
3206 *(tar.bz2|tbz2|tbz))
3207 DECOMP_CMD="tar -xvjf -"
3212 DECOMP_CMD="tar -xvzf -"
3216 *(tar.xz|txz|tar.lzma))
3217 DECOMP_CMD="tar -xvJf -"
3222 DECOMP_CMD="tar -xvf -"
3227 DECOMP_CMD="unrar x"
3252 DECOMP_CMD="bzip2 -d -c -"
3257 DECOMP_CMD="gzip -d -c -"
3262 DECOMP_CMD="xz -d -c -"
3267 print "ERROR: '$ARCHIVE' has unrecognized archive type." >&2
3273 if ! check_com ${DECOMP_CMD[(w)1]}; then
3274 echo "ERROR: ${DECOMP_CMD[(w)1]} not installed." >&2
3279 GZTARGET="${ARCHIVE:t:r}"
3280 if [[ -f $ARCHIVE ]] ; then
3282 print "Extracting '$ARCHIVE' ..."
3283 if $USES_STDIN; then
3284 if $USES_STDOUT; then
3285 ${=DECOMP_CMD} < "$ARCHIVE" > $GZTARGET
3287 ${=DECOMP_CMD} < "$ARCHIVE"
3290 if $USES_STDOUT; then
3291 ${=DECOMP_CMD} "$ARCHIVE" > $GZTARGET
3293 ${=DECOMP_CMD} "$ARCHIVE"
3296 [[ $? -eq 0 && -n "$DELETE_ORIGINAL" ]] && rm -f "$ARCHIVE"
3298 elif [[ "$ARCHIVE" == (#s)(https|http|ftp)://* ]] ; then
3299 if check_com curl; then
3300 WGET_CMD="curl -L -k -s -o -"
3301 elif check_com wget; then
3302 WGET_CMD="wget -q -O - --no-check-certificate"
3304 print "ERROR: neither wget nor curl is installed" >&2
3308 print "Downloading and Extracting '$ARCHIVE' ..."
3309 if $USES_STDIN; then
3310 if $USES_STDOUT; then
3311 ${=WGET_CMD} "$ARCHIVE" | ${=DECOMP_CMD} > $GZTARGET
3314 ${=WGET_CMD} "$ARCHIVE" | ${=DECOMP_CMD}
3318 if $USES_STDOUT; then
3319 ${=DECOMP_CMD} =(${=WGET_CMD} "$ARCHIVE") > $GZTARGET
3321 ${=DECOMP_CMD} =(${=WGET_CMD} "$ARCHIVE")
3326 print "ERROR: '$ARCHIVE' is neither a valid file nor a supported URI." >&2
3336 '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)"' \
3337 '_urls:Remote Archives:_urls'
3343 '-d[delete original archivefile after extraction]' \
3344 '*:Archive Or Uri:__archive_or_uri'
3346 compdef _simple_extract simple-extract
3347 alias se=simple-extract
3349 #f5# Set all ulimit parameters to \kbd{unlimited}
3360 #f5# Change the xterm title from within GNU-screen
3363 if [[ $1 != "-f" ]] ; then
3364 if [[ -z ${DISPLAY} ]] ; then
3365 printf 'xtrename only makes sense in X11.\n'
3371 if [[ -z $1 ]] ; then
3372 printf 'usage: xtrename [-f] "title for xterm"\n'
3373 printf ' renames the title of xterm from _within_ screen.\n'
3374 printf ' also works without screen.\n'
3375 printf ' will not work if DISPLAY is unset, use -f to override.\n'
3378 print -n "\eP\e]0;${1}\C-G\e\\"
3382 # Create small urls via http://goo.gl using curl(1).
3383 # API reference: https://code.google.com/apis/urlshortener/
3386 setopt extended_glob
3388 if [[ -z $1 ]]; then
3389 print "USAGE: zurl <URL>"
3393 local PN url prog api json contenttype item
3398 # Prepend 'http://' to given URL where necessary for later output.
3399 if [[ ${url} != http(s|)://* ]]; then
3403 if check_com -c curl; then
3406 print "curl is not available, but mandatory for ${PN}. Aborting."
3409 api='https://www.googleapis.com/urlshortener/v1/url'
3410 contenttype="Content-Type: application/json"
3411 json="{\"longUrl\": \"${url}\"}"
3412 data=(${(f)"$($prog --silent -H ${contenttype} -d ${json} $api)"})
3413 # Parse the response
3414 for item in "${data[@]}"; do
3419 printf '%s\n' "$item"
3427 #f2# Find history events by search pattern and list them by date.
3430 local usage help ident format_l format_s first_char remain first last
3431 usage='USAGE: whatwhen [options] <searchstring> <search range>'
3432 help='Use `whatwhen -h'\'' for further explanations.'
3433 ident=${(l,${#${:-Usage: }},, ,)}
3434 format_l="${ident}%s\t\t\t%s\n"
3435 format_s="${format_l//(\\t)##/\\t}"
3436 # Make the first char of the word to search for case
3437 # insensitive; e.g. [aA]
3438 first_char=[${(L)1[1]}${(U)1[1]}]
3440 # Default search range is `-100'.
3442 # Optional, just used for `<first> <last>' given.
3446 printf '%s\n\n' 'ERROR: No search string specified. Aborting.'
3447 printf '%s\n%s\n\n' ${usage} ${help} && return 1
3450 printf '%s\n\n' ${usage}
3452 printf $format_l '-h' 'show help text'
3454 print 'SEARCH RANGE:'
3455 printf $format_l "'0'" 'the whole history,'
3456 printf $format_l '-<n>' 'offset to the current history number; (default: -100)'
3457 printf $format_s '<[-]first> [<last>]' 'just searching within a give range'
3458 printf '\n%s\n' 'EXAMPLES:'
3459 printf ${format_l/(\\t)/} 'whatwhen grml' '# Range is set to -100 by default.'
3460 printf $format_l 'whatwhen zsh -250'
3461 printf $format_l 'whatwhen foo 1 99'
3464 printf '%s\n%s\n\n' ${usage} ${help} && return 1
3467 # -l list results on stout rather than invoking $EDITOR.
3468 # -i Print dates as in YYYY-MM-DD.
3469 # -m Search for a - quoted - pattern within the history.
3470 fc -li -m "*${first_char}${remain}*" $first $last
3475 # mercurial related stuff
3476 if check_com -c hg ; then
3477 # gnu like diff for mercurial
3478 # http://www.selenic.com/mercurial/wiki/index.cgi/TipsAndTricks
3479 #f5# GNU like diff for mercurial
3482 for i in $(hg status -marn "$@") ; diff -ubwd <(hg cat "$i") "$i"
3485 # build debian package
3486 #a2# Alias for \kbd{hg-buildpackage}
3487 alias hbp='hg-buildpackage'
3489 # execute commands on the versioned patch-queue from the current repos
3490 alias mq='hg -R $(readlink -f $(hg root)/.hg/patches)'
3492 # diffstat for specific version of a mercurial repository
3493 # hgstat => display diffstat between last revision and tip
3494 # hgstat 1234 => display diffstat between revision 1234 and tip
3495 #f5# Diffstat for specific version of a mercurial repos
3498 [[ -n "$1" ]] && hg diff -r $1 -r tip | diffstat || hg export tip | diffstat
3501 fi # end of check whether we have the 'hg'-executable
3503 # grml-small cleanups
3505 # The following is used to remove zsh-config-items that do not work
3506 # in grml-small by default.
3507 # If you do not want these adjustments (for whatever reason), set
3508 # $GRMLSMALL_SPECIFIC to 0 in your .zshrc.pre file (which this configuration
3509 # sources if it is there).
3511 if (( GRMLSMALL_SPECIFIC > 0 )) && isgrmlsmall ; then
3514 unalias 'V' &> /dev/null
3515 unfunction vman &> /dev/null
3516 unfunction viless &> /dev/null
3517 unfunction 2html &> /dev/null
3519 # manpages are not in grmlsmall
3520 unfunction manzsh &> /dev/null
3521 unfunction man2 &> /dev/null
3527 ## genrefcard.pl settings
3529 ### doc strings for external functions from files
3530 #m# f5 grml-wallpaper() Sets a wallpaper (try completion for possible values)
3532 ### example: split functions-search 8,16,24,32
3533 #@# split functions-search 8
3535 ## END OF FILE #################################################################
3536 # vim:filetype=zsh foldmethod=marker autoindent expandtab shiftwidth=4