Add (deactivated) completion for aliases
[grml-etc-core.git] / etc / zsh / zshrc
index 95c910a..541eced 100644 (file)
@@ -3,7 +3,7 @@
 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
 # Bug-Reports:   see http://grml.org/bugs/
 # License:       This file is licensed under the GPL v2.
-# Latest change: Don Dez 06 23:21:21 CET 2007 [mika]
+# Latest change: Wed Aug 06 23:50:53 CEST 2008 [mika]
 ################################################################################
 # This file is sourced only for interactive shells. It
 # should contain commands to set up aliases, functions,
@@ -92,6 +92,99 @@ if [[ -n $ZSH_PROFILE_RC ]] ; then
 fi
 # }}}
 
+# {{{ check for version/system
+# check for versions (compatibility reasons)
+is4(){
+    [[ $ZSH_VERSION == <4->* ]] && return 0
+    return 1
+}
+
+is41(){
+    [[ $ZSH_VERSION == 4.<1->* || $ZSH_VERSION == <5->* ]] && return 0
+    return 1
+}
+
+is42(){
+    [[ $ZSH_VERSION == 4.<2->* || $ZSH_VERSION == <5->* ]] && return 0
+    return 1
+}
+
+is43(){
+    [[ $ZSH_VERSION == 4.<3->* || $ZSH_VERSION == <5->* ]] && return 0
+    return 1
+}
+
+#f1# Checks whether or not you're running grml
+isgrml(){
+    [[ -f /etc/grml_version ]] && return 0
+    return 1
+}
+
+#f1# Checks whether or not you're running a grml cd
+isgrmlcd(){
+    [[ -f /etc/grml_cd ]] && return 0
+    return 1
+}
+
+if isgrml ; then
+#f1# Checks whether or not you're running grml-small
+    isgrmlsmall() {
+        [[ ${${${(f)"$(</etc/grml_version)"}%% *}##*-} == 'small' ]] && return 0 ; return 1
+    }
+else
+    isgrmlsmall() { return 1 }
+fi
+
+#f1# are we running within an utf environment?
+isutfenv() {
+    case "$LANG $CHARSET $LANGUAGE" in
+        *utf*) return 0 ;;
+        *UTF*) return 0 ;;
+        *)     return 1 ;;
+    esac
+}
+
+# check for user, if not running as root set $SUDO to sudo
+(( EUID != 0 )) && SUDO='sudo' || SUDO=''
+
+# change directory to home on first invocation of zsh
+# important for rungetty -> autologin
+# Thanks go to Bart Schaefer!
+isgrml && checkhome() {
+    if [[ -z "$ALREADY_DID_CD_HOME" ]] ; then
+        export ALREADY_DID_CD_HOME=$HOME
+        cd
+    fi
+}
+
+# check for zsh v3.1.7+
+
+if ! [[ ${ZSH_VERSION} == 3.1.<7->*      \
+     || ${ZSH_VERSION} == 3.<2->.<->*    \
+     || ${ZSH_VERSION} == <4->.<->*   ]] ; then
+
+    printf '-!-\n'
+    printf '-!- In this configuration we try to make use of features, that only\n'
+    printf '-!- require version 3.1.7 of the shell; That way this setup can be\n'
+    printf '-!- used with a wide range of zsh versions, while using fairly\n'
+    printf '-!- advanced features in all supported versions.\n'
+    printf '-!-\n'
+    printf '-!- However, you are running zsh version %s.\n' "$ZSH_VERSION"
+    printf '-!-\n'
+    printf '-!- While this *may* work, it might as well fail.\n'
+    printf '-!- Please consider updating to at least version 3.1.7 of zsh.\n'
+    printf '-!-\n'
+    printf '-!- DO NOT EXPECT THIS TO WORK FLAWLESSLY!\n'
+    printf '-!- If it does today, you'\''ve been lucky.\n'
+    printf '-!-\n'
+    printf '-!- Ye been warned!\n'
+    printf '-!-\n'
+
+    function zstyle() { : }
+fi
+
+# }}}
+
 # utility functions {{{
 # this function checks if a command exists and returns either true
 # or false. This avoids using 'which' and 'whence', which will
@@ -165,6 +258,29 @@ 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 () {
+        local -a u
+        local w
+        local parameter=${1}
+
+        if [[ -z ${parameter} ]] ; then
+            printf 'usage: uprint <parameter>\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() {
     if (( ${#argv} < 1 )) ; then
@@ -194,7 +310,7 @@ xcat() {
 # setup files. This should be called at the end of .zshrc.
 xunfunction() {
     local -a funcs
-    funcs=(check_com salias xcat xsource xunfunction)
+    funcs=(salias xcat xsource xunfunction zrcautoload)
 
     for func in $funcs ; do
         [[ -n ${functions[$func]} ]] \
@@ -202,11 +318,41 @@ xunfunction() {
     done
     return 0
 }
+
+# autoload wrapper - use this one instead of autoload directly
+function zrcautoload() {
+    setopt local_options extended_glob
+    local fdir ffile
+    local -i ffound
+
+    ffile=${1}
+    (( found = 0 ))
+    for fdir in ${fpath} ; do
+        [[ -e ${fdir}/${ffile} ]] && (( ffound = 1 ))
+    done
+
+    (( ffound == 0 )) && return 1
+    if [[ $ZSH_VERSION == 3.1.<6-> || $ZSH_VERSION == <4->* ]] ; then
+        autoload -U ${ffile} || return 1
+    else
+        autoload ${ffile} || return 1
+    fi
+    return 0
+}
+
 #}}}
 
+# 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 }
+
+# }}}
+
 # locale setup {{{
 if [[ -z "$LANG" ]] ; then
-    xsource "/etc/default/locale"
+   xsource "/etc/default/locale"
 fi
 
 export LANG=${LANG:-en_US.iso885915}
@@ -245,76 +391,18 @@ fi
 unset xof
 # }}}
 
-# {{{ check for version/system
-# check for versions (compatibility reasons)
-if autoload is-at-least && is-at-least 2>/dev/null ; then
-    is4()  { is-at-least 4 }
-    is41() { is-at-least 4.1 }
-    is42() { is-at-least 4.2 }
-else
-    is4(){
-        [[ $ZSH_VERSION == 4.* ]] && return 0
-        return 1
-    }
-    is42(){
-        [[ $ZSH_VERSION == 4.<2->* ]] && return 0
-        return 1
-    }
-fi
-
-#f1# Checks whether or not you're running grml
-isgrml(){
-    [[ -f /etc/grml_version ]] && return 0
-    return 1
-}
-
-#f1# Checks whether or not you're running a grml cd
-isgrmlcd(){
-    [[ -f /etc/grml_cd ]] && return 0
-    return 1
-}
-
-if isgrml ; then
-#f1# Checks whether or not you're running grml-small
-    isgrmlsmall() {
-        [[ ${${${(f)"$(</etc/grml_version)"}%% *}##*-} == 'small' ]] && return 0 ; return 1
-    }
-else
-    isgrmlsmall() { return 1 }
-fi
-
-#f1# are we running within an utf environment?
-isutfenv() {
-    case "$LANG $CHARSET $LANGUAGE" in
-        *utf*) return 0 ;;
-        *UTF*) return 0 ;;
-        *)     return 1 ;;
-    esac
-}
-
-# check for user, if not running as root set $SUDO to sudo
-(( EUID != 0 )) && SUDO='sudo' || SUDO=''
-
-# change directory to home on first invocation of zsh
-# important for rungetty -> autologin
-# Thanks go to Bart Schaefer!
-isgrml && checkhome() {
-    if [[ -z "$ALREADY_DID_CD_HOME" ]] ; then
-        export ALREADY_DID_CD_HOME=$HOME
-        cd
-    fi
-}
-# }}}
-
 # {{{ set some variables
-#v#
 if check_com -c vim ; then
+#v#
     export EDITOR=${EDITOR:-vim}
 else
     export EDITOR=${EDITOR:-vi}
 fi
+
 #v#
+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 :-/
@@ -324,7 +412,7 @@ export SHELL='/bin/zsh'
 check_com -c dircolors && eval $(dircolors -b)
 
 # set width of man pages to 80 for more convenient reading
-# (( ${+MANWIDTH} )) || export MANWIDTH=80
+# export MANWIDTH=${MANWIDTH:-80}
 
 # Search path for the cd command
 #  cdpath=(.. ~)
@@ -335,11 +423,11 @@ check_com -c dircolors && eval $(dircolors -b)
 if [[ -n "$BROKEN_COMPLETION_DIR" ]] ; then
     print 'Warning: not setting completion directories because broken files have been found.' >&2
 else
-    [[ -d /etc/zsh/completion.d ]] && fpath+=( /etc/zsh/completion.d )
+    [[ -d /etc/zsh/completion.d ]] && fpath=( $fpath /etc/zsh/completion.d )
     if [[ -d /etc/zsh/functions.d ]] ; then
         fpath+=( /etc/zsh/functions.d )
         for func in /etc/zsh/functions.d/[^_]*[^~] ; do
-            autoload -U ${func:t}
+            zrcautoload -U ${func:t}
         done
     fi
 fi
@@ -384,7 +472,9 @@ bindkey '\e[1~' beginning-of-line       # home
 bindkey '\e[4~' end-of-line             # end
 bindkey '\e[A'  up-line-or-search       # cursor up
 bindkey '\e[B'  down-line-or-search     # <ESC>-
-bindkey '^x'    history-beginning-search-backward # alternative ways of searching the shell history
+
+bindkey '^xp'   history-beginning-search-backward
+bindkey '^xP'   history-beginning-search-forward
 # bindkey -s '^L' "|less\n"             # ctrl-L pipes to less
 # bindkey -s '^B' " &\n"                # ctrl-B runs it in the background
 # if terminal type is set to 'rxvt':
@@ -395,7 +485,7 @@ bindkey '\e[8~' end-of-line             # end
 # insert unicode character
 # usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an ยง
 # See for example http://unicode.org/charts/ for unicode characters code
-autoload insert-unicode-char
+zrcautoload insert-unicode-char
 zle -N insert-unicode-char
 #k# Insert Unicode character
 bindkey '^Xi' insert-unicode-char
@@ -412,12 +502,166 @@ bindkey '^Xi' insert-unicode-char
 #  bindkey . rationalise-dot
 
 #  bindkey '\eq' push-line-or-edit
-  
-# use the vi navigation keys (hjkl) besides cursor keys in menu selection
-  bindkey -M menuselect 'h' vi-backward-char                # left
-  bindkey -M menuselect 'k' vi-up-line-or-history           # up
-  bindkey -M menuselect 'l' vi-forward-char                 # right
-  bindkey -M menuselect 'j' vi-down-line-or-history         # bottom
+
+## toggle the ,. abbreviation feature on/off
+# NOABBREVIATION: default abbreviation-state
+#                 0 - enabled (default)
+#                 1 - disabled
+NOABBREVIATION=${NOABBREVIATION:-0}
+
+grml_toggle_abbrev() {
+    if (( ${NOABBREVIATION} > 0 )) ; then
+        NOABBREVIATION=0
+    else
+        NOABBREVIATION=1
+    fi
+}
+
+zle -N grml_toggle_abbrev
+bindkey '^xA' grml_toggle_abbrev
+
+# }}}
+
+# a generic accept-line wrapper {{{
+
+# This widget can prevent unwanted autocorrections from command-name
+# to _command-name, rehash automatically on enter and call any number
+# of builtin and user-defined widgets in different contexts.
+#
+# For a broader description, see:
+# <http://bewatermyfriend.org/posts/2007/12-26.11-50-38-tooltime.html>
+#
+# The code is imported from the file 'zsh/functions/accept-line' from
+# <http://ft.bewatermyfriend.org/comp/zsh/zsh-dotfiles.tar.bz2>, which
+# distributed under the same terms as zsh itself.
+
+# A newly added command will may not be found or will cause false
+# correction attempts, if you got auto-correction set. By setting the
+# following style, we force accept-line() to rehash, if it cannot
+# find the first word on the command line in the $command[] hash.
+zstyle ':acceptline:*' rehash true
+
+function Accept-Line() {
+    setopt localoptions noksharrays
+    local -a subs
+    local -xi aldone
+    local sub
+
+    zstyle -a ":acceptline:${alcontext}" actions subs
+
+    (( ${#subs} < 1 )) && return 0
+
+    (( aldone = 0 ))
+    for sub in ${subs} ; do
+        [[ ${sub} == 'accept-line' ]] && sub='.accept-line'
+        zle ${sub}
+
+        (( aldone > 0 )) && break
+    done
+}
+
+function Accept-Line-getdefault() {
+    local default_action
+
+    zstyle -s ":acceptline:${alcontext}" default_action default_action
+    case ${default_action} in
+        ((accept-line|))
+            printf ".accept-line"
+            ;;
+        (*)
+            printf ${default_action}
+            ;;
+    esac
+}
+
+function accept-line() {
+    setopt localoptions noksharrays
+    local -a cmdline
+    local -x alcontext
+    local buf com fname format msg default_action
+
+    alcontext='default'
+    buf="${BUFFER}"
+    cmdline=(${(z)BUFFER})
+    com="${cmdline[1]}"
+    fname="_${com}"
+
+    zstyle -t ":acceptline:${alcontext}" rehash \
+        && [[ -z ${commands[$com]} ]]           \
+        && rehash
+
+    if    [[ -n ${reswords[(r)$com]} ]] \
+       || [[ -n ${aliases[$com]}     ]] \
+       || [[ -n ${functions[$com]}   ]] \
+       || [[ -n ${builtins[$com]}    ]] \
+       || [[ -n ${commands[$com]}    ]] ; then
+
+        # there is something sensible to execute, just do it.
+        alcontext='normal'
+        zle Accept-Line
+
+        default_action=$(Accept-Line-getdefault)
+        zstyle -T ":acceptline:${alcontext}" call_default \
+            && zle ${default_action}
+        return
+    fi
+
+    if    [[ -o correct              ]] \
+       || [[ -o correctall           ]] \
+       && [[ -n ${functions[$fname]} ]] ; then
+
+        # nothing there to execute but there is a function called
+        # _command_name; a completion widget. Makes no sense to
+        # call it on the commandline, but the correct{,all} options
+        # will ask for it nevertheless, so warn the user.
+        if [[ ${LASTWIDGET} == 'accept-line' ]] ; then
+            # Okay, we warned the user before, he called us again,
+            # so have it his way.
+            alcontext='force'
+            zle Accept-Line
+
+            default_action=$(Accept-Line-getdefault)
+            zstyle -T ":acceptline:${alcontext}" call_default \
+                && zle ${default_action}
+            return
+        fi
+
+        # prepare warning message for the user, configurable via zstyle.
+        zstyle -s ":acceptline:${alcontext}" compwarnfmt msg
+
+        if [[ -z ${msg} ]] ; then
+            msg="%c will not execute and completion %f exists."
+        fi
+
+        zformat -f msg "${msg}" "c:${com}" "f:${fname}"
+
+        zle -M -- "${msg}"
+        return
+    elif [[ -n ${buf//[$' \t\n']##/} ]] ; then
+        # If we are here, the commandline contains something that is not
+        # executable, which is neither subject to _command_name correction
+        # and is not empty. might be a variable assignment
+        alcontext='misc'
+        zle Accept-Line
+
+        default_action=$(Accept-Line-getdefault)
+        zstyle -T ":acceptline:${alcontext}" call_default \
+            && zle ${default_action}
+        return
+    fi
+
+    # If we got this far, the commandline only contains whitespace, or is empty.
+    alcontext='empty'
+    zle Accept-Line
+
+    default_action=$(Accept-Line-getdefault)
+    zstyle -T ":acceptline:${alcontext}" call_default \
+        && zle ${default_action}
+}
+
+zle -N accept-line
+zle -N Accept-Line
+
 # }}}
 
 # power completion - abbreviation expansion {{{
@@ -503,6 +747,12 @@ abk=(
 
 globalias() {
     local MATCH
+
+    if (( NOABBREVIATION > 0 )) ; then
+        LBUFFER="${LBUFFER},."
+        return 0
+    fi
+
     matched_chars='[.-|_a-zA-Z0-9]#'
     LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
     LBUFFER+=${abk[$MATCH]:-$MATCH}
@@ -513,8 +763,8 @@ bindkey ",." globalias
 # }}}
 
 # {{{ autoloading
-autoload -U zmv    # who needs mmv or rename?
-autoload history-search-end
+zrcautoload zmv    # who needs mmv or rename?
+zrcautoload history-search-end
 
 # we don't want to quote/espace URLs on our own...
 # if autoload -U url-quote-magic ; then
@@ -527,10 +777,10 @@ 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
-autoload run-help # use via 'esc-h'
+zrcautoload run-help # use via 'esc-h'
 
 # completion system
-if autoload -U compinit && compinit 2>/dev/null ; then
+if zrcautoload compinit && compinit 2>/dev/null ; then
     compinit 2>/dev/null || print 'Notice: no compinit available :('
 else
     print 'Notice: no compinit available :('
@@ -538,7 +788,7 @@ else
     function compdef { }
 fi
 
-is4 && autoload -U zed # use ZLE editor to edit a file or function
+is4 && zrcautoload zed # use ZLE editor to edit a file or function
 
 is4 && \
 for mod in complist deltochar mathfunc ; do
@@ -561,7 +811,7 @@ if is4 ; then
     unset tmpargs
 fi
 
-if is4 && autoload -U insert-files && zle -N insert-files ; then
+if is4 && zrcautoload insert-files && zle -N insert-files ; then
     #k# Insert files
     bindkey "^Xf" insert-files # C-x-f
 fi
@@ -571,13 +821,26 @@ bindkey ' '   magic-space    # also do history expansion on space
 bindkey '\ei' menu-complete  # menu completion via esc-i
 
 # press esc-e for editing command line in $EDITOR or $VISUAL
-if is4 && autoload -U edit-command-line && zle -N edit-command-line ; then
+if is4 && zrcautoload edit-command-line && zle -N edit-command-line ; then
     #k# Edit the current line in \kbd{\$EDITOR}
     bindkey '\ee' edit-command-line
 fi
 
-#k# menu selection: pick item but stay in the menu
-is4 && bindkey -M menuselect '\e^M' accept-and-menu-complete
+if is4 && [[ -n ${(k)modules[zsh/complist]} ]] ; then
+    #k# menu selection: pick item but stay in the menu
+    bindkey -M menuselect '\e^M' accept-and-menu-complete
+
+    # use the vi navigation keys (hjkl) besides cursor keys in menu completion
+    #bindkey -M menuselect 'h' vi-backward-char        # left
+    #bindkey -M menuselect 'k' vi-up-line-or-history   # up
+    #bindkey -M menuselect 'l' vi-forward-char         # right
+    #bindkey -M menuselect 'j' vi-down-line-or-history # bottom
+
+    # accept a completion and try to complete again by using menu
+    # completion; very useful with completing directories
+    # by using 'undo' one's got a simple file browser
+    bindkey -M menuselect '^o' accept-and-infer-next-history
+fi
 
 # press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd
 _bkdate() { BUFFER="$BUFFER$(date '+%F')"; CURSOR=$#BUFFER; }
@@ -594,7 +857,7 @@ zle -N insert-last-typed-word;
 bindkey "\em" insert-last-typed-word
 
 # set command prediction from history, see 'man 1 zshcontrib'
-#  is4 && autoload -U predict-on && \
+#  is4 && zrcautoload predict-on && \
 #  zle -N predict-on         && \
 #  zle -N predict-off        && \
 #  bindkey "^X^Z" predict-on && \
@@ -665,6 +928,7 @@ setopt extended_glob        # in order to use #, ~ and ^ for filename generation
                             # grep word *~(*.gz|*.bz|*.bz2|*.zip|*.Z) ->
                             # -> searches for word not in compressed files
                             # don't forget to quote '^', '~' and '#'!
+setopt longlistjobs         # display PID when suspending processes as well
 setopt notify               # report the status of backgrounds jobs immediately
 setopt hash_list_all        # Whenever a command completion is attempted, make sure \
                             # the entire command path is hashed first.
@@ -714,15 +978,21 @@ isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
 
 # dirstack handling {{{
 
-DIRSTACKSIZE=20
-if [[ -f ~/.zdirs ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then
-    dirstack=( ${(f)"$(< ~/.zdirs)"} )
+DIRSTACKSIZE=${DIRSTACKSIZE:-20}
+DIRSTACKFILE=${DIRSTACKFILE:-${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[0] ]] && cd $dirstack[0] && cd $OLDPWD
 fi
 
 chpwd() {
-    builtin dirs -pl >! ~/.zdirs
+    if is42 ; then
+        builtin print -l ${(u)dirstack} >! ${DIRSTACKFILE}
+    else
+        uprint dirstack >! ${DIRSTACKFILE}
+    fi
 }
 
 # }}}
@@ -806,7 +1076,7 @@ __vcs_dir() {
 # }}}
 
 # {{{ set prompt
-if autoload promptinit && promptinit 2>/dev/null ; then
+if zrcautoload promptinit && promptinit 2>/dev/null ; then
     promptinit # people should be able to use their favourite prompt
 else
     print 'Notice: no promptinit available :('
@@ -856,7 +1126,7 @@ is4 && [[ -z $NOPRECMD ]] && \
 preexec () {
     [[ -n $NOPRECMD ]] && return 0
 # set hostname if not running on host with name 'grml'
-    if [[ "$HOSTNAME" != $(hostname) ]] ; then
+    if [[ -n "$HOSTNAME" ]] && [[ "$HOSTNAME" != $(hostname) ]] ; then
        NAME="@$HOSTNAME"
     fi
 # get the name of the program currently running and hostname of local machine
@@ -881,7 +1151,7 @@ preexec () {
 }
 
 # set colors
-if autoload colors && colors 2>/dev/null ; then
+if zrcautoload colors && colors 2>/dev/null ; then
     BLUE="%{${fg[blue]}%}"
     RED="%{${fg_bold[red]}%}"
     GREEN="%{${fg[green]}%}"
@@ -1018,21 +1288,20 @@ iso2utf() {
 }
 
 # set up software synthesizer via speakup
-# TODO: make this a function?
-alias swspeak='
-  aumix -w 90 -v 90 -p 90 -m 90
-  if ! [[ -r /dev/softsynth ]] ; then
-     flite -o play -t "Sorry, software synthesizer not available. Did you boot with swspeak bootoption?"
-     return 1
-  else
-     setopt singlelinezle
-     unsetopt prompt_cr
-     export PS1="%m%# "
-     nice -n -20 speechd-up
-     sleep 2
-     flite -o play -t "Finished setting up software synthesizer"
-  fi
-'
+swspeak() {
+    aumix -w 90 -v 90 -p 90 -m 90
+    if ! [[ -r /dev/softsynth ]] ; then
+        flite -o play -t "Sorry, software synthesizer not available. Did you boot with swspeak bootoption?"
+        return 1
+    else
+        setopt singlelinezle
+        unsetopt prompt_cr
+        export PS1="%m%# "
+        nice -n -20 speechd-up
+        sleep 2
+        flite -o play -t "Finished setting up software synthesizer"
+    fi
+}
 
 # I like clean prompt, so provide simple way to get that
 check_com 0 || alias 0='return 0'
@@ -1151,7 +1420,11 @@ if [[ -r /etc/debian_version ]] ; then
         fi
     }
 
-    isgrmlcd && alias su="sudo -s"          # get a root shell
+    # get a root shell as normal user in live-cd mode:
+    if isgrmlcd && [[ $UID -ne 0 ]] ; then
+       alias su="sudo su"
+     fi
+
     #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
     alias llog="$PAGER /var/log/syslog"     # take a look at the syslog
     #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
 
 # {{{ Use hard limits, except for a smaller stack and no core dumps
 unlimit
-limit stack 8192
+is4 && limit stack 8192
 isgrmlcd && limit core 0 # important for a live-cd-system
 limit -s
 # }}}
 
-# {{{ completion stuff
+# {{{ completion system
 
 # called later (via is4 && grmlcomp)
 # notice: 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
-# TODO: make grmlcomp() readable. :-)
 grmlcomp() {
-## completion system
-## no initial indention in grmlcomp(), the lines are long enough already.
-zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )' # allow one error for every three characters typed in approximate completer
-zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)' # don't complete backup files as executables
-zstyle ':completion:*:correct:*'       insert-unambiguous true             # start menu completion only if it could find no unambiguous initial string
-zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}' #
-zstyle ':completion:*:correct:*'       original true                       #
-zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}      # activate color-completion(!)
-zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'  # format on completion
-zstyle ':completion:*:*:cd:*:directory-stack' menu yes select              # complete 'cd -<tab>' with menu
-zstyle ':completion:*:expand:*'        tag-order all-expansions            # insert all expansions for expand completer
-zstyle ':completion:*:history-words'   list false                          #
-zstyle ':completion:*:history-words'   menu yes                            # activate menu
-zstyle ':completion:*:history-words'   remove-all-dups yes                 # ignore duplicate entries
-zstyle ':completion:*:history-words'   stop yes                            #
-zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'        # match uppercase from lowercase
-zstyle ':completion:*:matches'         group 'yes'                         # separate matches into groups
-zstyle ':completion:*'                 group-name ''
-if [[ -z "$NOMENU" ]] ; then
-    zstyle ':completion:*'               menu select=5                     # if there are more than 5 options allow selecting from a menu
-else
-    setopt no_auto_menu # don't use any menus at all
-fi
-zstyle ':completion:*:messages'        format '%d'                         #
-zstyle ':completion:*:options'         auto-description '%d'               #
-zstyle ':completion:*:options'         description 'yes'                   # describe options in full
-zstyle ':completion:*:processes'       command 'ps -au$USER'               # on processes completion complete all user processes
-zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters        # offer indexes before parameters in subscripts
-zstyle ':completion:*'                 verbose true                        # provide verbose completion information
-
-# recent (as of Dec 2007) zsh versions are able to provide descriptions
-# for commands (read: 1st word in the line) that it will list for the user
-# to choose from. The following disables that, because it's not exactly fast.
-zstyle ':completion:*:-command-:*:'    verbose false
-
-zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' # set format for warnings
-zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'       # define files to ignore for zcompile
-zstyle ':completion:correct:'          prompt 'correct to: %e'             #
-zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'    # Ignore completion functions for commands you don't have:
-
-# complete manual by their section
-zstyle ':completion:*:manuals'    separate-sections true
-zstyle ':completion:*:manuals.*'  insert-sections   true
-zstyle ':completion:*:man:*'      menu yes select
-
-## correction
-# run rehash on completion so new installed program are found automatically:
-_force_rehash() {
-    (( CURRENT == 1 )) && rehash
-    return 1 # Because we didn't really complete anything
-}
-# some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
-if [[ -n "$NOCOR" ]] ; then
-    zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
-    setopt nocorrect # do not try to correct the spelling if possible
-else
-#    zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _ignored _correct _approximate _files
-    setopt correct  # try to correct the spelling if possible
-    zstyle -e ':completion:*' completer '
-        if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then
-            _last_try="$HISTNO$BUFFER$CURSOR"
-            reply=(_complete _match _ignored _prefix _files)
-        else
-            if [[ $words[1] == (rm|mv) ]] ; then
-                reply=(_complete _files)
+    # TODO: This could use some additional information
+
+    # allow one error for every three characters typed in approximate completer
+    zstyle ':completion:*:approximate:'    max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )'
+
+    # don't complete backup files as executables
+    zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)'
+
+    # start menu completion only if it could find no unambiguous initial string
+    zstyle ':completion:*:correct:*'       insert-unambiguous true
+    zstyle ':completion:*:corrections'     format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}'
+    zstyle ':completion:*:correct:*'       original true
+
+    # activate color-completion
+    zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}
+
+    # format on completion
+    zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'
+
+    # complete 'cd -<tab>' with menu
+    zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
+
+    # insert all expansions for expand completer
+    zstyle ':completion:*:expand:*'        tag-order all-expansions
+    zstyle ':completion:*:history-words'   list false
+
+    # activate menu
+    zstyle ':completion:*:history-words'   menu yes
+
+    # ignore duplicate entries
+    zstyle ':completion:*:history-words'   remove-all-dups yes
+    zstyle ':completion:*:history-words'   stop yes
+
+    # match uppercase from lowercase
+    zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'
+
+    # separate matches into groups
+    zstyle ':completion:*:matches'         group 'yes'
+    zstyle ':completion:*'                 group-name ''
+
+    if [[ -z "$NOMENU" ]] ; then
+        # if there are more than 5 options allow selecting from a menu
+        zstyle ':completion:*'               menu select=5
+    else
+        # don't use any menus at all
+        setopt no_auto_menu
+    fi
+
+    zstyle ':completion:*:messages'        format '%d'
+    zstyle ':completion:*:options'         auto-description '%d'
+
+    # describe options in full
+    zstyle ':completion:*:options'         description 'yes'
+
+    # on processes completion complete all user processes
+    zstyle ':completion:*:processes'       command 'ps -au$USER'
+
+    # offer indexes before parameters in subscripts
+    zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
+
+    # provide verbose completion information
+    zstyle ':completion:*'                 verbose true
+
+    # recent (as of Dec 2007) zsh versions are able to provide descriptions
+    # for commands (read: 1st word in the line) that it will list for the user
+    # to choose from. The following disables that, because it's not exactly fast.
+    zstyle ':completion:*:-command-:*:'    verbose false
+
+    # set format for warnings
+    zstyle ':completion:*:warnings'        format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d'
+
+    # define files to ignore for zcompile
+    zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'
+    zstyle ':completion:correct:'          prompt 'correct to: %e'
+
+    # Ignore completion functions for commands you don't have:
+    zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'
+
+    # Provide more processes in completion of programs like killall:
+    zstyle ':completion:*:processes-names' command 'ps c -u ${USER} -o command | uniq'
+
+    # complete manual by their section
+    zstyle ':completion:*:manuals'    separate-sections true
+    zstyle ':completion:*:manuals.*'  insert-sections   true
+    zstyle ':completion:*:man:*'      menu yes select
+
+    # run rehash on completion so new installed program are found automatically:
+    _force_rehash() {
+        (( CURRENT == 1 )) && rehash
+        return 1
+    }
+
+    ## correction
+    # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it
+    if [[ -n "$NOCOR" ]] ; then
+        zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
+        setopt nocorrect
+    else
+        # try to be smart about when to use what completer...
+        setopt correct
+        zstyle -e ':completion:*' completer '
+            if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then
+                _last_try="$HISTNO$BUFFER$CURSOR"
+                reply=(_complete _match _ignored _prefix _files)
             else
-                reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files)
-            fi
-        fi'
-fi
-# zstyle ':completion:*' completer _complete _correct _approximate
-# zstyle ':completion:*' expand prefix suffix
-
-# automatic rehash? Credits go to Frank Terbeck
-# my_accept() {
-#   local buf
-#   [[ -z ${BUFFER} ]] && zle accept-line && return
-#   buf=( ${(z)BUFFER}  )
-#   [[ -z ${commands[${buf[1]}]} ]] && rehash
-#   zle accept-line
-# }
-# zle -N my_accept
-# bindkey "^M" my_accept
+                if [[ $words[1] == (rm|mv) ]] ; then
+                    reply=(_complete _files)
+                else
+                    reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files)
+                fi
+            fi'
+    fi
 
-# command for process lists, the local web server details and host completion
-zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html'
+    # zstyle ':completion:*' completer _complete _correct _approximate
+    # zstyle ':completion:*' expand prefix suffix
 
-# caching
-[[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \
-                          zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/
+    # complete shell aliases
+    # zstyle ':completion:*' completer _expand_alias _complete _approximate
 
-# host completion /* add brackets as vim can't parse zsh's complex cmdlines 8-) {{{ */
-if is42 ; then
-    [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
-    [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
-else
-    _ssh_hosts=()
-    _etc_hosts=()
-fi
-hosts=(
-    $(hostname)
-    "$_ssh_hosts[@]"
-    "$_etc_hosts[@]"
-    grml.org
-    localhost
-)
-zstyle ':completion:*:hosts' hosts $hosts
-#  zstyle '*' hosts $hosts
-
-# specify your logins:
-# my_accounts=(
-#  {grml,grml1}@foo.invalid
-#  grml-devel@bar.invalid
-# )
-# other_accounts=(
-#  {fred,root}@foo.invalid
-#  vera@bar.invalid
-# )
-# zstyle ':completion:*:my-accounts' users-hosts $my_accounts
-# zstyle ':completion:*:other-accounts' users-hosts $other_accounts
-
-# specify specific port/service settings:
-#  telnet_users_hosts_ports=(
-#    user1@host1:
-#    user2@host2:
-#    @mail-server:{smtp,pop3}
-#    @news-server:nntp
-#    @proxy-server:8000
-#  )
-# zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
-
-# use generic completion system for programs not yet defined:
-compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
-
-# see upgrade function in this file
-compdef _hosts upgrade
+    # 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/
+
+    # host completion /* add brackets as vim can't parse zsh's complex cmdlines 8-) {{{ */
+    if is42 ; then
+        [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
+        [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
+    else
+        _ssh_hosts=()
+        _etc_hosts=()
+    fi
+    hosts=(
+        $(hostname)
+        "$_ssh_hosts[@]"
+        "$_etc_hosts[@]"
+        grml.org
+        localhost
+    )
+    zstyle ':completion:*:hosts' hosts $hosts
+    #  zstyle '*' hosts $hosts
+
+    # specify your logins:
+    # my_accounts=(
+    #  {grml,grml1}@foo.invalid
+    #  grml-devel@bar.invalid
+    # )
+    # other_accounts=(
+    #  {fred,root}@foo.invalid
+    #  vera@bar.invalid
+    # )
+    # zstyle ':completion:*:my-accounts' users-hosts $my_accounts
+    # zstyle ':completion:*:other-accounts' users-hosts $other_accounts
+
+    # specify specific port/service settings:
+    #  telnet_users_hosts_ports=(
+    #    user1@host1:
+    #    user2@host2:
+    #    @mail-server:{smtp,pop3}
+    #    @news-server:nntp
+    #    @proxy-server:8000
+    #  )
+    # zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
+
+    # use generic completion system for programs not yet defined; (_gnu_generic works
+    # with commands that provide a --help option with "standard" gnu-like output.)
+    compdef _gnu_generic tail head feh cp mv df stow uname ipacsum fetchipac
+
+    # see upgrade function in this file
+    compdef _hosts upgrade
 }
 # }}}
 
@@ -1473,13 +1781,13 @@ else
     # manzsh()  { man zshall | $MYLESS -p $1 ; }
 fi
 
-if check_com -c most ; then
+if check_com -c $PAGER ; then
     #f1# View Debian's changelog of a given package
     dchange() {
         if [[ -r /usr/share/doc/${1}/changelog.Debian.gz ]] ; then
-            most /usr/share/doc/${1}/changelog.Debian.gz
+            $PAGER /usr/share/doc/${1}/changelog.Debian.gz
         elif [[ -r /usr/share/doc/${1}/changelog.gz ]] ; then
-            most /usr/share/doc/${1}/changelog.gz
+            $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."
@@ -1500,10 +1808,10 @@ if check_com -c most ; then
     #f1# View Debian's NEWS of a given package
     dnews() {
         if [[ -r /usr/share/doc/${1}/NEWS.Debian.gz ]] ; then
-            most /usr/share/doc/${1}/NEWS.Debian.gz
+            $PAGER /usr/share/doc/${1}/NEWS.Debian.gz
         else
             if [[ -r /usr/share/doc/${1}/NEWS.gz ]] ; then
-                most /usr/share/doc/${1}/NEWS.gz
+                $PAGER /usr/share/doc/${1}/NEWS.gz
             else
                 echo "No NEWS file for package $1 found, sorry."
                 return 1
@@ -1516,7 +1824,7 @@ if check_com -c most ; then
     #f1# View upstream's changelog of a given package
     uchange() {
         if [[ -r /usr/share/doc/${1}/changelog.gz ]] ; then
-            most /usr/share/doc/${1}/changelog.gz
+            $PAGER /usr/share/doc/${1}/changelog.gz
         else
             echo "No changelog for package $1 found, sorry."
             return 1
@@ -1549,9 +1857,33 @@ compdef _functions edfunc
 #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}
-if [[ -d /etc/init.d ]] ; then
+if [[ -d /etc/init.d || -d /etc/service ]] ; then
+    __start_stop() {
+        local action_="${1:l}"  # e.g Start/Stop/Restart
+        local service_="$2"
+        local param_="$3"
+
+        local service_target_="$(readlink /etc/init.d/$service_)"
+        if [[ $service_target_ == "/usr/bin/sv" ]]; then
+            # runit
+            case "${action_}" in
+                start) if [[ ! -e /etc/service/$service_ ]]; then
+                           $SUDO ln -s "/etc/sv/$service_" "/etc/service/"
+                       else
+                           $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
+                       fi ;;
+                # there is no reload in runits sysv emulation
+                reload) $SUDO "/etc/init.d/$service_" "force-reload" "$param_" ;;
+                *) $SUDO "/etc/init.d/$service_" "${action_}" "$param_" ;;
+            esac
+        else
+            # sysvinit
+            $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
+        fi
+    }
+
     for i in Start Restart Stop Force-Reload Reload ; do
-        eval "$i() { $SUDO /etc/init.d/\$1 ${i:l} \$2 ; }"
+        eval "$i() { __start_stop $i \"\$1\" \"\$2\" ; }"
     done
 fi
 
@@ -1741,6 +2073,7 @@ for color in BLUE RED GREEN CYAN WHITE ; unset $color
 
 # source another config file if present {{{
 xsource "/etc/zsh/zshrc.local"
+xsource "${HOME}/.zshenv"
 # }}}
 
 # "persistent history" {{{