X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=etc%2Fzsh%2Fzshrc;h=4ad12c6b117843180aa2140b189d779af11db080;hb=1049e383c183bce753a1f11fdc05ddd0a3f1942e;hp=eb1767eeeed4c39b5f262eb27e4d2d2e8fd4c162;hpb=06a39dc69b644a1f757481e3af31e8c1025a88ea;p=grml-etc-core.git diff --git a/etc/zsh/zshrc b/etc/zsh/zshrc index eb1767e..4ad12c6 100644 --- a/etc/zsh/zshrc +++ b/etc/zsh/zshrc @@ -180,14 +180,22 @@ else isgrmlsmall() { return 1 } fi +GRML_OSTYPE=$(uname -s) + +islinux(){ + [[ $GRML_OSTYPE == "Linux" ]] +} + isdarwin(){ - [[ $OSTYPE == darwin* ]] && return 0 - return 1 + [[ $GRML_OSTYPE == "Darwin" ]] } isfreebsd(){ - [[ $OSTYPE == freebsd* ]] && return 0 - return 1 + [[ $GRML_OSTYPE == "FreeBSD" ]] +} + +isopenbsd(){ + [[ $GRML_OSTYPE == "OpenBSD" ]] } #f1# are we running within an utf environment? @@ -339,19 +347,18 @@ NOMENU=${NOMENU:-0} NOPRECMD=${NOPRECMD:-0} COMMAND_NOT_FOUND=${COMMAND_NOT_FOUND:-0} GRML_ZSH_CNF_HANDLER=${GRML_ZSH_CNF_HANDLER:-/usr/share/command-not-found/command-not-found} -BATTERY=${BATTERY:-0} +GRML_DISPLAY_BATTERY=${GRML_DISPLAY_BATTERY:-${BATTERY:-0}} GRMLSMALL_SPECIFIC=${GRMLSMALL_SPECIFIC:-1} ZSH_NO_DEFAULT_LOCALE=${ZSH_NO_DEFAULT_LOCALE:-0} typeset -ga ls_options typeset -ga grep_options -if ls --help 2> /dev/null | grep -q GNU; then +if ls --color=auto / >/dev/null 2>&1; then ls_options=( --color=auto ) -elif [[ $OSTYPE == freebsd* ]]; then +elif ls -G / >/dev/null 2>&1; then ls_options=( -G ) fi -if grep --help 2> /dev/null | grep -q GNU || \ - [[ $OSTYPE == freebsd* ]]; then +if grep --color=auto -q "a" <<< "a" >/dev/null 2>&1; then grep_options=( --color=auto ) fi @@ -521,10 +528,6 @@ for var in LANG LC_ALL LC_MESSAGES ; do [[ -n ${(P)var} ]] && export $var done -xsource "/etc/sysconfig/keyboard" - -TZ=$(xcat /etc/timezone) - # set some variables if check_com -c vim ; then #v# @@ -540,7 +543,12 @@ export PAGER=${PAGER:-less} export MAIL=${MAIL:-/var/mail/$USER} # if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/ -export SHELL='/bin/zsh' +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) @@ -605,8 +613,9 @@ if is4 ; then fi # completion system +COMPDUMPFILE=${COMPDUMPFILE:-${ZDOTDIR:-${HOME}}/.zcompdump} if zrcautoload compinit ; then - compinit || print 'Notice: no compinit available :(' + compinit -d ${COMPDUMPFILE} || print 'Notice: no compinit available :(' else print 'Notice: no compinit available :(' function compdef { } @@ -755,14 +764,17 @@ grmlcomp() { # host completion if is42 ; then + [[ -r ~/.ssh/config ]] && _ssh_config_hosts=(${${${(@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)~~"$( 0 )) ; then - NOABBREVIATION=0 - else - NOABBREVIATION=1 - fi -} -zle -N grml_toggle_abbrev - # add a command line to the shells history without executing it commit-to-history() { print -s ${(z)BUFFER} @@ -992,11 +989,10 @@ zle -N accept-line zle -N Accept-Line zle -N Accept-Line-HandleContext -# power completion - abbreviation expansion # power completion / abbreviation expansion / buffer expansion # see http://zshwiki.org/home/examples/zleiab for details # less risky than the global aliases but powerful as well -# just type the abbreviation key and afterwards ',.' to expand it +# just type the abbreviation key and afterwards 'ctrl-x .' to expand it declare -A abk setopt extendedglob setopt interactivecomments @@ -1028,11 +1024,6 @@ zleiab() { setopt extendedglob local MATCH - if (( NOABBREVIATION > 0 )) ; then - LBUFFER="${LBUFFER},." - return 0 - fi - LBUFFER=${LBUFFER%%(#m)[.\-+:|_a-zA-Z0-9]#} LBUFFER+=${abk[$MATCH]:-$MATCH} } @@ -1041,7 +1032,7 @@ zle -N zleiab help-show-abk() { - zle -M "$(print "Type ,. after these abbreviations to expand them:"; print -a -C 2 ${(kv)abk})" + zle -M "$(print "Available abbreviations for expansion:"; print -a -C 2 ${(kv)abk})" } zle -N help-show-abk @@ -1123,7 +1114,6 @@ inplaceMkDirs() { fi } -#k# mkdir -p from string under cursor or marked area zle -N inplaceMkDirs #v1# set number of lines to display per page @@ -1195,10 +1185,10 @@ help_zle_parse_keybindings() if [[ "$cline" == (#s)[[:space:]]#\#k\#[[:space:]]##(#b)(*)[[:space:]]#(#e) ]]; then lastkeybind_desc="$match[*]" num_lines_elapsed=0 - #zsh pattern: matches lines that set a keybinding using bindkey or compdef -k + #zsh pattern: matches lines that set a keybinding using bind2map, bindkey or compdef -k # ignores lines that are commentend out # grabs first in '' or "" enclosed string with length between 1 and 6 characters - elif [[ "$cline" == [^#]#(bindkey|compdef -k)[[:space:]](*)(#b)(\"((?)(#c1,6))\"|\'((?)(#c1,6))\')(#B)(*) ]]; then + elif [[ "$cline" == [^#]#(bind2maps[[:space:]](*)-s|bindkey|compdef -k)[[:space:]](*)(#b)(\"((?)(#c1,6))\"|\'((?)(#c1,6))\')(#B)(*) ]]; then #description prevously found ? description not more than 2 lines away ? keybinding not empty ? if [[ -n $lastkeybind_desc && $num_lines_elapsed -lt 2 && -n $match[1] ]]; then #substitute keybinding string with something readable @@ -1406,10 +1396,11 @@ 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# Display list of abbreviations that expand when followed by ,. -bind2maps emacs viins -- -s ',.' zleiab +#k# Perform abbreviation expansion +bind2maps emacs viins -- -s '^x.' zleiab +#k# Display list of abbreviations that would expand bind2maps emacs viins -- -s '^xb' help-show-abk +#k# mkdir -p from string under cursor or marked area bind2maps emacs viins -- -s '^xM' inplaceMkDirs #k# display help for keybindings and ZLE bind2maps emacs viins -- -s '^xz' help-zle @@ -1425,8 +1416,6 @@ bind2maps emacs viins -- -s '^xP' history-beginning-search-forward-end bind2maps emacs viins -- PageUp history-beginning-search-backward-end #k# search history forward for entry beginning with typed text bind2maps emacs viins -- PageDown history-beginning-search-forward-end -#k# Toggle abbreviation expansion on/off -bind2maps emacs viins -- -s '^xA' grml_toggle_abbrev bind2maps emacs viins -- -s "^x^h" commit-to-history #k# Kill left-side word or everything up to next slash bind2maps emacs viins -- -s '\ev' slash-backward-kill-word @@ -1452,7 +1441,7 @@ bind2maps emacs viins -- -s '^x1' jump_after_first_word bind2maps emacs viins -- -s "^x^x" hist-complete # insert unicode character -# usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an § +# usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an § # See for example http://unicode.org/charts/ for unicode characters code #k# Insert Unicode character bind2maps emacs viins -- -s '^xi' insert-unicode-char @@ -1561,6 +1550,7 @@ if [[ -f ${DIRSTACKFILE} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then fi chpwd() { + if (( $DIRSTACKSIZE <= 0 )) || [[ -z $DIRSTACKFILE ]]; then return; fi local -ax my_stack my_stack=( ${PWD} ${dirstack} ) if is42 ; then @@ -1616,7 +1606,16 @@ fi # is433 # set colors for use in prompts (modern zshs allow for the use of %F{red}foo%f # in prompts to get a red "foo" embedded, but it's good to keep these for # backwards compatibility). -if zrcautoload colors && colors 2>/dev/null ; then +if is437; then + BLUE="%F{blue}" + RED="%F{red}" + GREEN="%F{green}" + CYAN="%F{cyan}" + MAGENTA="%F{magenta}" + YELLOW="%F{yellow}" + WHITE="%F{white}" + NO_COLOR="%f" +elif zrcautoload colors && colors 2>/dev/null ; then BLUE="%{${fg[blue]}%}" RED="%{${fg_bold[red]}%}" GREEN="%{${fg[green]}%}" @@ -1652,28 +1651,132 @@ PS4='+%N:%i:%_> ' # - debian_chroot # - vcs_info setup and version specific fixes -# display battery status on right side of prompt via running 'BATTERY=1 zsh' -if [[ $BATTERY -gt 0 ]] ; then - if ! check_com -c acpi ; then - BATTERY=0 - fi -fi +# display battery status on right side of prompt using 'GRML_DISPLAY_BATTERY=1' in .zshrc.pre battery() { -if [[ $BATTERY -gt 0 ]] ; then - PERCENT="${${"$(acpi 2>/dev/null)"}/(#b)[[:space:]]#Battery <->: [^0-9]##, (<->)%*/${match[1]}}" - if [[ -z "$PERCENT" ]] ; then - PERCENT='acpi not present' +if [[ $GRML_DISPLAY_BATTERY -gt 0 ]] ; then + if islinux ; then + batterylinux + elif isopenbsd ; then + batteryopenbsd + elif isfreebsd ; then + batteryfreebsd + elif isdarwin ; then + batterydarwin else - if [[ "$PERCENT" -lt 20 ]] ; then - PERCENT="warning: ${PERCENT}%%" - else - PERCENT="${PERCENT}%%" - fi + #not yet supported + GRML_DISPLAY_BATTERY=0 fi fi } +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) + case $(< $bat/status) in + Charging) + GRML_BATTERY_LEVEL+=" ^" + ;; + Discharging) + if (( capacity < 20 )) ; then + GRML_BATTERY_LEVEL+=" !v" + else + GRML_BATTERY_LEVEL+=" v" + fi + ;; + *) # Full, Unknown + GRML_BATTERY_LEVEL+=" =" + ;; + esac + GRML_BATTERY_LEVEL+="${capacity}%%" + done +fi +} + +batteryopenbsd(){ +GRML_BATTERY_LEVEL='' +local bat batfull batwarn batnow num +for num in 0 1 ; do + 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)"%% *} + batnow=${"$(sysctl -n hw.sensors.acpibat${num}.amphour3)"%% *} + case "$(sysctl -n hw.sensors.acpibat${num}.raw0)" in + *" discharging"*) + if (( batnow < batwarn )) ; then + GRML_BATTERY_LEVEL+=" !v" + else + GRML_BATTERY_LEVEL+=" v" + fi + ;; + *" charging"*) + GRML_BATTERY_LEVEL+=" ^" + ;; + *) + GRML_BATTERY_LEVEL+=" =" + ;; + esac + GRML_BATTERY_LEVEL+="${$(( 100 * batnow / batfull ))%%.*}%%" + fi +done +} + +batteryfreebsd(){ +GRML_BATTERY_LEVEL='' +local num +local -A table +for num in 0 1 ; do + table=( ${=${${${${${(M)${(f)"$(acpiconf -i $num 2>&1)"}:#(State|Remaining capacity):*}%%( ##|%)}//:[ $'\t']##/@}// /-}//@/ }} ) + if [[ -n $table ]] && [[ $table[State] != "not-present" ]] ; then + case $table[State] in + *discharging*) + if (( $table[Remaining-capacity] < 20 )) ; then + GRML_BATTERY_LEVEL+=" !v" + else + GRML_BATTERY_LEVEL+=" v" + fi + ;; + *charging*) + GRML_BATTERY_LEVEL+=" ^" + ;; + *) + GRML_BATTERY_LEVEL+=" =" + ;; + esac + GRML_BATTERY_LEVEL+="$table[Remaining-capacity]%%" + fi +done +} + +batterydarwin(){ +GRML_BATTERY_LEVEL='' +local -a table +table=( ${$(pmset -g ps)[(w)7,8]%%(\%|);} ) +if [[ -n $table[2] ]] ; then + case $table[2] in + charging) + GRML_BATTERY_LEVEL+=" ^" + ;; + discharging) + if (( $table[1] < 20 )) ; then + GRML_BATTERY_LEVEL+=" !v" + else + GRML_BATTERY_LEVEL+=" v" + fi + ;; + *) + GRML_BATTERY_LEVEL+=" =" + ;; + esac + GRML_BATTERY_LEVEL+="$table[1]%%" +fi +} + # set variable debian_chroot if running in a chroot with /etc/debian_chroot if [[ -z "$debian_chroot" ]] && [[ -r /etc/debian_chroot ]] ; then debian_chroot=$(\n' + return 1 + fi + (( ${+grml_prompt_token_default[$1]} )) +} + function GRML_theme_add_token_usage () { cat <<__EOF__ Usage: grml_theme_add_token [-f|-i] [
 ]
@@ -1927,6 +2078,11 @@ function GRML_theme_add_token_usage () {
     return value is expected in the \$REPLY parameter. The use of these
     options is mutually exclusive.
 
+    There is a utility function \`grml_theme_has_token', which you can use
+    to test if a token exists before trying to add it. This can be a guard
+    for situations in which a \`grml_theme_add_token' call may happen more
+    than once.
+
   Example:
 
     To add a new token \`day' that expands to the current weekday in the
@@ -1990,7 +2146,7 @@ grml_theme_add_token: 
 and  need to by specified _both_!\n\n'
         shift 2
     fi
 
-    if (( ${+grml_prompt_token_default[$name]} )); then
+    if grml_theme_has_token $name; then
         printf '
 grml_theme_add_token: Token `%s'\'' exists! Giving up!\n\n' $name
         GRML_theme_add_token_usage
@@ -2035,7 +2191,7 @@ function grml_prompt_addto () {
     for it in "${items[@]}"; do
         zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" pre apre \
             || apre=${grml_prompt_pre_default[$it]}
-        zstyle -s ":prompt:grml:${grmltheme}:${lr}:$it" post apost \
+        zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" post apost \
             || apost=${grml_prompt_post_default[$it]}
         zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" token new \
             || new=${grml_prompt_token_default[$it]}
@@ -2145,7 +2301,7 @@ fi
 if is437; then
     # The prompt themes use modern features of zsh, that require at least
     # version 4.3.7 of the shell. Use the fallback otherwise.
-    if [[ $BATTERY -gt 0 ]]; then
+    if [[ $GRML_DISPLAY_BATTERY -gt 0 ]]; then
         zstyle ':prompt:grml:right:setup' items sad-smiley battery
         add-zsh-hook precmd battery
     fi
@@ -2257,8 +2413,6 @@ hash -d linux=/lib/modules/$(command uname -r)/build/
 hash -d log=/var/log
 hash -d slog=/var/log/syslog
 hash -d src=/usr/src
-hash -d templ=/usr/share/doc/grml-templates
-hash -d tt=/usr/share/doc/texttools-doc
 hash -d www=/var/www
 #d# end
 
@@ -2283,22 +2437,22 @@ fi
 
 # do we have GNU ls with color-support?
 if [[ "$TERM" != dumb ]]; then
-    #a1# List files with colors (\kbd{ls -b -CF \ldots})
-    alias ls='ls -b -CF '${ls_options:+"${ls_options[*]}"}
+    #a1# List files with colors (\kbd{ls -F \ldots})
+    alias ls='command ls -F '${ls_options:+"${ls_options[*]}"}
     #a1# List all files, with colors (\kbd{ls -la \ldots})
-    alias la='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='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='ls -hAl '${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 -lF \ldots})\\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
-    alias l='ls -lF '${ls_options:+"${ls_options[*]}"}
+    alias l='command ls -lF '${ls_options:+"${ls_options[*]}"}
 else
-    alias ls='ls -b -CF'
-    alias la='ls -la'
-    alias ll='ls -l'
-    alias lh='ls -hAl'
-    alias l='ls -lF'
+    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'
 fi
 
 alias mdstat='cat /proc/mdstat'
@@ -2388,7 +2542,8 @@ the zsh yet. :)
   "NOPRECMD=1 zsh" => disable the precmd + preexec commands (set GNU screen title)
   "NOTITLE=1  zsh" => disable setting the title of xterms without disabling
                       preexec() and precmd() completely
-  "BATTERY=1  zsh" => activate battery status (via acpi) on right side of prompt
+  "GRML_DISPLAY_BATTERY=1  zsh"
+                   => activate battery status on right side of prompt (WIP)
   "COMMAND_NOT_FOUND=1 zsh"
                    => Enable a handler if an external command was not found
                       The command called in the handler can be altered by setting
@@ -2434,7 +2589,7 @@ if [[ -r /etc/debian_version ]] ; then
     # 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
@@ -2522,6 +2677,7 @@ compdef _functions freload
 #f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s')
 sll() {
     [[ -z "$1" ]] && printf 'Usage: %s \n' "$0" && return 1
+    local file
     for file in "$@" ; do
         while [[ -h "$file" ]] ; do
             ls -l $file
@@ -2534,26 +2690,31 @@ sll() {
 #   PAGER='less -Mr' - If so, the use of $PAGER here needs fixing
 # with respect to wordsplitting. (ie. ${=PAGER})
 if check_com -c $PAGER ; then
-    #f3# View Debian's changelog of a given package
+    #f3# View Debian's changelog of given package(s)
     dchange() {
         emulate -L zsh
-        if [[ -r /usr/share/doc/$1/changelog.Debian.gz ]] ; then
-            $PAGER /usr/share/doc/$1/changelog.Debian.gz
-        elif [[ -r /usr/share/doc/$1/changelog.gz ]] ; then
-            $PAGER /usr/share/doc/$1/changelog.gz
-        else
-            if check_com -c aptitude ; then
-                echo "No changelog for package $1 found, using aptitude to retrieve it."
-                if isgrml ; then
-                    aptitude -t unstable changelog $1
+        [[ -z "$1" ]] && printf 'Usage: %s \n' "$0" && return 1
+
+        local package
+        for package in "$@" ; do
+            if [[ -r /usr/share/doc/${package}/changelog.Debian.gz ]] ; then
+                $PAGER /usr/share/doc/${package}/changelog.Debian.gz
+            elif [[ -r /usr/share/doc/${package}/changelog.gz ]] ; then
+                $PAGER /usr/share/doc/${package}/changelog.gz
+            elif [[ -r /usr/share/doc/${package}/changelog ]] ; then
+                $PAGER /usr/share/doc/${package}/changelog
+            else
+                if check_com -c aptitude ; then
+                    echo "No changelog for package $package found, using aptitude to retrieve it."
+                    aptitude changelog "$package"
+                elif check_com -c apt-get ; then
+                    echo "No changelog for package $package found, using apt-get to retrieve it."
+                    apt-get changelog "$package"
                 else
-                    aptitude changelog $1
+                    echo "No changelog for package $package found, sorry."
                 fi
-            else
-                echo "No changelog for package $1 found, sorry."
-                return 1
             fi
-        fi
+        done
     }
     _dchange() { _files -W /usr/share/doc -/ }
     compdef _dchange dchange
@@ -2739,11 +2900,6 @@ if check_com vim; then
     }
 fi
 
-# make a backup of a file
-bk() {
-    cp -a "$1" "${1}_$(date --iso-8601=seconds)"
-}
-
 ssl_hashes=( sha512 sha256 sha1 md5 )
 
 for sh in ${ssl_hashes}; do
@@ -2801,40 +2957,38 @@ export COLORTERM="yes"
 # general
 #a2# Execute \kbd{du -sch}
 alias da='du -sch'
-#a2# Execute \kbd{jobs -l}
-alias j='jobs -l'
 
 # listing stuff
 #a2# Execute \kbd{ls -lSrah}
-alias dir="ls -lSrah"
+alias dir="command ls -lSrah"
 #a2# Only show dot-directories
-alias lad='ls -d .*(/)'
+alias lad='command ls -d .*(/)'
 #a2# Only show dot-files
-alias lsa='ls -a .*(.)'
+alias lsa='command ls -a .*(.)'
 #a2# Only files with setgid/setuid/sticky flag
-alias lss='ls -l *(s,S,t)'
+alias lss='command ls -l *(s,S,t)'
 #a2# Only show symlinks
-alias lsl='ls -l *(@)'
+alias lsl='command ls -l *(@)'
 #a2# Display only executables
-alias lsx='ls -l *(*)'
+alias lsx='command ls -l *(*)'
 #a2# Display world-{readable,writable,executable} files
-alias lsw='ls -ld *(R,W,X.^ND/)'
+alias lsw='command ls -ld *(R,W,X.^ND/)'
 #a2# Display the ten biggest files
-alias lsbig="ls -flh *(.OL[1,10])"
+alias lsbig="command ls -flh *(.OL[1,10])"
 #a2# Only show directories
-alias lsd='ls -d *(/)'
+alias lsd='command ls -d *(/)'
 #a2# Only show empty directories
-alias lse='ls -d *(/^F)'
+alias lse='command ls -d *(/^F)'
 #a2# Display the ten newest files
-alias lsnew="ls -rtlh *(D.om[1,10])"
+alias lsnew="command ls -rtlh *(D.om[1,10])"
 #a2# Display the ten oldest files
-alias lsold="ls -rtlh *(D.Om[1,10])"
+alias lsold="command ls -rtlh *(D.Om[1,10])"
 #a2# Display the ten smallest files
-alias lssmall="ls -Srl *(.oL[1,10])"
+alias lssmall="command ls -Srl *(.oL[1,10])"
 #a2# Display the ten newest directories and ten newest .directories
-alias lsnewdir="ls -rthdl *(/om[1,10]) .*(D/om[1,10])"
+alias lsnewdir="command ls -rthdl *(/om[1,10]) .*(D/om[1,10])"
 #a2# Display the ten oldest directories and ten oldest .directories
-alias lsolddir="ls -rthdl *(/Om[1,10]) .*(D/Om[1,10])"
+alias lsolddir="command ls -rthdl *(/Om[1,10]) .*(D/Om[1,10])"
 
 # some useful aliases
 #a2# Remove current empty directory. Execute \kbd{cd ..; rmdir \$OLDCWD}
@@ -2865,10 +3019,74 @@ fi
 
 # useful functions
 
-#f5# Backup \kbd{file {\rm to} file\_timestamp}
+#f5# Backup \kbd{file_or_folder {\rm to} file_or_folder\_timestamp}
 bk() {
     emulate -L zsh
-    cp -b $1 $1_`date --iso-8601=m`
+    local current_date=$(date -u "+%Y-%m-%dT%H:%M:%SZ")
+    local clean keep move verbose result
+    setopt extended_glob
+    usage() {
+        cat << EOT
+bk [-hcmv] FILE [FILE ...]
+bk -r [-v] [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.
+-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.
+EOT
+    }
+    keep=1
+    while getopts ":hcmrv" opt; do
+        case $opt in
+            c) unset move clean && (( ++keep ));;
+            m) unset keep clean && (( ++move ));;
+            r) unset move keep && (( ++clean ));;
+            v) verbose="-v";;
+            h) usage;;
+            \?) usage >&2; return 1;;
+        esac
+    done
+    shift "$((OPTIND-1))"
+    if (( keep > 0 )); then
+        while (( $# > 0 )); do
+            if islinux || isfreebsd; then
+                cp $verbose -a "${1%/}" "${1%/}_$current_date"
+            else
+                cp $verbose -pR "${1%/}" "${1%/}_$current_date"
+            fi
+            (( result += $? ))
+            shift
+        done
+    elif (( move > 0 )); then
+        while (( $# > 0 )); do
+            mv $verbose "${1%/}" "${1%/}_$current_date"
+            (( result += $? ))
+            shift
+        done
+    elif (( clean > 0 )); then
+        if (( $# > 0 )); then
+            while (( $# > 0 )); do
+                rm $verbose -rf "${1%/}"_[0-9](#c4,)-(0[0-9]|1[0-2])-([0-2][0-9]|3[0-1])T([0-1][0-9]|2[0-3])(:[0-5][0-9])(#c2)Z
+                (( result += $? ))
+                shift
+            done
+        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
+            (( result += $? ))
+        fi
+    fi
+    return $result
 }
 
 #f5# cd to directoy and list files
@@ -2931,8 +3149,13 @@ modified() {
 check_com new || alias new=modified
 
 # use colors when GNU grep with color-support
-#a2# Execute \kbd{grep -{}-color=auto}
-(( $#grep_options > 0 )) && alias grep='grep '${grep_options:+"${grep_options[*]}"}
+if (( $#grep_options > 0 )); then
+    o=${grep_options:+"${grep_options[*]}"}
+    #a2# Execute \kbd{grep -{}-color=auto}
+    alias grep='grep '$o
+    alias egrep='egrep '$o
+    unset o
+fi
 
 # Translate DE<=>EN
 # 'translate' looks up fot a word in a file with language-to-language