From: Daniel Shahaf <d.s@daniel.shahaf.name>
To: zsh-workers@zsh.org
Subject: [PATCH 3/5] _subversion: commit, diff, revert: Update completions for svn 1.7 and newer
Date: Wed, 26 Jan 2022 14:18:45 +0000 [thread overview]
Message-ID: <20220126141847.10271-3-danielsh@tarpaulin.shahaf.local2> (raw)
In-Reply-To: <20220126141847.10271-1-danielsh@tarpaulin.shahaf.local2>
* _svn_deletedfiles: Remove.
The last version of svn(1) under which that function could possibly
complete anything, svn 1.6.x, was EOLed in 2013. Newer versions
don't have a "text-base" directory, so $controlled is set to an
empty array, so this function returned false for all files, so
in 'svn rm' (up to the previous commit) all files were completed
(because that's what '_files -g "*(e:false:)"' does).
* _svn_status: Remove.
Versions of svn newer than the aforementioned 1.6.x have an
entries file but never modify it, so the "mtime has changed" check
would false negative. Therefore, sequences such as:
.
svn <TAB>
echo >> some/versioned/file
svn ci <TAB>
.
wouldn't offer some/versioned/file.
.
Furthermore, completion would offer directories with no changed
files in them, and even unversioned directories. Now only changed
files/directories are offered.
* _cache_svn_status, _cache_svn_mtime: Remove.
If these hadn't been removed, I would have moved their declarations
to file scope so _svn_status could be used from outside this file,
too.
The replacement function, _svn_modified, doesn't have cache support, but
does honour the 'verbose' style to inhibit recursion to subdirectories.
---
Completion/Unix/Command/_subversion | 69 ++++++++++++++++++-----------
1 file changed, 43 insertions(+), 26 deletions(-)
diff --git a/Completion/Unix/Command/_subversion b/Completion/Unix/Command/_subversion
index 9ef3077f6..cb5cbd374 100644
--- a/Completion/Unix/Command/_subversion
+++ b/Completion/Unix/Command/_subversion
@@ -68,7 +68,6 @@ _svn () {
;;
args)
local cmd args usage idx
- typeset -gHA _cache_svn_status _cache_svn_mtime
cmd="${${(k)_svn_cmds[(R)*:$words[1]:*]}:-${(k)_svn_cmds[(i):$words[1]:]}}"
if (( $#cmd )); then
@@ -141,7 +140,7 @@ _svn () {
(commit)
args=(
${args/(#b)(*--file*):arg:/$match[1]:file:_files}
- '*:file:_files -g "*(e:_svn_status:)"'
+ '*:file: _svn_modified "committable"'
)
;;
(delete)
@@ -151,7 +150,7 @@ _svn () {
;;
(diff)
args+=(
- '*: : _alternative "files:file:_files -g \*\(e:_svn_status:\)" "urls:URL:_svn_urls"'
+ '*: : _alternative "files:file: _svn_modified revertable" "urls:URL:_svn_urls"'
)
;;
(help)
@@ -201,7 +200,7 @@ _svn () {
;;
(revert)
args+=(
- '*:file:_files -g "(.svn|*)(/e:_svn_deletedfiles:,e:_svn_status:)"'
+ '*:file: _svn_modified "revertable"'
)
;;
(x-unshelve)
@@ -368,33 +367,51 @@ _svn_conflicts() {
() { (( $# > 0 )) } $REPLY.(mine|r<->)(NY1)
}
-(( $+functions[_svn_deletedfiles] )) ||
-_svn_deletedfiles() {
- # Typical usage would be _files -g '.svn(/e:_svn_deletedfiles:)'
- local cont controlled
- reply=( )
- [[ $REPLY = (*/|).svn ]] || return
- controlled=( $REPLY/text-base/*.svn-base(N:r:t) )
- for cont in ${controlled}; do
- [[ -e $REPLY:h/$cont ]] || reply+=( ${REPLY%.svn}$cont )
- done
-}
+(( $+functions[_svn_modified] )) ||
+_svn_modified() {
+ setopt localoptions extendedglob
-(( $+functions[_svn_status] )) ||
-_svn_status() {
- local dir=$REPLY:h
- local pat="${1:-([ADMR~]|?M)}"
+ local depth dir expl partial_word space=' '
- zmodload -F zsh/stat b:zstat 2>/dev/null
- local key="$(zstat +device $dir):$(zstat +inode $dir)"
- local mtime="$(zstat +mtime $dir/.svn/entries)"
+ local svn_context=$1
- if (( ! $+_cache_svn_status[$key] || _cache_svn_mtime[$key] != mtime )); then
- _cache_svn_status[$key]="$(_call_program files svn status -q -N -- $dir)"
- _cache_svn_mtime[$key]="$mtime"
+ local partial_word=${(Q)words[CURRENT]}
+ if [[ -z $partial_word ]]; then
+ dir="./"
+ elif [[ -d $partial_word ]]; then
+ dir=$partial_word
+ else
+ dir=${partial_word:h}
fi
- (( ${(M)#${(f)_cache_svn_status[$key]}:#(#s)${~pat}*$REPLY} ))
+ if zstyle -T ":completion:${curcontext}:${curtag}" verbose; then
+ depth=infinity
+ else
+ depth=immediates
+ fi
+
+ local -a status_lines
+ # Run 'status'
+ status_lines=( ${(f)"$(_call_program modified-files "svn status -q --depth=${(q)depth} -- ${(q)dir}")"} )
+ # Filter to only the right set of statuses
+ case $svn_context in
+ (committable)
+ status_lines=( ${(M)status_lines:#(#s)([ADMR]?|?M)${space}???${space}${space}*} )
+ ;;
+ (revertable)
+ status_lines=( ${(M)status_lines:#(#s)([ACDMR~!]?|?[CM])${space}????${space}*} )
+ ;;
+ esac
+ # Strip the 7 status-letter columns and the column of spaces
+ status_lines=( ${status_lines#????????} )
+ # Strip one leading space. This is in case `svn status` ever adds another
+ # column. If that hasn't happened and you're reading this comment because
+ # the following line broke your use of filenames that start with a literal
+ # space, well, nice to meet you! I didn't know you existed.
+ status_lines=( ${status_lines#${space}} )
+
+ _wanted svn-modified expl 'modified files in svn' \
+ compadd - "${status_lines[@]}"
}
(( $+functions[_svn_remote_paths] )) ||
next prev parent reply other threads:[~2022-01-26 14:21 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-26 14:18 [PATCH 1/5] _subversion: _svn_status: Don't offer unversioned files Daniel Shahaf
2022-01-26 14:18 ` [PATCH 2/5] _subversion: svn rm: Complete all svn-controlled files, not only missing/deleted files Daniel Shahaf
2022-01-26 14:18 ` Daniel Shahaf [this message]
2022-01-26 14:18 ` [PATCH 4/5] _subversion: resolve: Complete conflicted files created by merges, too Daniel Shahaf
2022-01-26 14:18 ` [PATCH 5/5] _subversion: add: Complete target arguments to this subcommand Daniel Shahaf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220126141847.10271-3-danielsh@tarpaulin.shahaf.local2 \
--to=d.s@daniel.shahaf.name \
--cc=zsh-workers@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).