about summary refs log tree commit diff
path: root/Functions/VCS_Info
diff options
context:
space:
mode:
Diffstat (limited to 'Functions/VCS_Info')
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr9
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_git65
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_hg117
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_p415
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_svk9
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_svn9
-rw-r--r--Functions/VCS_Info/VCS_INFO_formats83
-rw-r--r--Functions/VCS_Info/vcs_info1
8 files changed, 210 insertions, 98 deletions
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr b/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr
index e85de311e..5d4deaac9 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr
@@ -5,6 +5,7 @@
 setopt localoptions noksharrays extendedglob NO_shwordsplit
 local bzrbase bzrbr
 local -a bzrinfo
+local -xA hook_com
 
 if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "use-simple" ; then
     bzrbase=${vcs_comm[basedir]}
@@ -21,6 +22,12 @@ fi
 
 rrn=${bzrbase:t}
 zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat bzrbr || bzrbr="%b:%r"
-zformat -f bzrbr "${bzrbr}" "b:${bzrinfo[2]}" "r:${bzrinfo[1]}"
+hook_com=( branch "${bzrinfo[2]}" revision "${bzrinfo[1]}" )
+if VCS_INFO_hook 'set-branch-format' "${bzrbr}"; then
+    zformat -f bzrbr "${bzrbr}" "b:${hook_com[branch]}" "r:${hook_com[revision]}"
+else
+    bzrbr=${hook_com[branch-replace]}
+fi
+hook_com=()
 VCS_INFO_formats '' "${bzrbr}" "${bzrbase}" '' '' "${bzrinfo[1]}" ''
 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 bf7c47927..4018b5d92 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
@@ -4,6 +4,8 @@
 
 setopt localoptions extendedglob NO_shwordsplit
 local gitdir gitbase gitbranch gitaction gitunstaged gitstaged gitsha1 gitmisc
+local stgitpatch stgitunapplied
+local -xA hook_com
 
 VCS_INFO_git_getaction () {
     local gitaction='' gitdir=$1
@@ -97,36 +99,6 @@ VCS_INFO_git_getbranch () {
     return 0
 }
 
-VCS_INFO_git_get_stgit_top_patch () {
-    local patchdir=$1
-
-    if [[ -d "$patchdir" ]]; then
-        local -a patches
-        patches=(${(f)"$(< "${patchdir}/applied")"})
-        printf '%s' $patches[-1]
-        return 0
-    fi
-
-    return 1
-}
-
-VCS_INFO_git_get_stgit_unapplied() {
-    local patchdir=$1
-
-    if [[ -d "$patchdir" ]]; then
-        local -a patches
-        patches=(${(f)"$(< "${patchdir}/unapplied")"})
-        if [[ -z $patches[@] ]]; then
-            printf 0
-        else
-            printf '%d' $#patches
-        fi
-        return 0
-    fi
-
-    return 1
-}
-
 gitdir=${vcs_comm[gitdir]}
 gitbranch="$(VCS_INFO_git_getbranch ${gitdir})"
 if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-revision && \
@@ -160,14 +132,37 @@ rrn=${gitbase:t}
 
 local patchdir=${gitdir}/patches/${gitbranch}
 if [[ -d $patchdir ]] ; then
-    stgitpatch=$(VCS_INFO_git_get_stgit_top_patch "${patchdir}")
-    stgitunapplied=$(VCS_INFO_git_get_stgit_unapplied "${patchdir}")
+    local -a stgit_applied stgit_unapplied
 
-    stgitpatch=${stgitpatch:-"no patch applied"}
+    stgit_applied=(${(f)"$(< "${patchdir}/applied")"})
+    stgit_applied=( ${(Oa)stgit_applied} )
+    stgit_unapplied=(${(f)"$(< "${patchdir}/unapplied")"})
+    stgit_unapplied=( ${(oa)stgit_applied} )
+
+    if VCS_INFO_hook 'gen-stgit-patch-string' "${stgit_applied[@]}"; then
+        if (( ${#stgit_applied} )); then
+            stgitpatch=${stgit_applied[1]}
+        else
+            stgitpatch="no patch applied"
+        fi
+    else
+        stgitpatch=${hook_com[stgit-patch-string]}
+    fi
+    if VCS_INFO_hook 'gen-stgit-unapplied-string' "${stgit_unapplied[@]}"; then
+        stgitunapplied=${#stgit_unapplied}
+    else
+        stgitunapplied=${hook_com[stgit-unapplied-string]}
+    fi
 
     zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" stgitformat stgitmsg || stgitmsg=" %p (%c)"
-    zformat -f stgitmsg "${stgitmsg}" "p:${stgitpatch}" "c:${stgitunapplied}"
-    gitmisc=${stgitmsg}
+    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}
+    else
+        gitmisc=${hook_com[stgit-replace]}
+    fi
+    hook_com=()
 else
     gitmisc=''
 fi
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
index 0b66463fa..1c103a541 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
@@ -3,21 +3,11 @@
 ## Distributed under the same BSD-ish license as zsh itself.
 
 setopt localoptions NO_shwordsplit
-local file hgbranch hgbranch_name hgbase hghash hglrev hgmisc r_branch r_info revformat
-
-VCS_INFO_hg_get_mq_top_patch () {
-    local patchdir=$1
-
-    if [[ -e "${patchdir}/status" ]]; then
-        local -a patches
-        patches=(${(f)"$(< "${patchdir}/status")"})
-        printf "%s" "${patches[-1]/[^:]*:/}"
-        return 0
-    fi
-
-    return 1
-}
-
+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
+local -xA hook_com
 
 hgbase=${vcs_comm[basedir]}
 rrn=${hgbase:t}
@@ -31,27 +21,70 @@ 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
 
-    HGRCPATH="/dev/null" ${vcs_comm[cmd]} branches \
-    | while read -r r_branch r_info ; do
-        if [[ ${r_branch} == ${hgbranch_name} ]] ; then
-            match=()
-            : ${r_info/(#b)([^:]##):(*)}
-            hglrev=${match[1]}
-            hghash=${match[2]}
-            break
+    if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" \
+            "check-for-changes" ; then
+
+        HGRCPATH="/dev/null" ${vcs_comm[cmd]} id --debug -i -n -b \
+        | read -r hghash hglrev r_branch
+
+        # Are there uncommitted-changes?
+        if [[ $hglrev[-1] == + ]] ; then
+            hgchanges=1
         fi
-    done
+
+        # Remove uncommitted-changes marker, if any
+        hglrev=${hglrev/+/}
+        hghash=${hghash/+/}
+    else
+        HGRCPATH="/dev/null" ${vcs_comm[cmd]} \
+        parents --template="{node} {rev} {branches}\n" \
+        | read -r hghash hglrev r_branch
+    fi
+
+    if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "get-bookmarks" \
+            && getbookmarks=1 || getbookmarks=0
+
+    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}
+    fi
 
     if [[ -n ${hglrev} ]] ; then
         zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" hgrevformat revformat || revformat="%r:%h"
-        zformat -f hglrev "${revformat}" "r:${hglrev}" "h:${hghash}"
+        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]}
+        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]}
+            fi
+            hook_com=()
+        fi
         zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat hgbranch || hgbranch="%b:%r"
-        zformat -f hgbranch "${hgbranch}" "b:${hgbranch_name}" "r:${hglrev}"
+        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=()
     fi
 else
     hgbranch="${hgbranch_name}"
@@ -60,12 +93,36 @@ fi
 local patchdir=${hgbase}/.hg/patches/
 
 if [[ -d $patchdir ]] ; then
-    hgmisc=$(VCS_INFO_hg_get_mq_top_patch "${patchdir}")
+    local -a mqpatches
+    if [[ -e "${patchdir}/status" ]]; then
+        mqpatches=( ${${(f)"$(< "${patchdir}/status")"}/(#s)[a-f0-9]##:/} )
+        mqpatches=( ${(Oa)mqpatches} )
+    else
+        mqpatches=( )
+    fi
 
-    hgmisc=${hgmisc:-"no patch applied"}
+    if VCS_INFO_hook 'gen-mq-patch-string' "${mqpatches[@]}"; then
+        if (( ${#mqpatches} )); then
+            hgmqstring=${mqpatches[1]}
+        else
+            hgmqstring="no patch applied"
+        fi
+    else
+        hgbmstring=${hook_com[hg-mqpatch-string]}
+    fi
+    hook_com=()
 else
-    hgmisc=''
+    hgmqstring=''
 fi
 
-VCS_INFO_formats '' "${hgbranch}" "${hgbase}" '' '' "${hglrev}" "${hgmisc}"
+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[@]}"
 return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4 b/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4
index e4bbb06c4..430cfa6f0 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4
@@ -6,6 +6,7 @@
 setopt localoptions extendedglob
 local p4base a b
 local -A p4info
+local -xA hook_com
 
 ${vcs_comm[cmd]} info | while IFS=: read a b; do p4info[${a// /_}]="${b## #}"; done
 p4base=${vcs_comm[basedir]}
@@ -16,9 +17,13 @@ local p4branch change
 # here down is synced as the revision.
 # I suppose the following might be slow on a tortuous client view.
 change="${${$(${vcs_comm[cmd]} changes -m 1 ...\#have)##Change }%% *}"
-zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat p4branch ||
-p4branch="%b:%r"
-zformat -f p4branch "${p4branch}" "b:${p4info[Client_name]}" \
-"r:$change"
-
+zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat p4branch || p4branch="%b:%r"
+hook_com=( branch "${p4info[Client_name]}" revision "${change}" )
+if VCS_INFO_hook 'set-branch-format' "${p4branch}"; then
+    zformat -f p4branch "${p4branch}" "b:${hook_com[branch]}" "r:${hook_com[revision]}"
+else
+    p4branch=${hook_com[branch-replace]}
+fi
+hook_com=()
 VCS_INFO_formats '' "${p4branch}" "${p4base}" '' '' "$change" ''
+return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk
index 3df9a7366..6107a14f3 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk
@@ -4,10 +4,17 @@
 
 setopt localoptions NO_shwordsplit
 local svkbranch svkbase
+local -xA hook_com
 
 svkbase=${vcs_comm[basedir]}
 rrn=${svkbase:t}
 zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat svkbranch || svkbranch="%b:%r"
-zformat -f svkbranch "${svkbranch}" "b:${vcs_comm[branch]}" "r:${vcs_comm[revision]}"
+hook_com=( branch "${vcs_comm[branch]}" revision "${vcs_comm[revision]}" )
+if VCS_INFO_hook 'set-branch-format' "${svkbranch}"; then
+    zformat -f svkbranch "${svkbranch}" "b:${hook_com[branch]}" "r:${hook_com[revision]}"
+else
+    svkbranch=${hook_com[branch-replace]}
+fi
+hook_com=()
 VCS_INFO_formats '' "${svkbranch}" "${svkbase}" '' '' "${vcs_comm[revision]}" ''
 return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn
index 75da22bda..b1cb7302b 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn
@@ -7,6 +7,7 @@
 setopt localoptions noksharrays extendedglob NO_shwordsplit
 local svnbase svnbranch a b rrn
 local -A svninfo parentinfo
+local -xA hook_com
 
 svnbase=".";
 svninfo=()
@@ -23,6 +24,12 @@ svnbase="$(VCS_INFO_realpath ${svnbase})"
 
 rrn=${svnbase:t}
 zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat svnbranch || svnbranch="%b:%r"
-zformat -f svnbranch "${svnbranch}" "b:${svninfo[URL]##*/}" "r:${svninfo[Revision]}"
+hook_com=( branch "${svninfo[URL]##*/}" revision "${svninfo[Revision]}" )
+if VCS_INFO_hook 'set-branch-format' "${svnbranch}"; then
+    zformat -f svnbranch "${svnbranch}" "b:${hook_com[branch]}" "r:${hook_com[revision]}"
+else
+    svnbranch=${hook_com[branch-replace]}
+fi
+hook_com=()
 VCS_INFO_formats '' "${svnbranch}" "${svnbase}" '' '' "${svninfo[Revision]}" ''
 return 0
diff --git a/Functions/VCS_Info/VCS_INFO_formats b/Functions/VCS_Info/VCS_INFO_formats
index 35b3b963d..db7a8dd48 100644
--- a/Functions/VCS_Info/VCS_INFO_formats
+++ b/Functions/VCS_Info/VCS_INFO_formats
@@ -3,7 +3,39 @@
 ## Distributed under the same BSD-ish license as zsh itself.
 
 setopt localoptions noksharrays NO_shwordsplit
-local action=$1 branch=$2 base=$3 staged=$4 unstaged=$5 rev=$6 misc=$7
+local msg tmp
+local -i i
+local -xA hook_com
+# The _origs are needed because hooks can change values and there would
+# be no way to get the originals back for later hooks (a hook is run for
+# each message, that's being created).
+hook_com=(
+    action        "$1"
+    action_orig   "$1"
+    branch        "$2"
+    branch_orig   "$2"
+    base          "$3"
+    base_orig     "$3"
+    staged        "$4"
+    staged_orig   "$4"
+    unstaged      "$5"
+    unstaged_orig "$5"
+    revision      "$6"
+    revision_orig "$6"
+    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]}"
 
 ## description:
 #   action:   a string that signals a certain non-default condition in the
@@ -13,18 +45,15 @@ local action=$1 branch=$2 base=$3 staged=$4 unstaged=$5 rev=$6 misc=$7
 #   base:     the full name of the repository's root directory.
 #   staged:   non-empty if the repository contains staged changes.
 #   unstaged: non-empty if the repository contains unstaged changes.
-#   rev:      an identifier of the currently checked out revision.
-#   misc:     a string that may contain anything the author likes.
+#   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.
 #
 # If an argument has no valid value for a given backend, an empty value
 # should be provided. eg:
 #   VCS_INFO_formats '' "${foobranch}" "${foobase}" '' '' '' "${foomisc}"
 
-local msg
-local -i i j
-
-if [[ -n ${action} ]] ; then
+if [[ -n ${hook_com[action]} ]] ; then
     zstyle -a ":vcs_info:${vcs}:${usercontext}:${rrn}" actionformats msgs
     (( ${#msgs} < 1 )) && msgs[1]=' (%s)-[%b|%a]-'
 else
@@ -32,29 +61,33 @@ else
     (( ${#msgs} < 1 )) && msgs[1]=' (%s)-[%b]-'
 fi
 
-if [[ -n ${staged} ]] ; then
-    zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" stagedstr staged
-    [[ -z ${staged} ]] && staged='S'
+if [[ -n ${hook_com[staged]} ]] ; then
+    zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" stagedstr tmp
+    [[ -z ${tmp} ]] && hook_com[staged]='S' || hook_com[staged]=${tmp}
 fi
 
-if [[ -n ${unstaged} ]] ; then
-    zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" unstagedstr unstaged
-    [[ -z ${unstaged} ]] && unstaged='U'
+if [[ -n ${hook_com[unstaged]} ]] ; then
+    zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" unstagedstr tmp
+    [[ -z ${tmp} ]] && hook_com[unstaged]='U' || hook_com[unstaged]=${tmp}
 fi
 
 (( ${#msgs} > maxexports )) && msgs[$(( maxexports + 1 )),-1]=()
 for i in {1..${#msgs}} ; do
-    zformat -f msg ${msgs[$i]}                      \
-                    a:${action}                     \
-                    b:${branch}                     \
-                    c:${staged}                     \
-                    i:${rev}                        \
-                    m:${misc}                       \
-                    r:${base:t}                     \
-                    s:${vcs}                        \
-                    u:${unstaged}                   \
-                    R:${base}                       \
-                    S:"$(VCS_INFO_reposub ${base})"
-    msgs[$i]=${msg}
+    if VCS_INFO_hook "set-message" $(( $i - 1 )) "${msgs[$i]}"; then
+        zformat -f msg ${msgs[$i]}                      \
+                        a:${hook_com[action]}           \
+                        b:${hook_com[branch]}           \
+                        c:${hook_com[staged]}           \
+                        i:${hook_com[revision]}         \
+                        m:${hook_com[misc]}             \
+                        r:${hook_com[base-name]}        \
+                        s:${hook_com[vcs]}              \
+                        u:${hook_com[unstaged]}         \
+                        R:${hook_com[base]}             \
+                        S:${hook_com[subdir]}
+        msgs[$i]=${msg}
+    else
+        msgs[$i]=${hook_com[message]}
+    fi
 done
 return 0
diff --git a/Functions/VCS_Info/vcs_info b/Functions/VCS_Info/vcs_info
index 4344d0b6e..906d984ef 100644
--- a/Functions/VCS_Info/vcs_info
+++ b/Functions/VCS_Info/vcs_info
@@ -18,6 +18,7 @@ static_functions=(
     VCS_INFO_check_com
     VCS_INFO_formats
     VCS_INFO_get_cmd
+    VCS_INFO_hook
     VCS_INFO_maxexports
     VCS_INFO_nvcsformats
     VCS_INFO_realpath