1
0
Fork 0
mirror of synced 2025-05-15 16:29:41 -04:00

Fix handling of filenames with space in bash completion (#341)

By calling __gitcompappend with the same suffix as the completion for git
does (i.e. " ") we can remove the call to sort -u as it is no longer
needed (bash seems to remove duplicates) and then spaces are handled correctly.

Also make the completion available in testhost.
This commit is contained in:
Erik Flodin 2025-03-03 21:36:36 +01:00
parent bee1558a4e
commit 2ac90b004c
No known key found for this signature in database
GPG key ID: 420A7C865EE3F85F
2 changed files with 29 additions and 39 deletions

View file

@ -123,6 +123,7 @@ testhost: require-docker .testyadm
--hostname testhost \
--rm -it \
-v "$(CURDIR)/.testyadm:/bin/yadm:ro" \
-v "$(CURDIR)/completion/bash/yadm:/usr/share/bash-completion/completions/yadm:ro" \
$(IMAGE) \
bash -l

View file

@ -1,88 +1,85 @@
# test if git completion is missing, but loader exists, attempt to load
if ! declare -F _git > /dev/null && ! declare -F __git_wrap__git_main > /dev/null; then
if declare -F _completion_loader > /dev/null; then
if ! declare -F _git >/dev/null && ! declare -F __git_wrap__git_main >/dev/null; then
if declare -F _completion_loader >/dev/null; then
_completion_loader git
fi
fi
# only operate if git completion is present
if declare -F _git > /dev/null || declare -F __git_wrap__git_main > /dev/null; then
if declare -F _git >/dev/null || declare -F __git_wrap__git_main >/dev/null; then
_yadm() {
local current=${COMP_WORDS[COMP_CWORD]}
local penultimate
if [ "$((COMP_CWORD-1))" -ge "0" ]; then
penultimate=${COMP_WORDS[COMP_CWORD-1]}
if ((COMP_CWORD >= 1)); then
penultimate=${COMP_WORDS[COMP_CWORD - 1]}
fi
local antepenultimate
if [ "$((COMP_CWORD-2))" -ge "0" ]; then
antepenultimate=${COMP_WORDS[COMP_CWORD-2]}
if ((COMP_CWORD >= 2)); then
antepenultimate=${COMP_WORDS[COMP_CWORD - 2]}
fi
local -x GIT_DIR
# shellcheck disable=SC2034
GIT_DIR="$(yadm introspect repo 2>/dev/null)"
case "$penultimate" in
bootstrap)
COMPREPLY=()
return 0
;;
;;
config)
COMPREPLY=( $(compgen -W "$(yadm introspect configs 2>/dev/null)") )
COMPREPLY=($(compgen -W "$(yadm introspect configs 2>/dev/null)"))
return 0
;;
;;
decrypt)
COMPREPLY=( $(compgen -W "-l" -- "$current") )
COMPREPLY=($(compgen -W "-l" -- "$current"))
return 0
;;
;;
init)
COMPREPLY=( $(compgen -W "-f -w" -- "$current") )
COMPREPLY=($(compgen -W "-f -w" -- "$current"))
return 0
;;
;;
introspect)
COMPREPLY=( $(compgen -W "commands configs repo switches" -- "$current") )
COMPREPLY=($(compgen -W "commands configs repo switches" -- "$current"))
return 0
;;
;;
help)
COMPREPLY=() # no specific help yet
return 0
;;
;;
list)
COMPREPLY=( $(compgen -W "-a" -- "$current") )
COMPREPLY=($(compgen -W "-a" -- "$current"))
return 0
;;
;;
esac
case "$antepenultimate" in
clone)
COMPREPLY=( $(compgen -W "-f -w -b --bootstrap --no-bootstrap" -- "$current") )
COMPREPLY=($(compgen -W "-f -w -b --bootstrap --no-bootstrap" -- "$current"))
return 0
;;
;;
esac
local yadm_switches=( $(yadm introspect switches 2>/dev/null) )
local yadm_switches=($(yadm introspect switches 2>/dev/null))
# this condition is so files are completed properly for --yadm-xxx options
if [[ " ${yadm_switches[*]} " != *" $penultimate "* ]]; then
# TODO: somehow solve the problem with [--yadm-xxx option] being
# incompatible with what git expects, namely [--arg=option]
if declare -F _git > /dev/null; then
if declare -F _git >/dev/null; then
_git
else
__git_wrap__git_main
fi
fi
if [[ "$current" =~ ^- ]]; then
local matching
matching=$(compgen -W "${yadm_switches[*]}" -- "$current")
__gitcompappend "$matching"
__gitcompappend "${yadm_switches[*]}" "" "$current" " "
fi
# Find the index of where the sub-command argument should go.
local command_idx
for (( command_idx=1 ; command_idx < ${#COMP_WORDS[@]} ; command_idx++ )); do
for ((command_idx = 1; command_idx < ${#COMP_WORDS[@]}; command_idx++)); do
local command_idx_arg="${COMP_WORDS[$command_idx]}"
if [[ " ${yadm_switches[*]} " = *" $command_idx_arg "* ]]; then
let command_idx++
@ -93,19 +90,11 @@ if declare -F _git > /dev/null || declare -F __git_wrap__git_main > /dev/null; t
fi
done
if [[ "$COMP_CWORD" = "$command_idx" ]]; then
local matching
matching=$(compgen -W "$(yadm introspect commands 2>/dev/null)" -- "$current")
__gitcompappend "$matching"
__gitcompappend "$(yadm introspect commands 2>/dev/null)" "" "$current" " "
fi
# remove duplicates found in COMPREPLY (a native bash way could be better)
if [ -n "${COMPREPLY[*]}" ]; then
COMPREPLY=($(echo "${COMPREPLY[@]}" | sort -u))
fi
}
complete -o bashdefault -o default -F _yadm yadm 2>/dev/null \
|| complete -o default -F _yadm yadm
complete -o bashdefault -o default -o nospace -F _yadm yadm 2>/dev/null ||
complete -o default -o nospace -F _yadm yadm
fi