diff options
Diffstat (limited to 'Functions')
-rw-r--r-- | Functions/VCS_Info/.distfiles | 1 | ||||
-rw-r--r-- | Functions/VCS_Info/Backends/VCS_INFO_detect_hg | 14 | ||||
-rw-r--r-- | Functions/VCS_Info/Backends/VCS_INFO_get_data_git | 35 | ||||
-rw-r--r-- | Functions/VCS_Info/Backends/VCS_INFO_get_data_hg | 295 | ||||
-rw-r--r-- | Functions/VCS_Info/VCS_INFO_formats | 26 | ||||
-rw-r--r-- | Functions/VCS_Info/VCS_INFO_hook | 10 | ||||
-rw-r--r-- | Functions/VCS_Info/VCS_INFO_quilt | 190 | ||||
-rw-r--r-- | Functions/VCS_Info/vcs_info | 30 |
8 files changed, 475 insertions, 126 deletions
diff --git a/Functions/VCS_Info/.distfiles b/Functions/VCS_Info/.distfiles index cde11b26c..988e7ada4 100644 --- a/Functions/VCS_Info/.distfiles +++ b/Functions/VCS_Info/.distfiles @@ -11,6 +11,7 @@ vcs_info_lastmsg VCS_INFO_maxexports VCS_INFO_nvcsformats vcs_info_printsys +VCS_INFO_quilt VCS_INFO_realpath VCS_INFO_reposub VCS_INFO_set diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_hg b/Functions/VCS_Info/Backends/VCS_INFO_detect_hg index 36078b7a7..e2866afd5 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_detect_hg +++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_hg @@ -4,9 +4,17 @@ setopt localoptions NO_shwordsplit -[[ $1 == '--flavours' ]] && return 1 +[[ $1 == '--flavours' ]] && { print -l hg-git hg-hgsubversion hg-hgsvn; return 0 } VCS_INFO_check_com ${vcs_comm[cmd]} || return 1 vcs_comm[detect_need_file]=store -VCS_INFO_bydir_detect '.hg' -return $? +VCS_INFO_bydir_detect '.hg' || return 1 + +if [[ -d ${vcs_comm[basedir]}/.hg/svn ]] ; then + vcs_comm[overwrite_name]='hg-hgsubversion' +elif [[ -d ${vcs_comm[basedir]}/.hgsvn ]] ; then + vcs_comm[overwrite_name]='hg-hgsvn' +elif [[ -e ${vcs_comm[basedir]}/.hg/git-mapfile ]] ; then + vcs_comm[overwrite_name]='hg-git' +fi +return 0 diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git index 4018b5d92..778d0610b 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git +++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git @@ -3,7 +3,7 @@ ## Distributed under the same BSD-ish license as zsh itself. setopt localoptions extendedglob NO_shwordsplit -local gitdir gitbase gitbranch gitaction gitunstaged gitstaged gitsha1 gitmisc +local gitdir gitbase gitbranch gitaction gitunstaged gitstaged gitsha1 local stgitpatch stgitunapplied local -xA hook_com @@ -139,33 +139,40 @@ if [[ -d $patchdir ]] ; then stgit_unapplied=(${(f)"$(< "${patchdir}/unapplied")"}) stgit_unapplied=( ${(oa)stgit_applied} ) - if VCS_INFO_hook 'gen-stgit-patch-string' "${stgit_applied[@]}"; then + if VCS_INFO_hook 'gen-applied-string' "${stgit_applied[@]}"; then if (( ${#stgit_applied} )); then stgitpatch=${stgit_applied[1]} else - stgitpatch="no patch applied" + stgitpatch="" fi else - stgitpatch=${hook_com[stgit-patch-string]} + stgitpatch=${hook_com[patch-string]} fi - if VCS_INFO_hook 'gen-stgit-unapplied-string' "${stgit_unapplied[@]}"; then + hook_com=() + if VCS_INFO_hook 'gen-unapplied-string' "${stgit_unapplied[@]}"; then stgitunapplied=${#stgit_unapplied} else - stgitunapplied=${hook_com[stgit-unapplied-string]} + stgitunapplied=${hook_com[unapplied-string]} fi - zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" stgitformat stgitmsg || stgitmsg=" %p (%c)" - hook_com=( patch "${stgitpatch}" unapplied "${stgitunapplied}" ) - if VCS_INFO_hook 'set-stgit-format' "${stgitformat}"; then - zformat -f stgitmsg "${stgitmsg}" "p:${hook_com[patch]}" "c:${hook_com[unapplied]}" - gitmisc=${stgitmsg} + if (( ${#stgit_applied} )); then + zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" patch-format stgitmsg || stgitmsg="%p (%n applied)" + else + zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" nopatch-format stgitmsg || stgitmsg="no patch applied" + fi + hook_com=( applied "${stgitpatch}" unapplied "${stgitunapplied}" + applied-n ${#stgit_applied} unapplied-n ${#stgit_unapplied} ) + if VCS_INFO_hook 'set-patch-format' "${stgitmsg}"; then + zformat -f stgitmsg "${stgitmsg}" "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \ + "n:${#stgit_applied}" "c:${#stgit_unapplied}" else - gitmisc=${hook_com[stgit-replace]} + stgitmsg=${hook_com[patch-replace]} fi hook_com=() else - gitmisc='' + stgitmsg='' fi -VCS_INFO_formats "${gitaction}" "${gitbranch}" "${gitbase}" "${gitstaged}" "${gitunstaged}" "${gitsha1}" "${gitmisc}" +backend_misc[patches]="${stgitmsg}" +VCS_INFO_formats "${gitaction}" "${gitbranch}" "${gitbase}" "${gitstaged}" "${gitunstaged}" "${gitsha1}" "${stgitmsg}" return 0 diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg index 1c103a541..2324bc809 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg +++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg @@ -1,128 +1,239 @@ ## vim:ft=zsh ## mercurial support by: Frank Terbeck <ft@bewatermyfriend.org> +## with large contributions by Seth House <seth@eseth.com> ## Distributed under the same BSD-ish license as zsh itself. -setopt localoptions NO_shwordsplit -local file hgbranch hgbranch_name hgbase hghash hglrev hgmqstring \ - r_branch hgchanges revformat bookmarks r_bmhash r_bmname hgbmstring -local -i getbookmarks -local -a hgbm mqpatches hgmisc_args +setopt localoptions extendedglob NO_shwordsplit + +local hgbase bmfile branchfile rebasefile dirstatefile mqseriesfile \ + mqstatusfile mqguardsfile patchdir mergedir \ + r_csetid r_lrev r_branch i_bmhash i_bmname \ + revformat branchformat hgactionstring hgchanges \ + hgbmstring hgmqstring applied_string unapplied_string guards_string + +local -a hgid_args defrevformat defbranchformat \ + hgbmarks mqpatches mqseries mqguards mqunapplied hgmisc \ + i_patchguards i_negguards i_posguards + local -xA hook_com hgbase=${vcs_comm[basedir]} rrn=${hgbase:t} +r_csetid='' # changeset id (long hash) +r_lrev='' # local revision +patchdir="${hgbase}/.hg/patches" +mergedir="${hgbase}/.hg/merge/" +bmfile="${hgbase}/.hg/bookmarks" +branchfile="${hgbase}/.hg/branch" +rebasefile="${hgbase}/.hg/rebasestate" +dirstatefile="${hgbase}/.hg/dirstate" +mqstatusfile="${patchdir}/status" # currently applied patches +mqseriesfile="${patchdir}/series" # all patches +mqguardsfile="${patchdir}/guards" + +# Look for any --flavours +VCS_INFO_adjust + +# Calling the 'hg' program is quite a bit too slow for prompts. +# Disabled by default anyway, so no harm done. +if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-revision ; then + # Calling hexdump is (much) faster than hg but doesn't get the local rev + if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" use-simple \ + && ( VCS_INFO_check_com hexdump ) && [[ -r ${dirstatefile} ]] ; then + r_csetid=$(hexdump -n 20 -e '1/1 "%02x"' ${dirstatefile}) + else + hgid_args=( --debug id -i -n -b ) + + # Looking for changes is a tad bit slower since the dirstate cache must + # first be refreshed before being read + zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" \ + "check-for-changes" || hgid_args+=( -r. ) + + local HGRCPATH + HGRCPATH="/dev/null" ${vcs_comm[cmd]} ${(z)hgid_args} \ + | read -r r_csetid r_lrev r_branch + fi +fi -file="${hgbase}/.hg/branch" -if [[ -r ${file} ]] ; then - hgbranch_name=$(< ${file}) +# If the user doesn't opt to invoke hg we can still get the current branch +if [[ -z ${r_branch} && -r ${branchfile} ]] ; then + r_branch=$(< ${branchfile}) else - hgbranch_name="default" + r_branch="default" fi -hghash='' -hglrev='' -hgbm=() -bookmarks="${hgbase}/.hg/bookmarks" -if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-revision ; then - # Calling the 'hg' program is quite a bit too slow for prompts. - # If there's a way around that, I'd be interested. - # Disabled by default anyway, so no harm done. - local HGRCPATH +# The working dir has uncommitted-changes if the revision ends with a + +if [[ $r_lrev[-1] == + ]] ; then + hgchanges=1 - if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" \ - "check-for-changes" ; then + r_lrev=${r_lrev%+} + r_csetid=${r_csetid%+} +fi - HGRCPATH="/dev/null" ${vcs_comm[cmd]} id --debug -i -n -b \ - | read -r hghash hglrev r_branch +# This directory only exists during a merge +[[ -d $mergedir ]] && hgactionstring="merging" - # Are there uncommitted-changes? - if [[ $hglrev[-1] == + ]] ; then - hgchanges=1 - fi +# This file only exists during a rebase +[[ -e $rebasefile ]] && hgactionstring="rebasing" + + +### Build the current revision display +[[ -n ${r_csetid} ]] && defrevformat+=( "%h" ) +[[ -n ${r_lrev} ]] && defrevformat+=( "%r" ) + +zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" \ + "hgrevformat" revformat || revformat=${(j/:/)defrevformat} + +hook_com=( localrev "${r_lrev}" "hash" "${r_csetid}" ) - # Remove uncommitted-changes marker, if any - hglrev=${hglrev/+/} - hghash=${hghash/+/} +if VCS_INFO_hook 'set-hgrev-format' "${revformat}"; then + zformat -f r_lrev "${revformat}" \ + "r:${hook_com[localrev]}" "h:${hook_com[hash]}" +else + r_lrev=${hook_com[rev-replace]} +fi + +hook_com=() + +### Build the branch display +[[ -n ${r_branch} ]] && defbranchformat+=( "%b" ) +[[ -n ${r_lrev} ]] && defbranchformat+=( "%r" ) + +zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" \ + branchformat branchformat || branchformat=${(j/:/)defbranchformat} + +hook_com=( branch "${r_branch}" revision "${r_lrev}" ) + +if VCS_INFO_hook 'set-branch-format' "${branchformat}"; then + zformat -f branchformat "${branchformat}" \ + "b:${hook_com[branch]}" "r:${hook_com[revision]}" +else + branchformat=${hook_com[branch-replace]} +fi + +hook_com=() + +### Look for current Bookmarks (this requires knowing the changeset id) +if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-bookmarks \ + && [[ -r "${bmfile}" ]] && [[ -n "$r_csetid" ]] ; then + while read -r i_bmhash i_bmname ; do + # Compare hash in bookmarks file with changeset id + [[ $r_csetid == $i_bmhash ]] && hgbmarks+=( $i_bmname ) + done < ${bmfile} + + if VCS_INFO_hook 'gen-hg-bookmark-string' "${hgbmarks[@]}"; then + hgbmstring=${(j:, :)hgbmarks} else - HGRCPATH="/dev/null" ${vcs_comm[cmd]} \ - parents --template="{node} {rev} {branches}\n" \ - | read -r hghash hglrev r_branch + hgbmstring=${hook_com[hg-bookmark-string]} fi - if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "get-bookmarks" \ - && getbookmarks=1 || getbookmarks=0 + hook_com=() +fi - if (( getbookmarks )) && [[ -r "${bookmarks}" ]] ; then - while read -r r_bmhash r_bmname ; do - if [[ $hghash == $r_bmhash ]] ; then - hgbm=( "$r_bmname" ${hgbm} ) - fi - done < ${bookmarks} +### Look for any applied Mercurial Queue patches +if zstyle -T ":vcs_info:${vcs}:${usercontext}:${rrn}" get-mq \ + && [[ -d $patchdir ]] ; then + if [[ -e $mqstatusfile ]]; then + mqpatches=( ${${(f)"$(< "${patchdir}/status")"}/(#s)[a-f0-9]##:/} ) + mqpatches=( ${(Oa)mqpatches} ) fi - if [[ -n ${hglrev} ]] ; then - zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" hgrevformat revformat || revformat="%r:%h" - hook_com=( localrev "${hglrev}" "hash" "${hghash}" ) - if VCS_INFO_hook 'set-hgrev-format' "${revformat}"; then - zformat -f hglrev "${revformat}" "r:${hook_com[localrev]}" "h:${hook_com[hash]}" - else - hglrev=${hook_com[rev-replace]} + if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-unapplied \ + && [[ -r ${mqseriesfile} ]]; then + # Okay, here's a little something that assembles a list of unapplied + # patches that takes into account if mq-guards are active or not. + + # Collect active guards + if [[ -r ${mqguardsfile} ]]; then + mqguards=( ${(f)"$(< "${mqguardsfile}")"} ) + mqguards=( ${(oa)mqguards} ) fi - hook_com=() - if (( getbookmarks )) ; then - if VCS_INFO_hook 'gen-hg-bookmark-string' "${hgbm[@]}"; then - hgbmstring=${(j.;.)hgbm} - else - hgbmstring=${hook_com[hg-bookmark-string]} + + while read -r i_patch i_patchguards ; do + # Skip commented lines + [[ ${i_patch} == [[:space:]]#"#"* ]] && continue + + # Keep list of all patches + mqseries+=( $i_patch ) + + # Separate negative and positive guards to more easily find the + # intersection of active guards with patch guards + i_patchguards=( ${(s: :)i_patchguards} ) + i_negguards=( ${${(M)i_patchguards:#*"#-"*}/(#s)\#-/} ) + i_posguards=( ${${(M)i_patchguards:#*"#+"*}/(#s)\#+/} ) + + # Patch with any negative guards is never pushed if guard is active + if [[ ${#i_negguards} -gt 0 + && ${#${(@M)mqguards:#${(~j,|,)i_negguards}}} -gt 0 ]] ; then + continue fi - hook_com=() - fi - zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat hgbranch || hgbranch="%b:%r" - hook_com=( branch "${hgbranch_name}" revision "${hglrev}" ) - if VCS_INFO_hook 'set-branch-format' "${hgbranch}"; then - zformat -f hgbranch "${hgbranch}" "b:${hook_com[branch]}" "r:${hook_com[revision]}" - else - hgbranch=${hook_com[branch-replace]} - fi - hook_com=() + + # Patch with positive guards is only pushed if guard is active + if [[ ${#i_posguards} -gt 0 ]] ; then + if [[ ${#${(@M)mqguards:#${(~j,|,)i_posguards}}} -gt 0 ]] ; then + mqunapplied+=( $i_patch ) + fi + continue + fi + + # If we made it this far the patch isn't guarded and should be pushed + mqunapplied+=( $i_patch ) + done < ${mqseriesfile} fi -else - hgbranch="${hgbranch_name}" -fi -local patchdir=${hgbase}/.hg/patches/ + if VCS_INFO_hook 'gen-applied-string' "${mqpatches[@]}"; then + (( ${#mqpatches} )) && applied_string=${mqpatches[1]} + else + applied_string=${hook_com[applied-string]} + fi -if [[ -d $patchdir ]] ; then - local -a mqpatches - if [[ -e "${patchdir}/status" ]]; then - mqpatches=( ${${(f)"$(< "${patchdir}/status")"}/(#s)[a-f0-9]##:/} ) - mqpatches=( ${(Oa)mqpatches} ) + hook_com=() + + if VCS_INFO_hook 'gen-unapplied-string' "${mqunapplied[@]}"; then + unapplied_string=${#mqunapplied} else - mqpatches=( ) + unapplied_string=${hook_com[unapplied-string]} fi - if VCS_INFO_hook 'gen-mq-patch-string' "${mqpatches[@]}"; then - if (( ${#mqpatches} )); then - hgmqstring=${mqpatches[1]} - else - hgmqstring="no patch applied" - fi + hook_com=() + + if VCS_INFO_hook 'gen-mqguards-string' "${mqguards[@]}"; then + guards_string=${(j:,:)mqguards} else - hgbmstring=${hook_com[hg-mqpatch-string]} + guards_string=${hook_com[guards-string]} fi + + if (( ${#mqpatches} )); then + zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" patch-format \ + hgmqstring || hgmqstring="%p (%n applied)" + else + zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" nopatch-format \ + hgmqstring || hgmqstring="no patch applied" + fi + + hook_com=( applied "${applied_string}" unapplied "${unapplied_string}" + applied-n ${#mqpatches} unapplied-n ${#mqunapplied} + guards "${guards_string}" guards-n ${#mqguards} ) + + if VCS_INFO_hook 'set-patch-format' ${qstring}; then + zformat -f hgmqstring "${hgmqstring}" \ + "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \ + "n:${#mqpatches}" "c:${#mqunapplied}" \ + "g:${hook_com[guards]}" "G:${#mqguards}" + else + hgmqstring=${hook_com[patch-replace]} + fi + hook_com=() -else - hgmqstring='' fi -if [[ -z "${hgmqstring}" ]] && [[ -z "${hgbmstring}" ]]; then - hgmisc_args=( '' ) # make sure there's at least *one* misc argument -elif [[ -z "${hgmqstring}" ]]; then - hgmisc_args=( "${hgmqstring}" ) -elif [[ -z "${hgbmstring}" ]]; then - hgmisc_args=( "${hgbmstring}" ) -else - hgmisc_args=( "${hgmqstring}" "${hgbmstring}" ) -fi -VCS_INFO_formats '' "${hgbranch}" "${hgbase}" '' "${hgchanges}" "${hglrev}" "${hgmisc_args[@]}" + +### Build the misc string +hgmisc+=( ${hgmqstring} ) +hgmisc+=( ${hgbmstring} ) + +backend_misc[patches]="${hgmqstring}" +backend_misc[bookmarks]="${hgbmstring}" + +VCS_INFO_formats "${hgactionstring}" "${branchformat}" "${hgbase}" '' "${hgchanges}" "${r_lrev}" "${(j:;:)hgmisc}" return 0 diff --git a/Functions/VCS_Info/VCS_INFO_formats b/Functions/VCS_Info/VCS_INFO_formats index db7a8dd48..469efa7d4 100644 --- a/Functions/VCS_Info/VCS_INFO_formats +++ b/Functions/VCS_Info/VCS_INFO_formats @@ -22,21 +22,18 @@ hook_com=( unstaged_orig "$5" revision "$6" revision_orig "$6" + misc "$7" + misc_orig "$7" vcs "${vcs}" vcs_orig "${vcs}" ) -shift 6 -i=0 -for tmp in "$@"; do - hook_com[misc$((i++))]="${tmp}" -done -hook_com[misc]=${(j:,:)argv} -hook_com[misc_orig]=${hook_com[misc]} hook_com[base-name]="${${hook_com[base]}:t}" hook_com[base-name_orig]="${hook_com[base_name]}" hook_com[subdir]="$(VCS_INFO_reposub ${hook_com[base]})" hook_com[subdir_orig]="${hook_com[subdir]}" +VCS_INFO_hook 'post-backend' + ## description: # action: a string that signals a certain non-default condition in the # repository (like 'rebase-i' in git). If this in non-empty, @@ -46,8 +43,7 @@ hook_com[subdir_orig]="${hook_com[subdir]}" # staged: non-empty if the repository contains staged changes. # unstaged: non-empty if the repository contains unstaged changes. # revision: an identifier of the currently checked out revision. -# misc0..N: a set of strings that may contain anything the author likes. -# the backends should document what they put in it and when. +# misc: a string that may contain anything the backend author likes. # # If an argument has no valid value for a given backend, an empty value # should be provided. eg: @@ -71,6 +67,15 @@ if [[ -n ${hook_com[unstaged]} ]] ; then [[ -z ${tmp} ]] && hook_com[unstaged]='U' || hook_com[unstaged]=${tmp} fi +if [[ ${quiltmode} != 'standalone' ]] && VCS_INFO_hook "pre-addon-quilt"; then + local -x REPLY + VCS_INFO_quilt addon + hook_com[quilt]="${REPLY}" + unset REPLY +elif [[ ${quiltmode} == 'standalone' ]]; then + hook_com[quilt]=${hook_com[misc]} +fi + (( ${#msgs} > maxexports )) && msgs[$(( maxexports + 1 )),-1]=() for i in {1..${#msgs}} ; do if VCS_INFO_hook "set-message" $(( $i - 1 )) "${msgs[$i]}"; then @@ -83,6 +88,7 @@ for i in {1..${#msgs}} ; do r:${hook_com[base-name]} \ s:${hook_com[vcs]} \ u:${hook_com[unstaged]} \ + Q:${hook_com[quilt]} \ R:${hook_com[base]} \ S:${hook_com[subdir]} msgs[$i]=${msg} @@ -90,4 +96,6 @@ for i in {1..${#msgs}} ; do msgs[$i]=${hook_com[message]} fi done +hook_com=() +backend_misc=() return 0 diff --git a/Functions/VCS_Info/VCS_INFO_hook b/Functions/VCS_Info/VCS_INFO_hook index 71845d808..7274d726f 100644 --- a/Functions/VCS_Info/VCS_INFO_hook +++ b/Functions/VCS_Info/VCS_INFO_hook @@ -20,8 +20,11 @@ if (( debug )); then fi zstyle -a "${context}" hooks hooks || return 0 -# protect some internal variables in hooks -typeset -r vcs rrn usercontext maxexports msgs vcs_comm +# Protect some internal variables in hooks. The `-g' parameter to +# typeset does *not* make the parameters global here (they are already +# "*-local-export). It prevents typeset from creating *new* *local* +# parameters in this function's scope. +typeset -g -r vcs rrn usercontext maxexports msgs vcs_comm for hook in ${hooks} ; do func="+vi-${hook}" if (( ${+functions[$func]} == 0 )); then @@ -29,6 +32,7 @@ for hook in ${hooks} ; do continue fi (( debug )) && printf ' + Running function: "%s"\n' "${func}" + true ${func} "$@" case $? in (0) @@ -38,5 +42,5 @@ for hook in ${hooks} ; do ;; esac done -typeset +r vcs rrn usercontext maxexports msgs vcs_comm +typeset -g +r vcs rrn usercontext maxexports msgs vcs_comm return $ret diff --git a/Functions/VCS_Info/VCS_INFO_quilt b/Functions/VCS_Info/VCS_INFO_quilt new file mode 100644 index 000000000..fc127c23b --- /dev/null +++ b/Functions/VCS_Info/VCS_INFO_quilt @@ -0,0 +1,190 @@ +## vim:ft=zsh:foldmethod=marker + +function VCS_INFO_quilt-match() { + emulate -L zsh + setopt extendedglob + local d mode="$1" param="$2" + local -a list + + case ${mode} in + (assoc) list=( ${(kOP)param} );; + (array) : "${foo[@]}" ${(t)foo}; list=( ${(OP)param} );; + (*) return 1;; + esac + for d in "${list[@]}"; do + if [[ ${PWD} == ${d%/##}(|/*) ]]; then + print "$d" + return 0 + fi + done + return 1 +} + +function VCS_INFO_quilt-standalone-detect() { + emulate -L zsh + setopt extendedglob + local param + local -i ret + + zstyle -s "${context}" quilt-standalone param || return 1 + [[ "${param}" == 'never' ]] && return 1 + [[ "${param}" == 'always' ]] && return 0 + + if (( ${+functions[$param]} )); then + ${param} + return $? + fi + + case ${(Pt)param} in + *association*) + local m + local -A A + m="$(VCS_INFO_quilt-match assoc ${param})" + A=(${(kvP)param}) + (( $? == 0 )) && [[ ${A[$m]} == "true" ]] && return 0 + return 1 + ;; + *array*) + typeset -gU ${param} + VCS_INFO_quilt-match array ${param} > /dev/null + return $? + ;; + *scalar*) + [[ "${(P)param}" == 'always' ]] && return 0 + [[ "${(P)param}" == 'never' ]] && return 1 + ;; + esac + # If nothing hit yet, it just wasn't meant to be. + return 1 +} + +function VCS_INFO_quilt-dirfind() { + # This is a wrapper around VCS_INFO_bydir_detect(). It makes sure + # that $vcs_comm[] is unchanged. Currently, changing anything in it + # should not be an issue, but this makes sure the code can safely + # be called elsewhere, too - if needed. + emulate -L zsh + setopt extendedglob + local dir="$1" file="$2"; shift $# + local ret oldfile olddir + + olddir=${vcs_comm[basedir]} + vcs_comm[basedir]='' + if [[ -n "${file}" ]]; then + oldfile=${vcs_comm[detect_need_file]} + vcs_comm[detect_need_file]=${file} + fi + VCS_INFO_bydir_detect ${dir} + ret=$? + [[ -n "${file}" ]] && vcs_comm[detect_need_file]=${oldfile} + printf '%s' ${vcs_comm[basedir]} + vcs_comm[basedir]="${olddir}" + return ${ret} +} + +function VCS_INFO_quilt() { + emulate -L zsh + setopt extendedglob + local mode="$1" + local patches pc tmp qstring root + local -i ret + local -x context + local -a applied unapplied applied_string unapplied_string quiltcommand + local -Ax hook_com + + context=":vcs_info:${vcs}.quilt-${mode}:${usercontext}:${rrn}" + zstyle -t "${context}" use-quilt || return 1 + + case ${mode} in + (standalone) + VCS_INFO_quilt-standalone-detect || return 1 + ;; + (addon) + ;; + (*) + printf 'Invalid mode: `%s'\''\n' "$1" + return 2 + ;; + esac + + zstyle -s "${context}" quilt-patch-dir patches || patches="${QUILT_PATCHES}" + if [[ "${patches}" != /* ]]; then + tmp=${patches:-patches} + patches="$(VCS_INFO_quilt-dirfind "${tmp}")" + ret=$? + (( ret )) && return ${ret} + patches=${patches}/${tmp} + else + [[ -d ${patches} ]] || return 1 + fi + + pc="$(VCS_INFO_quilt-dirfind .pc .version)" + ret=$? + if (( ret == 0 )); then + [[ ${quiltmode} == 'standalone' ]] && root=${pc} + pc=${pc}/.pc + if [[ -e ${pc}/applied-patches ]]; then + applied=( ${(f)"$(<$pc/applied-patches)"} ) + # throw away empty entries + applied=( ${applied:#} ) + applied=( ${(Oa)applied} ) + else + applied=() + fi + fi + if zstyle -t "${context}" get-unapplied; then + # This zstyle call needs to be moved further up if `quilt' needs + # to be run in more places than this one. + zstyle -s "${context}" quiltcommand quiltcommand || quiltcommand='quilt' + unapplied=( ${(f)"$(QUILT_PATCHES=$patches $quiltcommand --quiltrc /dev/null unapplied 2> /dev/null)"} ) + unapplied=( ${unapplied:#} ) + else + unapplied=() + fi + + if VCS_INFO_hook 'gen-applied-string' "${applied[@]}"; then + if (( ${#applied} )); then + applied_string=${applied[1]} + else + applied_string="" + fi + else + applied_string=${hook_com[applied-string]} + fi + hook_com=() + if VCS_INFO_hook 'gen-unapplied-string' "${unapplied[@]}"; then + unapplied_string="${#unapplied}" + else + unapplied_string=${hook_com[unapplied-string]} + fi + + if (( ${#applied} )); then + zstyle -s "${context}" patch-format qstring || qstring="%p (%n applied)" + else + zstyle -s "${context}" nopatch-format qstring || qstring="no patch applied" + fi + hook_com=( applied "${applied_string}" unapplied "${unapplied_string}" + applied-n ${#applied} unapplied-n ${#unapplied} ) + if VCS_INFO_hook 'set-patch-format' ${qstring}; then + zformat -f qstring "${qstring}" "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \ + "n:${#applied}" "c:${#unapplied}" + else + qstring=${hook_com[patch-replace]} + fi + hook_com=() + + case ${mode} in + (standalone) + VCS_INFO_formats '' '' "${root}" '' '' '' "${qstring}" + VCS_INFO_set + ;; + (addon) + # When VCS_INFO_quilt() is called with "addon" a "local -x REPLY" variable + # should be in place. That variable can be unset after it's being used. + REPLY="${qstring}" + ;; + esac + + VCS_INFO_hook 'post-quilt' ${mode} ${patches} ${pc:-\\-nopc-} +} +VCS_INFO_quilt "$@" diff --git a/Functions/VCS_Info/vcs_info b/Functions/VCS_Info/vcs_info index 7ae11230e..6ce1cd702 100644 --- a/Functions/VCS_Info/vcs_info +++ b/Functions/VCS_Info/vcs_info @@ -21,6 +21,7 @@ static_functions=( VCS_INFO_hook VCS_INFO_maxexports VCS_INFO_nvcsformats + VCS_INFO_quilt VCS_INFO_realpath VCS_INFO_reposub VCS_INFO_set @@ -45,12 +46,12 @@ vcs_info () { [[ -r . ]] || return 0 local pat - local -i found + local -i found retval local -a enabled disabled dps - local -x usercontext vcs rrn LC_MESSAGES + local -x usercontext vcs rrn quiltmode LC_MESSAGES local -ix maxexports local -ax msgs - local -Ax vcs_comm + local -Ax vcs_comm hook_com backend_misc user_data LC_MESSAGES=C if [[ -n ${LC_ALL} ]]; then @@ -58,9 +59,18 @@ vcs_info () { LANG=${LC_ALL} local -x LC_ALL fi - vcs='-init-'; rrn='-all-' + vcs='-init-'; rrn='-all-'; quiltmode='addon' usercontext=${1:-default} + VCS_INFO_hook "start-up" + retval=$? + if (( retval == 1 )); then + return 0 + elif (( retval == 2 )); then + VCS_INFO_set --nvcs + return 0 + fi + zstyle -a ":vcs_info:${vcs}:${usercontext}:${rrn}" "enable" enabled (( ${#enabled} == 0 )) && enabled=( all ) @@ -99,10 +109,20 @@ vcs_info () { done (( found == 0 )) && { - VCS_INFO_set --nvcs + vcs='-quilt-'; quiltmode='standalone' + VCS_INFO_quilt standalone || VCS_INFO_set --nvcs return 0 } + VCS_INFO_hook "pre-get-data" + retval=$? + if (( retval == 1 )); then + return 0 + elif (( retval == 2 )); then + VCS_INFO_set --nvcs + return 0 + fi + VCS_INFO_get_data_${vcs} || { VCS_INFO_set --nvcs return 1 |