Skip to content

Commit 2ac90b0

Browse files
committed
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.
1 parent bee1558 commit 2ac90b0

2 files changed

Lines changed: 29 additions & 39 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ testhost: require-docker .testyadm
123123
--hostname testhost \
124124
--rm -it \
125125
-v "$(CURDIR)/.testyadm:/bin/yadm:ro" \
126+
-v "$(CURDIR)/completion/bash/yadm:/usr/share/bash-completion/completions/yadm:ro" \
126127
$(IMAGE) \
127128
bash -l
128129

completion/bash/yadm

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,85 @@
11
# test if git completion is missing, but loader exists, attempt to load
2-
if ! declare -F _git > /dev/null && ! declare -F __git_wrap__git_main > /dev/null; then
3-
if declare -F _completion_loader > /dev/null; then
2+
if ! declare -F _git >/dev/null && ! declare -F __git_wrap__git_main >/dev/null; then
3+
if declare -F _completion_loader >/dev/null; then
44
_completion_loader git
55
fi
66
fi
77

88
# only operate if git completion is present
9-
if declare -F _git > /dev/null || declare -F __git_wrap__git_main > /dev/null; then
9+
if declare -F _git >/dev/null || declare -F __git_wrap__git_main >/dev/null; then
1010

1111
_yadm() {
1212

1313
local current=${COMP_WORDS[COMP_CWORD]}
1414
local penultimate
15-
if [ "$((COMP_CWORD-1))" -ge "0" ]; then
16-
penultimate=${COMP_WORDS[COMP_CWORD-1]}
15+
if ((COMP_CWORD >= 1)); then
16+
penultimate=${COMP_WORDS[COMP_CWORD - 1]}
1717
fi
1818
local antepenultimate
19-
if [ "$((COMP_CWORD-2))" -ge "0" ]; then
20-
antepenultimate=${COMP_WORDS[COMP_CWORD-2]}
19+
if ((COMP_CWORD >= 2)); then
20+
antepenultimate=${COMP_WORDS[COMP_CWORD - 2]}
2121
fi
2222

2323
local -x GIT_DIR
24-
# shellcheck disable=SC2034
2524
GIT_DIR="$(yadm introspect repo 2>/dev/null)"
2625

2726
case "$penultimate" in
2827
bootstrap)
2928
COMPREPLY=()
3029
return 0
31-
;;
30+
;;
3231
config)
33-
COMPREPLY=( $(compgen -W "$(yadm introspect configs 2>/dev/null)") )
32+
COMPREPLY=($(compgen -W "$(yadm introspect configs 2>/dev/null)"))
3433
return 0
35-
;;
34+
;;
3635
decrypt)
37-
COMPREPLY=( $(compgen -W "-l" -- "$current") )
36+
COMPREPLY=($(compgen -W "-l" -- "$current"))
3837
return 0
39-
;;
38+
;;
4039
init)
41-
COMPREPLY=( $(compgen -W "-f -w" -- "$current") )
40+
COMPREPLY=($(compgen -W "-f -w" -- "$current"))
4241
return 0
43-
;;
42+
;;
4443
introspect)
45-
COMPREPLY=( $(compgen -W "commands configs repo switches" -- "$current") )
44+
COMPREPLY=($(compgen -W "commands configs repo switches" -- "$current"))
4645
return 0
47-
;;
46+
;;
4847
help)
4948
COMPREPLY=() # no specific help yet
5049
return 0
51-
;;
50+
;;
5251
list)
53-
COMPREPLY=( $(compgen -W "-a" -- "$current") )
52+
COMPREPLY=($(compgen -W "-a" -- "$current"))
5453
return 0
55-
;;
54+
;;
5655
esac
5756

5857
case "$antepenultimate" in
5958
clone)
60-
COMPREPLY=( $(compgen -W "-f -w -b --bootstrap --no-bootstrap" -- "$current") )
59+
COMPREPLY=($(compgen -W "-f -w -b --bootstrap --no-bootstrap" -- "$current"))
6160
return 0
62-
;;
61+
;;
6362
esac
6463

65-
local yadm_switches=( $(yadm introspect switches 2>/dev/null) )
64+
local yadm_switches=($(yadm introspect switches 2>/dev/null))
6665

6766
# this condition is so files are completed properly for --yadm-xxx options
6867
if [[ " ${yadm_switches[*]} " != *" $penultimate "* ]]; then
6968
# TODO: somehow solve the problem with [--yadm-xxx option] being
7069
# incompatible with what git expects, namely [--arg=option]
71-
if declare -F _git > /dev/null; then
70+
if declare -F _git >/dev/null; then
7271
_git
7372
else
7473
__git_wrap__git_main
7574
fi
7675
fi
7776
if [[ "$current" =~ ^- ]]; then
78-
local matching
79-
matching=$(compgen -W "${yadm_switches[*]}" -- "$current")
80-
__gitcompappend "$matching"
77+
__gitcompappend "${yadm_switches[*]}" "" "$current" " "
8178
fi
8279

8380
# Find the index of where the sub-command argument should go.
8481
local command_idx
85-
for (( command_idx=1 ; command_idx < ${#COMP_WORDS[@]} ; command_idx++ )); do
82+
for ((command_idx = 1; command_idx < ${#COMP_WORDS[@]}; command_idx++)); do
8683
local command_idx_arg="${COMP_WORDS[$command_idx]}"
8784
if [[ " ${yadm_switches[*]} " = *" $command_idx_arg "* ]]; then
8885
let command_idx++
@@ -93,19 +90,11 @@ if declare -F _git > /dev/null || declare -F __git_wrap__git_main > /dev/null; t
9390
fi
9491
done
9592
if [[ "$COMP_CWORD" = "$command_idx" ]]; then
96-
local matching
97-
matching=$(compgen -W "$(yadm introspect commands 2>/dev/null)" -- "$current")
98-
__gitcompappend "$matching"
93+
__gitcompappend "$(yadm introspect commands 2>/dev/null)" "" "$current" " "
9994
fi
100-
101-
# remove duplicates found in COMPREPLY (a native bash way could be better)
102-
if [ -n "${COMPREPLY[*]}" ]; then
103-
COMPREPLY=($(echo "${COMPREPLY[@]}" | sort -u))
104-
fi
105-
10695
}
10796

108-
complete -o bashdefault -o default -F _yadm yadm 2>/dev/null \
109-
|| complete -o default -F _yadm yadm
97+
complete -o bashdefault -o default -o nospace -F _yadm yadm 2>/dev/null ||
98+
complete -o default -o nospace -F _yadm yadm
11099

111100
fi

0 commit comments

Comments
 (0)