Skip to content

Commit 57eed97

Browse files
committed
Rework zsh completion fallback
Don't rely on internals from the git completion. Instead set up the environment and then simply call _git and let it do the completion as it see fit. See #292.
1 parent aaf5196 commit 57eed97

File tree

1 file changed

+33
-70
lines changed

1 file changed

+33
-70
lines changed

completion/zsh/_yadm

Lines changed: 33 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#compdef yadm
22

33
# This completion tries to fallback to git's completion for git commands.
4-
# It handles two different types of fallbacks:
5-
# - The git completion shipped with git.
6-
# - The git completion shipped with zsh.
4+
5+
zstyle -T ':completion:*:yadm:argument-1:descriptions:' format && \
6+
zstyle ':completion:*:yadm:argument-1:descriptions' format '%d:'
7+
zstyle -T ':completion:*:yadm:*:yadm' group-name && \
8+
zstyle ':completion:*:yadm:*:yadm' group-name ''
79

810
_yadm-alt() {
911
return 0
@@ -72,64 +74,50 @@ _yadm-transcrypt() {
7274
}
7375

7476
_yadm-upgrade() {
75-
return 0
77+
_arguments \
78+
'-f[force deinit of submodules]' \
79+
': '
7680
}
7781

7882
_yadm-version() {
7983
return 0
8084
}
8185

8286
_yadm_commands() {
83-
local -a commands
84-
commands=(
85-
alt:'create links for alternates (yadm)'
86-
bootstrap:'execute bootstrap (yadm)'
87-
clone:'clone an existing repository (yadm)'
87+
local -a commands=(
88+
alt:'create links for alternates'
89+
bootstrap:'execute bootstrap'
90+
clone:'clone an existing yadm repository'
8891
config:'configure an yadm setting'
89-
decrypt:'decrypt files (yadm)'
90-
encrypt:'encrypt files (yadm)'
92+
decrypt:'decrypt files'
93+
encrypt:'encrypt files'
9194
enter:'run sub-shell with GIT variables set'
9295
git-crypt:'run git-crypt commands for the yadm repository'
9396
gitconfig:'run the git config command'
9497
help:'display yadm help information'
9598
init:'initialize an empty yadm repository'
9699
list:'list files tracked by yadm'
97-
perms:'fix perms for private files (yadm)'
100+
perms:'fix perms for private files'
98101
transcrypt:'run transcrypt commands for the yadm repository'
99102
upgrade:'upgrade legacy yadm paths'
100103
version:'show yadm version'
101104
)
102105

103-
integer _ret=1
106+
local oldcontext="$curcontext"
107+
local curcontext="${curcontext%:*:*}:git:"
104108

105-
if (( $+functions[_git_commands] )); then
106-
zstyle ':completion:*:*:yadm:*' user-commands $commands
107-
_call_function _ret _git_commands
108-
zstyle -d ':completion:*:*:yadm:*' user-commands
109-
else
110-
local curcontext=${curcontext%:*:*}:git:
111-
_tags common-commands alias-commands all-commands
112-
while _tags; do
113-
_requested common-commands && __git_zsh_cmd_common
114-
_requested alias-commands && __git_zsh_cmd_alias
115-
_requested all-commands && __git_zsh_cmd_all
116-
let _ret || break
117-
done
118-
_describe "yadm commands" commands
119-
fi
109+
words=("git" "${words[-1]}") CURRENT=2 service=git _git
120110

121-
return _ret
111+
curcontext="$oldcontext"
112+
_describe -t yadm "yadm commands" commands
113+
114+
return 0
122115
}
123116

124117
_yadm() {
125118
local curcontext=$curcontext state state_descr line
126119
declare -A opt_args
127120

128-
local -a orig_words=( ${words[@]} )
129-
local cur=${words[CURRENT]}
130-
local prev=${words[CURRENT-1]}
131-
let cword=CURRENT-1
132-
133121
_arguments -C \
134122
'(-Y --yadm-dir)'{-Y,--yadm-dir}'[override the standard yadm directory]: :_files -/' \
135123
'--yadm-data[override the standard yadm data directory]: :_files -/' \
@@ -147,55 +135,30 @@ _yadm() {
147135
(( $+opt_args[--yadm-repo] )) && repo_args+=(--yadm-repo "$opt_args[--yadm-repo]")
148136
(( $+opt_args[--yadm-data] )) && repo_args+=(--yadm-data "$opt_args[--yadm-data]")
149137
local -x GIT_DIR="$(_call_program gitdir yadm "${repo_args[@]}" introspect repo)"
150-
local __git_dir="$GIT_DIR"
138+
[[ -z "$GIT_DIR" ]] && return 1
151139

152140
integer _ret=1
153141
case $state in
154142
(command)
155143
_yadm_commands && _ret=0
156144
;;
157145
(option-or-argument)
158-
local command=$words[1]
146+
curcontext=${curcontext%:*:*}:yadm-${words[1]}:
147+
if ! _call_function _ret _yadm-${words[1]}; then
159148

160-
# First try to complete yadm commands
161-
curcontext=${curcontext%:*:*}:yadm-$command:
162-
if ! _call_function _ret _yadm-$command; then
163149
# Translate gitconfig to use the regular completion for config
164-
[[ $command = "gitconfig" ]] && command=config
165-
166-
# If is wasn't a valid command, try git's completion if available
167-
if (( $+functions[__git_zsh_bash_func] )); then
168-
words=( ${orig_words[@]} )
169-
curcontext=${curcontext%:*:*}:git:
170-
171-
__git_zsh_bash_func $command
172-
let _ret && _default && _ret=0
173-
else
174-
# If git's completion wasn't available, try zsh's
175-
curcontext=${curcontext%:*:*}:git-$command:
176-
if ! _call_function _ret _git-$command; then
177-
if [[ $words[1] = \!* ]]; then
178-
words[1]=${words[1]##\!}
179-
_normal && _ret=0
180-
elif zstyle -T :completion:$curcontext: use-fallback; then
181-
_default && _ret=0
182-
else
183-
_message "unknown sub-command: $command"
184-
fi
185-
fi
186-
fi
150+
[[ ${words[1]} = "gitconfig" ]] && words[1]=config
151+
152+
words=("git" "${(@)words}")
153+
CURRENT=$(( CURRENT + 1 ))
154+
155+
curcontext=${curcontext%:*:*}:git:
156+
service=git _git && _ret=0
187157
fi
188158
;;
189159
esac
190160

191161
return _ret
192162
}
193163

194-
# Ignore call from _git when using git's completion
195-
__yadm_zsh_main() {
196-
_ret=0
197-
}
198-
199-
# __git_zsh_bash_func comes from git's completion and _git_commands from zsh's
200-
(( $+functions[__git_zsh_bash_func] + $+functions[_git_commands] )) || _git
201-
_yadm
164+
(( $+functions[_git] )) && _yadm

0 commit comments

Comments
 (0)