Hi list,
I've been working on this for quite some time now. vcs_info is a
function that is able to get information about directories under
version control. That information can be used in prompts, for example.
I am submitting this for inclusion in the next zsh release - if the
developers deem it to be worthy. I think Functions/Misc/vcs_info would
be a proper place.
I short example of how a vcs_info enabled prompt can look like can be
found here:
<http://bewatermyfriend.org/posts/2008/09-17.13-43-05-computer.html>
I am attaching the vcs_info file to this mail. And I will post a
follow-up message, that will contain a documentation patch against
Doc/Zsh/contrib.yo.
If people want to give this a try, here is what the doc patch
contains:
[snip]
ZSHCONTRIB(1) ZSHCONTRIB(1)
NAME
zshcontrib - user contributions to zsh
[...]
UTILITIES
[...]
Gathering information from version control systems
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.
In order to do that, you may use the vcs_info function.
Supported VCSs:
bazaar http://bazaar-vcs.org/
codeville
http://codeville.org/
cvs http://www.nongnu.org/cvs/
darcs http://darcs.net/
git http://git.or.cz/
gnu arch
http://www.gnu.org/software/gnu-arch/
mercurial
http://selenic.com/mercurial/
monotone
http://monotone.ca/
subversion
http://subversion.tigris.org/
svk http://svk.bestpractical.com/
Loading vcs_info:
autoload -Uz vcs_info && vcs_info
If you plan to use the information from vcs_info in your prompt (which
is its primary use), you need to enable the PROMPT_SUBST option.
It can be used in any existing prompt, because it does not require any
$psvar entries to be left available.
Quickstart
To get this feature working quickly (including colors), you can do the
following (assuming, you loaded vcs_info properly - see above):
RED=$'%{\e[31m%}'
GR=$'%{\e[32m%}'
MA=$'%{\e[35m%}'
YE=$'%{\e[33m%}'
NC=$'%{\e[0m%}'
zstyle ':vcs_info:*' actionformats \
"${MA}(${NC}%s${MA})${YE}-${MA}[${GR}%b${YE}|${RED}%a${MA}]${NC} "
zstyle ':vcs_info:*' formats \
"${MA}(${NC}%s${MA})${Y}-${MA}[${GR}%b${MA}]${NC}%} "
zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat "%b${RED}:${YE}%r"
precmd () { vcs_info }
PS1="${MA}[${GR}%n${MA}] ${YE}%3~ "'${VCS_INFO_message_0_}'"${NC}%# "
Obviously, the last two lines are there for demonstration: You need to
call vcs_info from your precmd function. Once that is done you need a
single quoted '${VCS_INFO_message_0_}' in your prompt.
Now call the vcs_info_printsys utility from the command line:
% vcs_info_printsys
# list of supported version control backends:
# disabled systems are prefixed by a hash sign (#)
git
hg
bzr
darcs
svk
mtn
svn
cvs
cdv
tla
# flavours (cannot be used in the disable style; they
# are disabled with their master [git-svn -> git]):
git-p4
git-svn
You may not want all of these. Because there is no point in running the
code to detect systems you do not use. Ever. So, there is a way to dis-
able some backends altogether:
zstyle ':vcs_info:*' disable bzr cdv darcs mtn svk tla
If you rerun vcs_info_printsys now, you will see the backends listed in
the disable style marked as diabled by a hash sign. That means the
detection of these systems is skipped completely. No wasted time there.
Configuration
The vcs_info feature can be configured via zstyle.
First, the context in which we are working:
:vcs_info:<vcs-string>:<user-context>:<repo-root-name>
...where <vcs-string> is one of: git, git-svn, git-p4, hg, darcs, bzr,
cdv, mtn, svn, cvs, svk or tla.
...and <user-context> is a freely configurable string, assignable by
the user as the first argument to vcs_info (see its description below).
...and <repo-root-name> is the name of a repository in which you want a
style to match. So, if you want a setting specific to /usr/src/zsh,
with that being a cvs checkout, you can set <repo-root-name> to zsh to
make it so.
There is are three special values for <vcs-string>: The first is named
-init-, that is in effect as long as there was no decision what vcs
backend to use. The second is -preinit-; it is used before vcs_info is
run, when initializing the data exporting variables. The third special
value is 'formats' and is used by the vcs_info_lastmsg for looking up
its styles.
The initial value of <repo-root-name> is -all- and it is replaced with
the actual name, as soon as it is known. Only use this part of the con-
text for defining the formats, actionformats or branchformat styles. As
it is guaranteed that <repo-root-name> is set up correctly for these
only. For all other styles, just use '*' instead.
There are two pre-defined values for <user-context>:
default
the one used if none is specified
command
used by vcs_info_lastmsg to lookup its styles
You may not use print_systems_ as a user-context string, because it is
used internally.
You can of course use ':vcs_info:*' to match all VCSs in all user-con-
texts at once.
Another special context is formats, which is used by the
vcs_info_lastmsg utility function (see below).
This is a description of all styles, that are looked up:
formats
A list of formats, used when actionformats is not used
(which is most of the time).
actionformats
A list of formats, used if a there is a special action
going on in your current repository; (like an interactive
rebase or a merge conflict).
branchformat
Some backends replace %b in the formats and actionformats
styles above, not only by a branch name but also by a
revision number. This style let's you modify how that
string should look like.
nvcsformats
These "formats" are exported, when we didn't detect a
version control system for the current directory. This is
useful, if you want vcs_info to completely take over the
generation of your prompt. You would do something like
PS1='${VCS_INFO_message_0_}' to accomplish that.
max-exports
Defines the maximum number if VCS_INFO_message_*_ vari-
ables vcs_info will export.
enable Checked in the -init- context. If set to false, vcs_info
will do nothing.
disable
Provide a list of systems, you don't want the vcs_info 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 accu-
rate in all possible cases. This style is only used by
the bzr backend.
use-prompt-escapes
Determines if we assume that the assembled string from
vcs_info includes prompt escapes. (Used by
vcs_info_lastmsg.)
The default values for these styles in all contexts are:
formats
" (%s)-[%b|%a]-"
actionformats
" (%s)-[%b]-"
branchformat
"%b:%r" (for bzr, svn and svk)
nvcsformats
""
max-exports
2
enable true
disable
(empty list)
use-simple
false
use-prompt-escapes
true
In normal formats and actionformats, the following replacements are
done:
%s The vcs in use (git, hg, svn etc.)
%b Information about the current branch.
%a An identifier, that describes the action. Only makes
sense in actionformats.
%R base directory of the repository.
%r repository name. If %R is /foo/bar/repoXY, %r is repoXY.
%S subdirectory within a repository. If $PWD is
/foo/bar/reposXY/beer/tasty, %S is beer/tasty.
In branchformat these replacements are done:
%b the branch name
%r the current revision number
Not all vcs backends have to support all replacements. For nvcsformats
no replacements are performed at all. It is just a string.
Oddities
If you want to use the %b (bold off) prompt expansion in formats, which
expands %b itself, use %%b. That will cause the vcs_info expansion to
replace %%b with %b. So zsh's prompt expansion mechanism can handle it.
Similarly, to hand down %b from branchformat, use %%%%b. Sorry for this
inconvenience, but it cannot be easily avoided. Luckily we do not clash
with a lot of prompt expansions and this only needs to be done for
those.
Function descriptions (public API)
vcs_info
The main function, that runs all backends and assembles
all data into ${VCS_INFO_message_*_}. This is the func-
tion you want to call from precmd if you want to include
up-to-date information in your prompt (see Variable
description below).
vcs_info_printsys
Prints a list of all supported version control systems.
Useful to find out possible contexts (and which of them
are enabled) or values for the disable style.
vcs_info_lastmsg
Outputs the last ${VCS_INFO_message_*_} value. Takes into
account the value of the use-prompt-escapes style in
':vcs_info:formats:command:-all-'. It also only prints
max-exports values.
All functions named VCS_INFO_* are for internal use only.
Variable description
${VCS_INFO_message_N_} (Note the trailing underscore)
Where N is an integer, eg: VCS_INFO_message_0_ These
variables are the storage for the informational message
the last vcs_info call has assembled. These are strongly
connected to the formats, actionformats and nvcsformats
styles described above. Those styles are lists. The first
member of that list gets expanded into ${VCS_INFO_mes-
sage_0_}, the second into ${VCS_INFO_message_1_} and the
Nth into ${VCS_INFO_message_N-1_}. These parameters are
exported into the environment. (See the max-exports style
above.)
Examples
Don't use vcs_info at all (even though it's in your prompt):
zstyle ':vcs_info:*' enable false
Disable the backends for bzr and svk:
zstyle ':vcs_info:*' disable bzr svk
Provide a special formats for git:
zstyle ':vcs_info:git:*' formats ' GIT, BABY! [%b]'
zstyle ':vcs_info:git:*' actionformats ' GIT ACTION! [%b|%a]'
Use the quicker bzr backend
zstyle ':vcs_info:bzr:*' use-simple true
If you do use use-simle, please report if it does the-right-thing[tm].
Display the revision number in yellow for bzr and svn:
zstyle ':vcs_info:(svn|bzr):*' branchformat '%b%{'${fg[yellow]}'%}:%r'
If you want colors, make sure you enclose the color codes in %{...%},
if you want to use the string provided by vcs_info in prompts.
Here is how to print the vcs infomation as a command (not in a prompt):
alias vcsi='vcs_info command; vcs_info_lastmsg'
This way, you can even define different formats for output via
vcs_info_lastmsg in the ':vcs_info:formats:command:*' namespace.
[snap]
Comments welcome. :)
Regards, Frank