X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=etc%2Fzsh%2Fzshrc;h=04915b16b9cf43a1ec080096bd8628fae48f98ab;hb=ecfca5641730b961b6283d825e644ee7cda73805;hp=1597b36d8c9f40e4499dcb29e2bd00517ca65096;hpb=39b7de0b27c2365d80acfb4bbe092fa498fda66d;p=grml-etc-core.git diff --git a/etc/zsh/zshrc b/etc/zsh/zshrc index 1597b36..04915b1 100644 --- a/etc/zsh/zshrc +++ b/etc/zsh/zshrc @@ -113,93 +113,97 @@ fi # check for version/system # check for versions (compatibility reasons) -is4(){ +function is4 () { [[ $ZSH_VERSION == <4->* ]] && return 0 return 1 } -is41(){ +function is41 () { [[ $ZSH_VERSION == 4.<1->* || $ZSH_VERSION == <5->* ]] && return 0 return 1 } -is42(){ +function is42 () { [[ $ZSH_VERSION == 4.<2->* || $ZSH_VERSION == <5->* ]] && return 0 return 1 } -is425(){ +function is425 () { [[ $ZSH_VERSION == 4.2.<5->* || $ZSH_VERSION == 4.<3->* || $ZSH_VERSION == <5->* ]] && return 0 return 1 } -is43(){ +function is43 () { [[ $ZSH_VERSION == 4.<3->* || $ZSH_VERSION == <5->* ]] && return 0 return 1 } -is433(){ +function is433 () { [[ $ZSH_VERSION == 4.3.<3->* || $ZSH_VERSION == 4.<4->* \ || $ZSH_VERSION == <5->* ]] && return 0 return 1 } -is437(){ +function is437 () { [[ $ZSH_VERSION == 4.3.<7->* || $ZSH_VERSION == 4.<4->* \ || $ZSH_VERSION == <5->* ]] && return 0 return 1 } -is439(){ +function is439 () { [[ $ZSH_VERSION == 4.3.<9->* || $ZSH_VERSION == 4.<4->* \ || $ZSH_VERSION == <5->* ]] && return 0 return 1 } #f1# Checks whether or not you're running grml -isgrml(){ +function isgrml () { [[ -f /etc/grml_version ]] && return 0 return 1 } #f1# Checks whether or not you're running a grml cd -isgrmlcd(){ +function isgrmlcd () { [[ -f /etc/grml_cd ]] && return 0 return 1 } if isgrml ; then #f1# Checks whether or not you're running grml-small - isgrmlsmall() { + function isgrmlsmall () { if [[ ${${${(f)"$( autologin # Thanks go to Bart Schaefer! -isgrml && checkhome() { +isgrml && function checkhome () { if [[ -z "$ALREADY_DID_CD_HOME" ]] ; then export ALREADY_DID_CD_HOME=$HOME cd @@ -243,13 +247,13 @@ if ! [[ ${ZSH_VERSION} == 3.1.<7->* \ printf '-!- Ye been warned!\n' printf '-!-\n' - function zstyle() { : } + function zstyle () { : } fi # autoload wrapper - use this one instead of autoload directly # We need to define this function as early as this, because autoloading # 'is-at-least()' needs it. -function zrcautoload() { +function zrcautoload () { emulate -L zsh setopt extended_glob local fdir ffile @@ -270,10 +274,87 @@ function zrcautoload() { return 0 } +# The following is the ‘add-zsh-hook’ function from zsh upstream. It is +# included here to make the setup work with older versions of zsh (prior to +# 4.3.7) in which this function had a bug that triggers annoying errors during +# shell startup. This is exactly upstreams code from f0068edb4888a4d8fe94def, +# with just a few adjustments in coding style to make the function look more +# compact. This definition can be removed as soon as we raise the minimum +# version requirement to 4.3.7 or newer. +function add-zsh-hook () { + # Add to HOOK the given FUNCTION. + # HOOK is one of chpwd, precmd, preexec, periodic, zshaddhistory, + # zshexit, zsh_directory_name (the _functions subscript is not required). + # + # With -d, remove the function from the hook instead; delete the hook + # variable if it is empty. + # + # -D behaves like -d, but pattern characters are active in the function + # name, so any matching function will be deleted from the hook. + # + # Without -d, the FUNCTION is marked for autoload; -U is passed down to + # autoload if that is given, as are -z and -k. (This is harmless if the + # function is actually defined inline.) + emulate -L zsh + local -a hooktypes + hooktypes=( + chpwd precmd preexec periodic zshaddhistory zshexit + zsh_directory_name + ) + local usage="Usage: $0 hook function\nValid hooks are:\n $hooktypes" + local opt + local -a autoopts + integer del list help + while getopts "dDhLUzk" opt; do + case $opt in + (d) del=1 ;; + (D) del=2 ;; + (h) help=1 ;; + (L) list=1 ;; + ([Uzk]) autoopts+=(-$opt) ;; + (*) return 1 ;; + esac + done + shift $(( OPTIND - 1 )) + if (( list )); then + typeset -mp "(${1:-${(@j:|:)hooktypes}})_functions" + return $? + elif (( help || $# != 2 || ${hooktypes[(I)$1]} == 0 )); then + print -u$(( 2 - help )) $usage + return $(( 1 - help )) + fi + local hook="${1}_functions" + local fn="$2" + if (( del )); then + # delete, if hook is set + if (( ${(P)+hook} )); then + if (( del == 2 )); then + set -A $hook ${(P)hook:#${~fn}} + else + set -A $hook ${(P)hook:#$fn} + fi + # unset if no remaining entries --- this can give better + # performance in some cases + if (( ! ${(P)#hook} )); then + unset $hook + fi + fi + else + if (( ${(P)+hook} )); then + if (( ${${(P)hook}[(I)$fn]} == 0 )); then + set -A $hook ${(P)hook} $fn + fi + else + set -A $hook $fn + fi + autoload $autoopts -- $fn + fi +} + # Load is-at-least() for more precise version checks Note that this test will # *always* fail, if the is-at-least function could not be marked for # autoloading. -zrcautoload is-at-least || is-at-least() { return 1 } +zrcautoload is-at-least || function is-at-least () { return 1 } # set some important options (as early as possible) @@ -307,9 +388,6 @@ setopt extended_glob # display PID when suspending processes as well setopt longlistjobs -# try to avoid the 'zsh: no matches found...' -setopt nonomatch - # report the status of backgrounds jobs immediately setopt notify @@ -354,12 +432,12 @@ ZSH_NO_DEFAULT_LOCALE=${ZSH_NO_DEFAULT_LOCALE:-0} typeset -ga ls_options typeset -ga grep_options if ls --color=auto / >/dev/null 2>&1; then - ls_options=( --color=auto ) + ls_options+=( --color=auto ) elif ls -G / >/dev/null 2>&1; then - ls_options=( -G ) + ls_options+=( -G ) fi if grep --color=auto -q "a" <<< "a" >/dev/null 2>&1; then - grep_options=( --color=auto ) + grep_options+=( --color=auto ) fi # utility functions @@ -369,39 +447,38 @@ fi # Usage: check_com [-c|-g] word # -c only checks for external commands # -g does the usual tests and also checks for global aliases -check_com() { +function check_com () { emulate -L zsh local -i comonly gatoo + comonly=0 + gatoo=0 if [[ $1 == '-c' ]] ; then - (( comonly = 1 )) - shift + comonly=1 + shift 1 elif [[ $1 == '-g' ]] ; then - (( gatoo = 1 )) - else - (( comonly = 0 )) - (( gatoo = 0 )) + gatoo=1 + shift 1 fi if (( ${#argv} != 1 )) ; then - printf 'usage: check_com [-c] \n' >&2 + printf 'usage: check_com [-c|-g] \n' >&2 return 1 fi if (( comonly > 0 )) ; then - [[ -n ${commands[$1]} ]] && return 0 + (( ${+commands[$1]} )) && return 0 return 1 fi - if [[ -n ${commands[$1]} ]] \ - || [[ -n ${functions[$1]} ]] \ - || [[ -n ${aliases[$1]} ]] \ - || [[ -n ${reswords[(r)$1]} ]] ; then - + if (( ${+commands[$1]} )) \ + || (( ${+functions[$1]} )) \ + || (( ${+aliases[$1]} )) \ + || (( ${+reswords[(r)$1]} )) ; then return 0 fi - if (( gatoo > 0 )) && [[ -n ${galiases[$1]} ]] ; then + if (( gatoo > 0 )) && (( ${+galiases[$1]} )) ; then return 0 fi @@ -410,27 +487,26 @@ check_com() { # creates an alias and precedes the command with # sudo if $EUID is not zero. -salias() { +function salias () { emulate -L zsh local only=0 ; local multi=0 local key val - while [[ $1 == -* ]] ; do - case $1 in - (-o) only=1 ;; - (-a) multi=1 ;; - (--) shift ; break ;; - (-h) - printf 'usage: salias [-h|-o|-a] \n' + while getopts ":hao" opt; do + case $opt in + o) only=1 ;; + a) multi=1 ;; + h) + printf 'usage: salias [-hoa] \n' printf ' -h shows this help text.\n' printf ' -a replace '\'' ; '\'' sequences with '\'' ; sudo '\''.\n' printf ' be careful using this option.\n' printf ' -o only sets an alias if a preceding sudo would be needed.\n' return 0 ;; - (*) printf "unkown option: '%s'\n" "$1" ; return 1 ;; + *) salias -h >&2; return 1 ;; esac - shift done + shift "$((OPTIND-1))" if (( ${#argv} > 1 )) ; then printf 'Too many arguments %s\n' "${#argv}" @@ -448,32 +524,8 @@ salias() { return 0 } -# a "print -l ${(u)foo}"-workaround for pre-4.2.0 shells -# usage: uprint foo -# Where foo is the *name* of the parameter you want printed. -# Note that foo is no typo; $foo would be wrong here! -if ! is42 ; then - uprint () { - emulate -L zsh - local -a u - local w - local parameter=$1 - - if [[ -z ${parameter} ]] ; then - printf 'usage: uprint \n' - return 1 - fi - - for w in ${(P)parameter} ; do - [[ -z ${(M)u:#$w} ]] && u=( $u $w ) - done - - builtin print -l $u - } -fi - # Check if we can read given files and source those we can. -xsource() { +function xsource () { if (( ${#argv} < 1 )) ; then printf 'usage: xsource FILE(s)...\n' >&2 return 1 @@ -487,7 +539,7 @@ xsource() { } # Check if we can read a given file and 'cat(1)' it. -xcat() { +function xcat () { emulate -L zsh if (( ${#argv} != 1 )) ; then printf 'usage: xcat FILE\n' >&2 @@ -500,9 +552,10 @@ xcat() { # Remove these functions again, they are of use only in these # setup files. This should be called at the end of .zshrc. -xunfunction() { +function xunfunction () { emulate -L zsh local -a funcs + local func funcs=(salias xcat xsource xunfunction zrcautoload zrcautozle) for func in $funcs ; do [[ -n ${functions[$func]} ]] \ @@ -513,7 +566,7 @@ xunfunction() { # this allows us to stay in sync with grml's zshrc and put own # modifications in ~/.zshrc.local -zrclocal() { +function zrclocal () { xsource "/etc/zsh/zshrc.local" xsource "${ZDOTDIR:-${HOME}}/.zshrc.local" return 0 @@ -527,6 +580,7 @@ fi for var in LANG LC_ALL LC_MESSAGES ; do [[ -n ${(P)var} ]] && export $var done +builtin unset -v var # set some variables if check_com -c vim ; then @@ -542,14 +596,6 @@ export PAGER=${PAGER:-less} #v# export MAIL=${MAIL:-/var/mail/$USER} -# if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/ -if [[ -z "$SHELL" ]] ; then - SHELL="$(which zsh)" - if [[ -x "$SHELL" ]] ; then - export SHELL - fi -fi - # color setup for ls: check_com -c dircolors && eval $(dircolors -b) # color setup for ls on OS X / FreeBSD: @@ -569,13 +615,11 @@ isdarwin && xsource /sw/bin/init.sh # load our function and completion directories for fdir in /usr/share/grml/zsh/completion /usr/share/grml/zsh/functions; do fpath=( ${fdir} ${fdir}/**/*(/N) ${fpath} ) - if [[ ${fdir} == '/usr/share/grml/zsh/functions' ]] ; then - for func in ${fdir}/**/[^_]*[^~](N.) ; do - zrcautoload ${func:t} - done - fi done -unset fdir func +typeset -aU ffiles +ffiles=(/usr/share/grml/zsh/functions/**/[^_]*[^~](N.:t)) +(( ${#ffiles} > 0 )) && autoload -U "${ffiles[@]}" +unset -v fdir ffiles # support colors in less export LESS_TERMCAP_mb=$'\E[01;31m' @@ -597,13 +641,13 @@ REPORTTIME=5 watch=(notme root) # automatically remove duplicates from these arrays -typeset -U path cdpath fpath manpath +typeset -U path PATH cdpath CDPATH fpath FPATH manpath MANPATH # Load a few modules is4 && \ for mod in parameter complist deltochar mathfunc ; do zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :(" -done +done && builtin unset -v mod # autoload zsh modules when they are referenced if is4 ; then @@ -626,7 +670,7 @@ fi # called later (via is4 && grmlcomp) # note: use 'zstyle' for getting current settings # press ^xh (control-x h) for getting tags in context; ^x? (control-x ?) to run complete_debug with trace output -grmlcomp() { +function grmlcomp () { # TODO: This could use some additional information # Make sure the completion system is initialised @@ -729,7 +773,7 @@ grmlcomp() { zstyle ':completion:*' special-dirs .. # run rehash on completion so new installed program are found automatically: - _force_rehash() { + function _force_rehash () { (( CURRENT == 1 )) && rehash return 1 } @@ -758,20 +802,30 @@ grmlcomp() { # command for process lists, the local web server details and host completion zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html' - # caching - [[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \ - zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/ + # Some functions, like _apt and _dpkg, are very slow. We can use a cache in + # order to speed things up + if [[ ${GRML_COMP_CACHING:-yes} == yes ]]; then + GRML_COMP_CACHE_DIR=${GRML_COMP_CACHE_DIR:-${ZDOTDIR:-$HOME}/.cache} + if [[ ! -d ${GRML_COMP_CACHE_DIR} ]]; then + command mkdir -p "${GRML_COMP_CACHE_DIR}" + fi + zstyle ':completion:*' use-cache yes + zstyle ':completion:*:complete:*' cache-path "${GRML_COMP_CACHE_DIR}" + fi # host completion if is42 ; then + [[ -r ~/.ssh/config ]] && _ssh_config_hosts=(${${(s: :)${(ps:\t:)${${(@M)${(f)"$(<$HOME/.ssh/config)"}:#Host *}#Host }}}:#*[*?]*}) || _ssh_config_hosts=() [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=() [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(, Bernhard Tittelbach -beginning-or-end-of-somewhere() { +function beginning-or-end-of-somewhere () { local hno=$HISTNO if [[ ( "${LBUFFER[-1]}" == $'\n' && "${WIDGET}" == beginning-of* ) || \ ( "${RBUFFER[1]}" == $'\n' && "${WIDGET}" == end-of* ) ]]; then @@ -826,14 +880,14 @@ zle -N beginning-of-somewhere beginning-or-end-of-somewhere zle -N end-of-somewhere beginning-or-end-of-somewhere # add a command line to the shells history without executing it -commit-to-history() { +function commit-to-history () { print -s ${(z)BUFFER} zle send-break } zle -N commit-to-history # only slash should be considered as a word separator: -slash-backward-kill-word() { +function slash-backward-kill-word () { local WORDCHARS="${WORDCHARS:s@/@}" # zle backward-word zle backward-kill-word @@ -859,7 +913,7 @@ zle -N slash-backward-kill-word # find the first word on the command line in the $command[] hash. zstyle ':acceptline:*' rehash true -function Accept-Line() { +function Accept-Line () { setopt localoptions noksharrays local -a subs local -xi aldone @@ -879,7 +933,7 @@ function Accept-Line() { done } -function Accept-Line-getdefault() { +function Accept-Line-getdefault () { emulate -L zsh local default_action @@ -894,7 +948,7 @@ function Accept-Line-getdefault() { esac } -function Accept-Line-HandleContext() { +function Accept-Line-HandleContext () { zle Accept-Line default_action=$(Accept-Line-getdefault) @@ -902,9 +956,9 @@ function Accept-Line-HandleContext() { && zle ${default_action} } -function accept-line() { +function accept-line () { setopt localoptions noksharrays - local -ax cmdline + local -a cmdline local -x alcontext local buf com fname format msg default_action @@ -1016,7 +1070,7 @@ abk=( 'co' './configure && make && sudo make install' ) -zleiab() { +function zleiab () { emulate -L zsh setopt extendedglob local MATCH @@ -1027,22 +1081,21 @@ zleiab() { zle -N zleiab -help-show-abk() -{ +function help-show-abk () { zle -M "$(print "Available abbreviations for expansion:"; print -a -C 2 ${(kv)abk})" } zle -N help-show-abk # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd -insert-datestamp() { LBUFFER+=${(%):-'%D{%Y-%m-%d}'}; } +function insert-datestamp () { LBUFFER+=${(%):-'%D{%Y-%m-%d}'}; } zle -N insert-datestamp # press esc-m for inserting last typed word again (thanks to caphuso!) -insert-last-typed-word() { zle insert-last-word -- 0 -1 }; +function insert-last-typed-word () { zle insert-last-word -- 0 -1 }; zle -N insert-last-typed-word; -function grml-zsh-fg() { +function grml-zsh-fg () { if (( ${#jobstates} )); then zle .push-input [[ -o hist_ignore_space ]] && BUFFER=' ' || BUFFER='' @@ -1055,7 +1108,7 @@ function grml-zsh-fg() { zle -N grml-zsh-fg # run command line as user root via sudo: -sudo-command-line() { +function sudo-command-line () { [[ -z $BUFFER ]] && zle up-history if [[ $BUFFER != sudo\ * ]]; then BUFFER="sudo $BUFFER" @@ -1066,7 +1119,7 @@ zle -N sudo-command-line ### jump behind the first word on the cmdline. ### useful to add options. -function jump_after_first_word() { +function jump_after_first_word () { local words words=(${(z)BUFFER}) @@ -1079,7 +1132,7 @@ function jump_after_first_word() { zle -N jump_after_first_word #f5# Create directory under cursor or the selected area -inplaceMkDirs() { +function inplaceMkDirs () { # Press ctrl-xM to create the directory under the cursor or the selected area. # To select an area press ctrl-@ or ctrl-space and use the cursor. # Use case: you type "mv abc ~/testa/testb/testc/" and remember that the @@ -1118,8 +1171,7 @@ HELP_LINES_PER_PAGE=20 #v1# set location of help-zle cache file HELP_ZLE_CACHE_FILE=~/.cache/zsh_help_zle_lines.zsh # helper function for help-zle, actually generates the help text -help_zle_parse_keybindings() -{ +function help_zle_parse_keybindings () { emulate -L zsh setopt extendedglob unsetopt ksharrays #indexing starts at 1 @@ -1129,6 +1181,7 @@ help_zle_parse_keybindings() if [[ -r $HELP_ZLE_CACHE_FILE ]]; then local load_cache=0 + local f for f ($HELPZLE_KEYBINDING_FILES) [[ $f -nt $HELP_ZLE_CACHE_FILE ]] && load_cache=1 [[ $load_cache -eq 0 ]] && . $HELP_ZLE_CACHE_FILE && return fi @@ -1170,7 +1223,7 @@ help_zle_parse_keybindings() typeset -g -a help_zle_lines typeset -g help_zle_sln=1 - local k v + local k v f cline local lastkeybind_desc contents #last description starting with #k# that we found local num_lines_elapsed=0 #number of lines between last description and keybinding #search config files in the order they a called (and thus the order in which they overwrite keybindings) @@ -1219,8 +1272,7 @@ typeset -g help_zle_sln typeset -g -a help_zle_lines # Provides (partially autogenerated) help on keybindings and the zsh line editor -help-zle() -{ +function help-zle () { emulate -L zsh unsetopt ksharrays #indexing starts at 1 #help lines already generated ? no ? then do it @@ -1236,7 +1288,7 @@ zle -N help-zle ## complete word from currently visible Screen or Tmux buffer. if check_com -c screen || check_com -c tmux; then - _complete_screen_display() { + function _complete_screen_display () { [[ "$TERM" != "screen" ]] && return 1 local TMPFILE=$(mktemp) @@ -1267,17 +1319,17 @@ fi # Load a few more functions and tie them to widgets, so they can be bound: -function zrcautozle() { +function zrcautozle () { emulate -L zsh local fnc=$1 zrcautoload $fnc && zle -N $fnc } -function zrcgotwidget() { +function zrcgotwidget () { (( ${+widgets[$1]} )) } -function zrcgotkeymap() { +function zrcgotkeymap () { [[ -n ${(M)keymaps:#$1} ]] } @@ -1296,7 +1348,7 @@ zstyle ':completion:hist-complete:*' completer _history # An array to note missing features to ease diagnosis in case of problems. typeset -ga grml_missing_features -function zrcbindkey() { +function zrcbindkey () { if (( ARGC )) && zrcgotwidget ${argv[-1]}; then bindkey "$@" fi @@ -1393,7 +1445,6 @@ bind2maps emacs -- Left backward-char bind2maps viins vicmd -- Left vi-backward-char bind2maps emacs -- Right forward-char bind2maps viins vicmd -- Right vi-forward-char -bind2maps viins vicmd -- Right vi-forward-char #k# Perform abbreviation expansion bind2maps emacs viins -- -s '^x.' zleiab #k# Display list of abbreviations that would expand @@ -1451,6 +1502,7 @@ if zrcgotwidget history-incremental-pattern-search-backward; then do bind2maps emacs viins vicmd -- -s $seq $wid done + builtin unset -v seq wid fi if zrcgotkeymap menuselect; then @@ -1512,14 +1564,14 @@ alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magi #m# k ESC-h Call \kbd{run-help} for the 1st word on the command line alias run-help >&/dev/null && unalias run-help -for rh in run-help{,-git,-svk,-svn}; do +for rh in run-help{,-git,-ip,-openssl,-p4,-sudo,-svk,-svn}; do zrcautoload $rh done; unset rh # command not found handling (( ${COMMAND_NOT_FOUND} == 1 )) && -function command_not_found_handler() { +function command_not_found_handler () { emulate -L zsh if [[ -x ${GRML_ZSH_CNF_HANDLER} ]] ; then ${GRML_ZSH_CNF_HANDLER} $1 @@ -1529,8 +1581,6 @@ function command_not_found_handler() { # history -ZSHDIR=${ZDOTDIR:-${HOME}/.zsh} - #v# HISTFILE=${ZDOTDIR:-${HOME}}/.zsh_history isgrmlcd && HISTSIZE=500 || HISTSIZE=5000 @@ -1541,22 +1591,54 @@ isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history DIRSTACKSIZE=${DIRSTACKSIZE:-20} DIRSTACKFILE=${DIRSTACKFILE:-${ZDOTDIR:-${HOME}}/.zdirs} -if [[ -f ${DIRSTACKFILE} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then - dirstack=( ${(f)"$(< $DIRSTACKFILE)"} ) - # "cd -" won't work after login by just setting $OLDPWD, so - [[ -d $dirstack[1] ]] && cd $dirstack[1] && cd $OLDPWD -fi +if zstyle -T ':grml:chpwd:dirstack' enable; then + typeset -gaU GRML_PERSISTENT_DIRSTACK + function grml_dirstack_filter () { + local -a exclude + local filter entry + if zstyle -s ':grml:chpwd:dirstack' filter filter; then + $filter $1 && return 0 + fi + if zstyle -a ':grml:chpwd:dirstack' exclude exclude; then + for entry in "${exclude[@]}"; do + [[ $1 == ${~entry} ]] && return 0 + done + fi + return 1 + } -chpwd() { - if (( $DIRSTACKSIZE <= 0 )) || [[ -z $DIRSTACKFILE ]]; then return; fi - local -ax my_stack - my_stack=( ${PWD} ${dirstack} ) - if is42 ; then - builtin print -l ${(u)my_stack} >! ${DIRSTACKFILE} + function chpwd () { + (( ZSH_SUBSHELL )) && return + (( $DIRSTACKSIZE <= 0 )) && return + [[ -z $DIRSTACKFILE ]] && return + grml_dirstack_filter $PWD && return + GRML_PERSISTENT_DIRSTACK=( + $PWD "${(@)GRML_PERSISTENT_DIRSTACK[1,$DIRSTACKSIZE]}" + ) + builtin print -l ${GRML_PERSISTENT_DIRSTACK} >! ${DIRSTACKFILE} + } + + if [[ -f ${DIRSTACKFILE} ]]; then + # Enabling NULL_GLOB via (N) weeds out any non-existing + # directories from the saved dir-stack file. + dirstack=( ${(f)"$(< $DIRSTACKFILE)"}(N) ) + # "cd -" won't work after login by just setting $OLDPWD, so + [[ -d $dirstack[1] ]] && cd -q $dirstack[1] && cd -q $OLDPWD + fi + + if zstyle -t ':grml:chpwd:dirstack' filter-on-load; then + for i in "${dirstack[@]}"; do + if ! grml_dirstack_filter "$i"; then + GRML_PERSISTENT_DIRSTACK=( + "${GRML_PERSISTENT_DIRSTACK[@]}" + $i + ) + fi + done else - uprint my_stack >! ${DIRSTACKFILE} + GRML_PERSISTENT_DIRSTACK=( "${dirstack[@]}" ) fi -} +fi # directory based profiles @@ -1571,7 +1653,7 @@ if is433 ; then # chpwd_profiles # # For details see the `grmlzshrc.5' manual page. -function chpwd_profiles() { +function chpwd_profiles () { local profile context local -i reexecute @@ -1651,7 +1733,7 @@ PS4='+%N:%i:%_> ' # display battery status on right side of prompt using 'GRML_DISPLAY_BATTERY=1' in .zshrc.pre -battery() { +function battery () { if [[ $GRML_DISPLAY_BATTERY -gt 0 ]] ; then if islinux ; then batterylinux @@ -1668,13 +1750,19 @@ if [[ $GRML_DISPLAY_BATTERY -gt 0 ]] ; then fi } -batterylinux(){ +function batterylinux () { GRML_BATTERY_LEVEL='' local batteries bat capacity batteries=( /sys/class/power_supply/BAT*(N) ) if (( $#batteries > 0 )) ; then for bat in $batteries ; do - capacity=$(< $bat/capacity) + if [[ -e $bat/capacity ]]; then + capacity=$(< $bat/capacity) + else + typeset -F energy_full=$(< $bat/energy_full) + typeset -F energy_now=$(< $bat/energy_now) + typeset -i capacity=$(( 100 * $energy_now / $energy_full)) + fi case $(< $bat/status) in Charging) GRML_BATTERY_LEVEL+=" ^" @@ -1695,11 +1783,11 @@ if (( $#batteries > 0 )) ; then fi } -batteryopenbsd(){ +function batteryopenbsd () { GRML_BATTERY_LEVEL='' local bat batfull batwarn batnow num for num in 0 1 ; do - bat=$(sysctl -n hw.sensors.acpibat${num}) + bat=$(sysctl -n hw.sensors.acpibat${num} 2>/dev/null) if [[ -n $bat ]]; then batfull=${"$(sysctl -n hw.sensors.acpibat${num}.amphour0)"%% *} batwarn=${"$(sysctl -n hw.sensors.acpibat${num}.amphour1)"%% *} @@ -1724,7 +1812,7 @@ for num in 0 1 ; do done } -batteryfreebsd(){ +function batteryfreebsd () { GRML_BATTERY_LEVEL='' local num local -A table @@ -1751,7 +1839,7 @@ for num in 0 1 ; do done } -batterydarwin(){ +function batterydarwin () { GRML_BATTERY_LEVEL='' local -a table table=( ${$(pmset -g ps)[(w)7,8]%%(\%|);} ) @@ -1817,7 +1905,7 @@ grml_vcs_coloured_formats=( typeset GRML_VCS_COLOUR_MODE=xxx -grml_vcs_info_toggle_colour () { +function grml_vcs_info_toggle_colour () { emulate -L zsh if [[ $GRML_VCS_COLOUR_MODE == plain ]]; then grml_vcs_info_set_formats coloured @@ -1827,7 +1915,7 @@ grml_vcs_info_toggle_colour () { return 0 } -grml_vcs_info_set_formats () { +function grml_vcs_info_set_formats () { emulate -L zsh #setopt localoptions xtrace local mode=$1 AF F BF @@ -1870,7 +1958,7 @@ fi # below, which gets called when the user does this: prompt -h grml function prompt_grml_help () { - cat <<__EOF0__ + <<__EOF0__ prompt grml This is the prompt as used by the grml-live system . It is @@ -1927,7 +2015,7 @@ __EOF0__ } function prompt_grml-chroot_help () { - cat <<__EOF0__ + <<__EOF0__ prompt grml-chroot This is a variation of the grml prompt, see: prompt -h grml @@ -1941,7 +2029,7 @@ __EOF0__ } function prompt_grml-large_help () { - cat <<__EOF0__ + <<__EOF0__ prompt grml-large This is a variation of the grml prompt, see: prompt -h grml @@ -1960,7 +2048,10 @@ __EOF0__ function grml_prompt_setup () { emulate -L zsh autoload -Uz vcs_info - autoload -Uz add-zsh-hook + # The following autoload is disabled for now, since this setup includes a + # static version of the ‘add-zsh-hook’ function above. It needs to be + # reenabled as soon as that static definition is removed again. + #autoload -Uz add-zsh-hook add-zsh-hook precmd prompt_$1_precmd } @@ -2056,7 +2147,7 @@ function grml_theme_has_token () { } function GRML_theme_add_token_usage () { - cat <<__EOF__ + <<__EOF0__ Usage: grml_theme_add_token [-f|-i] [
 ]
 
      is the name for the newly added token. If the \`-f' or \`-i' options
@@ -2097,7 +2188,7 @@ function GRML_theme_add_token_usage () {
 
     After that, you will be able to use a changed \`items' style to
     assemble your prompt.
-__EOF__
+__EOF0__
 }
 
 function grml_theme_add_token () {
@@ -2268,11 +2359,9 @@ function prompt_grml_precmd_worker () {
     fi
 }
 
-grml_prompt_fallback() {
+function grml_prompt_fallback () {
     setopt prompt_subst
-    precmd() {
-        (( ${+functions[vcs_info]} )) && vcs_info
-    }
+    local p0 p1
 
     p0="${RED}%(?..%? )${WHITE}${debian_chroot:+($debian_chroot)}"
     p1="${BLUE}%n${NO_COLOR}@%m %40<...<%B%~%b%<< "'${vcs_info_msg_0_}'"%# "
@@ -2281,7 +2370,6 @@ grml_prompt_fallback() {
     else
         PROMPT="${RED}${p0}${BLUE}${p1}"
     fi
-    unset p0 p1
 }
 
 if zrcautoload promptinit && promptinit 2>/dev/null ; then
@@ -2294,6 +2382,7 @@ if zrcautoload promptinit && promptinit 2>/dev/null ; then
 else
     print 'Notice: no promptinit available :('
     grml_prompt_fallback
+    function precmd () { (( ${+functions[vcs_info]} )) && vcs_info; }
 fi
 
 if is437; then
@@ -2326,6 +2415,7 @@ if is437; then
     fi
 else
     grml_prompt_fallback
+    function precmd () { (( ${+functions[vcs_info]} )) && vcs_info; }
 fi
 
 # Terminal-title wizardry
@@ -2392,7 +2482,10 @@ function grml_control_xterm_title () {
     esac
 }
 
-zrcautoload add-zsh-hook || add-zsh-hook () { :; }
+# The following autoload is disabled for now, since this setup includes a
+# static version of the ‘add-zsh-hook’ function above. It needs to be
+# reenabled as soon as that static definition is removed again.
+#zrcautoload add-zsh-hook || add-zsh-hook () { :; }
 if [[ $NOPRECMD -eq 0 ]]; then
     add-zsh-hook precmd grml_reset_screen_title
     add-zsh-hook precmd grml_vcs_to_screen_title
@@ -2418,16 +2511,14 @@ hash -d www=/var/www
 if check_com -c screen ; then
     if [[ $UID -eq 0 ]] ; then
         if [[ -r /etc/grml/screenrc ]]; then
-            alias screen="${commands[screen]} -c /etc/grml/screenrc"
+            alias screen='screen -c /etc/grml/screenrc'
         fi
-    elif [[ -r $HOME/.screenrc ]] ; then
-        alias screen="${commands[screen]} -c $HOME/.screenrc"
-    else
+    elif [[ ! -r $HOME/.screenrc ]] ; then
         if [[ -r /etc/grml/screenrc_grml ]]; then
-            alias screen="${commands[screen]} -c /etc/grml/screenrc_grml"
+            alias screen='screen -c /etc/grml/screenrc_grml'
         else
             if [[ -r /etc/grml/screenrc ]]; then
-                alias screen="${commands[screen]} -c /etc/grml/screenrc"
+                alias screen='screen -c /etc/grml/screenrc'
             fi
         fi
     fi
@@ -2435,25 +2526,27 @@ fi
 
 # do we have GNU ls with color-support?
 if [[ "$TERM" != dumb ]]; then
-    #a1# List files with colors (\kbd{ls -F \ldots})
-    alias ls='command ls -F '${ls_options:+"${ls_options[*]}"}
+    #a1# List files with colors (\kbd{ls \ldots})
+    alias ls="command ls ${ls_options:+${ls_options[*]}}"
     #a1# List all files, with colors (\kbd{ls -la \ldots})
-    alias la='command ls -la '${ls_options:+"${ls_options[*]}"}
+    alias la="command ls -la ${ls_options:+${ls_options[*]}}"
     #a1# List files with long colored list, without dotfiles (\kbd{ls -l \ldots})
-    alias ll='command ls -l '${ls_options:+"${ls_options[*]}"}
+    alias ll="command ls -l ${ls_options:+${ls_options[*]}}"
     #a1# List files with long colored list, human readable sizes (\kbd{ls -hAl \ldots})
-    alias lh='command ls -hAl '${ls_options:+"${ls_options[*]}"}
-    #a1# List files with long colored list, append qualifier to filenames (\kbd{ls -lF \ldots})\\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
-    alias l='command ls -lF '${ls_options:+"${ls_options[*]}"}
+    alias lh="command ls -hAl ${ls_options:+${ls_options[*]}}"
+    #a1# List files with long colored list, append qualifier to filenames (\kbd{ls -l \ldots})\\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
+    alias l="command ls -l ${ls_options:+${ls_options[*]}}"
 else
-    alias ls='command ls -F'
     alias la='command ls -la'
     alias ll='command ls -l'
     alias lh='command ls -hAl'
-    alias l='command ls -lF'
+    alias l='command ls -l'
+fi
+
+if [[ -r /proc/mdstat ]]; then
+    alias mdstat='cat /proc/mdstat'
 fi
 
-alias mdstat='cat /proc/mdstat'
 alias ...='cd ../../'
 
 # generate alias named "$KERNELVERSION-reboot" so you can use boot with kexec:
@@ -2467,8 +2560,9 @@ alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
 
 # make sure it is not assigned yet
 [[ -n ${aliases[utf2iso]} ]] && unalias utf2iso
-utf2iso() {
+function utf2iso () {
     if isutfenv ; then
+        local ENV
         for ENV in $(env | command grep -i '.utf') ; do
             eval export "$(echo $ENV | sed 's/UTF-8/iso885915/ ; s/utf8/iso885915/')"
         done
@@ -2477,8 +2571,9 @@ utf2iso() {
 
 # make sure it is not assigned yet
 [[ -n ${aliases[iso2utf]} ]] && unalias iso2utf
-iso2utf() {
+function iso2utf () {
     if ! isutfenv ; then
+        local ENV
         for ENV in $(env | command grep -i '\.iso') ; do
             eval export "$(echo $ENV | sed 's/iso.*/UTF-8/ ; s/ISO.*/UTF-8/')"
         done
@@ -2487,12 +2582,12 @@ iso2utf() {
 
 # especially for roadwarriors using GNU screen and ssh:
 if ! check_com asc &>/dev/null ; then
-  asc() { autossh -t "$@" 'screen -RdU' }
+  function asc () { autossh -t "$@" 'screen -RdU' }
   compdef asc=ssh
 fi
 
 #f1# Hints for the use of zsh on grml
-zsh-help() {
+function zsh-help () {
     print "$bg[white]$fg[black]
 zsh-help - hints for use of zsh on grml
 =======================================$reset_color"
@@ -2561,38 +2656,54 @@ Enjoy your grml system with the zsh!$reset_color"
 
 # debian stuff
 if [[ -r /etc/debian_version ]] ; then
-    #a3# Execute \kbd{apt-cache search}
-    alias acs='apt-cache search'
-    #a3# Execute \kbd{apt-cache show}
-    alias acsh='apt-cache show'
-    #a3# Execute \kbd{apt-cache policy}
-    alias acp='apt-cache policy'
-    #a3# Execute \kbd{apt-get dist-upgrade}
-    salias adg="apt-get dist-upgrade"
-    #a3# Execute \kbd{apt-get install}
-    salias agi="apt-get install"
-    #a3# Execute \kbd{aptitude install}
-    salias ati="aptitude install"
-    #a3# Execute \kbd{apt-get upgrade}
-    salias ag="apt-get upgrade"
-    #a3# Execute \kbd{apt-get update}
-    salias au="apt-get update"
-    #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
-    salias -a up="aptitude update ; aptitude safe-upgrade"
-    #a3# Execute \kbd{dpkg-buildpackage}
-    alias dbp='dpkg-buildpackage'
-    #a3# Execute \kbd{grep-excuses}
-    alias ge='grep-excuses'
+    if [[ -z "$GRML_NO_APT_ALIASES" ]]; then
+        #a3# Execute \kbd{apt-cache search}
+        alias acs='apt-cache search'
+        #a3# Execute \kbd{apt-cache show}
+        alias acsh='apt-cache show'
+        #a3# Execute \kbd{apt-cache policy}
+        alias acp='apt-cache policy'
+        if check_com -c apt ; then
+	  #a3# Execute \kbd{apt dist-upgrade}
+	  salias adg="apt dist-upgrade"
+	  #a3# Execute \kbd{apt upgrade}
+	  salias ag="apt upgrade"
+	  #a3# Execute \kbd{apt install}
+	  salias agi="apt install"
+	  #a3# Execute \kbd{apt-get update}
+	  salias au="apt update"
+	else
+	  salias adg="apt-get dist-upgrade"
+	  salias ag="apt-get upgrade"
+	  salias agi="apt-get install"
+	  salias au="apt-get update"
+	fi
+        #a3# Execute \kbd{aptitude install}
+        salias ati="aptitude install"
+        #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
+        salias -a up="aptitude update ; aptitude safe-upgrade"
+        #a3# Execute \kbd{dpkg-buildpackage}
+        alias dbp='dpkg-buildpackage'
+        #a3# Execute \kbd{grep-excuses}
+        alias ge='grep-excuses'
+    fi
 
     # get a root shell as normal user in live-cd mode:
     if isgrmlcd && [[ $UID -ne 0 ]] ; then
        alias su="sudo su"
-     fi
+    fi
 
-    #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
-    salias llog="$PAGER /var/log/syslog"     # take a look at the syslog
-    #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
-    salias tlog="tail -f /var/log/syslog"    # follow the syslog
+fi
+
+# use /var/log/syslog iff present, fallback to journalctl otherwise
+if [ -e /var/log/syslog ] ; then
+  #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog || journalctl}
+  salias llog="$PAGER /var/log/syslog"     # take a look at the syslog
+  #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog || journalctl}
+  salias tlog="tail -f /var/log/syslog"    # follow the syslog
+elif check_com -c journalctl ; then
+  salias llog="journalctl"
+  salias tlog="journalctl -f"
 fi
 
 # sort installed Debian-packages by size
@@ -2604,29 +2715,28 @@ fi
 # if cdrecord is a symlink (to wodim) or isn't present at all warn:
 if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord; then
     if check_com -c wodim; then
-        cdrecord() {
-            cat <\n' "$0" && return 1
-    local file
-    for file in "$@" ; do
+#
+# Usage:
+#
+#      e.g.:   a -> b -> c -> d  ....
+#
+#      sll a
+#
+#
+#      if parameter is given with leading '=', lookup $PATH for parameter and resolve that
+#
+#      sll =java
+#
+#      Note: limit for recursive symlinks on linux:
+#            http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/namei.c?id=refs/heads/master#l808
+#            This limits recursive symlink follows to 8,
+#            while limiting consecutive symlinks to 40.
+#
+#      When resolving and displaying information about symlinks, no check is made
+#      that the displayed information does make any sense on your OS.
+#      We leave that decission to the user.
+#
+#      The zstat module is used to detect symlink loops. zstat is available since zsh4.
+#      With an older zsh you will need to abort with  in that case.
+#      When a symlink loop is detected, a warning ist printed and further processing is stopped.
+#
+#      Module zstat is loaded by default in grml zshrc, no extra action needed for that.
+#
+#      Known bugs:
+#      If you happen to come accross a symlink that points to a destination on an other partition
+#      with the same inode number, that will be marked as symlink loop though it is not.
+#      Two hints for this situation:
+#      I)  Play lottery the same day, as you seem to be rather lucky right now.
+#      II) Send patches.
+#
+#      return status:
+#      0 upon success
+#      1 file/dir not accesible
+#      2 symlink loop detected
+#
+#f1# List symlinks in detail (more detailed version of 'readlink -f', 'whence -s' and 'namei -l')
+function sll () {
+    if [[ -z ${1} ]] ; then
+        printf 'Usage: %s \n' "${0}"
+        return 1
+    fi
+
+    local file jumpd curdir
+    local -i 10 RTN LINODE i
+    local -a    SEENINODES
+    curdir="${PWD}"
+    RTN=0
+
+    for file in "${@}" ; do
+        SEENINODES=()
+        ls -l "${file:a}"   || RTN=1
+
         while [[ -h "$file" ]] ; do
-            ls -l $file
+            if is4 ; then
+                LINODE=$(zstat -L +inode "${file}")
+                for i in ${SEENINODES} ; do
+                    if (( ${i} == ${LINODE} )) ; then
+                        builtin cd -q "${curdir}"
+                        print 'link loop detected, aborting!'
+                        return 2
+                    fi
+                done
+                SEENINODES+=${LINODE}
+            fi
+            jumpd="${file:h}"
+            file="${file:t}"
+
+            if [[ -d ${jumpd} ]] ; then
+                builtin cd -q "${jumpd}"  || RTN=1
+            fi
             file=$(readlink "$file")
+
+            jumpd="${file:h}"
+            file="${file:t}"
+
+            if [[ -d ${jumpd} ]] ; then
+                builtin cd -q "${jumpd}"  || RTN=1
+            fi
+
+            ls -l "${PWD}/${file}"     || RTN=1
         done
+        shift 1
+        if (( ${#} >= 1 )) ; then
+            print ""
+        fi
+        builtin cd -q "${curdir}"
     done
+    return ${RTN}
 }
 
 # TODO: Is it supported to use pager settings like this?
@@ -2689,7 +2881,7 @@ sll() {
 # with respect to wordsplitting. (ie. ${=PAGER})
 if check_com -c $PAGER ; then
     #f3# View Debian's changelog of given package(s)
-    dchange() {
+    function dchange () {
         emulate -L zsh
         [[ -z "$1" ]] && printf 'Usage: %s \n' "$0" && return 1
 
@@ -2714,11 +2906,11 @@ if check_com -c $PAGER ; then
             fi
         done
     }
-    _dchange() { _files -W /usr/share/doc -/ }
+    function _dchange () { _files -W /usr/share/doc -/ }
     compdef _dchange dchange
 
     #f3# View Debian's NEWS of a given package
-    dnews() {
+    function dnews () {
         emulate -L zsh
         if [[ -r /usr/share/doc/$1/NEWS.Debian.gz ]] ; then
             $PAGER /usr/share/doc/$1/NEWS.Debian.gz
@@ -2731,11 +2923,11 @@ if check_com -c $PAGER ; then
             fi
         fi
     }
-    _dnews() { _files -W /usr/share/doc -/ }
+    function _dnews () { _files -W /usr/share/doc -/ }
     compdef _dnews dnews
 
     #f3# View Debian's copyright of a given package
-    dcopyright() {
+    function dcopyright () {
         emulate -L zsh
         if [[ -r /usr/share/doc/$1/copyright ]] ; then
             $PAGER /usr/share/doc/$1/copyright
@@ -2744,11 +2936,11 @@ if check_com -c $PAGER ; then
             return 1
         fi
     }
-    _dcopyright() { _files -W /usr/share/doc -/ }
+    function _dcopyright () { _files -W /usr/share/doc -/ }
     compdef _dcopyright dcopyright
 
     #f3# View upstream's changelog of a given package
-    uchange() {
+    function uchange () {
         emulate -L zsh
         if [[ -r /usr/share/doc/$1/changelog.gz ]] ; then
             $PAGER /usr/share/doc/$1/changelog.gz
@@ -2757,36 +2949,36 @@ if check_com -c $PAGER ; then
             return 1
         fi
     }
-    _uchange() { _files -W /usr/share/doc -/ }
+    function _uchange () { _files -W /usr/share/doc -/ }
     compdef _uchange uchange
 fi
 
 # zsh profiling
-profile() {
-    ZSH_PROFILE_RC=1 $SHELL "$@"
+function profile () {
+    ZSH_PROFILE_RC=1 zsh "$@"
 }
 
 #f1# Edit an alias via zle
-edalias() {
+function edalias () {
     [[ -z "$1" ]] && { echo "Usage: edalias " ; return 1 } || vared aliases'[$1]' ;
 }
 compdef _aliases edalias
 
 #f1# Edit a function via zle
-edfunc() {
+function edfunc () {
     [[ -z "$1" ]] && { echo "Usage: edfunc " ; return 1 } || zed -f "$1" ;
 }
 compdef _functions edfunc
 
 # use it e.g. via 'Restart apache2'
-#m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
-#m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
-#m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
-#m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
-#m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
-#m# f6 Status() \kbd{/etc/init.d/\em{process}}\quad\kbd{status}
+#m# f6 Start() \kbd{service \em{process}}\quad\kbd{start}
+#m# f6 Restart() \kbd{service \em{process}}\quad\kbd{restart}
+#m# f6 Stop() \kbd{service \em{process}}\quad\kbd{stop}
+#m# f6 Reload() \kbd{service \em{process}}\quad\kbd{reload}
+#m# f6 Force-Reload() \kbd{service \em{process}}\quad\kbd{force-reload}
+#m# f6 Status() \kbd{service \em{process}}\quad\kbd{status}
 if [[ -d /etc/init.d || -d /etc/service ]] ; then
-    __start_stop() {
+    function __start_stop () {
         local action_="${1:l}"  # e.g Start/Stop/Restart
         local service_="$2"
         local param_="$3"
@@ -2805,25 +2997,30 @@ if [[ -d /etc/init.d || -d /etc/service ]] ; then
                 *) $SUDO "/etc/init.d/$service_" "${action_}" "$param_" ;;
             esac
         else
-            # sysvinit
-            $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
+            # sysv/sysvinit-utils, upstart
+            if check_com -c service ; then
+              $SUDO service "$service_" "${action_}" "$param_"
+            else
+              $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
+            fi
         fi
     }
 
-    _grmlinitd() {
+    function _grmlinitd () {
         local -a scripts
         scripts=( /etc/init.d/*(x:t) )
         _describe "service startup script" scripts
     }
 
     for i in Start Restart Stop Force-Reload Reload Status ; do
-        eval "$i() { __start_stop $i \"\$1\" \"\$2\" ; }"
+        eval "function $i () { __start_stop $i \"\$1\" \"\$2\" ; }"
         compdef _grmlinitd $i
     done
+    builtin unset -v i
 fi
 
 #f1# Provides useful information on globbing
-H-Glob() {
+function H-Glob () {
     echo -e "
     /      directories
     .      plain files
@@ -2864,7 +3061,7 @@ H-Glob() {
 alias help-zshglob=H-Glob
 
 # grep for running process, like: 'any vim'
-any() {
+function any () {
     emulate -L zsh
     unsetopt KSH_ARRAYS
     if [[ -z "$1" ]] ; then
@@ -2879,7 +3076,7 @@ any() {
 # After resuming from suspend, system is paging heavily, leading to very bad interactivity.
 # taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
 [[ -r /proc/1/maps ]] && \
-deswap() {
+function deswap () {
     print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
     cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
     print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
@@ -2893,7 +3090,7 @@ deswap() {
 #       This will cause vim to send every file given on the
 #       commandline to be send to it's own tab (needs vim7).
 if check_com vim; then
-    vim() {
+    function vim () {
         VIM_PLEASE_SET_TITLE='yes' command vim ${VIM_OPTIONS} "$@"
     }
 fi
@@ -2911,7 +3108,7 @@ for sh in ${ssl_hashes}; do
     }'
 done; unset sh
 
-ssl-cert-fingerprints() {
+function ssl-cert-fingerprints () {
     emulate -L zsh
     local i
     if [[ -z $1 ]] ; then
@@ -2923,7 +3120,7 @@ ssl-cert-fingerprints() {
     done
 }
 
-ssl-cert-info() {
+function ssl-cert-info () {
     emulate -L zsh
     if [[ -z $1 ]] ; then
         printf 'usage: ssl-cert-info \n'
@@ -2934,13 +3131,17 @@ ssl-cert-info() {
 }
 
 # make sure our environment is clean regarding colors
-for color in BLUE RED GREEN CYAN YELLOW MAGENTA WHITE ; unset $color
+builtin unset -v BLUE RED GREEN CYAN YELLOW MAGENTA WHITE NO_COLOR
 
 # "persistent history"
-# just write important commands you always need to ~/.important_commands
+# just write important commands you always need to $GRML_IMPORTANT_COMMANDS
+# defaults for backward compatibility to ~/.important_commands
 if [[ -r ~/.important_commands ]] ; then
-    fc -R ~/.important_commands
+    GRML_IMPORTANT_COMMANDS=~/.important_commands
+else
+    GRML_IMPORTANT_COMMANDS=${GRML_IMPORTANT_COMMANDS:-${ZDOTDIR:-${HOME}}/.important_commands}
 fi
+[[ -r ${GRML_IMPORTANT_COMMANDS} ]] && builtin fc -R ${GRML_IMPORTANT_COMMANDS}
 
 # load the lookup subsystem if it's available on the system
 zrcautoload lookupinit && lookupinit
@@ -2954,9 +3155,7 @@ export COLORTERM="yes"
 
 # general
 #a2# Execute \kbd{du -sch}
-alias da='du -sch'
-#a2# Execute \kbd{jobs -l}
-alias j='jobs -l'
+[[ -n "$GRML_NO_SMALL_ALIASES" ]] || alias da='du -sch'
 
 # listing stuff
 #a2# Execute \kbd{ls -lSrah}
@@ -3020,28 +3219,88 @@ fi
 # useful functions
 
 #f5# Backup \kbd{file_or_folder {\rm to} file_or_folder\_timestamp}
-bk() {
+function bk () {
     emulate -L zsh
-    while (( $# > 0 )); do
-        if islinux; then
-            cp -a "$1" "$1_$(date --iso-8601=m)"
-        elif isopenbsd; then
-            cp -R "$1" "$1_$(date "+%FT%H:%M")"
-        else;
-            echo 'sorry, not yet implemented, send a patch!' >&2
-        fi
-        shift
+    local current_date=$(date -u "+%Y-%m-%dT%H:%M:%SZ")
+    local clean keep move verbose result all to_bk
+    setopt extended_glob
+    keep=1
+    while getopts ":hacmrv" opt; do
+        case $opt in
+            a) (( all++ ));;
+            c) unset move clean && (( ++keep ));;
+            m) unset keep clean && (( ++move ));;
+            r) unset move keep && (( ++clean ));;
+            v) verbose="-v";;
+            h) <<__EOF0__
+bk [-hcmv] FILE [FILE ...]
+bk -r [-av] [FILE [FILE ...]]
+Backup a file or folder in place and append the timestamp
+Remove backups of a file or folder, or all backups in the current directory
+
+Usage:
+-h    Display this help text
+-c    Keep the file/folder as is, create a copy backup using cp(1) (default)
+-m    Move the file/folder, using mv(1)
+-r    Remove backups of the specified file or directory, using rm(1). If none
+      is provided, remove all backups in the current directory.
+-a    Remove all (even hidden) backups.
+-v    Verbose
+
+The -c, -r and -m options are mutually exclusive. If specified at the same time,
+the last one is used.
+
+The return code is the sum of all cp/mv/rm return codes.
+__EOF0__
+return 0;;
+            \?) bk -h >&2; return 1;;
+        esac
     done
+    shift "$((OPTIND-1))"
+    if (( keep > 0 )); then
+        if islinux || isfreebsd; then
+            for to_bk in "$@"; do
+                cp $verbose -a "${to_bk%/}" "${to_bk%/}_$current_date"
+                (( result += $? ))
+            done
+        else
+            for to_bk in "$@"; do
+                cp $verbose -pR "${to_bk%/}" "${to_bk%/}_$current_date"
+                (( result += $? ))
+            done
+        fi
+    elif (( move > 0 )); then
+        while (( $# > 0 )); do
+            mv $verbose "${1%/}" "${1%/}_$current_date"
+            (( result += $? ))
+            shift
+        done
+    elif (( clean > 0 )); then
+        if (( $# > 0 )); then
+            for to_bk in "$@"; do
+                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
+                (( result += $? ))
+            done
+        else
+            if (( all > 0 )); then
+                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)
+            else
+                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
+            fi
+            (( result += $? ))
+        fi
+    fi
+    return $result
 }
 
 #f5# cd to directoy and list files
-cl() {
+function cl () {
     emulate -L zsh
     cd $1 && ls -a
 }
 
 # smart cd function, allows switching to /etc when running 'cd /etc/fstab'
-cd() {
+function cd () {
     if (( ${#argv} == 1 )) && [[ -f ${1} ]]; then
         [[ ! -e ${1:h} ]] && return 1
         print "Correcting ${1} to ${1:h}"
@@ -3052,7 +3311,7 @@ cd() {
 }
 
 #f5# Create Directoy and \kbd{cd} to it
-mkcd() {
+function mkcd () {
     if (( ARGC != 1 )); then
         printf 'usage: mkcd \n'
         return 1;
@@ -3066,27 +3325,25 @@ mkcd() {
 }
 
 #f5# Create temporary directory and \kbd{cd} to it
-cdt() {
-    local t
-    t=$(mktemp -d)
-    echo "$t"
-    builtin cd "$t"
+function cdt () {
+    builtin cd "$(mktemp -d)"
+    builtin pwd
 }
 
 #f5# List files which have been accessed within the last {\it n} days, {\it n} defaults to 1
-accessed() {
+function accessed () {
     emulate -L zsh
     print -l -- *(a-${1:-1})
 }
 
 #f5# List files which have been changed within the last {\it n} days, {\it n} defaults to 1
-changed() {
+function changed () {
     emulate -L zsh
     print -l -- *(c-${1:-1})
 }
 
 #f5# List files which have been modified within the last {\it n} days, {\it n} defaults to 1
-modified() {
+function modified () {
     emulate -L zsh
     print -l -- *(m-${1:-1})
 }
@@ -3103,16 +3360,16 @@ if (( $#grep_options > 0 )); then
 fi
 
 # Translate DE<=>EN
-# 'translate' looks up fot a word in a file with language-to-language
+# 'translate' looks up a word in a file with language-to-language
 # translations (field separator should be " : "). A typical wordlist looks
-# like at follows:
-#  | english-word : german-transmission
+# like the following:
+#  | english-word : german-translation
 # It's also only possible to translate english to german but not reciprocal.
-# Use the following oneliner to turn back the sort order:
+# Use the following oneliner to reverse the sort order:
 #  $ awk -F ':' '{ print $2" : "$1" "$3 }' \
 #    /usr/local/lib/words/en-de.ISO-8859-1.vok > ~/.translate/de-en.ISO-8859-1.vok
 #f5# Translates a word
-trans() {
+function trans () {
     emulate -L zsh
     case "$1" in
         -[dD]*)
@@ -3131,10 +3388,10 @@ trans() {
 # Usage: simple-extract 
 # Using option -d deletes the original archive file.
 #f5# Smart archive extractor
-simple-extract() {
+function simple-extract () {
     emulate -L zsh
     setopt extended_glob noclobber
-    local DELETE_ORIGINAL DECOMP_CMD USES_STDIN USES_STDOUT GZTARGET WGET_CMD
+    local ARCHIVE DELETE_ORIGINAL DECOMP_CMD USES_STDIN USES_STDOUT GZTARGET WGET_CMD
     local RC=0
     zparseopts -D -E "d=DELETE_ORIGINAL"
     for ARCHIVE in "${@}"; do
@@ -3233,11 +3490,13 @@ simple-extract() {
 
         elif [[ "$ARCHIVE" == (#s)(https|http|ftp)://* ]] ; then
             if check_com curl; then
-                WGET_CMD="curl -L -k -s -o -"
+                WGET_CMD="curl -L -s -o -"
             elif check_com wget; then
-                WGET_CMD="wget -q -O - --no-check-certificate"
+                WGET_CMD="wget -q -O -"
+            elif check_com fetch; then
+                WGET_CMD="fetch -q -o -"
             else
-                print "ERROR: neither wget nor curl is installed" >&2
+                print "ERROR: neither wget, curl nor fetch is installed" >&2
                 RC=$((RC+4))
                 continue
             fi
@@ -3266,35 +3525,22 @@ simple-extract() {
     return $RC
 }
 
-__archive_or_uri()
-{
+function __archive_or_uri () {
     _alternative \
         '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)"' \
         '_urls:Remote Archives:_urls'
 }
 
-_simple_extract()
-{
+function _simple_extract () {
     _arguments \
         '-d[delete original archivefile after extraction]' \
         '*:Archive Or Uri:__archive_or_uri'
 }
 compdef _simple_extract simple-extract
-alias se=simple-extract
-
-#f5# Set all ulimit parameters to \kbd{unlimited}
-allulimit() {
-    ulimit -c unlimited
-    ulimit -d unlimited
-    ulimit -f unlimited
-    ulimit -l unlimited
-    ulimit -n unlimited
-    ulimit -s unlimited
-    ulimit -t unlimited
-}
+[[ -n "$GRML_NO_SMALL_ALIASES" ]] || alias se=simple-extract
 
 #f5# Change the xterm title from within GNU-screen
-xtrename() {
+function xtrename () {
     emulate -L zsh
     if [[ $1 != "-f" ]] ; then
         if [[ -z ${DISPLAY} ]] ; then
@@ -3317,7 +3563,7 @@ xtrename() {
 
 # Create small urls via http://goo.gl using curl(1).
 # API reference: https://code.google.com/apis/urlshortener/
-function zurl() {
+function zurl () {
     emulate -L zsh
     setopt extended_glob
 
@@ -3361,7 +3607,7 @@ function zurl() {
 }
 
 #f2# Find history events by search pattern and list them by date.
-whatwhen()  {
+function whatwhen () {
     emulate -L zsh
     local usage help ident format_l format_s first_char remain first last
     usage='USAGE: whatwhen [options]  '
@@ -3413,8 +3659,9 @@ if check_com -c hg ; then
     # gnu like diff for mercurial
     # http://www.selenic.com/mercurial/wiki/index.cgi/TipsAndTricks
     #f5# GNU like diff for mercurial
-    hgdi() {
+    function hgdi () {
         emulate -L zsh
+        local i
         for i in $(hg status -marn "$@") ; diff -ubwd <(hg cat "$i") "$i"
     }
 
@@ -3423,13 +3670,13 @@ if check_com -c hg ; then
     alias hbp='hg-buildpackage'
 
     # execute commands on the versioned patch-queue from the current repos
-    alias mq='hg -R $(readlink -f $(hg root)/.hg/patches)'
+    [[ -n "$GRML_NO_SMALL_ALIASES" ]] || alias mq='hg -R $(readlink -f $(hg root)/.hg/patches)'
 
     # diffstat for specific version of a mercurial repository
     #   hgstat      => display diffstat between last revision and tip
     #   hgstat 1234 => display diffstat between revision 1234 and tip
     #f5# Diffstat for specific version of a mercurial repos
-    hgstat() {
+    function hgstat () {
         emulate -L zsh
         [[ -n "$1" ]] && hg diff -r $1 -r tip | diffstat || hg export tip | diffstat
     }