1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
| | ## 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 msgs
local -i maxexports
static_functions=(
VCS_INFO_adjust
VCS_INFO_bydir_detect
VCS_INFO_check_com
VCS_INFO_formats
VCS_INFO_get_cmd
VCS_INFO_hexdump
VCS_INFO_hook
VCS_INFO_set-patch-format
VCS_INFO_set-branch-format
VCS_INFO_maxexports
VCS_INFO_nvcsformats
VCS_INFO_patch2subject
VCS_INFO_quilt
VCS_INFO_reposub
VCS_INFO_set
vcs_info_hookadd
vcs_info_hookdel
vcs_info_lastmsg
vcs_info_printsys
vcs_info_setsys
)
for func in ${static_functions} ; do
autoload -Uz ${func}
done
[[ -n ${(Mk)parameters:#vcs_info_msg_<->_} ]] && unset ${parameters[(I)vcs_info_msg_<->_]}
VCS_INFO_maxexports
VCS_INFO_set --nvcs '-preinit-'
vcs_info_setsys
# and now, finally create the real vcs_info function
vcs_info () {
emulate -L zsh
setopt extendedglob NO_warn_create_global
[[ -r . ]] || return 0
local pat
local -i retval
local -a enabled disabled dps
local usercontext vcs rrn quiltmode
local -x LC_MESSAGES
local -i maxexports
local -a msgs
# vcs_comm is used internally for passing values among VCS_INFO_* functions.
# It is not part of the public API.
#
# VCS_INFO_detect_* functions should set vcs_comm[basedir] to the path to
# the root of the working copy.
#
# hook_com, backend_misc, and user_data are public API; see zshcontrib(1)
# and Misc/vcs_info-examples.
local -A vcs_comm hook_com backend_misc user_data
LC_MESSAGES=C
if [[ -n ${LC_ALL} ]]; then
local -x LANG
LANG=${LC_ALL}
local -x LC_ALL
fi
vcs='-init-'; rrn='-all-'; quiltmode='addon'
usercontext=${1:-default}
VCS_INFO_hook "start-up"
retval=$?
if (( retval == 1 )); then
return 0
elif (( retval == 2 )); then
# This needs `max-exports' set. We're still setting it again later
# for more specific contexts.
VCS_INFO_maxexports
VCS_INFO_set --nvcs
return 0
fi
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 --nvcs
return 0
fi
if [[ -n ${(M)enabled:#(#i)all} ]] ; then
enabled=( ${VCS_INFO_backends} )
zstyle -a ":vcs_info:${vcs}:${usercontext}:${rrn}" "disable" disabled
fi
zstyle -a ":vcs_info:${vcs}:${usercontext}:${rrn}" "disable-patterns" dps
for pat in ${dps} ; do
if [[ ${PWD} == ${~pat} ]] ; then
VCS_INFO_maxexports
[[ -n ${vcs_info_msg_0_} ]] && VCS_INFO_set --nvcs
return 0
fi
done
VCS_INFO_maxexports
local -A chosen_vcs_comm chosen_backend_misc
local chosen_vcs basedir_realpath chosen_basedir_realpath choose_first_available
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_get_cmd
if VCS_INFO_detect_${vcs}; then
# Most backends already set vcs_comm[basedir] to an absolute path
# with symlinks resolved:
#
# * Backends using VCS_INFO_bydir_detect:
# bzr, cdv, darcs, fossil, hg, mtn, p4, svn
#
# * cvs - custom logic, but uses :P too
#
# * git - $(git rev-parse --show-toplevel) resolves symlinks and
# returns an absolute path
#
# * for tla (GNU Arch) I can't find any online documentation or
# packages (seems to be dead)
#
# * svk doesn't use :P modifier and returns the path as is from
# the config file (as far as I understand)
#
# So I'm not sure whether to modify the backends or just resolve
# the path here to be sure. VCS_INFO_get_data_* usually reads
# vcs_comm[basedir] too. In particular, I'm not sure if it's safe to
# resolve symlinks in vcs_comm[basedir] for svk.
#
# Because most backends already do :P substitution, I expect all
# the info needed to resolve the path to be cached in memory by the
# OS (so it shouldn't cause performance issues).
basedir_realpath="${vcs_comm[basedir]:P}"
zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" choose-closest-backend
choose_first_available=$?
[[ "${PWD:P}/" == "${basedir_realpath}"/* ]] || [[ "${basedir_realpath}" == "/" ]] || choose_first_available=1
# If choose_first_available is 0 at this point, all basedir_realpaths
# (and thus chosen_basedir_realpath) are parents (and thus prefixes)
# of PWD:P. So comparing their lengths is enough to figure out which
# one is closer to PWD.
if (( choose_first_available )) || (( ${#basedir_realpath} > ${#chosen_basedir_realpath} )) ; then
chosen_vcs="${vcs}"
chosen_vcs_comm=("${(kv)vcs_comm[@]}")
chosen_backend_misc=("${(kv)backend_misc[@]}")
chosen_basedir_realpath="${basedir_realpath}"
(( choose_first_available )) && break
fi
fi
done
vcs="${chosen_vcs}"
vcs_comm=("${(kv)chosen_vcs_comm[@]}")
backend_misc=("${(kv)chosen_backend_misc[@]}")
[ -z "${vcs}" ] && {
vcs='-quilt-'; quiltmode='standalone'
VCS_INFO_quilt standalone || VCS_INFO_set --nvcs
return 0
}
VCS_INFO_hook "pre-get-data"
retval=$?
if (( retval == 1 )); then
return 0
elif (( retval == 2 )); then
VCS_INFO_set --nvcs
return 0
fi
VCS_INFO_get_data_${vcs} || {
VCS_INFO_set --nvcs
return 1
}
VCS_INFO_set
return 0
}
vcs_info "$@"
|