mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-27 16:50:58 +01:00
Frank Terbeck, Seth House: 27712, 22713, 27714:
VCS Info hooks and Mercurial improvements
This commit is contained in:
parent
8b1da80a7a
commit
94777f64e8
9 changed files with 488 additions and 110 deletions
|
|
@ -324,7 +324,7 @@ cindex(version control utility)
|
|||
In a lot of cases, it is nice to automatically retrieve information from
|
||||
version control systems (VCSs), such as subversion, CVS or git, to be able
|
||||
to provide it to the user; possibly in the user's prompt. So that you can
|
||||
instantly tell on which branch you are currently on, for example.
|
||||
instantly tell which branch you are currently on, for example.
|
||||
|
||||
In order to do that, you may use the tt(vcs_info) function.
|
||||
|
||||
|
|
@ -419,7 +419,8 @@ example(:vcs_info:<vcs-string>:<user-context>:<repo-root-name>)
|
|||
startitem()
|
||||
item(tt(<vcs-string>))(
|
||||
is one of: git, git-svn, git-p4, hg, darcs, bzr,
|
||||
cdv, mtn, svn, cvs, svk, tla or p4.
|
||||
cdv, mtn, svn, cvs, svk, tla or p4. When hooks are active the hooks name
|
||||
is added after a `+'. (See tt(Hooks in vcs_info) below.)
|
||||
)
|
||||
item(tt(<user-context>))(
|
||||
is a freely configurable string, assignable by
|
||||
|
|
@ -532,14 +533,17 @@ example(zstyle ':vcs_info:*' disable-patterns "$HOME/.zsh+LPAR()|/*+RPAR()")
|
|||
)
|
||||
kindex(check-for-changes)
|
||||
item(tt(check-for-changes))(
|
||||
If enabled, this style (currently only used by the tt(git) backend) causes the
|
||||
tt(%c) and tt(%u) format escapes to be filled with information. The strings
|
||||
filled into these escapes can be controlled via the var(stagedstr) and
|
||||
var(unstagedstr) styles.
|
||||
If enabled, this style causes the tt(%c) and tt(%u) format escapes to be filled
|
||||
with information. The strings filled into these escapes can be controlled via
|
||||
the var(stagedstr) and var(unstagedstr) styles. The only backends that
|
||||
currently support this option are tt(git) and tt(hg) (tt(hg) only supports
|
||||
unstaged).
|
||||
|
||||
Note, that the actions taken if this style is enabled are potentially expensive
|
||||
(read: they take time, depending on how big the current repository is).
|
||||
Therefore, it is disabled by default.
|
||||
Therefore, it is disabled by default. In order to use this style with
|
||||
the tt(hg) backend you must also use the var(get-revision) style to avoid
|
||||
having to start the interpreter more than once.
|
||||
)
|
||||
kindex(stagedstr)
|
||||
item(tt(stagedstr))(
|
||||
|
|
@ -599,10 +603,16 @@ If set to true, vcs_info goes the extra mile to figure out the revision of
|
|||
a repository's work tree (currently for the tt(git) and tt(hg) backends,
|
||||
where this kind of information is not always vital). For tt(git), the
|
||||
hash value of the currently checked out commit is available via the tt(%i)
|
||||
expansion. With tt(hg), the local revision number is available via tt(%i)
|
||||
and the corresponding global hash is available via tt(%m).
|
||||
expansion. With tt(hg), the local revision number and the corresponding
|
||||
global hash are available via tt(%i); in addition, the topmost
|
||||
applied tt(mq) patch and bookmarks are available via tt(%m).
|
||||
If this style is set in the tt(hg) context, the backend supports the
|
||||
branchformat style.
|
||||
var(branchformat) style.
|
||||
)
|
||||
kindex(get-bookmarks)
|
||||
item(tt(get-bookmarks))(
|
||||
If set to true, the tt(hg) backend will try to get a list of current
|
||||
bookmarks. They will be available in via the `tt(%m)' replacement.
|
||||
)
|
||||
kindex(use-prompt-escapes)
|
||||
item(tt(use-prompt-escapes))(
|
||||
|
|
@ -610,6 +620,16 @@ Determines if we assume that the assembled
|
|||
string from var(vcs_info) includes prompt escapes. (Used by
|
||||
tt(vcs_info_lastmsg).)
|
||||
)
|
||||
kindex(debug)
|
||||
item(tt(debug))(
|
||||
Enable debugging output, to track possible problems. Currently this style
|
||||
is only used by tt(vcs_info)'s hooks system.
|
||||
)
|
||||
kindex(hooks)
|
||||
item(tt(hooks))(
|
||||
A list style, that defines hook-function names. See tt(Hooks in vcs_info)
|
||||
below for details.
|
||||
)
|
||||
enditem()
|
||||
|
||||
The default values for these styles in all contexts are:
|
||||
|
|
@ -632,7 +652,10 @@ sitem(tt(command))((empty string))
|
|||
sitem(tt(use-server))(false)
|
||||
sitem(tt(use-simple))(false)
|
||||
sitem(tt(get-revision))(false)
|
||||
sitem(tt(get-bookmarks))(false)
|
||||
sitem(tt(use-prompt-escapes))(true)
|
||||
sitem(tt(debug))(false)
|
||||
sitem(tt(hooks))((empty list))
|
||||
endsitem()
|
||||
|
||||
In normal tt(formats) and tt(actionformats), the following replacements are
|
||||
|
|
@ -657,8 +680,9 @@ var(/foo/bar/reposXY/beer/tasty), tt(%S) is var(beer/tasty).)
|
|||
sitem(tt(%m))(A "misc" replacement. It is at the discretion of the backend
|
||||
to decide what this replacement expands to. It is currently used by
|
||||
the tt(hg) and tt(git) backends. The tt(hg) backend replaces tt(%m) with the
|
||||
topmost Mq patch applied (qtop) and the tt(git) backend replaces it
|
||||
with the string from the var(stgitformat) style.)
|
||||
topmost tt(mq) patch applied (qtop) and a list of any current bookmarks. The
|
||||
tt(git) backend replaces it with the string from the var(stgitformat)
|
||||
style.)
|
||||
endsitem()
|
||||
|
||||
In tt(branchformat) these replacements are done:
|
||||
|
|
@ -747,6 +771,168 @@ enditem()
|
|||
|
||||
All variables named VCS_INFO_* are for internal use only.
|
||||
|
||||
subsect(Hooks in vcs_info)
|
||||
|
||||
Hooks are places in tt(vcs_info) where you can run your own code. That
|
||||
code can communicate with the code that called it and through that,
|
||||
change the system's behaviour.
|
||||
|
||||
For configuration, hooks change the style context:
|
||||
example(:vcs_info:<vcs-string>+<hook-name>:<user-context>:<repo-root-name>)
|
||||
|
||||
To register functions to a hook, you need to list them in the tt(hooks)
|
||||
style in the appropriate context.
|
||||
|
||||
Example:
|
||||
example(zstyle ':vcs_info:*+foo:*' hooks bar baz)
|
||||
|
||||
This registers functions to the hook `foo' for all backends. In order to
|
||||
avoid namespace problems, all registered function names are prepended by
|
||||
a `+vi-', so the actual functions called for the `foo' hook are
|
||||
`tt(+vi-bar)' and `tt(+vi-baz)'.
|
||||
|
||||
If something seems weird, you can enable the `debug' boolean style in
|
||||
the proper context and the hook-calling code will print what it tried
|
||||
to execute and whether the function in question existed.
|
||||
|
||||
When you register more than one function to a hook, all functions are
|
||||
executed one after another until one function returns non-zero or until
|
||||
all functions have been called.
|
||||
|
||||
There are a number of variables, that are special in hook contexts:
|
||||
|
||||
startitem()
|
||||
item(tt(ret))(
|
||||
The return value, that the hooks system will return to the caller. The
|
||||
default is an integer `zero'. If and how a changed tt(ret) value changes
|
||||
the execution of the caller depends on the specific hook. See the hook's
|
||||
documentation below for details.
|
||||
)
|
||||
item(tt(hook_com))(
|
||||
An associated array, which is used for bidirectional communication from
|
||||
the caller to hook functions. The used keys depend on the specific hook.
|
||||
)
|
||||
item(tt(context))(
|
||||
The active context of the hook. Functions that wish to change this
|
||||
variable should make it local scope first.
|
||||
)
|
||||
enditem()
|
||||
|
||||
Finally, the full list of currently available hooks:
|
||||
|
||||
startitem()
|
||||
item(tt(gen-hg-bookmark-string))(
|
||||
Called in the Mercurial backend (the tt(get-revision) and tt(get-bookmarks)
|
||||
styles must be active) when a bookmark string is generated.
|
||||
|
||||
This hook gets the names of the Mercurial bookmarks, that
|
||||
tt(vcs_info) collected from `hg'.
|
||||
|
||||
When setting tt(ret) to non-zero, the string in
|
||||
tt(${hook_com[hg-bookmark-string]}) will be used as the
|
||||
`tt(misc1)' replacement in the variables set by tt(vcs_info).
|
||||
)
|
||||
item(tt(gen-mq-patch-string))(
|
||||
Called in the Mercurial backend when a mq-patch string is generated. That
|
||||
only happens if a tt(.hg/patches) directory exists in the repository.
|
||||
|
||||
This hook gets the names of all applied mq patches which tt(vcs_info)
|
||||
collected so far in the opposite order, which mean that the first argument
|
||||
is the top-most patch and so forth.
|
||||
|
||||
When setting tt(ret) to non-zero, the string in
|
||||
tt(${hook_com[hg-mqpatch-string]}) will be used as the
|
||||
`tt(misc0)' replacement in the variables set by tt(vcs_info).
|
||||
)
|
||||
item(tt(gen-stgit-patch-string))(
|
||||
Called in the git backend when a stgit-patch string is generated. That
|
||||
only happens if stgit is in use in the repository.
|
||||
|
||||
This hook gets the names of all applied stgit patches which tt(vcs_info)
|
||||
collected so far in the opposite order, which mean that the first argument
|
||||
is the top-most patch and so forth.
|
||||
|
||||
When setting tt(ret) to non-zero, the string in
|
||||
tt(${hook_com[stgit-patch-string]}) will be used as the
|
||||
`tt(misc0)' replacement in the variables set by tt(vcs_info).
|
||||
)
|
||||
item(tt(gen-stgit-unapplied-string))(
|
||||
Called in the git backend when a stgit-unapplied string is generated. That
|
||||
only happens if stgit is in use in the repository.
|
||||
|
||||
This hook gets the names of all unapplied stgit patches which tt(vcs_info)
|
||||
collected so far.
|
||||
|
||||
When setting tt(ret) to non-zero, the string in
|
||||
tt(${hook_com[stgit-unapplied-string]}) will be used as the
|
||||
`tt(misc0)' replacement in the variables set by tt(vcs_info).
|
||||
)
|
||||
item(tt(set-branch-format))(
|
||||
Called before a `tt(branchformat)' is set. The only argument to the
|
||||
hook is the format that is configured at this point.
|
||||
|
||||
The `tt(hook_com)' keys considered are `tt(branch)' and `tt(revision)'.
|
||||
They are set to the values figured out so far by tt(vcs_info) and any
|
||||
change will be used directly when the actual replacement is done.
|
||||
|
||||
If tt(ret) is set to to non-zero, the string in
|
||||
tt(${hook_com[branch-replace]}) will be used unchanged as the
|
||||
`tt(%b)' replacement in the variables set by tt(vcs_info).
|
||||
)
|
||||
item(tt(set-hgrev-format))(
|
||||
Called before a `tt(hgrevformat)' is set. The only argument to the
|
||||
hook is the format that is configured at this point.
|
||||
|
||||
The `tt(hook_com)' keys considered are `tt(hash)' and `tt(localref)'.
|
||||
They are set to the values figured out so far by tt(vcs_info) and any
|
||||
change will be used directly when the actual replacement is done.
|
||||
|
||||
If tt(ret) is set to to non-zero, the string in
|
||||
tt(${hook_com[rev-replace]}) will be used unchanged as the
|
||||
`tt(%i)' replacement in the variables set by tt(vcs_info).
|
||||
)
|
||||
item(tt(set-message))(
|
||||
Called each time before a `tt(vcs_info_msg_N_)' message is set.
|
||||
It takes two arguments; the first being the `N' in the message
|
||||
variable name, the second is the currently configured format or
|
||||
actionformat.
|
||||
|
||||
There are a number of `tt(hook_com)' keys, that are used here:
|
||||
`tt(action)', `tt(branch)', `tt(base)', `tt(base-name)', `tt(subdir)',
|
||||
`tt(staged)', `tt(unstaged)', `tt(revision)', `tt(misc)', `tt(vcs)'
|
||||
and one `tt(miscN)' entry for each backend-specific data field (tt(N)
|
||||
starting at zero). They are set to the values figured out so far by
|
||||
tt(vcs_info) and any change will be used directly when the actual
|
||||
replacement is done.
|
||||
|
||||
Since this hook is triggered multiple times (once for each configured
|
||||
format or actionformat), each of the `tt(hook_com)' keys mentioned
|
||||
above (except for the tt(miscN) entries) has an `tt(_orig)' counterpart,
|
||||
so even if you changed a value to your liking you can still get the
|
||||
original value in the next run. Changing the `tt(_orig)' values is
|
||||
probably not a good idea.
|
||||
|
||||
If tt(ret) is set to to non-zero, the string in
|
||||
tt(${hook_com[message]}) will be used unchanged as the message by
|
||||
tt(vcs_info).
|
||||
)
|
||||
item(tt(set-stgit-format))(
|
||||
Called before a `tt(stgitformat)' is set. The only argument to the
|
||||
hook is the format that is configured at this point.
|
||||
|
||||
The `tt(hook_com)' keys considered are `tt(patch)' and `tt(unapplied)'.
|
||||
They are set to the values figured out so far by tt(vcs_info) and any
|
||||
change will be used directly when the actual replacement is done.
|
||||
|
||||
If tt(ret) is set to to non-zero, the string in
|
||||
tt(${hook_com[stgit-replace]}) will be used unchanged as the
|
||||
`tt(misc0)' replacement in the variables set by tt(vcs_info).
|
||||
)
|
||||
enditem()
|
||||
|
||||
If all of this sounds rather confusing, take a look at the tt(Examples)
|
||||
section below. It contains some explanatory code.
|
||||
|
||||
subsect(Examples)
|
||||
|
||||
Don't use tt(vcs_info) at all (even though it's in your prompt):
|
||||
|
|
@ -779,6 +965,86 @@ example(alias vcsi='vcs_info command; vcs_info_lastmsg')
|
|||
This way, you can even define different formats for output via
|
||||
tt(vcs_info_lastmsg) in the ':vcs_info:*:command:*' namespace.
|
||||
|
||||
Now as promised, some code that uses hooks:
|
||||
say, you'd like to replace the string `svn' by `subversion' in
|
||||
tt(vcs_info)'s tt(%s) format-replacement.
|
||||
|
||||
First, we will tell tt(vcs_info) to call a function when populating
|
||||
the message variables with the gathered information:
|
||||
example(zstyle ':vcs_info:*+set-message:*' hooks svn2subversion)
|
||||
|
||||
Nothing happens. Which is reasonable, since there we didn't define
|
||||
the actual function yet. To see what the hooks subsystem is trying to
|
||||
do, enable the `tt(debug)' style:
|
||||
example(zstyle ':vcs_info:*+*:*' debug true)
|
||||
|
||||
That should give you an idea what is going on. Specifically, the function
|
||||
that we are looking for is `tt(+vi-svn2subversion)'. Note, the `tt(+vi-)'
|
||||
prefix. So, everything is in order, just as documented. When you are done
|
||||
checking out the debugging output, disable it again:
|
||||
example(zstyle ':vcs_info:*+*:*' debug false)
|
||||
|
||||
Now, let's define the function:
|
||||
example(
|
||||
function +vi-svn2subversion+LPAR()RPAR() {
|
||||
[[ ${hook_com[vcs_orig]} == svn ]] && hook_com[vcs]=subversion
|
||||
})
|
||||
|
||||
Simple enough. And it could have even been simpler, if only we had
|
||||
registered our function in a less generic context. If we do it only in
|
||||
the `tt(svn)' backend's context, we don't need to test which the active
|
||||
backend is:
|
||||
example(zstyle ':vcs_info:svn+set-message:*' hooks svn2subversion)
|
||||
example(
|
||||
function +vi-svn2subversion+LPAR()RPAR() {
|
||||
hook_com[vcs]=subversion
|
||||
})
|
||||
|
||||
And finally a little more elaborate example, that uses a hook to create
|
||||
a customised bookmark string for the tt(hg) backend.
|
||||
|
||||
Again, we start off by registering a function:
|
||||
example(zstyle ':vcs_info:hg+gen-hg-bookmark-string:*' hooks hgbookmarks)
|
||||
|
||||
And then we define the `tt(+vi-hgbookmarks) function:
|
||||
example(
|
||||
function +vi-hgbookmarks+LPAR()RPAR() {
|
||||
# The default is to connect all bookmark names by
|
||||
# semicolons. This mixes things up a little.
|
||||
# Imagine, there's one type of bookmarks that is
|
||||
# special to you. Say, because it's *your* work.
|
||||
# Those bookmarks look always like this: "sh/*"
|
||||
# (because your initials are sh, for example).
|
||||
# This makes the bookmarks string use only those
|
||||
# bookmarks. If there's more than one, it
|
||||
# concatenates them using commas.
|
||||
local s i)
|
||||
example(
|
||||
# The bookmarks returned by `hg' are available in
|
||||
# the functions positional parameters.
|
||||
(( $# == 0 )) && return 0
|
||||
for i in "$@"; do
|
||||
if [[ $i == sh/* ]]; then
|
||||
[[ -n $s ]] && s=$s,
|
||||
s=${s}$i
|
||||
fi
|
||||
done)
|
||||
example(
|
||||
# Now, the communication with the code that calls
|
||||
# the hook functions is done via the hook_com[]
|
||||
# hash. The key, at which the `gen-hg-bookmark-string'
|
||||
# hook looks at is `hg-bookmark-string'. So:
|
||||
hook_com[hg-bookmark-string]=$s)
|
||||
example(
|
||||
# And to signal, that we want to use the sting we
|
||||
# just generated, set the special variable `ret' to
|
||||
# something other than the default zero:
|
||||
ret=1
|
||||
return 0
|
||||
})
|
||||
|
||||
This concludes our guided tour through zsh's tt(vcs_info).
|
||||
|
||||
|
||||
texinode(Prompt Themes)(ZLE Functions)(Version Control Information)(User Contributions)
|
||||
sect(Prompt Themes)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue