summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2008-09-19 12:58:46 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2008-09-19 12:58:46 +0000
commit23f2b4503c9d7697e382fed550d3bf846b81dd5c (patch)
tree8953de32c2d4126882d9d4c66bcbe7b8615e3419
parentd9f1432e074872aa3a89515bc65ede5ad6551a47 (diff)
downloadzsh-23f2b4503c9d7697e382fed550d3bf846b81dd5c.tar.gz
zsh-23f2b4503c9d7697e382fed550d3bf846b81dd5c.tar.xz
zsh-23f2b4503c9d7697e382fed550d3bf846b81dd5c.zip
users/13252 and elsewhere: Frank Terbeck plus tweaks:
add VCS_Info function system
-rw-r--r--ChangeLog4
-rw-r--r--Doc/Zsh/contrib.yo336
-rw-r--r--Etc/CONTRIBUTORS2
-rw-r--r--Functions/VCS_Info/.distfiles15
-rw-r--r--Functions/VCS_Info/Backends/.distfiles24
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_bzr12
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_cdv12
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_cvs11
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_darcs12
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_git15
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_hg12
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_mtn12
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_p49
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_svk40
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_svn11
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_tla11
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr26
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_cdv11
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_cvs18
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_darcs11
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_git104
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_hg12
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_mtn12
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_p414
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_svk13
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_svn28
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_tla13
-rw-r--r--Functions/VCS_Info/VCS_INFO_adjust8
-rw-r--r--Functions/VCS_Info/VCS_INFO_bydir_detect25
-rw-r--r--Functions/VCS_Info/VCS_INFO_check_com8
-rw-r--r--Functions/VCS_Info/VCS_INFO_formats23
-rw-r--r--Functions/VCS_Info/VCS_INFO_maxexports13
-rw-r--r--Functions/VCS_Info/VCS_INFO_nvcsformats15
-rw-r--r--Functions/VCS_Info/VCS_INFO_realpath16
-rw-r--r--Functions/VCS_Info/VCS_INFO_reposub13
-rw-r--r--Functions/VCS_Info/VCS_INFO_set32
-rw-r--r--Functions/VCS_Info/vcs_info90
-rw-r--r--Functions/VCS_Info/vcs_info_lastmsg18
-rw-r--r--Functions/VCS_Info/vcs_info_printsys37
-rw-r--r--Functions/VCS_Info/vcs_info_setsys22
-rw-r--r--Src/zsh.mdd2
41 files changed, 1119 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index e1223aa1c..6b0b778b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2008-09-19  Peter Stephenson  <pws@csr.com>
 
+	* users/13252 and others: Frank Terbeck (plus doc tweaks):
+	Functions/VCS_Info/**/*, Doc/Zsh/contrib.yo, Src/zsh.mdd:
+	add VCS_Info function system.
+
 	* Unposted, but see users/13251: Doc/Zsh/mod_mapfile.yo: update
 	users/13239.
 
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 0d3b16aa9..00ebbe335 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -11,6 +11,7 @@ such as shell functions, look for comments in the function source files.
 
 startmenu()
 menu(Utilities)
+menu(Version Control Information)
 menu(Prompt Themes)
 menu(ZLE Functions)
 menu(Exception Handling)
@@ -20,7 +21,7 @@ menu(User Configuration Functions)
 menu(Other Functions)
 endmenu()
 
-texinode(Utilities)(Prompt Themes)()(User Contributions)
+texinode(Utilities)(Version Control Information)()(User Contributions)
 sect(Utilities)
 
 subsect(Accessing On-Line Help)
@@ -316,7 +317,338 @@ functions to be executed.
 )
 enditem()
 
-texinode(Prompt Themes)(ZLE Functions)(Utilities)(User Contributions)
+texinode(Version Control Information)(Prompt Themes)(Utilities)(User Contributions)
+sect(Gathering information from version control systems)
+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.
+
+In order to do that, you may use the tt(vcs_info) function.
+
+The following VCSs are supported:
+startsitem()
+sitem(tt(bazaar))(http://bazaar-vcs.org/)
+sitem(tt(codeville))(http://codeville.org/)
+sitem(tt(cvs))(http://www.nongnu.org/cvs/)
+sitem(tt(darcs))(http://darcs.net/)
+sitem(tt(git))(http://git.or.cz/)
+sitem(tt(gnu arch))(http://www.gnu.org/software/gnu-arch/)
+sitem(tt(mercurial))(http://selenic.com/mercurial/)
+sitem(tt(monotone))(http://monotone.ca/)
+sitem(tt(perforce))(http://www.perforce.com/)
+sitem(tt(subversion))(http://subversion.tigris.org/)
+sitem(tt(svk))(http://svk.bestpractical.com/)
+endsitem()
+
+To load var(vcs_info):
+
+example(autoload -Uz vcs_info && vcs_info)
+
+If you plan to use the information from var(vcs_info) in your prompt (which
+is its primary use), you need to enable the tt(PROMPT_SUBST) option.
+
+It can be used in any existing prompt, because it does not require any
+tt($psvar) entries to be left available.
+
+subsect(Quickstart)
+
+To get this feature working quickly (including colors), you can do the
+following (assuming, you loaded var(vcs_info) properly - see above):
+
+example(zstyle ':vcs_info:*' actionformats \ 
+    '%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{3}|%F{1}%a%F{5}]%f '
+zstyle ':vcs_info:*' formats       \ 
+    '%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{5}]%f '
+zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat '%b%F{1}:%F{3}%r'
+precmd () { vcs_info }
+PS1='%F{5}[%F{2}%n%F{5}] %F{3}%3~ ${vcs_info_msg_0_}'"%f%# ')
+
+Obviously, the last two lines are there for demonstration: You need to
+call var(vcs_info) from your var(precmd) function. Once that is done you need
+a tt(single quoted) var('${vcs_info_msg_0_}') in your prompt.
+
+Now call the tt(vcs_info_printsys) utility from the command line:
+
+example(% vcs_info_printsys
+## list of supported version control backends:
+## disabled systems are prefixed by a hash sign (#)
+bzr
+cdv
+cvs
+darcs
+git
+hg
+mtn
+p4
+svk
+svn
+tla
+## flavours (cannot be used in the enable or disable styles; they
+## are enabled and disabled with their master [git-svn -> git])
+## they *can* be used contexts: ':vcs_info:git-svn:*'.
+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.  So there is a way to disable
+some backends altogether:
+
+example(zstyle ':vcs_info:*' disable bzr cdv darcs mtn svk tla)
+
+You may also pick a few from that list and enable only those:
+
+example(zstyle ':vcs_info:*' enable git cvs svn)
+
+If you rerun tt(vcs_info_printsys) after one of these commands, you will
+see the backends listed in the var(disable) style (or backends not in the
+var(enable) style - if you used that) marked as disabled by a hash sign.
+That means the detection of these systems is skipped tt(completely). No
+wasted time there.
+
+subsect(Configuration)
+
+The var(vcs_info) feature can be configured via var(zstyle).
+
+First, the context in which we are working:
+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.
+)
+item(tt(<user-context>))(
+is a freely configurable string, assignable by
+the user as the first argument to var(vcs_info) (see its description
+below).
+)
+item(tt(<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 var(/usr/src/zsh),
+with that being a cvs checkout, you can set tt(<repo-root-name>) to
+var(zsh) to make it so.
+)
+enditem()
+
+There are three special values for tt(<vcs-string>): The first is named
+var(-init-), that is in effect as long as there was no decision what vcs
+backend to use. The second is var(-preinit-); it is used tt(before)
+var(vcs_info) is run, when initializing the data exporting variables. The
+third special value is var(formats) and is used by the tt(vcs_info_lastmsg)
+for looking up its styles.
+
+The initial value of tt(<repo-root-name>) is var(-all-) and it is replaced
+with the actual name, as soon as it is known. Only use this part of the
+context for defining the var(formats), var(actionformats) or
+var(branchformat) styles. As it is guaranteed that tt(<repo-root-name>) is
+set up correctly for these only. For all other styles, just use tt('*')
+instead.
+
+There are two pre-defined values for tt(<user-context>):
+startsitem()
+sitem(tt(default))(the one used if none is specified)
+sitem(tt(command))(used by vcs_info_lastmsg to lookup its styles)
+endsitem()
+
+You can of course use tt(':vcs_info:*') to match all VCSs in all
+user-contexts at once.
+
+This is a description of all styles that are looked up.
+
+startitem()
+kindex(formats)
+item(tt(formats))(
+A list of formats, used when actionformats is not used
+(which is most of the time).
+)
+kindex(actionformats)
+item(tt(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).
+)
+kindex(branchformat)
+item(tt(branchformat))(
+Some backends replace var(%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.
+)
+kindex(nvcsformats)
+item(tt(nvcsformats))(
+These "formats" are exported, when we didn't detect
+a version control system for the current directory. This is useful, if you
+want var(vcs_info) to completely take over the generation of your prompt.
+You would do something like tt(PS1='${vcs_info_msg_0_}') to accomplish
+that.
+)
+kindex(max-exports)
+item(tt(max-exports))(
+Defines the maximum number if
+var(vcs_info_msg_*_) variables var(vcs_info) will export.
+)
+kindex(enable)
+item(tt(enable))(
+A list of backends you want to use. Checked in the
+var(-init-) context. If this list contains an item called tt(NONE) no
+backend is used at all and var(vcs_info) will do nothing. If this list
+contains tt(ALL) var(vcs_info) will use all backends known to it. Only with
+tt(ALL) in tt(enable), the tt(disable) style has any effect. tt(ALL) and
+tt(NONE) are actually tested case insensitively.)
+sitem(tt(disable))(A list of VCSs, you don't want var(vcs_info) to test for
+repositories (checked in the var(-init-) context, too). Only used if
+tt(enable) contains tt(ALL).
+)
+kindex(use-simple)
+item(tt(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. This style is only
+used by the tt(bzr) backend.
+)
+kindex(use-prompt-escapes)
+item(tt(use-prompt-escapes))(
+Determines if we assume that the assembled
+string from var(vcs_info) includes prompt escapes. (Used by
+tt(vcs_info_lastmsg).)
+)
+enditem()
+
+The default values for these styles in all contexts are:
+
+startsitem()
+sitem(tt(formats))(" (%s)-[%b|%a]-")
+sitem(tt(actionformats))(" (%s)-[%b]-")
+sitem(tt(branchformat))("%b:%r" (for bzr, svn and svk))
+sitem(tt(nvcsformats))("")
+sitem(tt(max-exports))(2)
+sitem(tt(enable))(ALL)
+sitem(tt(disable))((empty list))
+sitem(tt(use-simple))(false)
+sitem(tt(use-prompt-escapes))(true)
+endsitem()
+
+In normal tt(formats) and tt(actionformats), the following replacements are
+done:
+
+startsitem()
+sitem(tt(%s))(The vcs in use (git, hg, svn etc.))
+sitem(tt(%b))(Information about the current branch.)
+sitem(tt(%a))(An identifier, that describes the action. Only makes sense in
+actionformats.)
+sitem(tt(%R))(base directory of the repository.)
+sitem(tt(%r))(repository name. If tt(%R) is var(/foo/bar/repoXY), tt(%r) is
+var(repoXY).)
+sitem(tt(%S))(subdirectory within a repository. If tt($PWD) is
+var(/foo/bar/reposXY/beer/tasty), tt(%S) is var(beer/tasty).)
+endsitem()
+
+In tt(branchformat) these replacements are done:
+
+startsitem()
+sitem(tt(%b))(the branch name)
+sitem(tt(%r))(the current revision number)
+endsitem()
+
+Not all vcs backends have to support all replacements. For tt(nvcsformats)
+no replacements are performed at all. It is just a string.
+
+subsect(Oddities)
+
+If you want to use the tt(%b) (bold off) prompt expansion in var(formats),
+which expands tt(%b) itself, use tt(%%b). That will cause the var(vcs_info)
+expansion to replace tt(%%b) with tt(%b). So zsh's prompt expansion
+mechanism can handle it. Similarly, to hand down tt(%b) from
+var(branchformat), use tt(%%%%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.
+
+
+subsect(Function descriptions (public API))
+
+startitem()
+findex(vcs_info)
+item(tt(vcs_info) [var(user-context)])(
+The main function, that runs all
+backends and assembles all data into var(${vcs_info_msg_*_}). This is the
+function you want to call from tt(precmd) if you want to include up-to-date
+information in your prompt (see Variable description below). If an argument
+is given, that string will be used instead of tt(default) in the
+user-context field of the style context.)
+sitem(tt(vcs_info_lastmsg))(Outputs the last var(${vcs_info_msg_*_}) value.
+Takes into account the value of the use-prompt-escapes style in
+var(':vcs_info:formats:command:-all-'). It also only prints tt(max-exports)
+values.
+)
+findex(vcs_info_printsys)
+item(tt(vcs_info_printsys) [var(user-context)])(
+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 var(disable) style.)
+sitem(tt(vcs_info_setsys))(Initializes var(vcs_info)'s internal list of
+available backends. With this function, you can add support for new VCSs
+without restarting the shell.
+)
+enditem()
+
+All functions named VCS_INFO_* are for internal use only.
+
+subsect(Variable description)
+
+startitem()
+item(tt(${vcs_info_msg_N_}) (Note the trailing underscore))
+(
+Where var(N) is an integer, eg: var(vcs_info_msg_0_) These variables
+are the storage for the informational message the last var(vcs_info) call
+has assembled. These are strongly connected to the formats,
+tt(actionformats) and tt(nvcsformats) styles described above. Those styles
+are lists. The first member of that list gets expanded into
+var(${vcs_info_msg_0_}), the second into var(${vcs_info_msg_1_})
+and the Nth into var(${vcs_info_msg_N-1_}). These parameters are
+exported into the environment. (See the tt(max-exports) style above.)
+)
+enditem()
+
+All variables named VCS_INFO_* are for internal use only.
+
+subsect(Examples)
+
+Don't use tt(vcs_info) at all (even though it's in your prompt):
+example(zstyle ':vcs_info:*' enable NONE)
+
+Disable the backends for tt(bzr) and tt(svk):
+example(zstyle ':vcs_info:*' disable bzr svk)
+
+Disable everything em(but) tt(bzr) and tt(svk):
+example(zstyle ':vcs_info:*' enable bzr svk)
+
+Provide a special formats for tt(git):
+example(zstyle ':vcs_info:git:*' formats       ' GIT, BABY! [%b]'
+zstyle ':vcs_info:git:*' actionformats ' GIT ACTION! [%b|%a]')
+
+Use the quicker tt(bzr) backend
+example(zstyle ':vcs_info:bzr:*' use-simple true)
+
+If you do use tt(use-simple), please report if it does `the-right-thing[tm]'.
+
+Display the revision number in yellow for tt(bzr) and tt(svn):
+example(zstyle ':vcs_info:(svn|bzr):*' branchformat '%b%{'${fg[yellow]}'%}:%r')
+
+If you want colors, make sure you enclose the color codes in tt(%{...%}),
+if you want to use the string provided by tt(vcs_info) in prompts.
+
+Here is how to print the vcs infomation as a command (not in a prompt):
+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:formats:command:*' namespace.
+
+
+texinode(Prompt Themes)(ZLE Functions)(Version Control Information)(User Contributions)
 sect(Prompt Themes)
 
 subsect(Installation)
diff --git a/Etc/CONTRIBUTORS b/Etc/CONTRIBUTORS
index 09713d76e..4684c5f7b 100644
--- a/Etc/CONTRIBUTORS
+++ b/Etc/CONTRIBUTORS
@@ -24,6 +24,8 @@ Matthias Kopferman, Mikael Magnusson, Dan Nelson, Phil Pennock, Toby
 Peterson, R. Ramkumar, Bart Schaefer, Joerg Sonnenberger, Peter Stephenson,
 Takimoto Jun, River Tarnell, Philippe Troin, Geoff Wing, Matt Wozniski.
 
+The VCS_Info function system was written by Frank Terbeck.
+
 Contributors to completion functions include those above plus Zack Cerza,
 Danek Duvall, Tobias Gruetzmacher, Dough Kearns, Hannu Koivisto, Henryk
 Konsek, Scott Murray, Tomasz Pala, Carlos Phillips, Haakon Riiser, Felix
diff --git a/Functions/VCS_Info/.distfiles b/Functions/VCS_Info/.distfiles
new file mode 100644
index 000000000..44e52905b
--- /dev/null
+++ b/Functions/VCS_Info/.distfiles
@@ -0,0 +1,15 @@
+DISTFILES_SRC='
+vcs_info
+VCS_INFO_adjust
+VCS_INFO_bydir_detect
+VCS_INFO_check_com
+VCS_INFO_formats
+vcs_info_lastmsg
+VCS_INFO_maxexports
+VCS_INFO_nvcsformats
+vcs_info_printsys
+VCS_INFO_realpath
+VCS_INFO_reposub
+VCS_INFO_set
+vcs_info_setsys
+'
diff --git a/Functions/VCS_Info/Backends/.distfiles b/Functions/VCS_Info/Backends/.distfiles
new file mode 100644
index 000000000..e39e9c71c
--- /dev/null
+++ b/Functions/VCS_Info/Backends/.distfiles
@@ -0,0 +1,24 @@
+DISTFILES_SRC='
+VCS_INFO_detect_bzr
+VCS_INFO_detect_cdv
+VCS_INFO_detect_cvs
+VCS_INFO_detect_darcs
+VCS_INFO_detect_git
+VCS_INFO_detect_hg
+VCS_INFO_detect_mtn
+VCS_INFO_detect_p4
+VCS_INFO_detect_svk
+VCS_INFO_detect_svn
+VCS_INFO_detect_tla
+VCS_INFO_get_data_bzr
+VCS_INFO_get_data_cdv
+VCS_INFO_get_data_cvs
+VCS_INFO_get_data_darcs
+VCS_INFO_get_data_git
+VCS_INFO_get_data_hg
+VCS_INFO_get_data_mtn
+VCS_INFO_get_data_p4
+VCS_INFO_get_data_svk
+VCS_INFO_get_data_svn
+VCS_INFO_get_data_tla
+'
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_bzr b/Functions/VCS_Info/Backends/VCS_INFO_detect_bzr
new file mode 100644
index 000000000..0b12fb54f
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_bzr
@@ -0,0 +1,12 @@
+## vim:ft=zsh
+## bazaar support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+[[ $1 == '--flavours' ]] && return 1
+
+VCS_INFO_check_com bzr || return 1
+vcs_comm[detect_need_file]=branch/format
+VCS_INFO_bydir_detect '.bzr'
+return $?
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_cdv b/Functions/VCS_Info/Backends/VCS_INFO_detect_cdv
new file mode 100644
index 000000000..356bd069c
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_cdv
@@ -0,0 +1,12 @@
+## vim:ft=zsh
+## codeville support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+[[ $1 == '--flavours' ]] && return 1
+
+VCS_INFO_check_com cdv || return 1
+vcs_comm[detect_need_file]=format
+VCS_INFO_bydir_detect '.cdv'
+return $?
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_cvs b/Functions/VCS_Info/Backends/VCS_INFO_detect_cvs
new file mode 100644
index 000000000..61b43cc43
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_cvs
@@ -0,0 +1,11 @@
+## vim:ft=zsh
+## cvs support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+[[ $1 == '--flavours' ]] && return 1
+
+VCS_INFO_check_com svn || return 1
+[[ -d "./CVS" ]] && [[ -r "./CVS/Repository" ]] && return 0
+return 1
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_darcs b/Functions/VCS_Info/Backends/VCS_INFO_detect_darcs
new file mode 100644
index 000000000..942d8afbb
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_darcs
@@ -0,0 +1,12 @@
+## vim:ft=zsh
+## darcs support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+[[ $1 == '--flavours' ]] && return 1
+
+VCS_INFO_check_com darcs || return 1
+vcs_comm[detect_need_file]=format
+VCS_INFO_bydir_detect '_darcs'
+return $?
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_git b/Functions/VCS_Info/Backends/VCS_INFO_detect_git
new file mode 100644
index 000000000..627b8cf23
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_git
@@ -0,0 +1,15 @@
+## vim:ft=zsh
+## git support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+[[ $1 == '--flavours' ]] && { print -l git-p4 git-svn; return 0 }
+
+if VCS_INFO_check_com git && git rev-parse --is-inside-work-tree &> /dev/null ; then
+    vcs_comm[gitdir]="$(git rev-parse --git-dir 2> /dev/null)" || return 1
+    if   [[ -d ${vcs_comm[gitdir]}/svn ]]             ; then vcs_comm[overwrite_name]='git-svn'
+    elif [[ -d ${vcs_comm[gitdir]}/refs/remotes/p4 ]] ; then vcs_comm[overwrite_name]='git-p4' ; fi
+    return 0
+fi
+return 1
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_hg b/Functions/VCS_Info/Backends/VCS_INFO_detect_hg
new file mode 100644
index 000000000..8a6c0c8a6
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_hg
@@ -0,0 +1,12 @@
+## vim:ft=zsh
+## mercurial support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+[[ $1 == '--flavours' ]] && return 1
+
+VCS_INFO_check_com hg || return 1
+vcs_comm[detect_need_file]=branch
+VCS_INFO_bydir_detect '.hg'
+return $?
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_mtn b/Functions/VCS_Info/Backends/VCS_INFO_detect_mtn
new file mode 100644
index 000000000..cb0fec1bd
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_mtn
@@ -0,0 +1,12 @@
+## vim:ft=zsh
+## monotone support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+[[ $1 == '--flavours' ]] && return 1
+
+VCS_INFO_check_com mtn || return 1
+vcs_comm[detect_need_file]=revision
+VCS_INFO_bydir_detect '_MTN'
+return $?
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_p4 b/Functions/VCS_Info/Backends/VCS_INFO_detect_p4
new file mode 100644
index 000000000..3cd649a0d
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_p4
@@ -0,0 +1,9 @@
+## vim:ft=zsh
+## perforce support by: Phil Pennock
+## Distributed under the same BSD-ish license as zsh itself.
+
+[[ -n ${P4CONFIG} ]] || return 1
+VCS_INFO_check_com p4 || return 1
+vcs_comm[detect_need_file]="${P4CONFIG}"
+VCS_INFO_bydir_detect .
+return $?
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_svk b/Functions/VCS_Info/Backends/VCS_INFO_detect_svk
new file mode 100644
index 000000000..476b59101
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_svk
@@ -0,0 +1,40 @@
+## vim:ft=zsh
+## svk support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+[[ $1 == '--flavours' ]] && return 1
+
+# This detection function is a bit different from the others.
+# We need to read svk's config file to detect a svk repository
+# in the first place. Therefore, we'll just proceed and read
+# the other information, too. This is more then any of the
+# other detections do but this takes only one file open for
+# svk at most. VCS_INFO_get_data_svk() gets simpler, too. :-)
+
+setopt localoptions noksharrays extendedglob
+local -i fhash
+fhash=0
+
+VCS_INFO_check_com svk || return 1
+[[ -f ~/.svk/config ]] || return 1
+
+while IFS= read -r line ; do
+    if [[ -n ${vcs_comm[basedir]} ]] ; then
+        line=${line## ##}
+        [[ ${line} == depotpath:* ]] && vcs_comm[branch]=${line##*/}
+        [[ ${line} == revision:* ]] && vcs_comm[revision]=${line##*[[:space:]]##}
+        [[ -n ${vcs_comm[branch]} ]] && [[ -n ${vcs_comm[revision]} ]] && break
+        continue
+    fi
+    (( fhash > 0 )) && [[ ${line} == '  '[^[:space:]]*:* ]] && break
+    [[ ${line} == '  hash:'* ]] && fhash=1 && continue
+    (( fhash == 0 )) && continue
+    [[ ${PWD}/ == ${${line## ##}%:*}/* ]] && vcs_comm[basedir]=${${line## ##}%:*}
+done < ~/.svk/config
+
+[[ -n ${vcs_comm[basedir]} ]]  && \
+[[ -n ${vcs_comm[branch]} ]]   && \
+[[ -n ${vcs_comm[revision]} ]] && return 0
+return 1
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_svn b/Functions/VCS_Info/Backends/VCS_INFO_detect_svn
new file mode 100644
index 000000000..f22c34ee5
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_svn
@@ -0,0 +1,11 @@
+## vim:ft=zsh
+## subversion support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+[[ $1 == '--flavours' ]] && return 1
+
+VCS_INFO_check_com svn || return 1
+[[ -d ".svn" ]] && return 0
+return 1
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_tla b/Functions/VCS_Info/Backends/VCS_INFO_detect_tla
new file mode 100644
index 000000000..3b2042897
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_tla
@@ -0,0 +1,11 @@
+## vim:ft=zsh
+## gnu arch support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+[[ $1 == '--flavours' ]] && return 1
+
+VCS_INFO_check_com tla || return 1
+vcs_comm[basedir]="$(tla tree-root 2> /dev/null)" && return 0
+return 1
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr b/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr
new file mode 100644
index 000000000..995b2ad2d
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr
@@ -0,0 +1,26 @@
+## vim:ft=zsh
+## bazaar support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions noksharrays extendedglob NO_shwordsplit
+local bzrbase bzrbr
+local -a bzrinfo
+
+if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "use-simple" ; then
+    bzrbase=${vcs_comm[basedir]}
+    bzrinfo[2]=${bzrbase:t}
+    if [[ -f ${bzrbase}/.bzr/branch/last-revision ]] ; then
+        bzrinfo[1]=$(< ${bzrbase}/.bzr/branch/last-revision)
+        bzrinfo[1]=${${bzrinfo[1]}%% *}
+    fi
+else
+    bzrbase=${${(M)${(f)"$( bzr info )"}:# ##branch\ root:*}/*: ##/}
+    bzrinfo=( ${${${(M)${(f)"$( bzr version-info )"}:#(#s)(revno|branch-nick)*}/*: /}/*\//} )
+    bzrbase="$(VCS_INFO_realpath ${bzrbase})"
+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]}"
+VCS_INFO_formats '' "${bzrbr}" "${bzrbase}"
+return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_cdv b/Functions/VCS_Info/Backends/VCS_INFO_get_data_cdv
new file mode 100644
index 000000000..be8b4d837
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_cdv
@@ -0,0 +1,11 @@
+## vim:ft=zsh
+## codeville support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+local cdvbase
+
+cdvbase=${vcs_comm[basedir]}
+rrn=${cdvbase:t}
+VCS_INFO_formats '' "${cdvbase:t}" "${cdvbase}"
+return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_cvs b/Functions/VCS_Info/Backends/VCS_INFO_get_data_cvs
new file mode 100644
index 000000000..fa1ceca02
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_cvs
@@ -0,0 +1,18 @@
+## vim:ft=zsh
+## cvs support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+local cvsbranch cvsbase
+
+cvsbase="."
+while [[ -d "${cvsbase}/../CVS" ]]; do
+    cvsbase="${cvsbase}/.."
+done
+cvsbase="$(VCS_INFO_realpath ${cvsbase})"
+cvsbranch=$(< ./CVS/Repository)
+rrn=${cvsbase:t}
+cvsbranch=${cvsbranch##${rrn}/}
+[[ -z ${cvsbranch} ]] && cvsbranch=${rrn}
+VCS_INFO_formats '' "${cvsbranch}" "${cvsbase}"
+return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_darcs b/Functions/VCS_Info/Backends/VCS_INFO_get_data_darcs
new file mode 100644
index 000000000..9fd3554ca
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_darcs
@@ -0,0 +1,11 @@
+## vim:ft=zsh
+## darcs support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+local darcsbase
+
+darcsbase=${vcs_comm[basedir]}
+rrn=${darcsbase:t}
+VCS_INFO_formats '' "${darcsbase:t}" "${darcsbase}"
+return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
new file mode 100644
index 000000000..0d8a4f915
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
@@ -0,0 +1,104 @@
+## vim:ft=zsh
+## git support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions extendedglob NO_shwordsplit
+local gitdir gitbase gitbranch gitaction
+
+VCS_INFO_git_getaction () {
+    local gitaction='' gitdir=$1
+    local tmp
+
+    for tmp in "${gitdir}/rebase-apply" \
+               "${gitdir}/rebase"       \
+               "${gitdir}/../.dotest" ; do
+        if [[ -d ${tmp} ]] ; then
+            if   [[ -f "${tmp}/rebasing" ]] ; then
+                gitaction="rebase"
+            elif [[ -f "${tmp}/applying" ]] ; then
+                gitaction="am"
+            else
+                gitaction="am/rebase"
+            fi
+            printf '%s' ${gitaction}
+            return 0
+        fi
+    done
+
+    for tmp in "${gitdir}/rebase-merge/interactive" \
+               "${gitdir}/.dotest-merge/interactive" ; do
+        if [[ -f "${tmp}" ]] ; then
+            printf '%s' "rebase-i"
+            return 0
+        fi
+    done
+
+    for tmp in "${gitdir}/rebase-merge" \
+               "${gitdir}/.dotest-merge" ; do
+        if [[ -d "${tmp}" ]] ; then
+            printf '%s' "rebase-m"
+            return 0
+        fi
+    done
+
+    if [[ -f "${gitdir}/MERGE_HEAD" ]] ; then
+        printf '%s' "merge"
+        return 0
+    fi
+
+    if [[ -f "${gitdir}/BISECT_LOG" ]] ; then
+        printf '%s' "bisect"
+        return 0
+    fi
+    return 1
+}
+
+VCS_INFO_git_getbranch () {
+    local gitbranch gitdir=$1
+    local gitsymref='git symbolic-ref HEAD'
+
+    if    [[ -d "${gitdir}/rebase-apply" ]] \
+       || [[ -d "${gitdir}/rebase" ]]       \
+       || [[ -d "${gitdir}/../.dotest" ]]   \
+       || [[ -f "${gitdir}/MERGE_HEAD" ]] ; then
+        gitbranch="$(${(z)gitsymref} 2> /dev/null)"
+        [[ -z ${gitbranch} ]] && [[ -r ${gitdir}/rebase-apply/head-name ]] \
+            && gitbranch="$(< ${gitdir}/rebase-apply/head-name)"
+
+    elif   [[ -f "${gitdir}/rebase-merge/interactive" ]] \
+        || [[ -d "${gitdir}/rebase-merge" ]] ; then
+        gitbranch="$(< ${gitdir}/rebase-merge/head-name)"
+
+    elif   [[ -f "${gitdir}/.dotest-merge/interactive" ]] \
+        || [[ -d "${gitdir}/.dotest-merge" ]] ; then
+        gitbranch="$(< ${gitdir}/.dotest-merge/head-name)"
+
+    else
+        gitbranch="$(${(z)gitsymref} 2> /dev/null)"
+
+        if [[ $? -ne 0 ]] ; then
+            gitbranch="$(git describe --exact-match HEAD 2>/dev/null)"
+
+            if [[ $? -ne 0 ]] ; then
+                gitbranch="${${"$(< $gitdir/HEAD)"}[1,7]}..."
+            fi
+        fi
+    fi
+
+    printf '%s' "${gitbranch##refs/heads/}"
+    return 0
+}
+
+gitdir=${vcs_comm[gitdir]}
+gitbranch="$(VCS_INFO_git_getbranch ${gitdir})"
+
+if [[ -z ${gitdir} ]] || [[ -z ${gitbranch} ]] ; then
+    return 1
+fi
+
+VCS_INFO_adjust
+gitaction="$(VCS_INFO_git_getaction ${gitdir})"
+gitbase=${PWD%/${$( git rev-parse --show-prefix )%/##}}
+rrn=${gitbase:t}
+VCS_INFO_formats "${gitaction}" "${gitbranch}" "${gitbase}"
+return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
new file mode 100644
index 000000000..af9d85c5f
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
@@ -0,0 +1,12 @@
+## vim:ft=zsh
+## mercurial support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+local hgbranch hgbase
+
+hgbase=${vcs_comm[basedir]}
+rrn=${hgbase:t}
+hgbranch=$(< ${hgbase}/.hg/branch)
+VCS_INFO_formats '' "${hgbranch}" "${hgbase}"
+return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_mtn b/Functions/VCS_Info/Backends/VCS_INFO_get_data_mtn
new file mode 100644
index 000000000..5974df87a
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_mtn
@@ -0,0 +1,12 @@
+## vim:ft=zsh
+## monotone support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions extendedglob NO_shwordsplit
+local mtnbranch mtnbase
+
+mtnbase=${vcs_comm[basedir]}
+rrn=${mtnbase:t}
+mtnbranch=${${(M)${(f)"$( mtn status )"}:#(#s)Current branch:*}/*: /}
+VCS_INFO_formats '' "${mtnbranch}" "${mtnbase}"
+return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4 b/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4
new file mode 100644
index 000000000..82ca6ef1c
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4
@@ -0,0 +1,14 @@
+## vim:ft=zsh
+## perforce support by: Phil Pennock
+## Distributed under the same BSD-ish license as zsh itself.
+
+# XXX: This soooo needs to be cached
+setopt localoptions extendedglob
+local p4base a b
+local -A p4info
+
+p4 info | while IFS=: read a b; do p4info[${a// /_}]="${b## #}"; done
+p4base=${vcs_comm[basedir]}
+
+# We'll use the client name as the branch; close enough
+VCS_INFO_formats '' "${p4info[Client_name]}" "${p4base}"
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk
new file mode 100644
index 000000000..fa9548c03
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk
@@ -0,0 +1,13 @@
+## vim:ft=zsh
+## svk support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+local svkbranch svkbase
+
+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]}"
+VCS_INFO_formats '' "${svkbranch}" "${svkbase}"
+return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn
new file mode 100644
index 000000000..7a23419b0
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn
@@ -0,0 +1,28 @@
+## vim:ft=zsh
+## subversion support by:
+##  + Frank Terbeck <ft@bewatermyfriend.org>
+##  + Phil Pennock
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions noksharrays extendedglob NO_shwordsplit
+local svnbase svnbranch a b rrn
+local -A svninfo parentinfo
+
+svnbase=".";
+svninfo=()
+svn info --non-interactive | while IFS=: read a b; do svninfo[${a// /_}]="${b## #}"; done
+while [[ -d "${svnbase}/../.svn" ]]; do
+    parentinfo=()
+    svn info --non-interactive "${svnbase}/.." | while IFS=: read a b; do parentinfo[${a// /_}]="${b## #}"; done
+    [[ ${parentinfo[Repository_UUID]} != ${svninfo[Repository_UUID]} ]] && break
+    svninfo=(${(kv)parentinfo})
+    svnbase="${svnbase}/.."
+done
+
+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]}"
+VCS_INFO_formats '' "${svnbranch}" "${svnbase}"
+return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_tla b/Functions/VCS_Info/Backends/VCS_INFO_get_data_tla
new file mode 100644
index 000000000..e1921725f
--- /dev/null
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_tla
@@ -0,0 +1,13 @@
+## vim:ft=zsh
+## gnu arch support by: Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions extendedglob NO_shwordsplit
+local tlabase tlabranch
+
+tlabase="$(VCS_INFO_realpath ${vcs_comm[basedir]})"
+rrn=${tlabase:t}
+# tree-id gives us something like 'foo@example.com/demo--1.0--patch-4', so:
+tlabranch=${${"$( tla tree-id )"}/*\//}
+VCS_INFO_formats '' "${tlabranch}" "${tlabase}"
+return 0
diff --git a/Functions/VCS_Info/VCS_INFO_adjust b/Functions/VCS_Info/VCS_INFO_adjust
new file mode 100644
index 000000000..5ee2a4940
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_adjust
@@ -0,0 +1,8 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+[[ -n ${vcs_comm[overwrite_name]} ]] && vcs=${vcs_comm[overwrite_name]}
+return 0
diff --git a/Functions/VCS_Info/VCS_INFO_bydir_detect b/Functions/VCS_Info/VCS_INFO_bydir_detect
new file mode 100644
index 000000000..aff59f300
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_bydir_detect
@@ -0,0 +1,25 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+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
diff --git a/Functions/VCS_Info/VCS_INFO_check_com b/Functions/VCS_Info/VCS_INFO_check_com
new file mode 100644
index 000000000..6d65360d5
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_check_com
@@ -0,0 +1,8 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+(( ${+commands[$1]} )) && [[ -x ${commands[$1]} ]] && return 0
+return 1
diff --git a/Functions/VCS_Info/VCS_INFO_formats b/Functions/VCS_Info/VCS_INFO_formats
new file mode 100644
index 000000000..346833539
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_formats
@@ -0,0 +1,23 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions noksharrays NO_shwordsplit
+local action=$1 branch=$2 base=$3
+local msg
+local -i i j
+
+if [[ -n ${action} ]] ; then
+    zstyle -a ":vcs_info:${vcs}:${usercontext}:${rrn}" actionformats msgs
+    (( ${#msgs} < 1 )) && msgs[1]=' (%s)-[%b|%a]-'
+else
+    zstyle -a ":vcs_info:${vcs}:${usercontext}:${rrn}" formats msgs
+    (( ${#msgs} < 1 )) && msgs[1]=' (%s)-[%b]-'
+fi
+
+(( ${#msgs} > maxexports )) && msgs[$(( maxexports + 1 )),-1]=()
+for i in {1..${#msgs}} ; do
+    zformat -f msg ${msgs[$i]} a:${action} b:${branch} s:${vcs} r:${base:t} R:${base} S:"$(VCS_INFO_reposub ${base})"
+    msgs[$i]=${msg}
+done
+return 0
diff --git a/Functions/VCS_Info/VCS_INFO_maxexports b/Functions/VCS_Info/VCS_INFO_maxexports
new file mode 100644
index 000000000..ea952517f
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_maxexports
@@ -0,0 +1,13 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+
+zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" "max-exports" maxexports || maxexports=2
+if [[ ${maxexports} != <-> ]] || (( maxexports < 1 )); then
+    printf 'vcs_info(): expecting numeric arg >= 1 for max-exports (got %s).\n' ${maxexports}
+    printf 'Defaulting to 2.\n'
+    maxexports=2
+fi
+return 0
diff --git a/Functions/VCS_Info/VCS_INFO_nvcsformats b/Functions/VCS_Info/VCS_INFO_nvcsformats
new file mode 100644
index 000000000..581aa5a97
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_nvcsformats
@@ -0,0 +1,15 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions noksharrays NO_shwordsplit
+local c v rr
+
+if [[ $1 == '-preinit-' ]] ; then
+    c='default'
+    v='-preinit-'
+    rr='-all-'
+fi
+zstyle -a ":vcs_info:${v:-$vcs}:${c:-$usercontext}:${rrn:-$rr}" nvcsformats msgs
+(( ${#msgs} > maxexports )) && msgs[${maxexports},-1]=()
+return 0
diff --git a/Functions/VCS_Info/VCS_INFO_realpath b/Functions/VCS_Info/VCS_INFO_realpath
new file mode 100644
index 000000000..481d5e98f
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_realpath
@@ -0,0 +1,16 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+# a portable 'readlink -f'
+# forcing a subshell, to ensure chpwd() is not removed
+# from the calling shell (if VCS_INFO_realpath() is called
+# manually).
+
+setopt localoptions NO_shwordsplit
+
+(
+    (( ${+functions[chpwd]} )) && unfunction chpwd
+    setopt chaselinks
+    cd $1 2>/dev/null && pwd
+)
diff --git a/Functions/VCS_Info/VCS_INFO_reposub b/Functions/VCS_Info/VCS_INFO_reposub
new file mode 100644
index 000000000..0fab863f1
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_reposub
@@ -0,0 +1,13 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions extendedglob NO_shwordsplit
+local base=${1%%/##}
+
+[[ ${PWD} == ${base}/* ]] || {
+    printf '.'
+    return 1
+}
+printf '%s' ${PWD#$base/}
+return 0
diff --git a/Functions/VCS_Info/VCS_INFO_set b/Functions/VCS_Info/VCS_INFO_set
new file mode 100644
index 000000000..a2b838cdb
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_set
@@ -0,0 +1,32 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions noksharrays NO_shwordsplit
+local -i i j
+
+if [[ $1 == '--clear' ]] ; then
+    for i in {0..9} ; do
+        unset vcs_info_msg_${i}_
+    done
+fi
+if [[ $1 == '--nvcs' ]] ; then
+    [[ $2 == '-preinit-' ]] && (( maxexports == 0 )) && (( maxexports = 1 ))
+    for i in {0..$((maxexports - 1))} ; do
+        typeset -gx vcs_info_msg_${i}_=
+    done
+    VCS_INFO_nvcsformats $2
+fi
+
+(( ${#msgs} - 1 < 0 )) && return 0
+for i in {0..$(( ${#msgs} - 1 ))} ; do
+    (( j = i + 1 ))
+    typeset -gx vcs_info_msg_${i}_=${msgs[$j]}
+done
+
+if (( i < maxexports )) ; then
+    for j in {$(( i + 1 ))..${maxexports}} ; do
+        [[ -n ${(P)${:-vcs_info_msg_${j}_}} ]] && typeset -gx vcs_info_msg_${j}_=
+    done
+fi
+return 0
diff --git a/Functions/VCS_Info/vcs_info b/Functions/VCS_Info/vcs_info
new file mode 100644
index 000000000..9a4d2489e
--- /dev/null
+++ b/Functions/VCS_Info/vcs_info
@@ -0,0 +1,90 @@
+## vim:ft=zsh:foldmethod=marker
+##
+## vcs_info - provide version control information
+##
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+##
+## This file and all corresponding files in Functions/VCS_Info/ are
+## distributed under the same BSD-ish license as zsh itself.
+##
+
+setopt localoptions noksharrays extendedglob NO_shwordsplit
+local file func sys
+local -a static_functions
+
+static_functions=(
+    VCS_INFO_adjust
+    VCS_INFO_bydir_detect
+    VCS_INFO_check_com
+    VCS_INFO_formats
+    VCS_INFO_maxexports
+    VCS_INFO_nvcsformats
+    VCS_INFO_realpath
+    VCS_INFO_reposub
+    VCS_INFO_set
+
+    vcs_info_lastmsg
+    vcs_info_printsys
+    vcs_info_setsys
+)
+
+for func in ${static_functions} ; do
+    autoload -Uz ${func}
+done
+
+VCS_INFO_set --nvcs '-preinit-'
+vcs_info_setsys
+
+# and now, finally create the real vcs_info function
+vcs_info () {
+    setopt localoptions noksharrays extendedglob
+    local -i found
+    local -a enabled disabled
+    local -x usercontext vcs rrn
+    local -ix maxexports
+    local -ax msgs
+    local -Ax vcs_comm
+
+    vcs='-init-'; rrn='-all-'
+    usercontext=${1:-default}
+
+    zstyle -a ":vcs_info:${vcs}:${usercontext}:${rrn}" "enable" enabled
+    (( ${#enabled} == 0 )) && enabled=( all )
+
+    if [[ -n ${(M)enabled:#(#i)none} ]] ; then
+        [[ -n ${vcs_info_msg_0_} ]] && VCS_INFO_set --clear
+        return 0
+    fi
+
+    if [[ -n ${(M)enabled:#(#i)all} ]] ; then
+        enabled=( ${VCS_INFO_backends} )
+        zstyle -a ":vcs_info:${vcs}:${usercontext}:${rrn}" "disable" disabled
+    fi
+
+    VCS_INFO_maxexports
+
+    (( found = 0 ))
+    for vcs in ${enabled} ; do
+        [[ -n ${(M)disabled:#${vcs}} ]] && continue
+        if (( ${+functions[VCS_INFO_detect_${vcs}]} == 0 )) ; then
+            printf 'vcs_info: configured unknown backend: '\''%s'\''\n' ${vcs}
+            printf 'vcs_info: use '\''vcs_info_printsys'\'' to find supported systems.\n'
+            continue
+        fi
+        vcs_comm=()
+        VCS_INFO_detect_${vcs} && (( found = 1 )) && break
+    done
+
+    (( found == 0 )) && {
+        VCS_INFO_set --nvcs
+        return 0
+    }
+
+    VCS_INFO_get_data_${vcs} || {
+        VCS_INFO_set --nvcs
+        return 1
+    }
+
+    VCS_INFO_set
+    return 0
+}
diff --git a/Functions/VCS_Info/vcs_info_lastmsg b/Functions/VCS_Info/vcs_info_lastmsg
new file mode 100644
index 000000000..fe99d5999
--- /dev/null
+++ b/Functions/VCS_Info/vcs_info_lastmsg
@@ -0,0 +1,18 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions NO_shwordsplit
+local -i i
+local -ix maxexports
+
+VCS_INFO_maxexports
+for i in {0..$((maxexports - 1))} ; do
+    printf '$vcs_info_msg_%d_: "' $i
+    if zstyle -T ':vcs_info:formats:command:-all-' use-prompt-escapes ; then
+        print -nP ${(P)${:-vcs_info_msg_${i}_}}
+    else
+        print -n ${(P)${:-vcs_info_msg_${i}_}}
+    fi
+    printf '"\n'
+done
diff --git a/Functions/VCS_Info/vcs_info_printsys b/Functions/VCS_Info/vcs_info_printsys
new file mode 100644
index 000000000..d84682296
--- /dev/null
+++ b/Functions/VCS_Info/vcs_info_printsys
@@ -0,0 +1,37 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions noksharrays extendedglob NO_shwordsplit
+local sys
+local -a disabled enabled
+
+zstyle -a ":vcs_info:-init-:${1:-default}:-all-" "enable" enabled
+(( ${#enabled} == 0 )) && enabled=( all )
+
+if [[ -n ${(M)enabled:#(#i)all} ]] ; then
+    enabled=( ${VCS_INFO_backends} )
+    zstyle -a ":vcs_info:-init-:${1:-default}:-all-" "disable" disabled
+else
+    for sys in ${VCS_INFO_backends} ; do
+        [[ -z ${(M)enabled:#$sys} ]] && disabled+=( ${sys} )
+    done
+    enabled=( ${VCS_INFO_backends} )
+fi
+
+print -l '## list of supported version control backends:' \
+         '## disabled systems are prefixed by a hash sign (#)'
+
+for sys in ${VCS_INFO_backends} ; do
+    [[ -n ${(M)disabled:#${sys}} ]] && printf '#'
+    printf '%s\n' ${sys}
+done
+
+print -l '## flavours (cannot be used in the enable or disable styles; they' \
+         '## are enabled and disabled with their master [git-svn -> git])'   \
+         '## they *can* be used contexts: '\'':vcs_info:git-svn:*'\''.'
+
+for sys in ${VCS_INFO_backends} ; do
+    VCS_INFO_detect_${sys} --flavours
+done
+return 0
diff --git a/Functions/VCS_Info/vcs_info_setsys b/Functions/VCS_Info/vcs_info_setsys
new file mode 100644
index 000000000..b3b78348d
--- /dev/null
+++ b/Functions/VCS_Info/vcs_info_setsys
@@ -0,0 +1,22 @@
+## vim:ft=zsh
+## Written by Frank Terbeck <ft@bewatermyfriend.org>
+## Distributed under the same BSD-ish license as zsh itself.
+
+setopt localoptions noksharrays extendedglob typeset_silent NO_shwordsplit
+local sys
+typeset -g VCS_INFO_backends
+
+VCS_INFO_backends=()
+
+for file in ${^fpath}/VCS_INFO_get_data_*~*(\~|.zwc)(N) ; do
+    file=${file:t}
+    : ${file:#(#b)VCS_INFO_get_data_(*)}
+    sys=${match[1]}
+
+    [[ -n ${(M)VCS_INFO_backends:#${sys}} ]] && continue
+    VCS_INFO_backends+=(${sys})
+    autoload -Uz VCS_INFO_detect_${sys}
+    autoload -Uz VCS_INFO_get_data_${sys}
+done
+
+return 0
diff --git a/Src/zsh.mdd b/Src/zsh.mdd
index ab36ec8d7..1cba4b9dc 100644
--- a/Src/zsh.mdd
+++ b/Src/zsh.mdd
@@ -2,7 +2,7 @@ name=zsh/main
 link=static
 load=yes
 # load=static should replace use of alwayslink
-functions='Functions/Exceptions/* Functions/Misc/* Functions/MIME/* Functions/Prompts/*'
+functions='Functions/Exceptions/* Functions/Misc/* Functions/MIME/* Functions/Prompts/* Functions/VCS_Info/* Functions/VCS_Info/Backends/*'
 
 nozshdep=1
 alwayslink=1