2010-05-10 12:46:48 +02:00
|
|
|
# A collection of vcs_info usage examples
|
|
|
|
|
|
|
|
### Running vcs_info #########################################################
|
|
|
|
|
2010-05-14 09:55:38 +02:00
|
|
|
# As always, there's more than one way to skin a cat. Running vcs_info is no
|
2010-05-10 12:46:48 +02:00
|
|
|
# exception. Here is a rundown of three common ways to get it into action.
|
|
|
|
#
|
|
|
|
# All three ways need vcs_info to be marked for autoloading first, so you'd
|
|
|
|
# do this somewhere in your setup:
|
|
|
|
|
|
|
|
autoload -Uz vcs_info
|
|
|
|
|
|
|
|
# Episode I: "The prompt_subst way"
|
|
|
|
# Also known as the Quick-Start-Way. Probably the simplest way to add
|
|
|
|
# vcs_info functionality to existing setups. You just drop a vcs_info call
|
|
|
|
# to your `precmd' (or into a `precmd_functions[]' entry) and include a
|
|
|
|
# single-quoted ${vcs_info_msg_0_} in your PS1 definition:
|
|
|
|
|
|
|
|
precmd() { vcs_info }
|
|
|
|
# This needs prompt_subst set, hence the name. So:
|
|
|
|
setopt prompt_subst
|
|
|
|
PS1='%!-%3~ ${vcs_info_msg_0_}%# '
|
|
|
|
|
|
|
|
# Episode II: "The way of the psvar"
|
|
|
|
# With $psvar you got a simple way to get user defined things into your
|
|
|
|
# prompt without having to set `prompt_subst', which requires extra
|
|
|
|
# attention to quoting if you like characters like ` in your prompt...
|
|
|
|
# As described in <http://xana.scru.org/xana2/quanks/vcsinfoprompt/>:
|
|
|
|
|
|
|
|
precmd() {
|
|
|
|
psvar=()
|
|
|
|
|
|
|
|
vcs_info
|
2017-02-07 09:57:33 +01:00
|
|
|
[[ -n $vcs_info_msg_0_ ]] && print -v 'psvar[1]' -Pr -- "$vcs_info_msg_0_"
|
2010-05-10 12:46:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# You can now use `%1v' to drop the $vcs_info_msg_0_ contents in your prompt;
|
|
|
|
# like this:
|
|
|
|
|
|
|
|
PS1="%m%(1v.%F{red}%1v%f.)%# "
|
|
|
|
|
|
|
|
# Episode III: "The justsetitinprecmd way"
|
|
|
|
# This is the way I prefer. When you see it, you may think "Setting that
|
|
|
|
# variable in precmd() each time? What a waste..."; but let me assure you,
|
|
|
|
# you're running vcs_info already, setting one variable is not an issue.
|
|
|
|
#
|
|
|
|
# You're getting the benefit of being able to programmatically setting your
|
|
|
|
# prompt, which is nice especially when you're going to do weird things in
|
|
|
|
# there anyway. Here goes:
|
|
|
|
|
|
|
|
precmd() {
|
|
|
|
# As always first run the system so everything is setup correctly.
|
|
|
|
vcs_info
|
|
|
|
# And then just set PS1, RPS1 and whatever you want to. This $PS1
|
|
|
|
# is (as with the other examples above too) just an example of a very
|
|
|
|
# basic single-line prompt. See "man zshmisc" for details on how to
|
|
|
|
# make this less readable. :-)
|
2020-12-05 19:23:17 +01:00
|
|
|
if [[ -z ${vcs_info_msg_0_} ]]; then
|
2010-05-10 12:46:48 +02:00
|
|
|
# Oh hey, nothing from vcs_info, so we got more space.
|
|
|
|
# Let's print a longer part of $PWD...
|
|
|
|
PS1="%5~%# "
|
|
|
|
else
|
|
|
|
# vcs_info found something, that needs space. So a shorter $PWD
|
|
|
|
# makes sense.
|
|
|
|
PS1="%3~${vcs_info_msg_0_}%# "
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
### check-for-changes just in some places ####################################
|
|
|
|
|
|
|
|
# Some backends (git and mercurial at the time of writing) can tell you
|
|
|
|
# whether there are local changes in the current repository. While that's
|
|
|
|
# nice, the actions needed to obtain the information can be potentially
|
|
|
|
# expensive. So if you're working on something the size of the linux kernel
|
|
|
|
# or some corporate code monstrosity you may want to think twice about
|
|
|
|
# enabling the `check-for-changes' style unconditionally.
|
|
|
|
#
|
|
|
|
# Zsh's zstyle configuration system let's you do some magic to enable styles
|
|
|
|
# only depending on some code you're running.
|
|
|
|
#
|
|
|
|
# So, what I'm doing is this: I'm keeping my own projects in `~/src/code'.
|
|
|
|
# There are the projects I want the information for most. They are also
|
|
|
|
# a lot smaller than the linux kernel so the information can be retrieved
|
|
|
|
# instantaneously - even on my old laptop at 600MHz. And the following code
|
|
|
|
# enables `check-for-changes' only in that subtree:
|
|
|
|
|
|
|
|
zstyle -e ':vcs_info:git:*' \
|
|
|
|
check-for-changes 'estyle-cfc && reply=( true ) || reply=( false )'
|
|
|
|
|
|
|
|
function estyle-cfc() {
|
|
|
|
local d
|
|
|
|
local -a cfc_dirs
|
|
|
|
cfc_dirs=(
|
|
|
|
${HOME}/src/code/*(/)
|
|
|
|
)
|
|
|
|
|
|
|
|
for d in ${cfc_dirs}; do
|
|
|
|
d=${d%/##}
|
|
|
|
[[ $PWD == $d(|/*) ]] && return 0
|
|
|
|
done
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-19 21:21:35 +02:00
|
|
|
### Hook Examples ############################################################
|
2010-05-10 12:46:48 +02:00
|
|
|
|
2010-07-19 21:21:35 +02:00
|
|
|
# A number of examples in this file revolve around the concept of `hooks'
|
|
|
|
# in vcs_info. Hooks are places in vcs_info where you may put in your
|
|
|
|
# own code to achieve something "totally awesome"[tm].
|
|
|
|
#
|
|
|
|
# Hooks can be confusing. It's hard to keep track of what's going on.
|
|
|
|
# In order to help you with that vcs_info can output some debugging
|
|
|
|
# information when it processes hooks. This will tell you which hooks
|
|
|
|
# are being run and which functions are attempted to run (and if the
|
|
|
|
# functions in question were found or not).
|
|
|
|
#
|
|
|
|
# If you feel like you need to see what's attempted and where, I suggest
|
|
|
|
# you use the following line and see for yourself.
|
|
|
|
zstyle ':vcs_info:*+*:*' debug true
|
|
|
|
|
|
|
|
# You can just comment it out (or disable it) again when you've seen enough.
|
|
|
|
# Debugging is off by default - of course.
|
|
|
|
zstyle ':vcs_info:*+*:*' debug false
|
|
|
|
|
|
|
|
# Further down, every example that uses a function named `+vi-*' uses a hook.
|
|
|
|
|
|
|
|
|
|
|
|
### Truncate Long Hashes
|
2010-05-10 12:46:48 +02:00
|
|
|
|
|
|
|
### Truncate a long hash to 12 characters (which is usually unique enough)
|
|
|
|
# Use zformat syntax (remember %i is the hash): %12.12i
|
|
|
|
|
2010-07-19 21:21:35 +02:00
|
|
|
# git:
|
|
|
|
zstyle ':vcs_info:git*' formats "(%s)-[%12.12i %b]-" # hash & branch
|
|
|
|
|
2010-05-10 12:46:48 +02:00
|
|
|
|
2012-09-29 00:09:37 +02:00
|
|
|
### Fetch the full 40-character Mercurial revision id
|
|
|
|
# There is no great way to obtain branch, local rev, and untracked changes in
|
|
|
|
# addition to the full 40-character global rev id with a single invocation of
|
2020-07-12 15:04:50 +02:00
|
|
|
# Mercurial. This hook obtains the full global rev id using xxd(1) (in the
|
2012-09-29 00:09:37 +02:00
|
|
|
# same way the use-simple flag does) while retaining all the other vcs_info
|
|
|
|
# default functionality and information.
|
|
|
|
zstyle ':vcs_info:hg*+set-message:*' hooks hg-fullglobalrev
|
|
|
|
|
|
|
|
# Output the full 40-char global rev id
|
|
|
|
function +vi-hg-fullglobalrev() {
|
|
|
|
local dirstatefile="${hook_com[base]}/.hg/dirstate"
|
2020-07-12 15:04:50 +02:00
|
|
|
local grevid="$(xxd -p -l 20 < ${dirstatefile})"
|
2012-09-29 00:09:37 +02:00
|
|
|
# Omit %h from your hgrevformat since it will be included below
|
|
|
|
hook_com[revision]="${hook_com[revision]} ${grevid}"
|
2010-05-10 12:46:48 +02:00
|
|
|
}
|
|
|
|
|
2012-09-29 00:09:37 +02:00
|
|
|
|
2011-06-01 23:21:04 +02:00
|
|
|
### Display the existence of files not yet known to VCS
|
|
|
|
|
|
|
|
### git: Show marker (T) if there are untracked files in repository
|
|
|
|
# Make sure you have added staged to your 'formats': %c
|
|
|
|
zstyle ':vcs_info:git*+set-message:*' hooks git-untracked
|
|
|
|
|
|
|
|
+vi-git-untracked(){
|
|
|
|
if [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == 'true' ]] && \
|
2021-06-26 08:04:05 +02:00
|
|
|
git status --porcelain | grep -q '^?? ' 2> /dev/null ; then
|
2011-06-01 23:21:04 +02:00
|
|
|
# This will show the marker if there are any untracked files in repo.
|
|
|
|
# If instead you want to show the marker only if there are untracked
|
|
|
|
# files in $PWD, use:
|
|
|
|
#[[ -n $(git ls-files --others --exclude-standard) ]] ; then
|
|
|
|
hook_com[staged]+='T'
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2010-07-19 21:21:35 +02:00
|
|
|
|
|
|
|
### Compare local changes to remote changes
|
|
|
|
|
|
|
|
### git: Show +N/-N when your local branch is ahead-of or behind remote HEAD.
|
|
|
|
# Make sure you have added misc to your 'formats': %m
|
|
|
|
zstyle ':vcs_info:git*+set-message:*' hooks git-st
|
|
|
|
function +vi-git-st() {
|
|
|
|
local ahead behind
|
|
|
|
local -a gitstatus
|
|
|
|
|
2021-04-13 15:56:36 +02:00
|
|
|
# Exit early in case the worktree is on a detached HEAD
|
|
|
|
git rev-parse ${hook_com[branch]}@{upstream} >/dev/null 2>&1 || return 0
|
|
|
|
|
2021-04-13 15:56:31 +02:00
|
|
|
local -a ahead_and_behind=(
|
|
|
|
$(git rev-list --left-right --count HEAD...${hook_com[branch]}@{upstream} 2>/dev/null)
|
|
|
|
)
|
2010-07-19 21:21:35 +02:00
|
|
|
|
2021-04-13 15:56:31 +02:00
|
|
|
ahead=${ahead_and_behind[1]}
|
|
|
|
behind=${ahead_and_behind[2]}
|
|
|
|
|
|
|
|
(( $ahead )) && gitstatus+=( "+${ahead}" )
|
2010-07-19 21:21:35 +02:00
|
|
|
(( $behind )) && gitstatus+=( "-${behind}" )
|
|
|
|
|
|
|
|
hook_com[misc]+=${(j:/:)gitstatus}
|
|
|
|
}
|
|
|
|
|
2010-08-02 23:05:54 +02:00
|
|
|
### git: Show remote branch name for remote-tracking branches
|
|
|
|
zstyle ':vcs_info:git*+set-message:*' hooks git-remotebranch
|
|
|
|
|
|
|
|
function +vi-git-remotebranch() {
|
|
|
|
local remote
|
|
|
|
|
|
|
|
# Are we on a remote-tracking branch?
|
|
|
|
remote=${$(git rev-parse --verify ${hook_com[branch]}@{upstream} \
|
|
|
|
--symbolic-full-name 2>/dev/null)/refs\/remotes\/}
|
|
|
|
|
2011-10-19 20:14:08 +02:00
|
|
|
# The first test will show a tracking branch whenever there is one. The
|
|
|
|
# second test, however, will only show the remote branch's name if it
|
|
|
|
# differs from the local one.
|
2010-08-02 23:05:54 +02:00
|
|
|
if [[ -n ${remote} ]] ; then
|
2011-10-19 20:14:08 +02:00
|
|
|
#if [[ -n ${remote} && ${remote#*/} != ${hook_com[branch]} ]] ; then
|
2010-08-02 23:05:54 +02:00
|
|
|
hook_com[branch]="${hook_com[branch]} [${remote}]"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-12-02 02:54:17 +01:00
|
|
|
### Derive hook names dynamically
|
|
|
|
# With the following line:
|
|
|
|
zstyle -e ':vcs_info:git+set-message:*' hooks 'reply=( ${${(k)functions[(I)[+]vi-git-set-message*]}#+vi-} )'
|
|
|
|
# Any function named `+vi-git-set-message-<anything>' would be automatically
|
|
|
|
# registered as a hook. For example:
|
|
|
|
+vi-git-set-message-foo() {}
|
|
|
|
+vi-git-set-message-bar() {}
|
|
|
|
# Both of these functions would be called, even if they are defined after the zstyle is set.
|
|
|
|
|
|
|
|
|
2019-12-21 16:58:24 +01:00
|
|
|
## git: Display pertinent environment variables
|
|
|
|
# If environment variables such as $GIT_DIR, $GIT_WORK_TREE, etc are set in the
|
|
|
|
# environment, they'll be shown in the value of the %m expando.
|
|
|
|
#
|
|
|
|
# Note that the %m expando is not used by default. To see a change, either change
|
|
|
|
# `[misc]' to `[branch]', or set the `formats` style to a value that includes `%m'.
|
|
|
|
zstyle ':vcs_info:git+post-backend:*' hooks git-post-backend-envvars
|
|
|
|
+vi-git-post-backend-envvars() {
|
|
|
|
local param
|
|
|
|
# This uses the ${parameters} special variable (provided by the zsh/parameter
|
|
|
|
# module), in conjunction with the parameter expansion flags ${(k)foo} and
|
|
|
|
# ${(M)foo:#pattern} (documented in "Parameter Expansion" in zshexpn(1))
|
|
|
|
# and the (R) subscript flag (documented in "Subscript Flags" in zshparam(1)),
|
|
|
|
# to iterate over the names of all environment variables named "GIT_*". Then
|
|
|
|
# it uses the ${(P)foo} parameter expansion flag to show the values of those
|
|
|
|
# parameters.
|
|
|
|
#
|
|
|
|
# The value of ${hook_com[misc]} is substituted for %m in the values of the
|
|
|
|
# 'formats' and 'actionformats' styles.
|
|
|
|
for param in ${(Mk)parameters[(R)*export*]:#GIT_*}; do
|
|
|
|
hook_com[misc]+=";%U${param//'%'/%%}%u=%F{white}${${(P)param}//'%'/%%}%f"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-19 21:21:35 +02:00
|
|
|
### hg: Show marker when the working directory is not on a branch head
|
2010-05-10 12:46:48 +02:00
|
|
|
# This may indicate that running `hg up` will do something
|
|
|
|
# NOTE: the branchheads.cache file is not updated with every Mercurial
|
|
|
|
# operation, so it will sometimes give false positives. Think of this more as a
|
|
|
|
# hint that you might not be on a branch head instead of the final word.
|
|
|
|
zstyle ':vcs_info:hg+set-hgrev-format:*' hooks hg-storerev
|
|
|
|
zstyle ':vcs_info:hg+set-message:*' hooks hg-branchhead
|
|
|
|
|
2010-05-14 09:55:38 +02:00
|
|
|
# The hash is available in the hgrev-format hook, store a copy of it in the
|
2010-05-10 12:46:48 +02:00
|
|
|
# user_data array so we can access it in the second function
|
|
|
|
function +vi-hg-storerev() {
|
|
|
|
user_data[hash]=${hook_com[hash]}
|
|
|
|
}
|
|
|
|
|
|
|
|
function +vi-hg-branchhead() {
|
|
|
|
local branchheadsfile i_tiphash i_branchname
|
|
|
|
local -a branchheads
|
|
|
|
|
|
|
|
local branchheadsfile=${hook_com[base]}/.hg/branchheads.cache
|
|
|
|
|
|
|
|
# Bail out if any mq patches are applied
|
|
|
|
[[ -s ${hook_com[base]}/.hg/patches/status ]] && return 0
|
|
|
|
|
|
|
|
if [[ -r ${branchheadsfile} ]] ; then
|
|
|
|
while read -r i_tiphash i_branchname ; do
|
|
|
|
branchheads+=( $i_tiphash )
|
|
|
|
done < ${branchheadsfile}
|
|
|
|
|
|
|
|
if [[ ! ${branchheads[(i)${user_data[hash]}]} -le ${#branchheads} ]] ; then
|
|
|
|
hook_com[revision]="^ ${hook_com[revision]}"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-04-07 22:22:58 +02:00
|
|
|
### Show information about patch series
|
|
|
|
# This is used with with hg mq, quilt, and git rebases and conflicts.
|
|
|
|
#
|
|
|
|
# All these cases have a notion of a "series of patches/commits" that is being
|
|
|
|
# applied. The following shows the information about the most recent patch to
|
|
|
|
# have been applied:
|
|
|
|
zstyle ':vcs_info:*+gen-applied-string:*' hooks gen-applied-string
|
|
|
|
function +vi-gen-applied-string() {
|
|
|
|
# Separate the patch id from the patch log message.
|
|
|
|
if [[ $1 == *\ * ]]; then
|
|
|
|
local patch_name_or_filename="${1%% *}"
|
|
|
|
local patch_description="${1#* }"
|
|
|
|
else
|
|
|
|
local patch_name_or_filename="$1"
|
|
|
|
local patch_description=""
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Apply escaping; see `Oddities' in the manual.
|
|
|
|
patch_name_or_filename=${patch_name_or_filename//'%'/%%}
|
|
|
|
patch_description=${patch_description//'%'/%%}
|
|
|
|
|
|
|
|
# Apply different colouring to the patch description.
|
|
|
|
if [[ -n ${patch_description} ]]; then
|
|
|
|
patch_description="%F{yellow}${patch_description}%f"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Re-assemble $1, escaped and coloured.
|
|
|
|
hook_com[applied-string]="${patch_name_or_filename} ${patch_description}"
|
|
|
|
ret=1
|
|
|
|
}
|
|
|
|
# The value of hook_com[applied-string] is incorporated into the %m expando
|
|
|
|
# (see the 'patch-format' style for details), which is not included in the
|
|
|
|
# 'formats' and 'actionformats' style by default, so to actually use this,
|
|
|
|
# you'll need to add %m (or %Q under quilt in add-on mode) to your 'formats'
|
|
|
|
# and 'actionformats' styles, as in:
|
|
|
|
#
|
|
|
|
# zstyle ':vcs_info:*' actionformats ' (%s)-[%b|%a]%u%c- %m'
|
|
|
|
# zstyle ':vcs_info:*' formats ' (%s)-[%b]%u%c- %m'
|
|
|
|
#
|
|
|
|
# Or you could add it as a new word, as in:
|
|
|
|
#
|
|
|
|
# zstyle ':vcs_info:*' actionformats ' (%s)-[%b|%a]%u%c-' '%m'
|
|
|
|
# zstyle ':vcs_info:*' formats ' (%s)-[%b]%u%c-' '%m'
|
|
|
|
#
|
|
|
|
# In the latter case, you will need to arrange to print ${vcs_info_msg_1_} in
|
|
|
|
# addition to ${vcs_info_msg_0_}; see the top of this file for details.
|
|
|
|
|
|
|
|
|
2010-05-14 09:55:38 +02:00
|
|
|
### Run vcs_info selectively to increase speed in large repos ################
|
2010-05-10 12:46:48 +02:00
|
|
|
|
|
|
|
# The following example shows a possible setup for vcs_info which displays
|
|
|
|
# staged and unstaged changes in the vcs_info prompt and prevents running
|
|
|
|
# it too often for speed reasons.
|
|
|
|
|
|
|
|
|
|
|
|
# Allow substitutions and expansions in the prompt, necessary for
|
|
|
|
# using a single-quoted $vcs_info_msg_0_ in PS1, RPOMPT (as used here) and
|
|
|
|
# similar. Other ways of using the information are described above.
|
|
|
|
setopt promptsubst
|
|
|
|
# Load vcs_info to display information about version control repositories.
|
|
|
|
autoload -Uz vcs_info
|
|
|
|
|
|
|
|
# Check the repository for changes so they can be used in %u/%c (see
|
|
|
|
# below). This comes with a speed penalty for bigger repositories.
|
|
|
|
zstyle ':vcs_info:*' check-for-changes true
|
|
|
|
zstyle ':vcs_info:*' get-revision true
|
|
|
|
|
2014-03-28 12:00:35 +01:00
|
|
|
# Alternatively, the following would set only %c, but is faster:
|
|
|
|
#zstyle ':vcs_info:*' check-for-changes false
|
|
|
|
#zstyle ':vcs_info:*' check-for-staged-changes true
|
|
|
|
|
2010-05-10 12:46:48 +02:00
|
|
|
|
|
|
|
# Default to running vcs_info. If possible we prevent running it later for
|
|
|
|
# speed reasons. If set to a non empty value vcs_info is run.
|
|
|
|
FORCE_RUN_VCS_INFO=1
|
|
|
|
|
|
|
|
# Only run vcs_info when necessary to speed up the prompt and make using
|
|
|
|
# check-for-changes bearable in bigger repositories. This setup was
|
|
|
|
# inspired by Bart Trojanowski
|
|
|
|
# (http://jukie.net/~bart/blog/pimping-out-zsh-prompt).
|
|
|
|
#
|
|
|
|
# This setup is by no means perfect. It can only detect changes done
|
|
|
|
# through the VCS's commands run by the current shell. If you use your
|
|
|
|
# editor to commit changes to the VCS or if you run them in another shell
|
|
|
|
# this setup won't detect them. To fix this just run "cd ." which causes
|
|
|
|
# vcs_info to run and update the information. If you use aliases to run
|
|
|
|
# the VCS commands update the case check below.
|
|
|
|
zstyle ':vcs_info:*+pre-get-data:*' hooks pre-get-data
|
|
|
|
+vi-pre-get-data() {
|
|
|
|
# Only Git and Mercurial support and need caching. Abort if any other
|
|
|
|
# VCS is used.
|
|
|
|
[[ "$vcs" != git && "$vcs" != hg ]] && return
|
|
|
|
|
|
|
|
# If the shell just started up or we changed directories (or for other
|
|
|
|
# custom reasons) we must run vcs_info.
|
|
|
|
if [[ -n $FORCE_RUN_VCS_INFO ]]; then
|
|
|
|
FORCE_RUN_VCS_INFO=
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
# If we got to this point, running vcs_info was not forced, so now we
|
|
|
|
# default to not running it and selectively choose when we want to run
|
2014-09-12 23:30:35 +02:00
|
|
|
# it (ret=0 means run it, ret=1 means don't).
|
2010-05-10 12:46:48 +02:00
|
|
|
ret=1
|
|
|
|
# If a git/hg command was run then run vcs_info as the status might
|
|
|
|
# need to be updated.
|
|
|
|
case "$(fc -ln $(($HISTCMD-1)))" in
|
|
|
|
git*)
|
|
|
|
ret=0
|
|
|
|
;;
|
|
|
|
hg*)
|
|
|
|
ret=0
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
# Call vcs_info as precmd before every prompt.
|
|
|
|
prompt_precmd() {
|
|
|
|
vcs_info
|
|
|
|
}
|
|
|
|
add-zsh-hook precmd prompt_precmd
|
|
|
|
|
|
|
|
# Must run vcs_info when changing directories.
|
|
|
|
prompt_chpwd() {
|
|
|
|
FORCE_RUN_VCS_INFO=1
|
|
|
|
}
|
|
|
|
add-zsh-hook chpwd prompt_chpwd
|
|
|
|
|
|
|
|
# Display the VCS information in the right prompt. The {..:- } is a
|
|
|
|
# workaround for Zsh below 4.3.9.
|
|
|
|
RPROMPT='${vcs_info_msg_0_:- }'
|
|
|
|
|
|
|
|
|
|
|
|
### Quilt support ############################################################
|
|
|
|
|
|
|
|
# Vcs_info does its best to support the patch management system quilt
|
|
|
|
# <http://savannah.nongnu.org/projects/quilt>. The information gathered by
|
|
|
|
# the quilt support always (and I'm saying always, because there are two
|
|
|
|
# ways quilt support can be active - see "man zshcontrib" for details)
|
|
|
|
# ends up in the `%Q' replacement in formats.
|
|
|
|
#
|
|
|
|
# Quilt support is also disabled by default. To turn its `addon' mode
|
|
|
|
# on for all backends, do:
|
|
|
|
zstyle ':vcs_info:*' use-quilt true
|
|
|
|
|
|
|
|
# Then use `%Q' somewhere in the `formats' and `actionformats' styles:
|
|
|
|
zstyle ':vcs_info:*' formats " (%s)-[%b%Q]-"
|
|
|
|
zstyle ':vcs_info:*' actionformats " (%s)-[%b%Q|%a]-"
|
|
|
|
|
|
|
|
# In the quilt support code, the zstyle context changes a little, it's now:
|
|
|
|
# :vcs_info:<vcs>.quilt-<quiltmode>:*:*
|
|
|
|
# "<vcs>" is the version-control-system string and "<quiltmode>" is either
|
|
|
|
# `addon' or `standalone'. So, if you'd use quilt on top of CVS, the
|
|
|
|
# context becomes ":vcs_info:cvs.quilt-addon:*:*".
|
|
|
|
|
|
|
|
# That's almost all you need to know. Almost.
|
|
|
|
#
|
|
|
|
# Quilt support has a standalone mode. Even though quilt is not really
|
|
|
|
# a version control system, it keeps track of patches. It can work on top
|
|
|
|
# of a real VCS (like subversion or CVS - which is covered by addon mode)
|
|
|
|
# or apply patches to a normal directory tree that's not under version
|
|
|
|
# control. The debian project does this for a large number of packages,
|
|
|
|
# during their automatic build process.
|
2010-05-14 09:55:38 +02:00
|
|
|
# The `use-quilt' style only enables addon-mode, because for standalone
|
2010-05-10 12:46:48 +02:00
|
|
|
# mode we'd have to try to detect whether quilt is "active" in a directory.
|
|
|
|
# You can fine-tune that "detection" using the `quilt-standalone' style.
|
|
|
|
# If the value of that style is a function name, that function is executed
|
|
|
|
# without arguments to determine whether quilt-detection should be attempted.
|
|
|
|
# It's the most powerful way of doing this and we'll give a simple
|
|
|
|
# example later.
|
|
|
|
|
|
|
|
# First let's assume you want standalone mode to be active only in
|
|
|
|
# /usr/src/debian, ~/src/debian and their subdirectories. That's simple:
|
|
|
|
|
|
|
|
typeset -a foobar
|
|
|
|
foobar=(
|
|
|
|
/usr/src/debian
|
|
|
|
~/src/debian
|
|
|
|
)
|
|
|
|
zstyle ':vcs_info:*' quilt-standalone foobar
|
|
|
|
|
|
|
|
# As mentioned earlier, using a function in this style is more powerful:
|
|
|
|
function foobar() {
|
|
|
|
# You can do any sort of wicked wizardry here. This example just
|
|
|
|
# checks if we're in "/usr/src/debian" or a subdirectory and if so
|
|
|
|
# enables standalone detection.
|
|
|
|
[[ $PWD == /usr/src/debian(|/*) ]] && return 0
|
|
|
|
|
|
|
|
# Returning non-zero means false, which means don't enable the
|
|
|
|
# "detection".
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# In standalone-mode, vcs_info pretends as if quilt actually was a VCS.
|
2012-03-23 17:34:38 +01:00
|
|
|
# Well, kind of. The vcs string is set to '-quilt-.quilt-standalone'. So let's
|
|
|
|
# define a format just for that mode:
|
|
|
|
zstyle ':vcs_info:-quilt-.quilt-standalone:*' formats " [%s%Q]-"
|
2010-05-10 12:46:48 +02:00
|
|
|
|
|
|
|
# As with other format insertions, you got total control over what is being
|
|
|
|
# inserted. The `%Q' insertion is controlled by the `quiltformat' and
|
|
|
|
# `quilt-nopatch-format' styles.
|
|
|
|
|
|
|
|
# quiltformat (default: "%p (%n applied)")
|
|
|
|
# The `%p' replacement tells you which patches are applied. `%n' tells you
|
|
|
|
# How many patches are applied. `%u' and `%N' do the same for unapplied patches.
|
|
|
|
#
|
|
|
|
# Now you might say, that's way too much. That'll eat up my entire screen if I
|
|
|
|
# all my 1002 patches applied. Well, true.
|
|
|
|
# By default, `%p' contains the top-most applied patch. `%u' says contains the
|
|
|
|
# number of unapplied patches and is therefore the same as `%c'.
|
|
|
|
# There are two hooks you can use to setup what these contain. Those would be
|
|
|
|
# `gen-applied-string' and `gen-unapplied-string'. We'll go with the default
|
|
|
|
# here... ...no need to go into every insane detail.
|
2012-03-23 17:34:38 +01:00
|
|
|
zstyle ':vcs_info:*' patch-format '#%p [%n|%c]'
|
2010-05-10 12:46:48 +02:00
|
|
|
|
|
|
|
# quilt-nopatch-format (default: "no patch applied")
|
2012-03-23 17:34:38 +01:00
|
|
|
zstyle ':vcs_info:*' nopatch-format '#cleeaaaaan!1!!'
|
2010-05-10 12:46:48 +02:00
|
|
|
|
2010-05-14 09:55:38 +02:00
|
|
|
# To retrieve information about unapplied patches, vcs_info invokes `quilt'
|
2010-05-10 12:46:48 +02:00
|
|
|
# itself. Even though that's pretty quick, it's not needed for the default
|
|
|
|
# behaviour. If we want to have `%c' and `%u' to contain meaningful data,
|
|
|
|
# we have to enable retrieval of unapplied data:
|
2012-03-23 17:34:38 +01:00
|
|
|
zstyle ':vcs_info:*' get-unapplied true
|
2010-05-10 12:46:48 +02:00
|
|
|
|
|
|
|
# With quilt, the location of its patches are configurable. It's either
|
|
|
|
# $QUILT_PATCHES or `patches' if that's unset. Let's assume we're a debian
|
|
|
|
# developer and want $QUILT_PATCHES to always be `debian/patches' in stand-
|
|
|
|
# alone mode:
|
|
|
|
zstyle ':vcs_info:-quilt-.quilt-standalone:*:*' quilt-patch-dir debian/patches
|
|
|
|
|
|
|
|
# Since we're a debian developer, we also have some packages of our own,
|
|
|
|
# and so we want addon mode to also use a $QUILT_PATCHES value of
|
|
|
|
# `debian/patches' in some directories. In the other directories we never
|
|
|
|
# want the default `patches' though but a dedicated place for them.
|
2019-12-21 16:58:25 +01:00
|
|
|
# Say `~/patches/<repository-name>'.
|
|
|
|
#
|
|
|
|
# First of all, even without any configuration, vcs_info will do the right
|
|
|
|
# thing most of the time. Whenever quilt has already run in a directory,
|
|
|
|
# vcs_info will figure out whether that directory uses `patches' or
|
|
|
|
# `debian/patches' by interrogating metadata in the `.pc/' subdirectory,
|
|
|
|
# which quilt creates. To make vcs_info find the patches dir correctly even
|
|
|
|
# when the `.pc/' directory doesn't exist, read on.
|
|
|
|
#
|
|
|
|
# We'll use some evaluated-style magic to achieve that:
|
2010-05-10 12:46:48 +02:00
|
|
|
zstyle -e ':vcs_info:*.quilt-addon:*:*' quilt-patch-dir 'my-patches-func'
|
|
|
|
|
|
|
|
# That runs something called `my-patches-func', and the value of $reply is
|
|
|
|
# used as the value for the `quilt-patch-dir' style. We'll define the thing
|
|
|
|
# as a function - as the name suggests:
|
|
|
|
|
|
|
|
function my-patches-func() {
|
|
|
|
local p
|
|
|
|
# As the tidy debian developer we are, we're keeping our packages
|
|
|
|
# in VCSs and they are located in one place `~/src/mypkgs/'
|
|
|
|
if [[ $PWD == ${HOME}/src/mypkgs(|/*) ]]; then
|
|
|
|
reply=( debian/patches )
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Now the part about the dedicated directory is a little trickier.
|
2019-12-21 16:58:25 +01:00
|
|
|
# The variable in question here is `$context', which is the zstyle
|
|
|
|
# context used for lookups. Its last component is the repository-root-name,
|
|
|
|
# or ${rrn} for short. If you're in
|
2010-05-10 12:46:48 +02:00
|
|
|
# /usr/src/zsh/Functions
|
|
|
|
# and the repository being
|
|
|
|
# /usr/src/zsh
|
2019-12-21 16:58:25 +01:00
|
|
|
# then the value of `$rrn' would be `zsh'.
|
|
|
|
local rrn=${context##*:}
|
|
|
|
|
|
|
|
# Now, in case the variable is empty (it shouldn't at this point, but you
|
|
|
|
# never know), let's drop back to quilt's default value, "patches".
|
2010-05-10 12:46:48 +02:00
|
|
|
if [[ -z ${rrn} ]]; then
|
|
|
|
reply=( patches )
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
# If we're here, there's something in $rrn, so:
|
|
|
|
p="${HOME}/patches/${rrn}"
|
|
|
|
if [[ ! -d $p ]]; then
|
|
|
|
# ...and while we're at it, make sure it exists...
|
|
|
|
mkdir -p "$p"
|
|
|
|
fi
|
|
|
|
reply=( $p )
|
|
|
|
}
|
|
|
|
|
|
|
|
# And finally, let's use the `post-quilt' hook to let vcs_info help us
|
|
|
|
# with setting the $QUILT_PATCHES variable. Since vcs_info already knows
|
|
|
|
# which $QUILT_PATCHES value is correct, it should just export that variable
|
|
|
|
# for us. No need to configure something twice when it can work
|
|
|
|
# automatically. :-)
|
|
|
|
|
|
|
|
# Register the hook:
|
|
|
|
zstyle ':vcs_info:*+post-quilt:*:*' hooks set-quilt-patches
|
|
|
|
|
|
|
|
# Define the corresponding function:
|
|
|
|
function +vi-set-quilt-patches() {
|
|
|
|
# The `post-quilt' hook functions are called with three arguments:
|
|
|
|
# $1 the mode (`addon' vs. `standalone').
|
|
|
|
# $2 the path-name of the detected patches directory.
|
|
|
|
# $3 the path-name of the `.pc' directory (or "-nopc-" if it
|
|
|
|
# could not be found).
|
|
|
|
# So, what we're after is in $2 already, which makes this function
|
|
|
|
# rather trivial:
|
|
|
|
export QUILT_PATCHES="$2"
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
# This would take care of all the dedicated-patches-directory-in-${HOME}
|
|
|
|
# from earlier examples, too.
|
|
|
|
|
2021-04-07 22:22:58 +02:00
|
|
|
# Finally, the "Show information about patch series" example above this section
|
|
|
|
# may also be useful.
|
|
|
|
|
2010-05-10 12:46:48 +02:00
|
|
|
|
|
|
|
### Using vcs_info from CVS ##################################################
|
|
|
|
|
|
|
|
# You've decided you desperately need a newer feature of vcs_info than
|
|
|
|
# there is in your installed version of zsh. That's possible, but be aware
|
|
|
|
# that you are choosing not only the newest features but potentially also
|
|
|
|
# the newest bugs of vcs_info. Also note, that vcs_info from CVS *may* rely
|
|
|
|
# on features of zsh that are only available in a newer version than you
|
|
|
|
# got installed on your system.
|
|
|
|
#
|
|
|
|
# So, now that the warnings are out of the way - let's cut to the chase:
|
|
|
|
# First you'll need to decide where to put the files from CVS. Many people
|
|
|
|
# keep a directory for personal function files such as `~/.zfuncs' or
|
|
|
|
# similar. That's what we'll use here.
|
|
|
|
#
|
|
|
|
# Step one: "get the thing from CVS"
|
|
|
|
# % mkdir -p ~/.zfuncs
|
|
|
|
# % cd ~/.zfuncs
|
|
|
|
# % cvs -z3 -d:pserver:anonymous@zsh.cvs.sourceforge.net:/cvsroot/zsh \
|
|
|
|
# co -d VCS_Info -PA zsh/Functions/VCS_Info
|
|
|
|
#
|
|
|
|
# There, now you got a `~/.zfuncs/VCS_Info' directory that has all the files
|
|
|
|
# you need. Whenever you feel like updating the checkout, you can do:
|
|
|
|
# % cd ~/.zfuncs/VCS_Info; cvs up; cd -
|
|
|
|
#
|
|
|
|
# Step two: "Tell zsh to use the checkout"
|
|
|
|
# Zsh looks for function files in the directories listed in $fpath. If
|
|
|
|
# you're already using `~/.zfuncs' you probably have something like this
|
|
|
|
# in your setup:
|
|
|
|
|
|
|
|
fpath=( ~/.zfuncs $fpath )
|
|
|
|
|
|
|
|
# Note, that the private directory is added in *front* of the default
|
|
|
|
# value, so that files from that directory supersede the ones from system
|
|
|
|
# directories. To add the VCS_Info subtree (excluding the CVS directories)
|
|
|
|
# in front, change that line to this:
|
|
|
|
|
|
|
|
fpath=( ~/.zfuncs ~/.zfuncs/VCS_Info/**/*~*/(CVS)#(/) $fpath )
|
|
|
|
|
|
|
|
# The weirdly looking pattern requires the `extended_glob' option to be
|
|
|
|
# active, so make sure it is.
|
|
|
|
#
|
|
|
|
# Step three: "Restart Z shell"
|
|
|
|
# A simple
|
|
|
|
# % exec zsh
|
|
|
|
# gets you there. You should be all set now. Have fun.
|