fi
# load .zshrc.pre to give the user the chance to overwrite the defaults
-[[ -r ${HOME}/.zshrc.pre ]] && source ${HOME}/.zshrc.pre
+[[ -r ${ZDOTDIR:-${HOME}}/.zshrc.pre ]] && source ${ZDOTDIR:-${HOME}}/.zshrc.pre
# check for version/system
# check for versions (compatibility reasons)
local -i ffound
ffile=$1
- (( found = 0 ))
+ (( ffound = 0 ))
for fdir in ${fpath} ; do
[[ -e ${fdir}/${ffile} ]] && (( ffound = 1 ))
done
# modifications in ~/.zshrc.local
zrclocal() {
xsource "/etc/zsh/zshrc.local"
- xsource "${HOME}/.zshrc.local"
+ xsource "${ZDOTDIR:-${HOME}}/.zshrc.local"
return 0
}
# 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 [[ ${fpath} == '/usr/share/grml/zsh/functions' ]] ; then
+ if [[ ${fdir} == '/usr/share/grml/zsh/functions' ]] ; then
for func in ${fdir}/**/[^_]*[^~](N.) ; do
zrcautoload ${func:t}
done
# automatically remove duplicates from these arrays
typeset -U path cdpath fpath manpath
+# Remove zle-line-{init,finish} if it looks like it turns smkx. This would be
+# better fixed by working with those modes too, but we use way too many
+# hardcoded bindings for now.
+function remove_widget () {
+ local name=$1
+ local cap=$2
+ if (( ${+functions[$name]} )) && [[ ${functions[$name]} == *${cap}* ]]; then
+ local w=${widgets[$name]}
+ zle -D $name
+ [[ $w == user:* ]] && unfunction ${w#*:}
+ fi
+}
+remove_widget zle-line-init smkx
+remove_widget zle-line-finish rmkx
+unfunction remove_widget
+
# keybindings
if [[ "$TERM" != emacs ]] ; then
[[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
return 0
fi
- matched_chars='[.-|_a-zA-Z0-9]#'
- LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
+ LBUFFER=${LBUFFER%%(#m)[.\-+:|_a-zA-Z0-9]#}
LBUFFER+=${abk[$MATCH]:-$MATCH}
}
# history
-ZSHDIR=$HOME/.zsh
+ZSHDIR=${ZDOTDIR:-${HOME}/.zsh}
#v#
-HISTFILE=$HOME/.zsh_history
+HISTFILE=${ZDOTDIR:-${HOME}}/.zsh_history
isgrmlcd && HISTSIZE=500 || HISTSIZE=5000
isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history
# dirstack handling
DIRSTACKSIZE=${DIRSTACKSIZE:-20}
-DIRSTACKFILE=${DIRSTACKFILE:-${HOME}/.zdirs}
+DIRSTACKFILE=${DIRSTACKFILE:-${ZDOTDIR:-${HOME}}/.zdirs}
if [[ -f ${DIRSTACKFILE} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then
dirstack=( ${(f)"$(< $DIRSTACKFILE)"} )
MAGENTA="%{${fg[magenta]}%}"
YELLOW="%{${fg[yellow]}%}"
WHITE="%{${fg[white]}%}"
- NO_COLOUR="%{${reset_color}%}"
+ NO_COLOR="%{${reset_color}%}"
else
BLUE=$'%{\e[1;34m%}'
RED=$'%{\e[1;31m%}'
WHITE=$'%{\e[1;37m%}'
MAGENTA=$'%{\e[1;35m%}'
YELLOW=$'%{\e[1;33m%}'
- NO_COLOUR=$'%{\e[0m%}'
+ NO_COLOR=$'%{\e[0m%}'
fi
# gather version control information for inclusion in a prompt
zstyle ':vcs_info:*' actionformats "(%s%)-[%b|%a] " "zsh: %r"
zstyle ':vcs_info:*' formats "(%s%)-[%b] " "zsh: %r"
else
- # these are the same, just with a lot of colours:
- zstyle ':vcs_info:*' actionformats "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOUR} " \
+ # these are the same, just with a lot of colors:
+ zstyle ':vcs_info:*' actionformats "${MAGENTA}(${NO_COLOR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOR} " \
"zsh: %r"
- zstyle ':vcs_info:*' formats "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOUR}%} " \
+ zstyle ':vcs_info:*' formats "${MAGENTA}(${NO_COLOR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOR}%} " \
"zsh: %r"
zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat "%b${RED}:${YELLOW}%r"
fi
return 1
}
+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: rc, rc-always, change-root, user, at, host, path,
+ vcs, percent, sad-smiley, battery.
+
+ 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: rc user change-root at host path vcs precent
+
+ 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 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
+}
+
+typeset -gA grml_prompt_pre_default \
+ grml_prompt_post_default \
+ grml_prompt_token_default
+
+grml_prompt_pre_default=(
+ rc '%F{red}'
+ rc-always ''
+ change-root ''
+ user '%B%F{blue}'
+ at ''
+ host ''
+ path '%b'
+ vcs ''
+ percent ''
+ sad-smiley ''
+ battery ' '
+ newline ''
+ jobs '%F{cyan}'
+ history '%F{green}'
+ date '%F{blue}'
+ time '%F{blue}'
+ shell-level '%F{red}'
+ grml-chroot '%F{red}'
+)
+
+grml_prompt_post_default=(
+ rc '%f'
+ rc-always ''
+ change-root ''
+ user '%f%b'
+ at ''
+ host ''
+ path '%B'
+ vcs ''
+ percent ''
+ sad-smiley ''
+ battery ''
+ newline ''
+ jobs '%f'
+ history '%f'
+ date '%f'
+ time '%f'
+ shell-level '%f'
+ grml-chroot '%f '
+)
+
+grml_prompt_token_default=(
+ rc '%(?..%? )'
+ rc-always '%?'
+ change-root 'debian_chroot'
+ user '%n'
+ at '@'
+ host '%m '
+ path '%40<..<%~%<< '
+ vcs '0'
+ percent '%% '
+ sad-smiley '%(?..:()'
+ battery 'PERCENT'
+ newline $'\n'
+ jobs '[%j running job(s)] '
+ history '{history#%!} '
+ date '%D{%Y-%m-%d}'
+ time '%D{%H:%M:%S} '
+ shell-level '%(3L.+ .)'
+ grml-chroot 'GRML_CHROOT'
+)
+
+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:grml:${grmltheme}:${lr}:$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}"
+ 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
+ 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)
+
+ prompt_grml_precmd_worker
+}
+
+function prompt_grml-chroot_precmd () {
+ emulate -L zsh
+ local grmltheme=grml-chroot
+ local -a left_items right_items
+ left_items=(grml-chroot user at host path percent)
+ right_items=()
+
+ prompt_grml_precmd_worker
+}
+
+function prompt_grml-large_precmd () {
+ emulate -L zsh
+ local grmltheme=grml-large
+ local -a left_items right_items
+ left_items=(rc jobs history shell-level change-root time date newline
+ user at host path vcs percent)
+ right_items=(sad-smiley)
+
+ prompt_grml_precmd_worker
+}
+
+function prompt_grml_precmd_worker () {
+ emulate -L zsh
+ local -i vcscalled=0
+
+ grml_prompt_addto PS1 "${left_items[@]}"
+ if zstyle -T ":prompt:${grmltheme}:right:setup" use-rprompt; then
+ grml_prompt_addto RPS1 "${right_items[@]}"
+ fi
+}
+
# set prompt
if zrcautoload promptinit && promptinit 2>/dev/null ; then
promptinit # people should be able to use their favourite prompt
+
+ # Since we define the required functions in here and not in files in
+ # $fpath, we need to stick the theme's name into `$prompt_themes'
+ # ourselves, since promptinit does not pick them up otherwise.
+ prompt_themes+=( grml grml-chroot grml-large )
+ # Also, keep the array sorted...
+ prompt_themes=( "${(@on)prompt_themes}" )
+
+ if [[ $BATTERY -gt 0 ]]; then
+ zstyle ':prompt:grml:right:setup' items sad-smiley battery
+ add-zsh-hook precmd battery
+ fi
+ if [[ "$TERM" == dumb ]] ; then
+ for i in rc user path jobs history date time shell-level; do
+ zstyle ":prompt:grml(|-large|-chroot):*:items:$i" pre ''
+ zstyle ':prompt:grml(|-large|-chroot):*:items:$i' post ''
+ done
+ unset i
+ zstyle ':prompt:grml(|-large|-chroot):right:setup' use-rprompt false
+ elif (( EUID != 0 )); then
+ zstyle ':prompt:grml(|-large|-chroot):*:items:user' pre '%F{red}'
+ fi
else
print 'Notice: no promptinit available :('
fi
printf '%s' "${esc_end}"
}
-# TODO: revise all these NO* variables and especially their documentation
-# in zsh-help() below.
-is4 && [[ $NOPRECMD -eq 0 ]] && precmd () {
- [[ $NOPRECMD -gt 0 ]] && return 0
- # update VCS information
- (( ${+functions[vcs_info]} )) && vcs_info
-
- if [[ $TERM == screen* ]] ; then
- if [[ -n ${vcs_info_msg_1_} ]] ; then
- ESC_print ${vcs_info_msg_1_}
- else
- ESC_print "zsh"
- fi
- fi
- # just use DONTSETRPROMPT=1 to be able to overwrite RPROMPT
- if [[ ${DONTSETRPROMPT:-} -eq 0 ]] ; then
- if [[ $BATTERY -gt 0 ]] ; then
- # update battery (dropped into $PERCENT) information
- battery
- RPROMPT="%(?..:() ${PERCENT}"
- else
- RPROMPT="%(?..:() "
- fi
- fi
+function grml_reset_screen_title () {
# adjust title of xterm
# see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
[[ ${NOTITLE:-} -gt 0 ]] && return 0
esac
}
+function grml_vcs_to_screen_title () {
+ if [[ $TERM == screen* ]] ; then
+ if [[ -n ${vcs_info_msg_1_} ]] ; then
+ ESC_print ${vcs_info_msg_1_}
+ else
+ ESC_print "zsh"
+ fi
+ fi
+}
+
+zrcautoload add-zsh-hook || add-zsh-hook () { :; }
+if [[ $NOPRECMD -gt 0 ]]; then
+ add-zsh-hook precmd grml_reset_screen_title
+ add-zsh-hook precmd grml_vcs_to_screen_title
+fi
+
# preexec() => a function running before every command
is4 && [[ $NOPRECMD -eq 0 ]] && \
preexec () {
# prompt below)
if [[ $GRMLPROMPT -gt 0 ]] ; then
PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D
-${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "
+${BLUE}%n${NO_COLOR}@%m %40<...<%B%~%b%<< "
else
# This assembles the primary prompt string
if (( EUID != 0 )); then
- PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "
+ PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOR}@%m %40<...<%B%~%b%<< "
else
- PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "
+ PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOR}@%m %40<...<%B%~%b%<< "
fi
fi
fi
zstyle ':completion:*:manuals.*' insert-sections true
zstyle ':completion:*:man:*' menu yes select
+ # Search path for sudo completion
+ zstyle ':completion:*:sudo:*' command-path /usr/local/sbin \
+ /usr/local/bin \
+ /usr/sbin \
+ /usr/bin \
+ /sbin \
+ /bin \
+ /usr/X11R6/bin
+
# provide .. as a completion
zstyle ':completion:*' special-dirs ..
$(hostname)
"$_ssh_hosts[@]"
"$_etc_hosts[@]"
- grml.org
localhost
)
zstyle ':completion:*:hosts' hosts $hosts
_dnews() { _files -W /usr/share/doc -/ }
compdef _dnews dnews
+ #f1# View Debian's copyright of a given package
+ dcopyright() {
+ emulate -L zsh
+ if [[ -r /usr/share/doc/$1/copyright ]] ; then
+ $PAGER /usr/share/doc/$1/copyright
+ else
+ echo "No copyright file for package $1 found, sorry."
+ return 1
+ fi
+ }
+ _dcopyright() { _files -W /usr/share/doc -/ }
+ compdef _dcopyright dcopyright
+
#f1# View upstream's changelog of a given package
uchange() {
emulate -L zsh
# API reference: https://code.google.com/apis/urlshortener/
function zurl() {
emulate -L zsh
+ setopt extended_glob
+
if [[ -z $1 ]]; then
print "USAGE: zurl <URL>"
return 1
fi
- local PN url prog api json data
+ local PN url prog api json contenttype item
+ local -a data
PN=$0
url=$1
api='https://www.googleapis.com/urlshortener/v1/url'
contenttype="Content-Type: application/json"
json="{\"longUrl\": \"${url}\"}"
- data=$($prog --silent -H ${contenttype} -d ${json} $api)
- # Match against a regex and print it
- if [[ $data =~ '"id": "(http://goo.gl/[[:alnum:]]+)"' ]]; then
- print $match;
- fi
+ data=(${(f)"$($prog --silent -H ${contenttype} -d ${json} $api)"})
+ # Parse the response
+ for item in "${data[@]}"; do
+ case "$item" in
+ ' '#'"id":'*)
+ item=${item#*: \"}
+ item=${item%\",*}
+ printf '%s\n' "$item"
+ return 0
+ ;;
+ esac
+ done
+ return 1
}
#f2# Find history events by search pattern and list them by date.