X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=etc%2Fzsh%2Fzshrc;h=a4e1931a8374fc66dc3c4243af3d0bc1be908af2;hb=77db149d44a8b15fcb937caec992410660d6570f;hp=283c8ddf7e1ddc9bf6f6c00b13d7018e5aa84611;hpb=5df45d5ad3b55b9274bde7d467886f00eda1d628;p=grml-etc-core.git diff --git a/etc/zsh/zshrc b/etc/zsh/zshrc index 283c8dd..a4e1931 100644 --- a/etc/zsh/zshrc +++ b/etc/zsh/zshrc @@ -1010,78 +1010,38 @@ if [[ -n "$BATTERY" ]] ; then fi # }}} -# display version control information on right side of prompt if $VCS is set {{{ -# based on Mike Hommey's http://web.glandium.org/blog/?p=170 -__vcs_dir() { - local vcs base_dir sub_dir ref - - sub_dir() { - local sub_dir - sub_dir=$(readlink -f "${PWD}") - sub_dir=${sub_dir#$1} - echo ${sub_dir#/} - } - - git_dir() { - base_dir=$(git-rev-parse --show-cdup 2>/dev/null) || return 1 - base_dir=$(readlink -f "$base_dir/..") - sub_dir=$(git-rev-parse --show-prefix) - sub_dir=${sub_dir%/} - ref=$(git-symbolic-ref -q HEAD || git-name-rev --name-only HEAD 2>/dev/null) - ref=${ref#refs/heads/} - vcs="git" - } - - svn_dir() { - [[ -d ".svn" ]] || return 1 - base_dir="." - while [[ -d "$base_dir/../.svn" ]]; do base_dir="$base_dir/.."; done - base_dir=$(readlink -f "$base_dir") - sub_dir=$(sub_dir "${base_dir}") - ref=$(svn info "$base_dir" | awk '/^URL/ { sub(".*/","",$0); r=$0 } /^Revision/ { sub("[^0-9]*","",$0); print r":"$0 }') - vcs="svn" - } - - svk_dir() { - [[ -f ~/.svk/config ]] || return 1 - base_dir=$(awk '/: *$/ { sub(/^ */,"",$0); sub(/: *$/,"",$0); if (match("'${PWD}'", $0"(/|$)")) { print $0; d=1; } } /depotpath/ && d == 1 { sub(".*/","",$0); r=$0 } /revision/ && d == 1 { print r ":" $2; exit 1 }' ~/.svk/config) && return 1 - ref=${base_dir##* - } - base_dir=${base_dir%% - *} - sub_dir=$(sub_dir "${base_dir}") - vcs="svk" - } - - hg_dir() { - base_dir="." - while [[ ! -d "$base_dir/.hg" ]]; do - base_dir="$base_dir/.." - [[ $(readlink -f "${base_dir}") = "/" ]] && return 1 - done - base_dir=$(readlink -f "$base_dir") - sub_dir=$(sub_dir "${base_dir}") - ref=$(< "${base_dir}/.hg/branch") - vcs="hg" - } +# set colors for use in prompts {{{ +if zrcautoload colors && colors 2>/dev/null ; then + BLUE="%{${fg[blue]}%}" + RED="%{${fg_bold[red]}%}" + GREEN="%{${fg[green]}%}" + CYAN="%{${fg[cyan]}%}" + MAGENTA="%{${fg[magenta]}%}" + YELLOW="%{${fg[yellow]}%}" + WHITE="%{${fg[white]}%}" + NO_COLOUR="%{${reset_color}%}" +else + BLUE=$'%{\e[1;34m%}' + RED=$'%{\e[1;31m%}' + GREEN=$'%{\e[1;32m%}' + CYAN=$'%{\e[1;36m%}' + WHITE=$'%{\e[1;37m%}' + MAGENTA=$'%{\e[1;35m%}' + YELLOW=$'%{\e[1;33m%}' + NO_COLOUR=$'%{\e[0m%}' +fi - hg_dir || - git_dir || - svn_dir || - svk_dir # || - # base_dir="$PWD" - # echo "${vcs:+($vcs)}${base_dir/$HOME/~}${vcs:+[$ref]${sub_dir}}" - echo "${vcs:+($vcs)}${base_dir}${vcs:+[$ref]${sub_dir}}" -} +# }}} -# gather version control information for inclusion in a prompt +# gather version control information for inclusion in a prompt {{{ # vcs_info() documentation: {{{ # -# The vcs_info () feature can be configured via zstyle: +# The vcs_info() feature can be configured via zstyle: # First, the context in which we are working: # :vcs_info: -# ...where is one of: git, hg, bzr, svn or svk +# ...where is one of: +# - git, git-svn, hg, darcs, bzr, mtn, svn, cvs or svk # # You can of course use ':vcs_info:*' to match all VCSs at once. # @@ -1092,8 +1052,19 @@ __vcs_dir() { # promptformat - Used in most circumstances. # promptactionformat - Used if a there is a special action going on; # (like an interactive rebase or a merge conflict) -# enable - check in the 'init' context. If set to false, +# enable - Check in the 'init' context. If set to false, # vcs_info() will do nothing. +# disable - Provide a list of systems, you don't want +# the prompt to check for repositories (checked +# in the 'init' context, too). +# use-simple - If there are two different ways of gathering +# information, you can select the simpler one +# by setting this style to true; the default +# is to use the not-that-simple code, which is +# potentially a lot slower but might be more +# accurate in all possible cases. +# +# The use-simple style is currently only available for the bzr backend. # # The default values for these in all contexts are: # promptformat " (%s)-[%b|%a]-" @@ -1111,17 +1082,52 @@ __vcs_dir() { # # Not all vcs backends may support all replacements # +# Examples: +# Don't use vcs_info at all (even though it's in your prompt): +# % zstyle ':vcs_info:*' enable false +# +# Don't provide prompt info for bzr and svk: +# % zstyle ':vcs_info:*' disable bzr svk +# +# Provide a prompt specifically for git: +# % zstyle ':vcs_info:git' promptformat ' GIT, BABY! [%b]' +# % zstyle ':vcs_info:git' promptactionformat ' GIT ACTION! [%b|%a]' +# +# Use the quicker bzr backend (if you do, please report if it does +# the-right-thing[tm] - thanks): +# % zstyle ':vcs_info:bzr' use-simple true +# # If you want colors, make sure you enclose the color codes in %{...%}, because -# the string provided by vcs_info() is commonly used for prompts. +# the string provided by vcs_info() is used for prompts. # # Example: PROMPT='%(?..[%?]-)%3~%$(vcs_info)#' # # This *requires* 'setopt prompt_subst'. # }}} -VCS_INFO_default_action_format=' (%s)-[%b|%a]-' -VCS_INFO_default_format=' (%s)-[%b]-' +VCS_INFO_adjust () { #{{{ + [[ -n ${vcs_comm[overwrite_name]} ]] && vcs=${vcs_comm[overwrite_name]} + return 0 +} +# }}} +VCS_INFO_format () { # {{{ + local msg + + if [[ -n ${1} ]] ; then + zstyle -s ":vcs_info:${vcs}" promptactionformat msg + [[ -z ${msg} ]] && msg=' (%s)-[%b|%a]-' + else + zstyle -s ":vcs_info:${vcs}" promptformat msg + [[ -z ${msg} ]] && msg=' (%s)-[%b]-' + fi + printf '%s' ${msg} +} +# }}} VCS_INFO_realpath () { #{{{ # replacing 'readlink -f', which is really not portable. + + # If there *is* a chpwd() function unfunction it here. + # The *real* zsh does not loose its chpwd(), because we run + # in a different context (process substitution in $PROMPT). (( ${+functions[chpwd]} )) && unfunction chpwd setopt chaselinks cd $1 2>/dev/null && pwd @@ -1142,7 +1148,7 @@ VCS_INFO_git_getaction () { #{{{ else gitaction="am/rebase" fi - print '%s' ${gitaction} + printf '%s' ${gitaction} return 0 fi done @@ -1183,6 +1189,7 @@ VCS_INFO_git_getbranch () { #{{{ || [[ -d "${gitdir}/../.dotest" ]] \ || [[ -f "${gitdir}/MERGE_HEAD" ]] ; then gitbranch="$(${(z)gitsymref} 2> /dev/null)" + [[ -z ${gitbranch} ]] && gitbranch="$(< ${gitdir}/rebase-apply/head-name)" elif [[ -f "${gitdir}/rebase-merge/interactive" ]] \ || [[ -d "${gitdir}/rebase-merge" ]] ; then @@ -1211,16 +1218,14 @@ VCS_INFO_git_get_data () { # {{{ setopt localoptions extendedglob local gitdir gitbase gitbranch gitaction msg - gitdir="$(git rev-parse --git-dir 2> /dev/null)" - - if [[ $? -eq 0 ]] ; then - gitbranch="$(VCS_INFO_git_getbranch ${gitdir})" - fi + gitdir=${vcs_comm[gitdir]} + gitbranch="$(VCS_INFO_git_getbranch ${gitdir})" if [[ -z ${gitdir} ]] || [[ -z ${gitbranch} ]] ; then return fi + VCS_INFO_adjust gitaction="$(VCS_INFO_git_getaction ${gitdir})" msg=$(VCS_INFO_format ${gitaction}) @@ -1230,20 +1235,39 @@ VCS_INFO_git_get_data () { # {{{ printf '%s' ${msg} } # }}} +VCS_INFO_darcs_get_data () { # {{{ + local msg darcsbase + + darcsbase=${vcs_comm[basedir]} + msg=$(VCS_INFO_format) + zformat -f msg "${msg}" "a:" "b:${darcsbase:t}" "s:${vcs}" "r:${darcsbase:t}" "R:${darcsbase}" + printf '%s' ${msg} +} +# }}} VCS_INFO_hg_get_data () { # {{{ local msg hgbranch hgbase - hgbase=${1} + hgbase=${vcs_comm[basedir]} hgbranch=$(< ${hgbase}/.hg/branch) msg=$(VCS_INFO_format) zformat -f msg "${msg}" "a:" "b:${hgbranch}" "s:${vcs}" "r:${hgbase:t}" "R:${hgbase}" printf '%s' ${msg} } # }}} +VCS_INFO_mtn_get_data () { # {{{ + local msg mtnbranch mtnbase + + mtnbase=${vcs_comm[basedir]} + mtnbranch=$(mtn status | awk '/Current branch:/{ sub("Current branch: ", ""); print }') + msg=$(VCS_INFO_format) + zformat -f msg "${msg}" "a:" "b:${mtnbranch}" "s:${vcs}" "r:${mtnbase:t}" "R:${mtnbase}" + printf '%s' ${msg} +} +# }}} VCS_INFO_svk_get_data () { # {{{ local msg svkbranch svkbase - svkbase=${1} + svkbase=${vcs_comm[basedir]} svkbranch=${svkbase##* } svkbase=${svkbase%% @@ -1272,60 +1296,127 @@ VCS_INFO_svn_get_data () { # {{{ VCS_INFO_bzr_get_data () { # {{{ local msg bzrbranch bzrbase bzrrevno i j - bzrbase=$(bzr info | sed -rne 's, *branch root: ,,p') - case ${bzrbase} in - .) bzrbase=${PWD} ;; - esac + if zstyle -t ":vcs_info:${vcs}" "use-simple" ; then + bzrbase=${vcs_comm[basedir]} + bzrbranch=${bzrbase:t} + if [[ -f ${bzrbase}/.bzr/branch/last-revision ]] ; then + bzrrevno=$(< ${bzrbase}/.bzr/branch/last-revision) + bzrrevno=${bzrrevno%% *} + fi + else + bzrbase=$(bzr info 2>/dev/null | sed -rne 's, *branch root: ,,p') + bzrbase=$(VCS_INFO_realpath ${bzrbase}) + + bzr version-info 2> /dev/null | while read i j; do + case "${i}" in + revno:) + bzrrevno=${j} ;; + branch-nick:) + bzrbranch=${j} ;; + esac + done + fi - bzr version-info | while read i j; do - case "${i}" in - revno:) - bzrrevno=${j} ;; - branch-nick:) - bzrbranch=${j} ;; - esac + msg=$(VCS_INFO_format) + zformat -f msg "${msg}" "a:" "b:${bzrbranch}:${bzrrevno}" "s:${vcs}" "r:${bzrbase:t}" "R:${bzrbase}" + printf '%s' ${msg} +} +# }}} +VCS_INFO_cvs_get_data () { # {{{ + local msg cvsbranch cvsbase basename + + cvsbase="." + while [[ -d "${cvsbase}/../CVS" ]]; do + cvsbase="${cvsbase}/.." done + cvsbase=$(VCS_INFO_realpath ${cvsbase}) + cvsbranch=$(< ./CVS/Repository) + basename=${cvsbase:t} + cvsbranch=${cvsbranch##${basename}/} + [[ -z ${cvsbranch} ]] && cvsbranch=${basename} msg=$(VCS_INFO_format) - zformat -f msg "${msg}" "a:" "b:${bzrbranch}:${bzrrevno}" "s:${vcs}" "r:${bzrbase:t}" "R:${bzrbase}" + zformat -f msg "${msg}" "a:" "b:${cvsbranch}" "s:${vcs}" "r:${basename}" "R:${cvsbase}" printf '%s' ${msg} } # }}} # VCS_INFO_*_detect () {{{ +VCS_INFO_detect_by_dir() { + local dirname=${1} + local basedir="." realbasedir + + realbasedir=$(VCS_INFO_realpath ${basedir}) + while [[ ${realbasedir} != '/' ]]; do + if [[ -n ${vcs_comm[detect_need_file]} ]] ; then + [[ -d ${basedir}/${dirname} ]] && \ + [[ -f ${basedir}/${dirname}/${vcs_comm[detect_need_file]} ]] && \ + break + else + [[ -d ${basedir}/${dirname} ]] && break + fi + + basedir=${basedir}/.. + realbasedir=$(VCS_INFO_realpath ${basedir}) + done + + [[ ${realbasedir} == "/" ]] && return 1 + vcs_comm[basedir]=${realbasedir} + return 0 +} + VCS_INFO_bzr_detect() { check_com -c bzr || return 1 - [[ -d ".bzr" ]] && return 0 + vcs_comm[detect_need_file]=branch/format + VCS_INFO_detect_by_dir '.bzr' + return $? +} + +VCS_INFO_cvs_detect() { + check_com -c svn || return 1 + [[ -d "CVS" ]] && return 0 return 1 } +VCS_INFO_darcs_detect() { + check_com -c darcs || return 1 + vcs_comm[detect_need_file]=format + VCS_INFO_detect_by_dir '_darcs' + return $? +} + VCS_INFO_git_detect() { - check_com -c git && git rev-parse --is-inside-work-tree &> /dev/null && return 0 + if check_com -c git && git rev-parse --is-inside-work-tree &> /dev/null ; then + vcs_comm[gitdir]="$(git rev-parse --git-dir 2> /dev/null)" || return 1 + [[ -d ${vcs_comm[gitdir]}/svn ]] && vcs_comm[overwrite_name]='git-svn' + return 0 + fi return 1 } VCS_INFO_hg_detect() { - local basedir="." - check_com -c hg || return 1 - while [[ ! -d ${basedir}/.hg ]]; do - basedir=${basedir}/.. - [[ $(VCS_INFO_realpath ${basedir}) = "/" ]] && return 1 - done + vcs_comm[detect_need_file]=branch + VCS_INFO_detect_by_dir '.hg' + return $? +} - printf '%s' $(VCS_INFO_realpath ${basedir}) - return 0 +VCS_INFO_mtn_detect() { + check_com -c mtn || return 1 + vcs_comm[detect_need_file]=revision + VCS_INFO_detect_by_dir '_MTN' + return $? } VCS_INFO_svk_detect() { - local output + local basedir check_com -c svk || return 1 [[ -f ~/.svk/config ]] || return 1 - output=$(awk '/: *$/ { sub(/^ */,"",$0); sub(/: *$/,"",$0); if (match("'${PWD}'", $0"(/|$)")) { print $0; d=1; } } /depotpath/ && d == 1 { sub(".*/","",$0); r=$0 } /revision/ && d == 1 { print r ":" $2; exit 1 }' ~/.svk/config) && return 1 + basedir=$(awk '/: *$/ { sub(/^ */,"",$0); sub(/: *$/,"",$0); if (match("'${PWD}'", $0"(/|$)")) { print $0; d=1; } } /depotpath/ && d == 1 { sub(".*/","",$0); r=$0 } /revision/ && d == 1 { print r ":" $2; exit 1 }' ~/.svk/config) && return 1 - printf '%s' ${output} + vcs_comm[basedir]=${basedir} return 0 } @@ -1336,48 +1427,43 @@ VCS_INFO_svn_detect() { } # }}} -VCS_INFO_format () { # {{{ - local msg - - if [[ -n ${1} ]] ; then - zstyle -s ":vcs_info:${vcs}" promptactionformat msg - [[ -z ${msg} ]] && msg=${VCS_INFO_default_action_format} - else - zstyle -s ":vcs_info:${vcs}" promptformat msg - [[ -z ${msg} ]] && msg=${VCS_INFO_default_format} - fi - printf '%s' ${msg} -} -# }}} vcs_info () { # {{{ - local string output + local string local -i found - local -a VCSs + local -a VCSs disabled local -x vcs + local -Ax vcs_comm vcs="init" zstyle -T ":vcs_info:${vcs}" "enable" || return 0 + zstyle -a ":vcs_info:${vcs}" "disable" disabled - VCSs=(git hg bzr svn svk) + VCSs=(git hg bzr darcs mtn svn cvs svk) (( found = 0 )) for vcs in ${VCSs} ; do - output=$(VCS_INFO_${vcs}_detect) && (( found = 1 )) && break + [[ -n ${(M)disabled:#${vcs}} ]] && continue + vcs_comm=() + VCS_INFO_${vcs}_detect && (( found = 1 )) && break done (( found == 0 )) && return 0 - string=$(VCS_INFO_${vcs}_get_data ${output}) || return 1 + string=$(VCS_INFO_${vcs}_get_data) || return 1 printf '%s' ${string} return 0 } # }}} # change vcs_info formats for the grml prompt -zstyle ':vcs_info:*' promptactionformat \ -"%{${fg[magenta]}%}(%{${reset_color}%}%s%{${fg[magenta]}%})%{${fg[yellow]}%}-%{${fg[magenta]}%}[%{${fg[green]}%}%b%{${fg[yellow]}%}|%{${fg[red]}%}%a%{${fg[magenta]}%}]%{${reset_color}%} " -zstyle ':vcs_info:*' promptformat \ -"%{${fg[magenta]}%}(%{${reset_color}%}%s%{${fg[magenta]}%})%{${fg[yellow]}%}-%{${fg[magenta]}%}[%{${fg[green]}%}%b%{${fg[magenta]}%}]%{${reset_color}%} " +if [[ "$TERM" == dumb ]] ; then + zstyle ':vcs_info:*' promptactionformat "(%s%)-[%b|%a] " + zstyle ':vcs_info:*' promptformat "(%s%)-[%b] " +else + # these are the same, just with a lot of colours: + zstyle ':vcs_info:*' promptactionformat "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOUR} " + zstyle ':vcs_info:*' promptformat "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOUR}%} " +fi # }}} @@ -1388,6 +1474,7 @@ else print 'Notice: no promptinit available :(' fi +setopt prompt_subst # precmd() => a function which is executed just before each prompt # use 'NOPRECMD=1' to disable the precmd + preexec commands @@ -1409,8 +1496,6 @@ is4 && [[ -z $NOPRECMD ]] && precmd () { if [[ -n $BATTERY ]] ; then RPROMPT="%(?..:()% ${PERCENT}${SCREENTITLE}" # RPROMPT="${PERCENT}${SCREENTITLE}" - elif [[ -n $VCS ]] ; then - RPROMPT="%(?..:()% $(__vcs_dir)${SCREENTITLE}" else RPROMPT="%(?..:()% ${SCREENTITLE}" # RPROMPT="${SCREENTITLE}" @@ -1456,23 +1541,6 @@ preexec () { esac } -# set colors -if zrcautoload colors && colors 2>/dev/null ; then - BLUE="%{${fg[blue]}%}" - RED="%{${fg_bold[red]}%}" - GREEN="%{${fg[green]}%}" - CYAN="%{${fg[cyan]}%}" - WHITE="%{${fg[white]}%}" - NO_COLOUR="%{${reset_color}%}" -else - BLUE=$'%{\e[1;34m%}' - RED=$'%{\e[1;31m%}' - GREEN=$'%{\e[1;32m%}' - CYAN=$'%{\e[1;36m%}' - WHITE=$'%{\e[1;37m%}' - NO_COLOUR=$'%{\e[0m%}' -fi - EXITCODE="%(?..%?%1v )" PS2='`%_> ' # secondary prompt, printed when the shell needs more information to complete a command. PS3='?# ' # selection prompt used within a select loop. @@ -1485,7 +1553,7 @@ fi # don't use colors on dumb terminals (like emacs): if [[ "$TERM" == dumb ]] ; then - PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< %# " + PROMPT="${EXITCODE}${debian_chroot:+($debian_chroot)}%n@%m %40<...<%B%~%b%<< "'$(vcs_info)'"%# " else # only if $GRMLPROMPT is set (e.g. via 'GRMLPROMPT=1 zsh') use the extended prompt # set variable identifying the chroot you work in (used in the prompt below) @@ -1493,10 +1561,11 @@ else PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D ${BLUE}%n${NO_COLOUR}@%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%<< %# " # primary prompt string + PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "'$(vcs_info)'"%# " else - PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< %# " # primary prompt string + PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< "'$(vcs_info)'"%# " fi fi fi @@ -2374,7 +2443,7 @@ bk() { # }}} # {{{ make sure our environment is clean regarding colors -for color in BLUE RED GREEN CYAN WHITE ; unset $color +for color in BLUE RED GREEN CYAN YELLOW MAGENTA WHITE ; unset $color # }}} # source another config file if present {{{