Skip to content

Commit c05fdf4

Browse files
committed
completion: try to complete copy or command
When using clush -c we should try to complete local files. When not using -c, if a taget has already been set we can also try to complete a command. We could do like ssh and try to complete it on any node in the nodeset, but a local completion is probably good enough. And still complete possible options but only do so if a dash was present, this is similar to what e.g. `ls` completion does Fixes #584
1 parent 129d6ed commit c05fdf4

File tree

1 file changed

+59
-9
lines changed

1 file changed

+59
-9
lines changed

bash_completion.d/clush

+59-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,43 @@
11
# clush bash completion
22
#
33
# to install in /usr/share/bash-completion/completions/ or ~/.local/share/bash-completion/completions/
4+
_clush_command_or_file() {
5+
# undo our nospace setting...
6+
compopt +o nospace
7+
8+
# complete either files (copy mode) or commands (if target set)
9+
case "$target_set,$mode" in
10+
*,copy)
11+
# available since bash-completion 2.12
12+
if declare -F _comp_compgen_filedir >/dev/null; then
13+
_comp_compgen_filedir
14+
else
15+
_filedir
16+
fi
17+
;;
18+
1,command)
19+
# available since bash-completion 2.12
20+
if declare -F _comp_command_offset >/dev/null; then
21+
_comp_command_offset "$i"
22+
else
23+
_command_offset "$i"
24+
fi
25+
;;
26+
esac
27+
}
28+
429
_clush()
530
{
631
# shellcheck disable=SC2034 # set/used by _init_completion
732
local cur prev words cword split
8-
local word options="" compopts="" skip=argv0 groupsource="" cleangroup=""
33+
local i word options="" compopts="" skip=argv0 groupsource="" cleangroup=""
34+
local mode=command target_set=""
935

1036
_init_completion -s -n : || return
1137

1238
# stop parsing if there had been any non-option before (or --)
13-
for word in "${words[@]}"; do
39+
for i in "${!words[@]}"; do
40+
word="${words[i]}"
1441
case "$skip" in
1542
"") ;;
1643
groupsource)
@@ -23,7 +50,13 @@ _clush()
2350
esac
2451
case "$word" in
2552
"") ;;
26-
--) return;;
53+
--)
54+
i=$((i+1)) # command from next word!
55+
_clush_command_or_file
56+
return
57+
;;
58+
-c|--copy|--rcopy) mode=copy;;
59+
-w|-g|--group) target_set=1; skip=any;;
2760
# no-arg options
2861
--version|-h|--help|-n|--nostdin|-a|--all|-q|--quiet|\
2962
-v|--verbose|-d|--debug) ;;
@@ -34,7 +67,12 @@ _clush()
3467
# options with = included in word
3568
--*=*) ;;
3669
-*) skip=any;;
37-
*) return;; # was non-option
70+
*)
71+
# likely non-option, in copy mode options like -w can come
72+
# later so just skip, otherwise likely start of command
73+
[ "$mode" = copy ] && continue
74+
_clush_command_or_file
75+
return;;
3876
esac
3977
done
4078

@@ -54,6 +92,7 @@ _clush()
5492
if [ "$prev" = "-w" ]; then
5593
compopts="@*" # include all nodes
5694
fi
95+
# shellcheck disable=SC2086 ## $compopts expanded on purpose
5796
options="$(cluset ${groupsource:+-s "$groupsource"} --completion $compopts)"
5897
if [ -n "$cleangroup" ]; then
5998
options=${options//@"$groupsource":/@}
@@ -75,17 +114,28 @@ _clush()
75114
;;
76115
# no-arg options
77116
--version|-h|--help|-n|--nostdin|-a|--all|-q|--quiet|\
78-
-v|--verbose|-d|--debug) ;;
79-
# any other option: just ignore.
117+
-v|--verbose|-d|--debug|-c|--copy|--rcopy) ;;
118+
# any other option: ignore next word (likely argument)
80119
-*)
81120
return;;
82121
esac
83-
# get all options from help text... not 100% accurate but good enough.
84-
[ -n "$options" ] || options="$(clush --help | grep -oP -- '(?<=[ \t])(-[a-z]|--[^= \t]*)')"
122+
# new option or no option:
123+
if [ -z "$options" ]; then
124+
case "$cur" in
125+
-*)
126+
# starts with dash - get all options from help text...
127+
options="$(clush --help | grep -oP -- '(?<=[ \t])(-[a-z]|--[^= \t]*)')"
128+
;;
129+
*)
130+
# otherwise complete command or file if appropriate and stop here
131+
_clush_command_or_file
132+
return
133+
esac
134+
fi
85135

86136
# append space for everything that doesn't end in `:` (likely a groupsource)
87137
mapfile -t COMPREPLY < <(compgen -W "$options" -- "$cur" | sed -e 's/[^:]$/& /')
88138
# remove the prefix from COMPREPLY if $cur contains colons and
89139
# COMP_WORDBREAKS splits on colons...
90140
__ltrim_colon_completions "$cur"
91-
} && complete -o nospace -F _clush ${BASH_SOURCE##*/}
141+
} && complete -o nospace -F _clush "${BASH_SOURCE##*/}"

0 commit comments

Comments
 (0)