+# Now for the fun part: The grml prompt themes in `promptsys' mode of operation
+
+# This actually defines three prompts:
+#
+# - grml
+# - grml-large
+# - grml-chroot
+#
+# They all share the same code and only differ with respect to which items they
+# contain. The main source of documentation is the `prompt_grml_help' function
+# below, which gets called when the user does this: prompt -h grml
+
+function prompt_grml_help () {
+ cat <<__EOF0__
+ prompt grml
+
+ This is the prompt as used by the grml-live system <http://grml.org>. It is
+ a rather simple one-line prompt, that by default looks something like this:
+
+ <user>@<host> <current-working-directory>[ <vcs_info-data>]%
+
+ The prompt itself integrates with zsh's prompt themes system (as you are
+ witnessing right now) and is configurable to a certain degree. In
+ particular, these aspects are customisable:
+
+ - The items used in the prompt (e.g. you can remove \`user' from
+ the list of activated items, which will cause the user name to
+ be omitted from the prompt string).
+
+ - The attributes used with the items are customisable via strings
+ used before and after the actual item.
+
+ The available items are: at, battery, change-root, date, grml-chroot,
+ history, host, jobs, newline, path, percent, rc, rc-always, sad-smiley,
+ shell-level, time, user, vcs
+
+ The actual configuration is done via zsh's \`zstyle' mechanism. The
+ context, that is used while looking up styles is:
+
+ ':prompt:grml:<left-or-right>:<subcontext>'
+
+ Here <left-or-right> is either \`left' or \`right', signifying whether the
+ style should affect the left or the right prompt. <subcontext> is either
+ \`setup' or 'items:<item>', where \`<item>' is one of the available items.
+
+ The styles:
+
+ - use-rprompt (boolean): If \`true' (the default), print a sad smiley
+ in $RPROMPT if the last command a returned non-successful error code.
+ (This in only valid if <left-or-right> is "right"; ignored otherwise)
+
+ - items (list): The list of items used in the prompt. If \`vcs' is
+ present in the list, the theme's code invokes \`vcs_info'
+ accordingly. Default (left): rc change-root user at host path vcs
+ percent; Default (right): sad-smiley
+
+ Available styles in 'items:<item>' are: pre, post. These are strings that
+ are inserted before (pre) and after (post) the item in question. Thus, the
+ following would cause the user name to be printed in red instead of the
+ default blue:
+
+ zstyle ':prompt:grml:*:items:user' pre '%F{red}'
+
+ Note, that the \`post' style may remain at its default value, because its
+ default value is '%f', which turns the foreground text attribute off (which
+ is exactly, what is still required with the new \`pre' value).
+__EOF0__
+}
+
+function prompt_grml-chroot_help () {
+ cat <<__EOF0__
+ prompt grml-chroot
+
+ This is a variation of the grml prompt, see: prompt -h grml
+
+ The main difference is the default value of the \`items' style. The rest
+ behaves exactly the same. Here are the defaults for \`grml-chroot':
+
+ - left: grml-chroot user at host path percent
+ - right: (empty list)
+__EOF0__
+}
+
+function prompt_grml-large_help () {
+ cat <<__EOF0__
+ prompt grml-large
+
+ This is a variation of the grml prompt, see: prompt -h grml
+
+ The main difference is the default value of the \`items' style. In
+ particular, this theme uses _two_ lines instead of one with the plain
+ \`grml' theme. The rest behaves exactly the same. Here are the defaults
+ for \`grml-large':
+
+ - left: rc jobs history shell-level change-root time date newline user
+ at host path vcs percent
+ - right: sad-smiley
+__EOF0__
+}
+
+function grml_prompt_setup () {
+ emulate -L zsh
+ autoload -Uz vcs_info
+ autoload -Uz add-zsh-hook
+ add-zsh-hook precmd prompt_$1_precmd
+}
+
+function prompt_grml_setup () {
+ grml_prompt_setup grml
+}
+
+function prompt_grml-chroot_setup () {
+ grml_prompt_setup grml-chroot
+}
+
+function prompt_grml-large_setup () {
+ grml_prompt_setup grml-large
+}
+
+# These maps define default tokens and pre-/post-decoration for items to be
+# used within the themes. All defaults may be customised in a context sensitive
+# matter by using zsh's `zstyle' mechanism.
+typeset -gA grml_prompt_pre_default \
+ grml_prompt_post_default \
+ grml_prompt_token_default \
+ grml_prompt_token_function
+
+grml_prompt_pre_default=(
+ at ''
+ battery ' '
+ change-root ''
+ date '%F{blue}'
+ grml-chroot '%F{red}'
+ history '%F{green}'
+ host ''
+ jobs '%F{cyan}'
+ newline ''
+ path '%B'
+ percent ''
+ rc '%B%F{red}'
+ rc-always ''
+ sad-smiley ''
+ shell-level '%F{red}'
+ time '%F{blue}'
+ user '%B%F{blue}'
+ vcs ''
+)
+
+grml_prompt_post_default=(
+ at ''
+ battery ''
+ change-root ''
+ date '%f'
+ grml-chroot '%f '
+ history '%f'
+ host ''
+ jobs '%f'
+ newline ''
+ path '%b'
+ percent ''
+ rc '%f%b'
+ rc-always ''
+ sad-smiley ''
+ shell-level '%f'
+ time '%f'
+ user '%f%b'
+ vcs ''
+)
+
+grml_prompt_token_default=(
+ at '@'
+ battery 'PERCENT'
+ change-root 'debian_chroot'
+ date '%D{%Y-%m-%d}'
+ grml-chroot 'GRML_CHROOT'
+ history '{history#%!} '
+ host '%m '
+ jobs '[%j running job(s)] '
+ newline $'\n'
+ path '%40<..<%~%<< '
+ percent '%# '
+ rc '%(?..%? )'
+ rc-always '%?'
+ sad-smiley '%(?..:()'
+ shell-level '%(3L.+ .)'
+ time '%D{%H:%M:%S} '
+ user '%n'
+ vcs '0'
+)
+
+function GRML_theme_add_token_usage () {
+ cat <<__EOF__
+ Usage: grml_theme_add_token <name> [-f|-i] <token/function> [<pre> <post>]
+
+ <name> is the name for the newly added token. If the \`-f' or \`-i' options
+ are used, <token/function> is the name of the function (see below for
+ details). Otherwise it is the literal token string to be used. <pre> and
+ <post> are optional.
+
+ Options:
+
+ -f <function> Use a function named \`<function>' each time the token
+ is to be expanded.
+
+ -i <function> Use a function named \`<function>' to initialise the
+ value of the token _once_ at runtime.
+
+ The functions are called with one argument: the token's new name. The
+ return value is expected in the \$REPLY parameter. The use of these
+ options is mutually exclusive.
+
+ Example:
+
+ To add a new token \`day' that expands to the current weekday in the
+ current locale in green foreground colour, use this:
+
+ grml_theme_add_token day '%D{%A}' '%F{green}' '%f'
+
+ Another example would be support for \$VIRTUAL_ENV:
+
+ function virtual_env_prompt () {
+ REPLY=\${VIRTUAL_ENV+\${VIRTUAL_ENV:t} }
+ }
+ grml_theme_add_token virtual-env -f virtual_env_prompt
+
+ After that, you will be able to use a changed \`items' style to
+ assemble your prompt.
+__EOF__
+}
+
+function grml_theme_add_token () {
+ emulate -L zsh
+ local name token pre post
+ local -i init funcall
+
+ if (( ARGC == 0 )); then
+ GRML_theme_add_token_usage
+ return 0
+ fi
+
+ init=0
+ funcall=0
+ pre=''
+ post=''
+ name=$1
+ shift
+ if [[ $1 == '-f' ]]; then
+ funcall=1
+ shift
+ elif [[ $1 == '-i' ]]; then
+ init=1
+ shift
+ fi
+
+ if (( ARGC == 0 )); then
+ printf '
+grml_theme_add_token: No token-string/function-name provided!\n\n'
+ GRML_theme_add_token_usage
+ return 1
+ fi
+ token=$1
+ shift
+ if (( ARGC != 0 && ARGC != 2 )); then
+ printf '
+grml_theme_add_token: <pre> and <post> need to by specified _both_!\n\n'
+ GRML_theme_add_token_usage
+ return 1
+ fi
+ if (( ARGC )); then
+ pre=$1
+ post=$2
+ shift 2
+ fi
+
+ if (( ${+grml_prompt_token_default[$name]} )); then
+ printf '
+grml_theme_add_token: Token `%s'\'' exists! Giving up!\n\n' $name
+ GRML_theme_add_token_usage
+ return 2
+ fi
+ if (( init )); then
+ $token $name
+ token=$REPLY
+ fi
+ grml_prompt_pre_default[$name]=$pre
+ grml_prompt_post_default[$name]=$post
+ if (( funcall )); then
+ grml_prompt_token_function[$name]=$token
+ grml_prompt_token_default[$name]=23
+ else
+ grml_prompt_token_default[$name]=$token
+ fi
+}
+
+function grml_typeset_and_wrap () {
+ emulate -L zsh
+ local target="$1"
+ local new="$2"
+ local left="$3"
+ local right="$4"
+
+ if (( ${+parameters[$new]} )); then
+ typeset -g "${target}=${(P)target}${left}${(P)new}${right}"
+ fi
+}
+
+function grml_prompt_addto () {
+ emulate -L zsh
+ local target="$1"
+ local lr it apre apost new v
+ local -a items
+ shift
+
+ [[ $target == PS1 ]] && lr=left || lr=right
+ zstyle -a ":prompt:${grmltheme}:${lr}:setup" items items || items=( "$@" )
+ typeset -g "${target}="
+ for it in "${items[@]}"; do
+ zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" pre apre \
+ || apre=${grml_prompt_pre_default[$it]}
+ 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]}
+ typeset -g "${target}=${(P)target}${apre}"
+ if (( ${+grml_prompt_token_function[$it]} )); then
+ ${grml_prompt_token_function[$it]} $it
+ typeset -g "${target}=${(P)target}${REPLY}"
+ else
+ case $it in
+ battery)
+ grml_typeset_and_wrap $target $new '' ''
+ ;;
+ change-root)
+ grml_typeset_and_wrap $target $new '(' ')'
+ ;;
+ grml-chroot)
+ if [[ -n ${(P)new} ]]; then
+ typeset -g "${target}=${(P)target}(CHROOT)"
+ fi
+ ;;
+ vcs)
+ v="vcs_info_msg_${new}_"
+ if (( ! vcscalled )); then
+ vcs_info
+ vcscalled=1
+ fi
+ if (( ${+parameters[$v]} )) && [[ -n "${(P)v}" ]]; then
+ typeset -g "${target}=${(P)target}${(P)v}"
+ fi
+ ;;
+ *) typeset -g "${target}=${(P)target}${new}" ;;
+ esac
+ fi
+ typeset -g "${target}=${(P)target}${apost}"
+ done
+}
+
+function prompt_grml_precmd () {
+ emulate -L zsh
+ local grmltheme=grml
+ local -a left_items right_items
+ left_items=(rc change-root user at host path vcs percent)
+ right_items=(sad-smiley)