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 getopts ":hao" opt; do
426 printf 'usage: salias [-hoa] <alias-expression>\n'
427 printf ' -h shows this help text.\n'
428 printf ' -a replace '\'' ; '\'' sequences with '\'' ; sudo '\''.\n'
429 printf ' be careful using this option.\n'
430 printf ' -o only sets an alias if a preceding sudo would be needed.\n'
433 *) salias -h >&2; return 1 ;;
436 shift "$((OPTIND-1))"
438 if (( ${#argv} > 1 )) ; then
439 printf 'Too many arguments %s\n' "${#argv}"
443 key="${1%%\=*}" ; val="${1#*\=}"
444 if (( EUID == 0 )) && (( only == 0 )); then
445 alias -- "${key}=${val}"
446 elif (( EUID > 0 )) ; then
447 (( multi > 0 )) && val="${val// ; / ; sudo }"
448 alias -- "${key}=sudo ${val}"
454 # a "print -l ${(u)foo}"-workaround for pre-4.2.0 shells
456 # Where foo is the *name* of the parameter you want printed.
457 # Note that foo is no typo; $foo would be wrong here!
465 if [[ -z ${parameter} ]] ; then
466 printf 'usage: uprint <parameter>\n'
470 for w in ${(P)parameter} ; do
471 [[ -z ${(M)u:#$w} ]] && u=( $u $w )
478 # Check if we can read given files and source those we can.
480 if (( ${#argv} < 1 )) ; then
481 printf 'usage: xsource FILE(s)...\n' >&2
485 while (( ${#argv} > 0 )) ; do
486 [[ -r "$1" ]] && source "$1"
492 # Check if we can read a given file and 'cat(1)' it.
495 if (( ${#argv} != 1 )) ; then
496 printf 'usage: xcat FILE\n' >&2
500 [[ -r $1 ]] && cat $1
504 # Remove these functions again, they are of use only in these
505 # setup files. This should be called at the end of .zshrc.
509 funcs=(salias xcat xsource xunfunction zrcautoload zrcautozle)
510 for func in $funcs ; do
511 [[ -n ${functions[$func]} ]] \
517 # this allows us to stay in sync with grml's zshrc and put own
518 # modifications in ~/.zshrc.local
520 xsource "/etc/zsh/zshrc.local"
521 xsource "${ZDOTDIR:-${HOME}}/.zshrc.local"
526 if (( ZSH_NO_DEFAULT_LOCALE == 0 )); then
527 xsource "/etc/default/locale"
530 for var in LANG LC_ALL LC_MESSAGES ; do
531 [[ -n ${(P)var} ]] && export $var
535 if check_com -c vim ; then
537 export EDITOR=${EDITOR:-vim}
539 export EDITOR=${EDITOR:-vi}
543 export PAGER=${PAGER:-less}
546 export MAIL=${MAIL:-/var/mail/$USER}
548 # if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/
549 if [[ -z "$SHELL" ]] ; then
551 if [[ -x "$SHELL" ]] ; then
556 # color setup for ls:
557 check_com -c dircolors && eval $(dircolors -b)
558 # color setup for ls on OS X / FreeBSD:
559 isdarwin && export CLICOLOR=1
560 isfreebsd && export CLICOLOR=1
562 # do MacPorts setup on darwin
563 if isdarwin && [[ -d /opt/local ]]; then
564 # Note: PATH gets set in /etc/zprofile on Darwin, so this can't go into
566 PATH="/opt/local/bin:/opt/local/sbin:$PATH"
567 MANPATH="/opt/local/share/man:$MANPATH"
569 # do Fink setup on darwin
570 isdarwin && xsource /sw/bin/init.sh
572 # load our function and completion directories
573 for fdir in /usr/share/grml/zsh/completion /usr/share/grml/zsh/functions; do
574 fpath=( ${fdir} ${fdir}/**/*(/N) ${fpath} )
575 if [[ ${fdir} == '/usr/share/grml/zsh/functions' ]] ; then
576 for func in ${fdir}/**/[^_]*[^~](N.) ; do
577 zrcautoload ${func:t}
583 # support colors in less
584 export LESS_TERMCAP_mb=$'\E[01;31m'
585 export LESS_TERMCAP_md=$'\E[01;31m'
586 export LESS_TERMCAP_me=$'\E[0m'
587 export LESS_TERMCAP_se=$'\E[0m'
588 export LESS_TERMCAP_so=$'\E[01;44;33m'
589 export LESS_TERMCAP_ue=$'\E[0m'
590 export LESS_TERMCAP_us=$'\E[01;32m'
595 # report about cpu-/system-/user-time of command if running longer than
599 # watch for everyone but me and root
602 # automatically remove duplicates from these arrays
603 typeset -U path cdpath fpath manpath
607 for mod in parameter complist deltochar mathfunc ; do
608 zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :("
611 # autoload zsh modules when they are referenced
613 zmodload -a zsh/stat zstat
614 zmodload -a zsh/zpty zpty
615 zmodload -ap zsh/mapfile mapfile
619 COMPDUMPFILE=${COMPDUMPFILE:-${ZDOTDIR:-${HOME}}/.zcompdump}
620 if zrcautoload compinit ; then
621 compinit -d ${COMPDUMPFILE} || print 'Notice: no compinit available :('
623 print 'Notice: no compinit available :('
629 # called later (via is4 && grmlcomp)
630 # note: use 'zstyle' for getting current settings
631 # press ^xh (control-x h) for getting tags in context; ^x? (control-x ?) to run complete_debug with trace output
633 # TODO: This could use some additional information
635 # Make sure the completion system is initialised
636 (( ${+_comps} )) || return 1
638 # allow one error for every three characters typed in approximate completer
639 zstyle ':completion:*:approximate:' max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )'
641 # don't complete backup files as executables
642 zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)'
644 # start menu completion only if it could find no unambiguous initial string
645 zstyle ':completion:*:correct:*' insert-unambiguous true
646 zstyle ':completion:*:corrections' format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}'
647 zstyle ':completion:*:correct:*' original true
649 # activate color-completion
650 zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
652 # format on completion
653 zstyle ':completion:*:descriptions' format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'
655 # automatically complete 'cd -<tab>' and 'cd -<ctrl-d>' with menu
656 # zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
658 # insert all expansions for expand completer
659 zstyle ':completion:*:expand:*' tag-order all-expansions
660 zstyle ':completion:*:history-words' list false
663 zstyle ':completion:*:history-words' menu yes
665 # ignore duplicate entries
666 zstyle ':completion:*:history-words' remove-all-dups yes
667 zstyle ':completion:*:history-words' stop yes
669 # match uppercase from lowercase
670 zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
672 # separate matches into groups
673 zstyle ':completion:*:matches' group 'yes'
674 zstyle ':completion:*' group-name ''
676 if [[ "$NOMENU" -eq 0 ]] ; then
677 # if there are more than 5 options allow selecting from a menu
678 zstyle ':completion:*' menu select=5
680 # don't use any menus at all
684 zstyle ':completion:*:messages' format '%d'
685 zstyle ':completion:*:options' auto-description '%d'
687 # describe options in full
688 zstyle ':completion:*:options' description 'yes'
690 # on processes completion complete all user processes
691 zstyle ':completion:*:processes' command 'ps -au$USER'
693 # offer indexes before parameters in subscripts
694 zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
696 # provide verbose completion information
697 zstyle ':completion:*' verbose true
699 # recent (as of Dec 2007) zsh versions are able to provide descriptions
700 # for commands (read: 1st word in the line) that it will list for the user
701 # to choose from. The following disables that, because it's not exactly fast.
702 zstyle ':completion:*:-command-:*:' verbose false
704 # set format for warnings
705 zstyle ':completion:*:warnings' format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d'
707 # define files to ignore for zcompile
708 zstyle ':completion:*:*:zcompile:*' ignored-patterns '(*~|*.zwc)'
709 zstyle ':completion:correct:' prompt 'correct to: %e'
711 # Ignore completion functions for commands you don't have:
712 zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'
714 # Provide more processes in completion of programs like killall:
715 zstyle ':completion:*:processes-names' command 'ps c -u ${USER} -o command | uniq'
717 # complete manual by their section
718 zstyle ':completion:*:manuals' separate-sections true
719 zstyle ':completion:*:manuals.*' insert-sections true
720 zstyle ':completion:*:man:*' menu yes select
722 # Search path for sudo completion
723 zstyle ':completion:*:sudo:*' command-path /usr/local/sbin \
731 # provide .. as a completion
732 zstyle ':completion:*' special-dirs ..
734 # run rehash on completion so new installed program are found automatically:
736 (( CURRENT == 1 )) && rehash
741 # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
742 if [[ "$NOCOR" -gt 0 ]] ; then
743 zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
746 # try to be smart about when to use what completer...
748 zstyle -e ':completion:*' completer '
749 if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then
750 _last_try="$HISTNO$BUFFER$CURSOR"
751 reply=(_complete _match _ignored _prefix _files)
753 if [[ $words[1] == (rm|mv) ]] ; then
754 reply=(_complete _files)
756 reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files)
761 # command for process lists, the local web server details and host completion
762 zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
765 [[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \
766 zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
770 [[ -r ~/.ssh/config ]] && _ssh_config_hosts=(${${${(@M)${(f)"$(<$HOME/.ssh/config)"}:#Host *}#Host }:#*[*?]*}) || _ssh_config_hosts=()
771 [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
772 [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
780 "$_ssh_config_hosts[@]"
785 zstyle ':completion:*:hosts' hosts $hosts
786 # TODO: so, why is this here?
787 # zstyle '*' hosts $hosts
789 # use generic completion system for programs not yet defined; (_gnu_generic works
790 # with commands that provide a --help option with "standard" gnu-like output.)
791 for compcom in cp deborphan df feh fetchipac gpasswd head hnb ipacsum mv \
793 [[ -z ${_comps[$compcom]} ]] && compdef _gnu_generic ${compcom}
796 # see upgrade function in this file
797 compdef _hosts upgrade
800 # Keyboard setup: The following is based on the same code, we wrote for
801 # debian's setup. It ensures the terminal is in the right mode, when zle is
802 # active, so the values from $terminfo are valid. Therefore, this setup should
803 # work on all systems, that have support for `terminfo'. It also requires the
804 # zsh in use to have the `zsh/terminfo' module built.
806 # If you are customising your `zle-line-init()' or `zle-line-finish()'
807 # functions, make sure you call the following utility functions in there:
809 # - zle-line-init(): zle-smkx
810 # - zle-line-finish(): zle-rmkx
812 # Use emacs-like key bindings by default:
817 ## beginning-of-line OR beginning-of-buffer OR beginning of history
818 ## by: Bart Schaefer <schaefer@brasslantern.com>, Bernhard Tittelbach
819 beginning-or-end-of-somewhere() {
821 if [[ ( "${LBUFFER[-1]}" == $'\n' && "${WIDGET}" == beginning-of* ) || \
822 ( "${RBUFFER[1]}" == $'\n' && "${WIDGET}" == end-of* ) ]]; then
823 zle .${WIDGET:s/somewhere/buffer-or-history/} "$@"
825 zle .${WIDGET:s/somewhere/line-hist/} "$@"
826 if (( HISTNO != hno )); then
827 zle .${WIDGET:s/somewhere/buffer-or-history/} "$@"
831 zle -N beginning-of-somewhere beginning-or-end-of-somewhere
832 zle -N end-of-somewhere beginning-or-end-of-somewhere
834 # add a command line to the shells history without executing it
835 commit-to-history() {
836 print -s ${(z)BUFFER}
839 zle -N commit-to-history
841 # only slash should be considered as a word separator:
842 slash-backward-kill-word() {
843 local WORDCHARS="${WORDCHARS:s@/@}"
845 zle backward-kill-word
847 zle -N slash-backward-kill-word
849 # a generic accept-line wrapper
851 # This widget can prevent unwanted autocorrections from command-name
852 # to _command-name, rehash automatically on enter and call any number
853 # of builtin and user-defined widgets in different contexts.
855 # For a broader description, see:
856 # <http://bewatermyfriend.org/posts/2007/12-26.11-50-38-tooltime.html>
858 # The code is imported from the file 'zsh/functions/accept-line' from
859 # <http://ft.bewatermyfriend.org/comp/zsh/zsh-dotfiles.tar.bz2>, which
860 # distributed under the same terms as zsh itself.
862 # A newly added command will may not be found or will cause false
863 # correction attempts, if you got auto-correction set. By setting the
864 # following style, we force accept-line() to rehash, if it cannot
865 # find the first word on the command line in the $command[] hash.
866 zstyle ':acceptline:*' rehash true
868 function Accept-Line() {
869 setopt localoptions noksharrays
873 local alcontext=${1:-$alcontext}
875 zstyle -a ":acceptline:${alcontext}" actions subs
877 (( ${#subs} < 1 )) && return 0
880 for sub in ${subs} ; do
881 [[ ${sub} == 'accept-line' ]] && sub='.accept-line'
884 (( aldone > 0 )) && break
888 function Accept-Line-getdefault() {
892 zstyle -s ":acceptline:${alcontext}" default_action default_action
893 case ${default_action} in
895 printf ".accept-line"
898 printf ${default_action}
903 function Accept-Line-HandleContext() {
906 default_action=$(Accept-Line-getdefault)
907 zstyle -T ":acceptline:${alcontext}" call_default \
908 && zle ${default_action}
911 function accept-line() {
912 setopt localoptions noksharrays
915 local buf com fname format msg default_action
919 cmdline=(${(z)BUFFER})
923 Accept-Line 'preprocess'
925 zstyle -t ":acceptline:${alcontext}" rehash \
926 && [[ -z ${commands[$com]} ]] \
930 && [[ -n ${reswords[(r)$com]} ]] \
931 || [[ -n ${aliases[$com]} ]] \
932 || [[ -n ${functions[$com]} ]] \
933 || [[ -n ${builtins[$com]} ]] \
934 || [[ -n ${commands[$com]} ]] ; then
936 # there is something sensible to execute, just do it.
938 Accept-Line-HandleContext
943 if [[ -o correct ]] \
944 || [[ -o correctall ]] \
945 && [[ -n ${functions[$fname]} ]] ; then
947 # nothing there to execute but there is a function called
948 # _command_name; a completion widget. Makes no sense to
949 # call it on the commandline, but the correct{,all} options
950 # will ask for it nevertheless, so warn the user.
951 if [[ ${LASTWIDGET} == 'accept-line' ]] ; then
952 # Okay, we warned the user before, he called us again,
953 # so have it his way.
955 Accept-Line-HandleContext
960 if zstyle -t ":acceptline:${alcontext}" nocompwarn ; then
962 Accept-Line-HandleContext
964 # prepare warning message for the user, configurable via zstyle.
965 zstyle -s ":acceptline:${alcontext}" compwarnfmt msg
967 if [[ -z ${msg} ]] ; then
968 msg="%c will not execute and completion %f exists."
971 zformat -f msg "${msg}" "c:${com}" "f:${fname}"
976 elif [[ -n ${buf//[$' \t\n']##/} ]] ; then
977 # If we are here, the commandline contains something that is not
978 # executable, which is neither subject to _command_name correction
979 # and is not empty. might be a variable assignment
981 Accept-Line-HandleContext
986 # If we got this far, the commandline only contains whitespace, or is empty.
988 Accept-Line-HandleContext
993 zle -N Accept-Line-HandleContext
995 # power completion / abbreviation expansion / buffer expansion
996 # see http://zshwiki.org/home/examples/zleiab for details
997 # less risky than the global aliases but powerful as well
998 # just type the abbreviation key and afterwards 'ctrl-x .' to expand it
1001 setopt interactivecomments
1003 # key # value (#d additional doc string)
1009 'G' '|& grep '${grep_options:+"${grep_options[*]}"}
1011 'Hl' ' --help |& less -r' #d (Display help in pager)
1015 'N' '&>/dev/null' #d (No Output)
1016 'R' '| tr A-z N-za-m' #d (ROT13)
1017 'SL' '| sort | less'
1022 'co' './configure && make && sudo make install'
1030 LBUFFER=${LBUFFER%%(#m)[.\-+:|_a-zA-Z0-9]#}
1031 LBUFFER+=${abk[$MATCH]:-$MATCH}
1038 zle -M "$(print "Available abbreviations for expansion:"; print -a -C 2 ${(kv)abk})"
1041 zle -N help-show-abk
1043 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
1044 insert-datestamp() { LBUFFER+=${(%):-'%D{%Y-%m-%d}'}; }
1045 zle -N insert-datestamp
1047 # press esc-m for inserting last typed word again (thanks to caphuso!)
1048 insert-last-typed-word() { zle insert-last-word -- 0 -1 };
1049 zle -N insert-last-typed-word;
1051 function grml-zsh-fg() {
1052 if (( ${#jobstates} )); then
1054 [[ -o hist_ignore_space ]] && BUFFER=' ' || BUFFER=''
1055 BUFFER="${BUFFER}fg"
1058 zle -M 'No background jobs. Doing nothing.'
1063 # run command line as user root via sudo:
1064 sudo-command-line() {
1065 [[ -z $BUFFER ]] && zle up-history
1066 if [[ $BUFFER != sudo\ * ]]; then
1067 BUFFER="sudo $BUFFER"
1068 CURSOR=$(( CURSOR+5 ))
1071 zle -N sudo-command-line
1073 ### jump behind the first word on the cmdline.
1074 ### useful to add options.
1075 function jump_after_first_word() {
1077 words=(${(z)BUFFER})
1079 if (( ${#words} <= 1 )) ; then
1082 CURSOR=${#${words[1]}}
1085 zle -N jump_after_first_word
1087 #f5# Create directory under cursor or the selected area
1089 # Press ctrl-xM to create the directory under the cursor or the selected area.
1090 # To select an area press ctrl-@ or ctrl-space and use the cursor.
1091 # Use case: you type "mv abc ~/testa/testb/testc/" and remember that the
1092 # directory does not exist yet -> press ctrl-XM and problem solved
1094 if ((REGION_ACTIVE==1)); then
1095 local F=$MARK T=$CURSOR
1096 if [[ $F -gt $T ]]; then
1100 # get marked area from buffer and eliminate whitespace
1101 PATHTOMKDIR=${BUFFER[F+1,T]%%[[:space:]]##}
1102 PATHTOMKDIR=${PATHTOMKDIR##[[:space:]]##}
1104 local bufwords iword
1105 bufwords=(${(z)LBUFFER})
1107 bufwords=(${(z)BUFFER})
1108 PATHTOMKDIR="${(Q)bufwords[iword]}"
1110 [[ -z "${PATHTOMKDIR}" ]] && return 1
1111 PATHTOMKDIR=${~PATHTOMKDIR}
1112 if [[ -e "${PATHTOMKDIR}" ]]; then
1113 zle -M " path already exists, doing nothing"
1115 zle -M "$(mkdir -p -v "${PATHTOMKDIR}")"
1120 zle -N inplaceMkDirs
1122 #v1# set number of lines to display per page
1123 HELP_LINES_PER_PAGE=20
1124 #v1# set location of help-zle cache file
1125 HELP_ZLE_CACHE_FILE=~/.cache/zsh_help_zle_lines.zsh
1126 # helper function for help-zle, actually generates the help text
1127 help_zle_parse_keybindings()
1131 unsetopt ksharrays #indexing starts at 1
1133 #v1# choose files that help-zle will parse for keybindings
1134 ((${+HELPZLE_KEYBINDING_FILES})) || HELPZLE_KEYBINDING_FILES=( /etc/zsh/zshrc ~/.zshrc.pre ~/.zshrc ~/.zshrc.local )
1136 if [[ -r $HELP_ZLE_CACHE_FILE ]]; then
1138 for f ($HELPZLE_KEYBINDING_FILES) [[ $f -nt $HELP_ZLE_CACHE_FILE ]] && load_cache=1
1139 [[ $load_cache -eq 0 ]] && . $HELP_ZLE_CACHE_FILE && return
1142 #fill with default keybindings, possibly to be overwriten in a file later
1143 #Note that due to zsh inconsistency on escaping assoc array keys, we encase the key in '' which we will remove later
1144 local -A help_zle_keybindings
1145 help_zle_keybindings['<Ctrl>@']="set MARK"
1146 help_zle_keybindings['<Ctrl>x<Ctrl>j']="vi-join lines"
1147 help_zle_keybindings['<Ctrl>x<Ctrl>b']="jump to matching brace"
1148 help_zle_keybindings['<Ctrl>x<Ctrl>u']="undo"
1149 help_zle_keybindings['<Ctrl>_']="undo"
1150 help_zle_keybindings['<Ctrl>x<Ctrl>f<c>']="find <c> in cmdline"
1151 help_zle_keybindings['<Ctrl>a']="goto beginning of line"
1152 help_zle_keybindings['<Ctrl>e']="goto end of line"
1153 help_zle_keybindings['<Ctrl>t']="transpose charaters"
1154 help_zle_keybindings['<Alt>t']="transpose words"
1155 help_zle_keybindings['<Alt>s']="spellcheck word"
1156 help_zle_keybindings['<Ctrl>k']="backward kill buffer"
1157 help_zle_keybindings['<Ctrl>u']="forward kill buffer"
1158 help_zle_keybindings['<Ctrl>y']="insert previously killed word/string"
1159 help_zle_keybindings["<Alt>'"]="quote line"
1160 help_zle_keybindings['<Alt>"']="quote from mark to cursor"
1161 help_zle_keybindings['<Alt><arg>']="repeat next cmd/char <arg> times (<Alt>-<Alt>1<Alt>0a -> -10 times 'a')"
1162 help_zle_keybindings['<Alt>u']="make next word Uppercase"
1163 help_zle_keybindings['<Alt>l']="make next word lowercase"
1164 help_zle_keybindings['<Ctrl>xd']="preview expansion under cursor"
1165 help_zle_keybindings['<Alt>q']="push current CL into background, freeing it. Restore on next CL"
1166 help_zle_keybindings['<Alt>.']="insert (and interate through) last word from prev CLs"
1167 help_zle_keybindings['<Alt>,']="complete word from newer history (consecutive hits)"
1168 help_zle_keybindings['<Alt>m']="repeat last typed word on current CL"
1169 help_zle_keybindings['<Ctrl>v']="insert next keypress symbol literally (e.g. for bindkey)"
1170 help_zle_keybindings['!!:n*<Tab>']="insert last n arguments of last command"
1171 help_zle_keybindings['!!:n-<Tab>']="insert arguments n..N-2 of last command (e.g. mv s s d)"
1172 help_zle_keybindings['<Alt>h']="show help/manpage for current command"
1174 #init global variables
1175 unset help_zle_lines help_zle_sln
1176 typeset -g -a help_zle_lines
1177 typeset -g help_zle_sln=1
1180 local lastkeybind_desc contents #last description starting with #k# that we found
1181 local num_lines_elapsed=0 #number of lines between last description and keybinding
1182 #search config files in the order they a called (and thus the order in which they overwrite keybindings)
1183 for f in $HELPZLE_KEYBINDING_FILES; do
1184 [[ -r "$f" ]] || continue #not readable ? skip it
1186 for cline in "${(f)contents}"; do
1187 #zsh pattern: matches lines like: #k# ..............
1188 if [[ "$cline" == (#s)[[:space:]]#\#k\#[[:space:]]##(#b)(*)[[:space:]]#(#e) ]]; then
1189 lastkeybind_desc="$match[*]"
1191 #zsh pattern: matches lines that set a keybinding using bind2map, bindkey or compdef -k
1192 # ignores lines that are commentend out
1193 # grabs first in '' or "" enclosed string with length between 1 and 6 characters
1194 elif [[ "$cline" == [^#]#(bind2maps[[:space:]](*)-s|bindkey|compdef -k)[[:space:]](*)(#b)(\"((?)(#c1,6))\"|\'((?)(#c1,6))\')(#B)(*) ]]; then
1195 #description prevously found ? description not more than 2 lines away ? keybinding not empty ?
1196 if [[ -n $lastkeybind_desc && $num_lines_elapsed -lt 2 && -n $match[1] ]]; then
1197 #substitute keybinding string with something readable
1198 k=${${${${${${${match[1]/\\e\^h/<Alt><BS>}/\\e\^\?/<Alt><BS>}/\\e\[5~/<PageUp>}/\\e\[6~/<PageDown>}//(\\e|\^\[)/<Alt>}//\^/<Ctrl>}/3~/<Alt><Del>}
1199 #put keybinding in assoc array, possibly overwriting defaults or stuff found in earlier files
1200 #Note that we are extracting the keybinding-string including the quotes (see Note at beginning)
1201 help_zle_keybindings[${k}]=$lastkeybind_desc
1205 ((num_lines_elapsed++))
1210 #calculate length of keybinding column
1212 for k (${(k)help_zle_keybindings[@]}) ((kstrlen < ${#k})) && kstrlen=${#k}
1213 #convert the assoc array into preformated lines, which we are able to sort
1214 for k v in ${(kv)help_zle_keybindings[@]}; do
1215 #pad keybinding-string to kstrlen chars and remove outermost characters (i.e. the quotes)
1216 help_zle_lines+=("${(r:kstrlen:)k[2,-2]}${v}")
1218 #sort lines alphabetically
1219 help_zle_lines=("${(i)help_zle_lines[@]}")
1220 [[ -d ${HELP_ZLE_CACHE_FILE:h} ]] || mkdir -p "${HELP_ZLE_CACHE_FILE:h}"
1221 echo "help_zle_lines=(${(q)help_zle_lines[@]})" >| $HELP_ZLE_CACHE_FILE
1222 zcompile $HELP_ZLE_CACHE_FILE
1224 typeset -g help_zle_sln
1225 typeset -g -a help_zle_lines
1227 # Provides (partially autogenerated) help on keybindings and the zsh line editor
1231 unsetopt ksharrays #indexing starts at 1
1232 #help lines already generated ? no ? then do it
1233 [[ ${+functions[help_zle_parse_keybindings]} -eq 1 ]] && {help_zle_parse_keybindings && unfunction help_zle_parse_keybindings}
1234 #already displayed all lines ? go back to the start
1235 [[ $help_zle_sln -gt ${#help_zle_lines} ]] && help_zle_sln=1
1236 local sln=$help_zle_sln
1237 #note that help_zle_sln is a global var, meaning we remember the last page we viewed
1238 help_zle_sln=$((help_zle_sln + HELP_LINES_PER_PAGE))
1239 zle -M "${(F)help_zle_lines[sln,help_zle_sln-1]}"
1243 ## complete word from currently visible Screen or Tmux buffer.
1244 if check_com -c screen || check_com -c tmux; then
1245 _complete_screen_display() {
1246 [[ "$TERM" != "screen" ]] && return 1
1248 local TMPFILE=$(mktemp)
1249 local -U -a _screen_display_wordlist
1250 trap "rm -f $TMPFILE" EXIT
1252 # fill array with contents from screen hardcopy
1253 if ((${+TMUX})); then
1254 #works, but crashes tmux below version 1.4
1255 #luckily tmux -V option to ask for version, was also added in 1.4
1256 tmux -V &>/dev/null || return
1257 tmux -q capture-pane \; save-buffer -b 0 $TMPFILE \; delete-buffer -b 0
1259 screen -X hardcopy $TMPFILE
1260 # screen sucks, it dumps in latin1, apparently always. so recode it
1262 check_com recode && recode latin1 $TMPFILE
1264 _screen_display_wordlist=( ${(QQ)$(<$TMPFILE)} )
1265 # remove PREFIX to be completed from that array
1266 _screen_display_wordlist[${_screen_display_wordlist[(i)$PREFIX]}]=""
1267 compadd -a _screen_display_wordlist
1269 #m# k CTRL-x\,\,\,S Complete word from GNU screen buffer
1271 compdef -k _complete_screen_display complete-word '^xS'
1274 # Load a few more functions and tie them to widgets, so they can be bound:
1276 function zrcautozle() {
1279 zrcautoload $fnc && zle -N $fnc
1282 function zrcgotwidget() {
1283 (( ${+widgets[$1]} ))
1286 function zrcgotkeymap() {
1287 [[ -n ${(M)keymaps:#$1} ]]
1290 zrcautozle insert-files
1291 zrcautozle edit-command-line
1292 zrcautozle insert-unicode-char
1293 if zrcautoload history-search-end; then
1294 zle -N history-beginning-search-backward-end history-search-end
1295 zle -N history-beginning-search-forward-end history-search-end
1297 zle -C hist-complete complete-word _generic
1298 zstyle ':completion:hist-complete:*' completer _history
1300 # The actual terminal setup hooks and bindkey-calls:
1302 # An array to note missing features to ease diagnosis in case of problems.
1303 typeset -ga grml_missing_features
1305 function zrcbindkey() {
1306 if (( ARGC )) && zrcgotwidget ${argv[-1]}; then
1311 function bind2maps () {
1312 local i sequence widget
1315 while [[ "$1" != "--" ]]; do
1321 if [[ "$1" == "-s" ]]; then
1325 sequence="${key[$1]}"
1329 [[ -z "$sequence" ]] && return 1
1331 for i in "${maps[@]}"; do
1332 zrcbindkey -M "$i" "$sequence" "$widget"
1336 if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then
1337 function zle-smkx () {
1339 printf '%s' ${terminfo[smkx]}
1341 function zle-rmkx () {
1343 printf '%s' ${terminfo[rmkx]}
1345 function zle-line-init () {
1348 function zle-line-finish () {
1351 zle -N zle-line-init
1352 zle -N zle-line-finish
1354 for i in {s,r}mkx; do
1355 (( ${+terminfo[$i]} )) || grml_missing_features+=($i)
1362 Home "${terminfo[khome]}"
1363 End "${terminfo[kend]}"
1364 Insert "${terminfo[kich1]}"
1365 Delete "${terminfo[kdch1]}"
1366 Up "${terminfo[kcuu1]}"
1367 Down "${terminfo[kcud1]}"
1368 Left "${terminfo[kcub1]}"
1369 Right "${terminfo[kcuf1]}"
1370 PageUp "${terminfo[kpp]}"
1371 PageDown "${terminfo[knp]}"
1372 BackTab "${terminfo[kcbt]}"
1375 # Guidelines for adding key bindings:
1377 # - Do not add hardcoded escape sequences, to enable non standard key
1378 # combinations such as Ctrl-Meta-Left-Cursor. They are not easily portable.
1380 # - Adding Ctrl characters, such as '^b' is okay; note that '^b' and '^B' are
1383 # - All keys from the $key[] mapping are obviously okay.
1385 # - Most terminals send "ESC x" when Meta-x is pressed. Thus, sequences like
1386 # '\ex' are allowed in here as well.
1388 bind2maps emacs -- Home beginning-of-somewhere
1389 bind2maps viins vicmd -- Home vi-beginning-of-line
1390 bind2maps emacs -- End end-of-somewhere
1391 bind2maps viins vicmd -- End vi-end-of-line
1392 bind2maps emacs viins -- Insert overwrite-mode
1393 bind2maps vicmd -- Insert vi-insert
1394 bind2maps emacs -- Delete delete-char
1395 bind2maps viins vicmd -- Delete vi-delete-char
1396 bind2maps emacs viins vicmd -- Up up-line-or-search
1397 bind2maps emacs viins vicmd -- Down down-line-or-search
1398 bind2maps emacs -- Left backward-char
1399 bind2maps viins vicmd -- Left vi-backward-char
1400 bind2maps emacs -- Right forward-char
1401 bind2maps viins vicmd -- Right vi-forward-char
1402 #k# Perform abbreviation expansion
1403 bind2maps emacs viins -- -s '^x.' zleiab
1404 #k# Display list of abbreviations that would expand
1405 bind2maps emacs viins -- -s '^xb' help-show-abk
1406 #k# mkdir -p <dir> from string under cursor or marked area
1407 bind2maps emacs viins -- -s '^xM' inplaceMkDirs
1408 #k# display help for keybindings and ZLE
1409 bind2maps emacs viins -- -s '^xz' help-zle
1410 #k# Insert files and test globbing
1411 bind2maps emacs viins -- -s "^xf" insert-files
1412 #k# Edit the current line in \kbd{\$EDITOR}
1413 bind2maps emacs viins -- -s '\ee' edit-command-line
1414 #k# search history backward for entry beginning with typed text
1415 bind2maps emacs viins -- -s '^xp' history-beginning-search-backward-end
1416 #k# search history forward for entry beginning with typed text
1417 bind2maps emacs viins -- -s '^xP' history-beginning-search-forward-end
1418 #k# search history backward for entry beginning with typed text
1419 bind2maps emacs viins -- PageUp history-beginning-search-backward-end
1420 #k# search history forward for entry beginning with typed text
1421 bind2maps emacs viins -- PageDown history-beginning-search-forward-end
1422 bind2maps emacs viins -- -s "^x^h" commit-to-history
1423 #k# Kill left-side word or everything up to next slash
1424 bind2maps emacs viins -- -s '\ev' slash-backward-kill-word
1425 #k# Kill left-side word or everything up to next slash
1426 bind2maps emacs viins -- -s '\e^h' slash-backward-kill-word
1427 #k# Kill left-side word or everything up to next slash
1428 bind2maps emacs viins -- -s '\e^?' slash-backward-kill-word
1429 # Do history expansion on space:
1430 bind2maps emacs viins -- -s ' ' magic-space
1431 #k# Trigger menu-complete
1432 bind2maps emacs viins -- -s '\ei' menu-complete # menu completion via esc-i
1433 #k# Insert a timestamp on the command line (yyyy-mm-dd)
1434 bind2maps emacs viins -- -s '^ed' insert-datestamp
1435 #k# Insert last typed word
1436 bind2maps emacs viins -- -s "\em" insert-last-typed-word
1437 #k# A smart shortcut for \kbd{fg<enter>}
1438 bind2maps emacs viins -- -s '^z' grml-zsh-fg
1439 #k# prepend the current command with "sudo"
1440 bind2maps emacs viins -- -s "^os" sudo-command-line
1441 #k# jump to after first word (for adding options)
1442 bind2maps emacs viins -- -s '^x1' jump_after_first_word
1443 #k# complete word from history with menu
1444 bind2maps emacs viins -- -s "^x^x" hist-complete
1446 # insert unicode character
1447 # usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an §
1448 # See for example http://unicode.org/charts/ for unicode characters code
1449 #k# Insert Unicode character
1450 bind2maps emacs viins -- -s '^xi' insert-unicode-char
1452 # use the new *-pattern-* widgets for incremental history search
1453 if zrcgotwidget history-incremental-pattern-search-backward; then
1454 for seq wid in '^r' history-incremental-pattern-search-backward \
1455 '^s' history-incremental-pattern-search-forward
1457 bind2maps emacs viins vicmd -- -s $seq $wid
1461 if zrcgotkeymap menuselect; then
1462 #m# k Shift-tab Perform backwards menu completion
1463 bind2maps menuselect -- BackTab reverse-menu-complete
1465 #k# menu selection: pick item but stay in the menu
1466 bind2maps menuselect -- -s '\e^M' accept-and-menu-complete
1467 # also use + and INSERT since it's easier to press repeatedly
1468 bind2maps menuselect -- -s '+' accept-and-menu-complete
1469 bind2maps menuselect -- Insert accept-and-menu-complete
1471 # accept a completion and try to complete again by using menu
1472 # completion; very useful with completing directories
1473 # by using 'undo' one's got a simple file browser
1474 bind2maps menuselect -- -s '^o' accept-and-infer-next-history
1477 # Finally, here are still a few hardcoded escape sequences; Special sequences
1478 # like Ctrl-<Cursor-key> etc do suck a fair bit, because they are not
1479 # standardised and most of the time are not available in a terminals terminfo
1482 # While we do not encourage adding bindings like these, we will keep these for
1483 # backward compatibility.
1485 ## use Ctrl-left-arrow and Ctrl-right-arrow for jumping to word-beginnings on
1486 ## the command line.
1488 bind2maps emacs viins vicmd -- -s '\eOc' forward-word
1489 bind2maps emacs viins vicmd -- -s '\eOd' backward-word
1490 # These are for xterm:
1491 bind2maps emacs viins vicmd -- -s '\e[1;5C' forward-word
1492 bind2maps emacs viins vicmd -- -s '\e[1;5D' backward-word
1493 ## the same for alt-left-arrow and alt-right-arrow
1495 bind2maps emacs viins vicmd -- -s '\e\e[C' forward-word
1496 bind2maps emacs viins vicmd -- -s '\e\e[D' backward-word
1498 bind2maps emacs viins vicmd -- -s '^[[1;3C' forward-word
1499 bind2maps emacs viins vicmd -- -s '^[[1;3D' backward-word
1500 # Also try ESC Left/Right:
1501 bind2maps emacs viins vicmd -- -s '\e'${key[Right]} forward-word
1502 bind2maps emacs viins vicmd -- -s '\e'${key[Left]} backward-word
1509 # we don't want to quote/espace URLs on our own...
1510 # if autoload -U url-quote-magic ; then
1511 # zle -N self-insert url-quote-magic
1512 # zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}='
1514 # print 'Notice: no url-quote-magic available :('
1516 alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic'
1518 #m# k ESC-h Call \kbd{run-help} for the 1st word on the command line
1519 alias run-help >&/dev/null && unalias run-help
1520 for rh in run-help{,-git,-svk,-svn}; do
1524 # command not found handling
1526 (( ${COMMAND_NOT_FOUND} == 1 )) &&
1527 function command_not_found_handler() {
1529 if [[ -x ${GRML_ZSH_CNF_HANDLER} ]] ; then
1530 ${GRML_ZSH_CNF_HANDLER} $1
1537 ZSHDIR=${ZDOTDIR:-${HOME}/.zsh}
1540 HISTFILE=${ZDOTDIR:-${HOME}}/.zsh_history
1541 isgrmlcd && HISTSIZE=500 || HISTSIZE=5000
1542 isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
1546 DIRSTACKSIZE=${DIRSTACKSIZE:-20}
1547 DIRSTACKFILE=${DIRSTACKFILE:-${ZDOTDIR:-${HOME}}/.zdirs}
1549 if [[ -f ${DIRSTACKFILE} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then
1550 dirstack=( ${(f)"$(< $DIRSTACKFILE)"} )
1551 # "cd -" won't work after login by just setting $OLDPWD, so
1552 [[ -d $dirstack[1] ]] && cd $dirstack[1] && cd $OLDPWD
1556 if (( $DIRSTACKSIZE <= 0 )) || [[ -z $DIRSTACKFILE ]]; then return; fi
1558 my_stack=( ${PWD} ${dirstack} )
1560 builtin print -l ${(u)my_stack} >! ${DIRSTACKFILE}
1562 uprint my_stack >! ${DIRSTACKFILE}
1566 # directory based profiles
1570 # chpwd_profiles(): Directory Profiles, Quickstart:
1574 # zstyle ':chpwd:profiles:/usr/src/grml(|/|/*)' profile grml
1575 # zstyle ':chpwd:profiles:/usr/src/debian(|/|/*)' profile debian
1578 # For details see the `grmlzshrc.5' manual page.
1579 function chpwd_profiles() {
1580 local profile context
1583 context=":chpwd:profiles:$PWD"
1584 zstyle -s "$context" profile profile || profile='default'
1585 zstyle -T "$context" re-execute && reexecute=1 || reexecute=0
1587 if (( ${+parameters[CHPWD_PROFILE]} == 0 )); then
1588 typeset -g CHPWD_PROFILE
1589 local CHPWD_PROFILES_INIT=1
1590 (( ${+functions[chpwd_profiles_init]} )) && chpwd_profiles_init
1591 elif [[ $profile != $CHPWD_PROFILE ]]; then
1592 (( ${+functions[chpwd_leave_profile_$CHPWD_PROFILE]} )) \
1593 && chpwd_leave_profile_${CHPWD_PROFILE}
1595 if (( reexecute )) || [[ $profile != $CHPWD_PROFILE ]]; then
1596 (( ${+functions[chpwd_profile_$profile]} )) && chpwd_profile_${profile}
1599 CHPWD_PROFILE="${profile}"
1603 chpwd_functions=( ${chpwd_functions} chpwd_profiles )
1607 # Prompt setup for grml:
1609 # set colors for use in prompts (modern zshs allow for the use of %F{red}foo%f
1610 # in prompts to get a red "foo" embedded, but it's good to keep these for
1611 # backwards compatibility).
1617 MAGENTA="%F{magenta}"
1621 elif zrcautoload colors && colors 2>/dev/null ; then
1622 BLUE="%{${fg[blue]}%}"
1623 RED="%{${fg_bold[red]}%}"
1624 GREEN="%{${fg[green]}%}"
1625 CYAN="%{${fg[cyan]}%}"
1626 MAGENTA="%{${fg[magenta]}%}"
1627 YELLOW="%{${fg[yellow]}%}"
1628 WHITE="%{${fg[white]}%}"
1629 NO_COLOR="%{${reset_color}%}"
1631 BLUE=$'%{\e[1;34m%}'
1633 GREEN=$'%{\e[1;32m%}'
1634 CYAN=$'%{\e[1;36m%}'
1635 WHITE=$'%{\e[1;37m%}'
1636 MAGENTA=$'%{\e[1;35m%}'
1637 YELLOW=$'%{\e[1;33m%}'
1638 NO_COLOR=$'%{\e[0m%}'
1641 # First, the easy ones: PS2..4:
1643 # secondary prompt, printed when the shell needs more information to complete a
1646 # selection prompt used within a select loop.
1648 # the execution trace prompt (setopt xtrace). default: '+%N:%i>'
1651 # Some additional features to use with our prompt:
1655 # - vcs_info setup and version specific fixes
1657 # display battery status on right side of prompt using 'GRML_DISPLAY_BATTERY=1' in .zshrc.pre
1660 if [[ $GRML_DISPLAY_BATTERY -gt 0 ]] ; then
1663 elif isopenbsd ; then
1665 elif isfreebsd ; then
1667 elif isdarwin ; then
1671 GRML_DISPLAY_BATTERY=0
1677 GRML_BATTERY_LEVEL=''
1678 local batteries bat capacity
1679 batteries=( /sys/class/power_supply/BAT*(N) )
1680 if (( $#batteries > 0 )) ; then
1681 for bat in $batteries ; do
1682 capacity=$(< $bat/capacity)
1683 case $(< $bat/status) in
1685 GRML_BATTERY_LEVEL+=" ^"
1688 if (( capacity < 20 )) ; then
1689 GRML_BATTERY_LEVEL+=" !v"
1691 GRML_BATTERY_LEVEL+=" v"
1695 GRML_BATTERY_LEVEL+=" ="
1698 GRML_BATTERY_LEVEL+="${capacity}%%"
1704 GRML_BATTERY_LEVEL=''
1705 local bat batfull batwarn batnow num
1707 bat=$(sysctl -n hw.sensors.acpibat${num} 2>/dev/null)
1708 if [[ -n $bat ]]; then
1709 batfull=${"$(sysctl -n hw.sensors.acpibat${num}.amphour0)"%% *}
1710 batwarn=${"$(sysctl -n hw.sensors.acpibat${num}.amphour1)"%% *}
1711 batnow=${"$(sysctl -n hw.sensors.acpibat${num}.amphour3)"%% *}
1712 case "$(sysctl -n hw.sensors.acpibat${num}.raw0)" in
1714 if (( batnow < batwarn )) ; then
1715 GRML_BATTERY_LEVEL+=" !v"
1717 GRML_BATTERY_LEVEL+=" v"
1721 GRML_BATTERY_LEVEL+=" ^"
1724 GRML_BATTERY_LEVEL+=" ="
1727 GRML_BATTERY_LEVEL+="${$(( 100 * batnow / batfull ))%%.*}%%"
1733 GRML_BATTERY_LEVEL=''
1737 table=( ${=${${${${${(M)${(f)"$(acpiconf -i $num 2>&1)"}:#(State|Remaining capacity):*}%%( ##|%)}//:[ $'\t']##/@}// /-}//@/ }} )
1738 if [[ -n $table ]] && [[ $table[State] != "not-present" ]] ; then
1739 case $table[State] in
1741 if (( $table[Remaining-capacity] < 20 )) ; then
1742 GRML_BATTERY_LEVEL+=" !v"
1744 GRML_BATTERY_LEVEL+=" v"
1748 GRML_BATTERY_LEVEL+=" ^"
1751 GRML_BATTERY_LEVEL+=" ="
1754 GRML_BATTERY_LEVEL+="$table[Remaining-capacity]%%"
1760 GRML_BATTERY_LEVEL=''
1762 table=( ${$(pmset -g ps)[(w)7,8]%%(\%|);} )
1763 if [[ -n $table[2] ]] ; then
1766 GRML_BATTERY_LEVEL+=" ^"
1769 if (( $table[1] < 20 )) ; then
1770 GRML_BATTERY_LEVEL+=" !v"
1772 GRML_BATTERY_LEVEL+=" v"
1776 GRML_BATTERY_LEVEL+=" ="
1779 GRML_BATTERY_LEVEL+="$table[1]%%"
1783 # set variable debian_chroot if running in a chroot with /etc/debian_chroot
1784 if [[ -z "$debian_chroot" ]] && [[ -r /etc/debian_chroot ]] ; then
1785 debian_chroot=$(</etc/debian_chroot)
1788 # gather version control information for inclusion in a prompt
1790 if zrcautoload vcs_info; then
1791 # `vcs_info' in zsh versions 4.3.10 and below have a broken `_realpath'
1792 # function, which can cause a lot of trouble with our directory-based
1794 if [[ ${ZSH_VERSION} == 4.3.<-10> ]] ; then
1795 function VCS_INFO_realpath () {
1796 setopt localoptions NO_shwordsplit chaselinks
1797 ( builtin cd -q $1 2> /dev/null && pwd; )
1801 zstyle ':vcs_info:*' max-exports 2
1803 if [[ -o restricted ]]; then
1804 zstyle ':vcs_info:*' enable NONE
1808 typeset -A grml_vcs_coloured_formats
1809 typeset -A grml_vcs_plain_formats
1811 grml_vcs_plain_formats=(
1812 format "(%s%)-[%b] " "zsh: %r"
1813 actionformat "(%s%)-[%b|%a] " "zsh: %r"
1814 rev-branchformat "%b:%r"
1817 grml_vcs_coloured_formats=(
1818 format "${MAGENTA}(${NO_COLOR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOR} "
1819 actionformat "${MAGENTA}(${NO_COLOR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOR} "
1820 rev-branchformat "%b${RED}:${YELLOW}%r"
1823 typeset GRML_VCS_COLOUR_MODE=xxx
1825 grml_vcs_info_toggle_colour () {
1827 if [[ $GRML_VCS_COLOUR_MODE == plain ]]; then
1828 grml_vcs_info_set_formats coloured
1830 grml_vcs_info_set_formats plain
1835 grml_vcs_info_set_formats () {
1837 #setopt localoptions xtrace
1838 local mode=$1 AF F BF
1839 if [[ $mode == coloured ]]; then
1840 AF=${grml_vcs_coloured_formats[actionformat]}
1841 F=${grml_vcs_coloured_formats[format]}
1842 BF=${grml_vcs_coloured_formats[rev-branchformat]}
1843 GRML_VCS_COLOUR_MODE=coloured
1845 AF=${grml_vcs_plain_formats[actionformat]}
1846 F=${grml_vcs_plain_formats[format]}
1847 BF=${grml_vcs_plain_formats[rev-branchformat]}
1848 GRML_VCS_COLOUR_MODE=plain
1851 zstyle ':vcs_info:*' actionformats "$AF" "zsh: %r"
1852 zstyle ':vcs_info:*' formats "$F" "zsh: %r"
1853 zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat "$BF"
1857 # Change vcs_info formats for the grml prompt. The 2nd format sets up
1858 # $vcs_info_msg_1_ to contain "zsh: repo-name" used to set our screen title.
1859 if [[ "$TERM" == dumb ]] ; then
1860 grml_vcs_info_set_formats plain
1862 grml_vcs_info_set_formats coloured
1865 # Now for the fun part: The grml prompt themes in `promptsys' mode of operation
1867 # This actually defines three prompts:
1873 # They all share the same code and only differ with respect to which items they
1874 # contain. The main source of documentation is the `prompt_grml_help' function
1875 # below, which gets called when the user does this: prompt -h grml
1877 function prompt_grml_help () {
1881 This is the prompt as used by the grml-live system <http://grml.org>. It is
1882 a rather simple one-line prompt, that by default looks something like this:
1884 <user>@<host> <current-working-directory>[ <vcs_info-data>]%
1886 The prompt itself integrates with zsh's prompt themes system (as you are
1887 witnessing right now) and is configurable to a certain degree. In
1888 particular, these aspects are customisable:
1890 - The items used in the prompt (e.g. you can remove \`user' from
1891 the list of activated items, which will cause the user name to
1892 be omitted from the prompt string).
1894 - The attributes used with the items are customisable via strings
1895 used before and after the actual item.
1897 The available items are: at, battery, change-root, date, grml-chroot,
1898 history, host, jobs, newline, path, percent, rc, rc-always, sad-smiley,
1899 shell-level, time, user, vcs
1901 The actual configuration is done via zsh's \`zstyle' mechanism. The
1902 context, that is used while looking up styles is:
1904 ':prompt:grml:<left-or-right>:<subcontext>'
1906 Here <left-or-right> is either \`left' or \`right', signifying whether the
1907 style should affect the left or the right prompt. <subcontext> is either
1908 \`setup' or 'items:<item>', where \`<item>' is one of the available items.
1912 - use-rprompt (boolean): If \`true' (the default), print a sad smiley
1913 in $RPROMPT if the last command a returned non-successful error code.
1914 (This in only valid if <left-or-right> is "right"; ignored otherwise)
1916 - items (list): The list of items used in the prompt. If \`vcs' is
1917 present in the list, the theme's code invokes \`vcs_info'
1918 accordingly. Default (left): rc change-root user at host path vcs
1919 percent; Default (right): sad-smiley
1921 Available styles in 'items:<item>' are: pre, post. These are strings that
1922 are inserted before (pre) and after (post) the item in question. Thus, the
1923 following would cause the user name to be printed in red instead of the
1926 zstyle ':prompt:grml:*:items:user' pre '%F{red}'
1928 Note, that the \`post' style may remain at its default value, because its
1929 default value is '%f', which turns the foreground text attribute off (which
1930 is exactly, what is still required with the new \`pre' value).
1934 function prompt_grml-chroot_help () {
1938 This is a variation of the grml prompt, see: prompt -h grml
1940 The main difference is the default value of the \`items' style. The rest
1941 behaves exactly the same. Here are the defaults for \`grml-chroot':
1943 - left: grml-chroot user at host path percent
1944 - right: (empty list)
1948 function prompt_grml-large_help () {
1952 This is a variation of the grml prompt, see: prompt -h grml
1954 The main difference is the default value of the \`items' style. In
1955 particular, this theme uses _two_ lines instead of one with the plain
1956 \`grml' theme. The rest behaves exactly the same. Here are the defaults
1959 - left: rc jobs history shell-level change-root time date newline user
1960 at host path vcs percent
1965 function grml_prompt_setup () {
1967 autoload -Uz vcs_info
1968 autoload -Uz add-zsh-hook
1969 add-zsh-hook precmd prompt_$1_precmd
1972 function prompt_grml_setup () {
1973 grml_prompt_setup grml
1976 function prompt_grml-chroot_setup () {
1977 grml_prompt_setup grml-chroot
1980 function prompt_grml-large_setup () {
1981 grml_prompt_setup grml-large
1984 # These maps define default tokens and pre-/post-decoration for items to be
1985 # used within the themes. All defaults may be customised in a context sensitive
1986 # matter by using zsh's `zstyle' mechanism.
1987 typeset -gA grml_prompt_pre_default \
1988 grml_prompt_post_default \
1989 grml_prompt_token_default \
1990 grml_prompt_token_function
1992 grml_prompt_pre_default=(
1997 grml-chroot '%F{red}'
2007 shell-level '%F{red}'
2013 grml_prompt_post_default=(
2034 grml_prompt_token_default=(
2036 battery 'GRML_BATTERY_LEVEL'
2037 change-root 'debian_chroot'
2039 grml-chroot 'GRML_CHROOT'
2040 history '{history#%!} '
2042 jobs '[%j running job(s)] '
2044 path '%40<..<%~%<< '
2048 sad-smiley '%(?..:()'
2049 shell-level '%(3L.+ .)'
2050 time '%D{%H:%M:%S} '
2055 function grml_theme_has_token () {
2056 if (( ARGC != 1 )); then
2057 printf 'usage: grml_theme_has_token <name>\n'
2060 (( ${+grml_prompt_token_default[$1]} ))
2063 function GRML_theme_add_token_usage () {
2065 Usage: grml_theme_add_token <name> [-f|-i] <token/function> [<pre> <post>]
2067 <name> is the name for the newly added token. If the \`-f' or \`-i' options
2068 are used, <token/function> is the name of the function (see below for
2069 details). Otherwise it is the literal token string to be used. <pre> and
2070 <post> are optional.
2074 -f <function> Use a function named \`<function>' each time the token
2077 -i <function> Use a function named \`<function>' to initialise the
2078 value of the token _once_ at runtime.
2080 The functions are called with one argument: the token's new name. The
2081 return value is expected in the \$REPLY parameter. The use of these
2082 options is mutually exclusive.
2084 There is a utility function \`grml_theme_has_token', which you can use
2085 to test if a token exists before trying to add it. This can be a guard
2086 for situations in which a \`grml_theme_add_token' call may happen more
2091 To add a new token \`day' that expands to the current weekday in the
2092 current locale in green foreground colour, use this:
2094 grml_theme_add_token day '%D{%A}' '%F{green}' '%f'
2096 Another example would be support for \$VIRTUAL_ENV:
2098 function virtual_env_prompt () {
2099 REPLY=\${VIRTUAL_ENV+\${VIRTUAL_ENV:t} }
2101 grml_theme_add_token virtual-env -f virtual_env_prompt
2103 After that, you will be able to use a changed \`items' style to
2104 assemble your prompt.
2108 function grml_theme_add_token () {
2110 local name token pre post
2111 local -i init funcall
2113 if (( ARGC == 0 )); then
2114 GRML_theme_add_token_usage
2124 if [[ $1 == '-f' ]]; then
2127 elif [[ $1 == '-i' ]]; then
2132 if (( ARGC == 0 )); then
2134 grml_theme_add_token: No token-string/function-name provided!\n\n'
2135 GRML_theme_add_token_usage
2140 if (( ARGC != 0 && ARGC != 2 )); then
2142 grml_theme_add_token: <pre> and <post> need to by specified _both_!\n\n'
2143 GRML_theme_add_token_usage
2152 if grml_theme_has_token $name; then
2154 grml_theme_add_token: Token `%s'\'' exists! Giving up!\n\n' $name
2155 GRML_theme_add_token_usage
2162 grml_prompt_pre_default[$name]=$pre
2163 grml_prompt_post_default[$name]=$post
2164 if (( funcall )); then
2165 grml_prompt_token_function[$name]=$token
2166 grml_prompt_token_default[$name]=23
2168 grml_prompt_token_default[$name]=$token
2172 function grml_typeset_and_wrap () {
2179 if (( ${+parameters[$new]} )); then
2180 typeset -g "${target}=${(P)target}${left}${(P)new}${right}"
2184 function grml_prompt_addto () {
2187 local lr it apre apost new v
2191 [[ $target == PS1 ]] && lr=left || lr=right
2192 zstyle -a ":prompt:${grmltheme}:${lr}:setup" items items || items=( "$@" )
2193 typeset -g "${target}="
2194 for it in "${items[@]}"; do
2195 zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" pre apre \
2196 || apre=${grml_prompt_pre_default[$it]}
2197 zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" post apost \
2198 || apost=${grml_prompt_post_default[$it]}
2199 zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" token new \
2200 || new=${grml_prompt_token_default[$it]}
2201 typeset -g "${target}=${(P)target}${apre}"
2202 if (( ${+grml_prompt_token_function[$it]} )); then
2203 ${grml_prompt_token_function[$it]} $it
2204 typeset -g "${target}=${(P)target}${REPLY}"
2208 grml_typeset_and_wrap $target $new '' ''
2211 grml_typeset_and_wrap $target $new '(' ')'
2214 if [[ -n ${(P)new} ]]; then
2215 typeset -g "${target}=${(P)target}(CHROOT)"
2219 v="vcs_info_msg_${new}_"
2220 if (( ! vcscalled )); then
2224 if (( ${+parameters[$v]} )) && [[ -n "${(P)v}" ]]; then
2225 typeset -g "${target}=${(P)target}${(P)v}"
2228 *) typeset -g "${target}=${(P)target}${new}" ;;
2231 typeset -g "${target}=${(P)target}${apost}"
2235 function prompt_grml_precmd () {
2237 local grmltheme=grml
2238 local -a left_items right_items
2239 left_items=(rc change-root user at host path vcs percent)
2240 right_items=(sad-smiley)
2242 prompt_grml_precmd_worker
2245 function prompt_grml-chroot_precmd () {
2247 local grmltheme=grml-chroot
2248 local -a left_items right_items
2249 left_items=(grml-chroot user at host path percent)
2252 prompt_grml_precmd_worker
2255 function prompt_grml-large_precmd () {
2257 local grmltheme=grml-large
2258 local -a left_items right_items
2259 left_items=(rc jobs history shell-level change-root time date newline
2260 user at host path vcs percent)
2261 right_items=(sad-smiley)
2263 prompt_grml_precmd_worker
2266 function prompt_grml_precmd_worker () {
2268 local -i vcscalled=0
2270 grml_prompt_addto PS1 "${left_items[@]}"
2271 if zstyle -T ":prompt:${grmltheme}:right:setup" use-rprompt; then
2272 grml_prompt_addto RPS1 "${right_items[@]}"
2276 grml_prompt_fallback() {
2279 (( ${+functions[vcs_info]} )) && vcs_info
2282 p0="${RED}%(?..%? )${WHITE}${debian_chroot:+($debian_chroot)}"
2283 p1="${BLUE}%n${NO_COLOR}@%m %40<...<%B%~%b%<< "'${vcs_info_msg_0_}'"%# "
2284 if (( EUID == 0 )); then
2285 PROMPT="${BLUE}${p0}${RED}${p1}"
2287 PROMPT="${RED}${p0}${BLUE}${p1}"
2292 if zrcautoload promptinit && promptinit 2>/dev/null ; then
2293 # Since we define the required functions in here and not in files in
2294 # $fpath, we need to stick the theme's name into `$prompt_themes'
2295 # ourselves, since promptinit does not pick them up otherwise.
2296 prompt_themes+=( grml grml-chroot grml-large )
2297 # Also, keep the array sorted...
2298 prompt_themes=( "${(@on)prompt_themes}" )
2300 print 'Notice: no promptinit available :('
2301 grml_prompt_fallback
2305 # The prompt themes use modern features of zsh, that require at least
2306 # version 4.3.7 of the shell. Use the fallback otherwise.
2307 if [[ $GRML_DISPLAY_BATTERY -gt 0 ]]; then
2308 zstyle ':prompt:grml:right:setup' items sad-smiley battery
2309 add-zsh-hook precmd battery
2311 if [[ "$TERM" == dumb ]] ; then
2312 zstyle ":prompt:grml(|-large|-chroot):*:items:grml-chroot" pre ''
2313 zstyle ":prompt:grml(|-large|-chroot):*:items:grml-chroot" post ' '
2314 for i in rc user path jobs history date time shell-level; do
2315 zstyle ":prompt:grml(|-large|-chroot):*:items:$i" pre ''
2316 zstyle ":prompt:grml(|-large|-chroot):*:items:$i" post ''
2319 zstyle ':prompt:grml(|-large|-chroot):right:setup' use-rprompt false
2320 elif (( EUID == 0 )); then
2321 zstyle ':prompt:grml(|-large|-chroot):*:items:user' pre '%B%F{red}'
2324 # Finally enable one of the prompts.
2325 if [[ -n $GRML_CHROOT ]]; then
2327 elif [[ $GRMLPROMPT -gt 0 ]]; then
2333 grml_prompt_fallback
2336 # Terminal-title wizardry
2338 function ESC_print () {
2339 info_print $'\ek' $'\e\\' "$@"
2341 function set_title () {
2342 info_print $'\e]0;' $'\a' "$@"
2345 function info_print () {
2346 local esc_begin esc_end
2350 printf '%s' ${esc_begin}
2352 printf '%s' "${esc_end}"
2355 function grml_reset_screen_title () {
2356 # adjust title of xterm
2357 # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
2358 [[ ${NOTITLE:-} -gt 0 ]] && return 0
2361 set_title ${(%):-"%n@%m: %~"}
2366 function grml_vcs_to_screen_title () {
2367 if [[ $TERM == screen* ]] ; then
2368 if [[ -n ${vcs_info_msg_1_} ]] ; then
2369 ESC_print ${vcs_info_msg_1_}
2376 function grml_maintain_name () {
2377 # set hostname if not running on host with name 'grml'
2378 if [[ -n "$HOSTNAME" ]] && [[ "$HOSTNAME" != $(hostname) ]] ; then
2383 function grml_cmd_to_screen_title () {
2384 # get the name of the program currently running and hostname of local
2385 # machine set screen window title if running in a screen
2386 if [[ "$TERM" == screen* ]] ; then
2387 local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME"
2392 function grml_control_xterm_title () {
2395 set_title "${(%):-"%n@%m:"}" "$1"
2400 zrcautoload add-zsh-hook || add-zsh-hook () { :; }
2401 if [[ $NOPRECMD -eq 0 ]]; then
2402 add-zsh-hook precmd grml_reset_screen_title
2403 add-zsh-hook precmd grml_vcs_to_screen_title
2404 add-zsh-hook preexec grml_maintain_name
2405 add-zsh-hook preexec grml_cmd_to_screen_title
2406 if [[ $NOTITLE -eq 0 ]]; then
2407 add-zsh-hook preexec grml_control_xterm_title
2411 # 'hash' some often used directories
2413 hash -d deb=/var/cache/apt/archives
2414 hash -d doc=/usr/share/doc
2415 hash -d linux=/lib/modules/$(command uname -r)/build/
2416 hash -d log=/var/log
2417 hash -d slog=/var/log/syslog
2418 hash -d src=/usr/src
2419 hash -d www=/var/www
2423 if check_com -c screen ; then
2424 if [[ $UID -eq 0 ]] ; then
2425 if [[ -r /etc/grml/screenrc ]]; then
2426 alias screen="${commands[screen]} -c /etc/grml/screenrc"
2428 elif [[ -r $HOME/.screenrc ]] ; then
2429 alias screen="${commands[screen]} -c $HOME/.screenrc"
2431 if [[ -r /etc/grml/screenrc_grml ]]; then
2432 alias screen="${commands[screen]} -c /etc/grml/screenrc_grml"
2434 if [[ -r /etc/grml/screenrc ]]; then
2435 alias screen="${commands[screen]} -c /etc/grml/screenrc"
2441 # do we have GNU ls with color-support?
2442 if [[ "$TERM" != dumb ]]; then
2443 #a1# List files with colors (\kbd{ls \ldots})
2444 alias ls="command ls ${ls_options:+${ls_options[*]}}"
2445 #a1# List all files, with colors (\kbd{ls -la \ldots})
2446 alias la="command ls -la ${ls_options:+${ls_options[*]}}"
2447 #a1# List files with long colored list, without dotfiles (\kbd{ls -l \ldots})
2448 alias ll="command ls -l ${ls_options:+${ls_options[*]}}"
2449 #a1# List files with long colored list, human readable sizes (\kbd{ls -hAl \ldots})
2450 alias lh="command ls -hAl ${ls_options:+${ls_options[*]}}"
2451 #a1# List files with long colored list, append qualifier to filenames (\kbd{ls -l \ldots})\\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
2452 alias l="command ls -l ${ls_options:+${ls_options[*]}}"
2454 alias la='command ls -la'
2455 alias ll='command ls -l'
2456 alias lh='command ls -hAl'
2457 alias l='command ls -l'
2460 alias mdstat='cat /proc/mdstat'
2461 alias ...='cd ../../'
2463 # generate alias named "$KERNELVERSION-reboot" so you can use boot with kexec:
2464 if [[ -x /sbin/kexec ]] && [[ -r /proc/cmdline ]] ; then
2465 alias "$(uname -r)-reboot"="kexec -l --initrd=/boot/initrd.img-"$(uname -r)" --command-line=\"$(cat /proc/cmdline)\" /boot/vmlinuz-"$(uname -r)""
2468 # see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
2469 alias term2iso="echo 'Setting terminal to iso mode' ; print -n '\e%@'"
2470 alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
2472 # make sure it is not assigned yet
2473 [[ -n ${aliases[utf2iso]} ]] && unalias utf2iso
2476 for ENV in $(env | command grep -i '.utf') ; do
2477 eval export "$(echo $ENV | sed 's/UTF-8/iso885915/ ; s/utf8/iso885915/')"
2482 # make sure it is not assigned yet
2483 [[ -n ${aliases[iso2utf]} ]] && unalias iso2utf
2485 if ! isutfenv ; then
2486 for ENV in $(env | command grep -i '\.iso') ; do
2487 eval export "$(echo $ENV | sed 's/iso.*/UTF-8/ ; s/ISO.*/UTF-8/')"
2492 # especially for roadwarriors using GNU screen and ssh:
2493 if ! check_com asc &>/dev/null ; then
2494 asc() { autossh -t "$@" 'screen -RdU' }
2498 #f1# Hints for the use of zsh on grml
2500 print "$bg[white]$fg[black]
2501 zsh-help - hints for use of zsh on grml
2502 =======================================$reset_color"
2505 Main configuration of zsh happens in /etc/zsh/zshrc.
2506 That file is part of the package grml-etc-core, if you want to
2507 use them on a non-grml-system just get the tar.gz from
2508 http://deb.grml.org/ or (preferably) get it from the git repository:
2510 http://git.grml.org/f/grml-etc-core/etc/zsh/zshrc
2512 This version of grml'\''s zsh setup does not use skel/.zshrc anymore.
2513 The file is still there, but it is empty for backwards compatibility.
2515 For your own changes use these two files:
2519 The former is sourced very early in our zshrc, the latter is sourced
2522 System wide configuration without touching configuration files of grml
2523 can take place in /etc/zsh/zshrc.local.
2525 For information regarding zsh start at http://grml.org/zsh/
2527 Take a look at grml'\''s zsh refcard:
2528 % xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
2530 Check out the main zsh refcard:
2531 % '$BROWSER' http://www.bash2zsh.com/zsh_refcard/refcard.pdf
2533 And of course visit the zsh-lovers:
2536 You can adjust some options through environment variables when
2537 invoking zsh without having to edit configuration files.
2538 Basically meant for bash users who are not used to the power of
2541 "NOCOR=1 zsh" => deactivate automatic correction
2542 "NOMENU=1 zsh" => do not use auto menu completion
2543 (note: use ctrl-d for completion instead!)
2544 "NOPRECMD=1 zsh" => disable the precmd + preexec commands (set GNU screen title)
2545 "NOTITLE=1 zsh" => disable setting the title of xterms without disabling
2546 preexec() and precmd() completely
2547 "GRML_DISPLAY_BATTERY=1 zsh"
2548 => activate battery status on right side of prompt (WIP)
2549 "COMMAND_NOT_FOUND=1 zsh"
2550 => Enable a handler if an external command was not found
2551 The command called in the handler can be altered by setting
2552 the GRML_ZSH_CNF_HANDLER variable, the default is:
2553 "/usr/share/command-not-found/command-not-found"
2555 A value greater than 0 is enables a feature; a value equal to zero
2556 disables it. If you like one or the other of these settings, you can
2557 add them to ~/.zshrc.pre to ensure they are set when sourcing grml'\''s
2561 $bg[white]$fg[black]
2562 Please report wishes + bugs to the grml-team: http://grml.org/bugs/
2563 Enjoy your grml system with the zsh!$reset_color"
2567 if [[ -r /etc/debian_version ]] ; then
2568 #a3# Execute \kbd{apt-cache search}
2569 alias acs='apt-cache search'
2570 #a3# Execute \kbd{apt-cache show}
2571 alias acsh='apt-cache show'
2572 #a3# Execute \kbd{apt-cache policy}
2573 alias acp='apt-cache policy'
2574 #a3# Execute \kbd{apt-get dist-upgrade}
2575 salias adg="apt-get dist-upgrade"
2576 #a3# Execute \kbd{apt-get install}
2577 salias agi="apt-get install"
2578 #a3# Execute \kbd{aptitude install}
2579 salias ati="aptitude install"
2580 #a3# Execute \kbd{apt-get upgrade}
2581 salias ag="apt-get upgrade"
2582 #a3# Execute \kbd{apt-get update}
2583 salias au="apt-get update"
2584 #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
2585 salias -a up="aptitude update ; aptitude safe-upgrade"
2586 #a3# Execute \kbd{dpkg-buildpackage}
2587 alias dbp='dpkg-buildpackage'
2588 #a3# Execute \kbd{grep-excuses}
2589 alias ge='grep-excuses'
2591 # get a root shell as normal user in live-cd mode:
2592 if isgrmlcd && [[ $UID -ne 0 ]] ; then
2596 #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
2597 salias llog="$PAGER /var/log/syslog" # take a look at the syslog
2598 #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
2599 salias tlog="tail -f /var/log/syslog" # follow the syslog
2602 # sort installed Debian-packages by size
2603 if check_com -c dpkg-query ; then
2604 #a3# List installed Debian-packages sorted by size
2605 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"
2608 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
2609 if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord; then
2610 if check_com -c wodim; then
2613 cdrecord is not provided under its original name by Debian anymore.
2614 See #377109 in the BTS of Debian for more details.
2616 Please use the wodim binary instead
2623 # Use hard limits, except for a smaller stack and no core dumps
2625 is425 && limit stack 8192
2626 isgrmlcd && limit core 0 # important for a live-cd-system
2631 # people should use 'grml-x'!
2632 if check_com -c 915resolution; then
2634 echo "Please use 915resolution as resolution modifying tool for Intel \
2640 #a1# Output version of running grml
2641 alias grml-version='cat /etc/grml_version'
2643 if check_com -c grml-debootstrap ; then
2645 echo "Installing debian to harddisk is possible by using grml-debootstrap."
2651 # now run the functions
2653 is4 && isgrml && grmlstuff
2657 is4 && xsource "/etc/zsh/keephack"
2659 # wonderful idea of using "e" glob qualifier by Peter Stephenson
2660 # You use it as follows:
2661 # $ NTREF=/reference/file
2663 # This lists all the files in the current directory newer than the reference file.
2664 # You can also specify the reference file inline; note quotes:
2665 # $ ls -l *(e:'nt ~/.zshenv':)
2667 if [[ -n $1 ]] ; then
2670 [[ $REPLY -nt $NTREF ]]
2675 #f1# Reload an autoloadable function
2676 freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }
2677 compdef _functions freload
2679 #f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
2681 [[ -z "$1" ]] && printf 'Usage: %s <file(s)>\n' "$0" && return 1
2683 for file in "$@" ; do
2684 while [[ -h "$file" ]] ; do
2686 file=$(readlink "$file")
2691 # TODO: Is it supported to use pager settings like this?
2692 # PAGER='less -Mr' - If so, the use of $PAGER here needs fixing
2693 # with respect to wordsplitting. (ie. ${=PAGER})
2694 if check_com -c $PAGER ; then
2695 #f3# View Debian's changelog of given package(s)
2698 [[ -z "$1" ]] && printf 'Usage: %s <package_name(s)>\n' "$0" && return 1
2701 for package in "$@" ; do
2702 if [[ -r /usr/share/doc/${package}/changelog.Debian.gz ]] ; then
2703 $PAGER /usr/share/doc/${package}/changelog.Debian.gz
2704 elif [[ -r /usr/share/doc/${package}/changelog.gz ]] ; then
2705 $PAGER /usr/share/doc/${package}/changelog.gz
2706 elif [[ -r /usr/share/doc/${package}/changelog ]] ; then
2707 $PAGER /usr/share/doc/${package}/changelog
2709 if check_com -c aptitude ; then
2710 echo "No changelog for package $package found, using aptitude to retrieve it."
2711 aptitude changelog "$package"
2712 elif check_com -c apt-get ; then
2713 echo "No changelog for package $package found, using apt-get to retrieve it."
2714 apt-get changelog "$package"
2716 echo "No changelog for package $package found, sorry."
2721 _dchange() { _files -W /usr/share/doc -/ }
2722 compdef _dchange dchange
2724 #f3# View Debian's NEWS of a given package
2727 if [[ -r /usr/share/doc/$1/NEWS.Debian.gz ]] ; then
2728 $PAGER /usr/share/doc/$1/NEWS.Debian.gz
2730 if [[ -r /usr/share/doc/$1/NEWS.gz ]] ; then
2731 $PAGER /usr/share/doc/$1/NEWS.gz
2733 echo "No NEWS file for package $1 found, sorry."
2738 _dnews() { _files -W /usr/share/doc -/ }
2739 compdef _dnews dnews
2741 #f3# View Debian's copyright of a given package
2744 if [[ -r /usr/share/doc/$1/copyright ]] ; then
2745 $PAGER /usr/share/doc/$1/copyright
2747 echo "No copyright file for package $1 found, sorry."
2751 _dcopyright() { _files -W /usr/share/doc -/ }
2752 compdef _dcopyright dcopyright
2754 #f3# View upstream's changelog of a given package
2757 if [[ -r /usr/share/doc/$1/changelog.gz ]] ; then
2758 $PAGER /usr/share/doc/$1/changelog.gz
2760 echo "No changelog for package $1 found, sorry."
2764 _uchange() { _files -W /usr/share/doc -/ }
2765 compdef _uchange uchange
2770 ZSH_PROFILE_RC=1 $SHELL "$@"
2773 #f1# Edit an alias via zle
2775 [[ -z "$1" ]] && { echo "Usage: edalias <alias_to_edit>" ; return 1 } || vared aliases'[$1]' ;
2777 compdef _aliases edalias
2779 #f1# Edit a function via zle
2781 [[ -z "$1" ]] && { echo "Usage: edfunc <function_to_edit>" ; return 1 } || zed -f "$1" ;
2783 compdef _functions edfunc
2785 # use it e.g. via 'Restart apache2'
2786 #m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
2787 #m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
2788 #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
2789 #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
2790 #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
2791 #m# f6 Status() \kbd{/etc/init.d/\em{process}}\quad\kbd{status}
2792 if [[ -d /etc/init.d || -d /etc/service ]] ; then
2794 local action_="${1:l}" # e.g Start/Stop/Restart
2798 local service_target_="$(readlink /etc/init.d/$service_)"
2799 if [[ $service_target_ == "/usr/bin/sv" ]]; then
2801 case "${action_}" in
2802 start) if [[ ! -e /etc/service/$service_ ]]; then
2803 $SUDO ln -s "/etc/sv/$service_" "/etc/service/"
2805 $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
2807 # there is no reload in runits sysv emulation
2808 reload) $SUDO "/etc/init.d/$service_" "force-reload" "$param_" ;;
2809 *) $SUDO "/etc/init.d/$service_" "${action_}" "$param_" ;;
2813 $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
2819 scripts=( /etc/init.d/*(x:t) )
2820 _describe "service startup script" scripts
2823 for i in Start Restart Stop Force-Reload Reload Status ; do
2824 eval "$i() { __start_stop $i \"\$1\" \"\$2\" ; }"
2825 compdef _grmlinitd $i
2829 #f1# Provides useful information on globbing
2836 p named pipes (FIFOs)
2837 * executable plain files (0100)
2838 % device files (character or block special)
2839 %b block special files
2840 %c character special files
2841 r owner-readable files (0400)
2842 w owner-writable files (0200)
2843 x owner-executable files (0100)
2844 A group-readable files (0040)
2845 I group-writable files (0020)
2846 E group-executable files (0010)
2847 R world-readable files (0004)
2848 W world-writable files (0002)
2849 X world-executable files (0001)
2850 s setuid files (04000)
2851 S setgid files (02000)
2852 t files with the sticky bit (01000)
2854 print *(m-1) # Files modified up to a day ago
2855 print *(a1) # Files accessed a day ago
2856 print *(@) # Just symlinks
2857 print *(Lk+50) # Files bigger than 50 kilobytes
2858 print *(Lk-50) # Files smaller than 50 kilobytes
2859 print **/*.c # All *.c files recursively starting in \$PWD
2860 print **/*.c~file.c # Same as above, but excluding 'file.c'
2861 print (foo|bar).* # Files starting with 'foo' or 'bar'
2862 print *~*.* # All Files that do not contain a dot
2863 chmod 644 *(.^x) # make all plain non-executable files publically readable
2864 print -l *(.c|.h) # Lists *.c and *.h
2865 print **/*(g:users:) # Recursively match all files that are owned by group 'users'
2866 echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
2868 alias help-zshglob=H-Glob
2870 # grep for running process, like: 'any vim'
2874 if [[ -z "$1" ]] ; then
2875 echo "any - grep for process(es) by keyword" >&2
2876 echo "Usage: any <keyword>" >&2 ; return 1
2878 ps xauwww | grep -i "${grep_options[@]}" "[${1[1]}]${1[2,-1]}"
2883 # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
2884 # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
2885 [[ -r /proc/1/maps ]] && \
2887 print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
2888 cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/') > /dev/null
2889 print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
2892 # a wrapper for vim, that deals with title setting
2894 # set this array to a set of options to vim you always want
2895 # to have set when calling vim (in .zshrc.local), like:
2896 # VIM_OPTIONS=( -p )
2897 # This will cause vim to send every file given on the
2898 # commandline to be send to it's own tab (needs vim7).
2899 if check_com vim; then
2901 VIM_PLEASE_SET_TITLE='yes' command vim ${VIM_OPTIONS} "$@"
2905 ssl_hashes=( sha512 sha256 sha1 md5 )
2907 for sh in ${ssl_hashes}; do
2908 eval 'ssl-cert-'${sh}'() {
2910 if [[ -z $1 ]] ; then
2911 printf '\''usage: %s <file>\n'\'' "ssh-cert-'${sh}'"
2914 openssl x509 -noout -fingerprint -'${sh}' -in $1
2918 ssl-cert-fingerprints() {
2921 if [[ -z $1 ]] ; then
2922 printf 'usage: ssl-cert-fingerprints <file>\n'
2925 for i in ${ssl_hashes}
2932 if [[ -z $1 ]] ; then
2933 printf 'usage: ssl-cert-info <file>\n'
2936 openssl x509 -noout -text -in $1
2937 ssl-cert-fingerprints $1
2940 # make sure our environment is clean regarding colors
2941 for color in BLUE RED GREEN CYAN YELLOW MAGENTA WHITE ; unset $color
2943 # "persistent history"
2944 # just write important commands you always need to ~/.important_commands
2945 if [[ -r ~/.important_commands ]] ; then
2946 fc -R ~/.important_commands
2949 # load the lookup subsystem if it's available on the system
2950 zrcautoload lookupinit && lookupinit
2954 # set terminal property (used e.g. by msgid-chooser)
2955 export COLORTERM="yes"
2960 #a2# Execute \kbd{du -sch}
2964 #a2# Execute \kbd{ls -lSrah}
2965 alias dir="command ls -lSrah"
2966 #a2# Only show dot-directories
2967 alias lad='command ls -d .*(/)'
2968 #a2# Only show dot-files
2969 alias lsa='command ls -a .*(.)'
2970 #a2# Only files with setgid/setuid/sticky flag
2971 alias lss='command ls -l *(s,S,t)'
2972 #a2# Only show symlinks
2973 alias lsl='command ls -l *(@)'
2974 #a2# Display only executables
2975 alias lsx='command ls -l *(*)'
2976 #a2# Display world-{readable,writable,executable} files
2977 alias lsw='command ls -ld *(R,W,X.^ND/)'
2978 #a2# Display the ten biggest files
2979 alias lsbig="command ls -flh *(.OL[1,10])"
2980 #a2# Only show directories
2981 alias lsd='command ls -d *(/)'
2982 #a2# Only show empty directories
2983 alias lse='command ls -d *(/^F)'
2984 #a2# Display the ten newest files
2985 alias lsnew="command ls -rtlh *(D.om[1,10])"
2986 #a2# Display the ten oldest files
2987 alias lsold="command ls -rtlh *(D.Om[1,10])"
2988 #a2# Display the ten smallest files
2989 alias lssmall="command ls -Srl *(.oL[1,10])"
2990 #a2# Display the ten newest directories and ten newest .directories
2991 alias lsnewdir="command ls -rthdl *(/om[1,10]) .*(D/om[1,10])"
2992 #a2# Display the ten oldest directories and ten oldest .directories
2993 alias lsolddir="command ls -rthdl *(/Om[1,10]) .*(D/Om[1,10])"
2995 # some useful aliases
2996 #a2# Remove current empty directory. Execute \kbd{cd ..; rmdir \$OLDCWD}
2997 alias rmcdir='cd ..; rmdir $OLDPWD || cd $OLDPWD'
2999 #a2# ssh with StrictHostKeyChecking=no \\&\quad and UserKnownHostsFile unset
3000 alias insecssh='ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
3001 #a2# scp with StrictHostKeyChecking=no \\&\quad and UserKnownHostsFile unset
3002 alias insecscp='scp -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
3004 # work around non utf8 capable software in utf environment via $LANG and luit
3005 if check_com isutfenv && check_com luit ; then
3006 if check_com -c mrxvt ; then
3007 isutfenv && [[ -n "$LANG" ]] && \
3008 alias mrxvt="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit mrxvt"
3011 if check_com -c aterm ; then
3012 isutfenv && [[ -n "$LANG" ]] && \
3013 alias aterm="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit aterm"
3016 if check_com -c centericq ; then
3017 isutfenv && [[ -n "$LANG" ]] && \
3018 alias centericq="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit centericq"
3024 #f5# Backup \kbd{file_or_folder {\rm to} file_or_folder\_timestamp}
3027 local current_date=$(date -u "+%Y-%m-%dT%H:%M:%SZ")
3028 local clean keep move verbose result all to_bk
3029 setopt extended_glob
3031 while getopts ":hacmrv" opt; do
3034 c) unset move clean && (( ++keep ));;
3035 m) unset keep clean && (( ++move ));;
3036 r) unset move keep && (( ++clean ));;
3039 bk [-hcmv] FILE [FILE ...]
3040 bk -r [-av] [FILE [FILE ...]]
3041 Backup a file or folder in place and append the timestamp
3042 Remove backups of a file or folder, or all backups in the current directory
3045 -h Display this help text
3046 -c Keep the file/folder as is, create a copy backup using cp(1) (default)
3047 -m Move the file/folder, using mv(1)
3048 -r Remove backups of the specified file or directory, using rm(1). If none
3049 is provided, remove all backups in the current directory.
3050 -a Remove all (even hidden) backups.
3053 The -c, -r and -m options are mutually exclusive. If specified at the same time,
3054 the last one is used.
3056 The return code is the sum of all cp/mv/rm return codes.
3059 \?) bk -h >&2; return 1;;
3062 shift "$((OPTIND-1))"
3063 if (( keep > 0 )); then
3064 if islinux || isfreebsd; then
3065 for to_bk in "$@"; do
3066 cp $verbose -a "${to_bk%/}" "${to_bk%/}_$current_date"
3070 for to_bk in "$@"; do
3071 cp $verbose -pR "${to_bk%/}" "${to_bk%/}_$current_date"
3075 elif (( move > 0 )); then
3076 while (( $# > 0 )); do
3077 mv $verbose "${1%/}" "${1%/}_$current_date"
3081 elif (( clean > 0 )); then
3082 if (( $# > 0 )); then
3083 for to_bk in "$@"; do
3084 rm $verbose -rf "${to_bk%/}"_[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
3088 if (( all > 0 )); then
3089 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)
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
3099 #f5# cd to directoy and list files
3105 # smart cd function, allows switching to /etc when running 'cd /etc/fstab'
3107 if (( ${#argv} == 1 )) && [[ -f ${1} ]]; then
3108 [[ ! -e ${1:h} ]] && return 1
3109 print "Correcting ${1} to ${1:h}"
3116 #f5# Create Directoy and \kbd{cd} to it
3118 if (( ARGC != 1 )); then
3119 printf 'usage: mkcd <new-directory>\n'
3122 if [[ ! -d "$1" ]]; then
3123 command mkdir -p "$1"
3125 printf '`%s'\'' already exists: cd-ing.\n' "$1"
3130 #f5# Create temporary directory and \kbd{cd} to it
3138 #f5# List files which have been accessed within the last {\it n} days, {\it n} defaults to 1
3141 print -l -- *(a-${1:-1})
3144 #f5# List files which have been changed within the last {\it n} days, {\it n} defaults to 1
3147 print -l -- *(c-${1:-1})
3150 #f5# List files which have been modified within the last {\it n} days, {\it n} defaults to 1
3153 print -l -- *(m-${1:-1})
3155 # modified() was named new() in earlier versions, add an alias for backwards compatibility
3156 check_com new || alias new=modified
3158 # use colors when GNU grep with color-support
3159 if (( $#grep_options > 0 )); then
3160 o=${grep_options:+"${grep_options[*]}"}
3161 #a2# Execute \kbd{grep -{}-color=auto}
3162 alias grep='grep '$o
3163 alias egrep='egrep '$o
3168 # 'translate' looks up fot a word in a file with language-to-language
3169 # translations (field separator should be " : "). A typical wordlist looks
3171 # | english-word : german-transmission
3172 # It's also only possible to translate english to german but not reciprocal.
3173 # Use the following oneliner to turn back the sort order:
3174 # $ awk -F ':' '{ print $2" : "$1" "$3 }' \
3175 # /usr/local/lib/words/en-de.ISO-8859-1.vok > ~/.translate/de-en.ISO-8859-1.vok
3176 #f5# Translates a word
3181 translate -l de-en $2
3184 translate -l en-de $2
3187 echo "Usage: $0 { -D | -E }"
3188 echo " -D == German to English"
3189 echo " -E == English to German"
3193 # Usage: simple-extract <file>
3194 # Using option -d deletes the original archive file.
3195 #f5# Smart archive extractor
3198 setopt extended_glob noclobber
3199 local DELETE_ORIGINAL DECOMP_CMD USES_STDIN USES_STDOUT GZTARGET WGET_CMD
3201 zparseopts -D -E "d=DELETE_ORIGINAL"
3202 for ARCHIVE in "${@}"; do
3204 *(tar.bz2|tbz2|tbz))
3205 DECOMP_CMD="tar -xvjf -"
3210 DECOMP_CMD="tar -xvzf -"
3214 *(tar.xz|txz|tar.lzma))
3215 DECOMP_CMD="tar -xvJf -"
3220 DECOMP_CMD="tar -xvf -"
3225 DECOMP_CMD="unrar x"
3250 DECOMP_CMD="bzip2 -d -c -"
3255 DECOMP_CMD="gzip -d -c -"
3260 DECOMP_CMD="xz -d -c -"
3265 print "ERROR: '$ARCHIVE' has unrecognized archive type." >&2
3271 if ! check_com ${DECOMP_CMD[(w)1]}; then
3272 echo "ERROR: ${DECOMP_CMD[(w)1]} not installed." >&2
3277 GZTARGET="${ARCHIVE:t:r}"
3278 if [[ -f $ARCHIVE ]] ; then
3280 print "Extracting '$ARCHIVE' ..."
3281 if $USES_STDIN; then
3282 if $USES_STDOUT; then
3283 ${=DECOMP_CMD} < "$ARCHIVE" > $GZTARGET
3285 ${=DECOMP_CMD} < "$ARCHIVE"
3288 if $USES_STDOUT; then
3289 ${=DECOMP_CMD} "$ARCHIVE" > $GZTARGET
3291 ${=DECOMP_CMD} "$ARCHIVE"
3294 [[ $? -eq 0 && -n "$DELETE_ORIGINAL" ]] && rm -f "$ARCHIVE"
3296 elif [[ "$ARCHIVE" == (#s)(https|http|ftp)://* ]] ; then
3297 if check_com curl; then
3298 WGET_CMD="curl -L -k -s -o -"
3299 elif check_com wget; then
3300 WGET_CMD="wget -q -O - --no-check-certificate"
3302 print "ERROR: neither wget nor curl is installed" >&2
3306 print "Downloading and Extracting '$ARCHIVE' ..."
3307 if $USES_STDIN; then
3308 if $USES_STDOUT; then
3309 ${=WGET_CMD} "$ARCHIVE" | ${=DECOMP_CMD} > $GZTARGET
3312 ${=WGET_CMD} "$ARCHIVE" | ${=DECOMP_CMD}
3316 if $USES_STDOUT; then
3317 ${=DECOMP_CMD} =(${=WGET_CMD} "$ARCHIVE") > $GZTARGET
3319 ${=DECOMP_CMD} =(${=WGET_CMD} "$ARCHIVE")
3324 print "ERROR: '$ARCHIVE' is neither a valid file nor a supported URI." >&2
3334 '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)"' \
3335 '_urls:Remote Archives:_urls'
3341 '-d[delete original archivefile after extraction]' \
3342 '*:Archive Or Uri:__archive_or_uri'
3344 compdef _simple_extract simple-extract
3345 alias se=simple-extract
3347 #f5# Set all ulimit parameters to \kbd{unlimited}
3358 #f5# Change the xterm title from within GNU-screen
3361 if [[ $1 != "-f" ]] ; then
3362 if [[ -z ${DISPLAY} ]] ; then
3363 printf 'xtrename only makes sense in X11.\n'
3369 if [[ -z $1 ]] ; then
3370 printf 'usage: xtrename [-f] "title for xterm"\n'
3371 printf ' renames the title of xterm from _within_ screen.\n'
3372 printf ' also works without screen.\n'
3373 printf ' will not work if DISPLAY is unset, use -f to override.\n'
3376 print -n "\eP\e]0;${1}\C-G\e\\"
3380 # Create small urls via http://goo.gl using curl(1).
3381 # API reference: https://code.google.com/apis/urlshortener/
3384 setopt extended_glob
3386 if [[ -z $1 ]]; then
3387 print "USAGE: zurl <URL>"
3391 local PN url prog api json contenttype item
3396 # Prepend 'http://' to given URL where necessary for later output.
3397 if [[ ${url} != http(s|)://* ]]; then
3401 if check_com -c curl; then
3404 print "curl is not available, but mandatory for ${PN}. Aborting."
3407 api='https://www.googleapis.com/urlshortener/v1/url'
3408 contenttype="Content-Type: application/json"
3409 json="{\"longUrl\": \"${url}\"}"
3410 data=(${(f)"$($prog --silent -H ${contenttype} -d ${json} $api)"})
3411 # Parse the response
3412 for item in "${data[@]}"; do
3417 printf '%s\n' "$item"
3425 #f2# Find history events by search pattern and list them by date.
3428 local usage help ident format_l format_s first_char remain first last
3429 usage='USAGE: whatwhen [options] <searchstring> <search range>'
3430 help='Use `whatwhen -h'\'' for further explanations.'
3431 ident=${(l,${#${:-Usage: }},, ,)}
3432 format_l="${ident}%s\t\t\t%s\n"
3433 format_s="${format_l//(\\t)##/\\t}"
3434 # Make the first char of the word to search for case
3435 # insensitive; e.g. [aA]
3436 first_char=[${(L)1[1]}${(U)1[1]}]
3438 # Default search range is `-100'.
3440 # Optional, just used for `<first> <last>' given.
3444 printf '%s\n\n' 'ERROR: No search string specified. Aborting.'
3445 printf '%s\n%s\n\n' ${usage} ${help} && return 1
3448 printf '%s\n\n' ${usage}
3450 printf $format_l '-h' 'show help text'
3452 print 'SEARCH RANGE:'
3453 printf $format_l "'0'" 'the whole history,'
3454 printf $format_l '-<n>' 'offset to the current history number; (default: -100)'
3455 printf $format_s '<[-]first> [<last>]' 'just searching within a give range'
3456 printf '\n%s\n' 'EXAMPLES:'
3457 printf ${format_l/(\\t)/} 'whatwhen grml' '# Range is set to -100 by default.'
3458 printf $format_l 'whatwhen zsh -250'
3459 printf $format_l 'whatwhen foo 1 99'
3462 printf '%s\n%s\n\n' ${usage} ${help} && return 1
3465 # -l list results on stout rather than invoking $EDITOR.
3466 # -i Print dates as in YYYY-MM-DD.
3467 # -m Search for a - quoted - pattern within the history.
3468 fc -li -m "*${first_char}${remain}*" $first $last
3473 # mercurial related stuff
3474 if check_com -c hg ; then
3475 # gnu like diff for mercurial
3476 # http://www.selenic.com/mercurial/wiki/index.cgi/TipsAndTricks
3477 #f5# GNU like diff for mercurial
3480 for i in $(hg status -marn "$@") ; diff -ubwd <(hg cat "$i") "$i"
3483 # build debian package
3484 #a2# Alias for \kbd{hg-buildpackage}
3485 alias hbp='hg-buildpackage'
3487 # execute commands on the versioned patch-queue from the current repos
3488 alias mq='hg -R $(readlink -f $(hg root)/.hg/patches)'
3490 # diffstat for specific version of a mercurial repository
3491 # hgstat => display diffstat between last revision and tip
3492 # hgstat 1234 => display diffstat between revision 1234 and tip
3493 #f5# Diffstat for specific version of a mercurial repos
3496 [[ -n "$1" ]] && hg diff -r $1 -r tip | diffstat || hg export tip | diffstat
3499 fi # end of check whether we have the 'hg'-executable
3501 # grml-small cleanups
3503 # The following is used to remove zsh-config-items that do not work
3504 # in grml-small by default.
3505 # If you do not want these adjustments (for whatever reason), set
3506 # $GRMLSMALL_SPECIFIC to 0 in your .zshrc.pre file (which this configuration
3507 # sources if it is there).
3509 if (( GRMLSMALL_SPECIFIC > 0 )) && isgrmlsmall ; then
3512 unalias 'V' &> /dev/null
3513 unfunction vman &> /dev/null
3514 unfunction viless &> /dev/null
3515 unfunction 2html &> /dev/null
3517 # manpages are not in grmlsmall
3518 unfunction manzsh &> /dev/null
3519 unfunction man2 &> /dev/null
3525 ## genrefcard.pl settings
3527 ### doc strings for external functions from files
3528 #m# f5 grml-wallpaper() Sets a wallpaper (try completion for possible values)
3530 ### example: split functions-search 8,16,24,32
3531 #@# split functions-search 8
3533 ## END OF FILE #################################################################
3534 # vim:filetype=zsh foldmethod=marker autoindent expandtab shiftwidth=4