Skip to content

Commit fbb660e

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 cea-hpc#584
1 parent dde1481 commit fbb660e

File tree

1 file changed

+43
-9
lines changed

1 file changed

+43
-9
lines changed

bash_completion.d/clush

+43-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
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) _comp_compgen_filedir;;
11+
1,command) _comp_command_offset "$i";;
12+
esac
13+
}
14+
415
_clush()
516
{
617
# shellcheck disable=SC2034 # set/used by _init_completion
718
local cur prev words cword split
8-
local word options="" compopts="" skip=argv0 groupsource="" cleangroup=""
19+
local i word options="" compopts="" skip=argv0 groupsource="" cleangroup=""
20+
local mode=command target_set=""
921

1022
_init_completion -s -n : || return
1123

1224
# stop parsing if there had been any non-option before (or --)
13-
for word in "${words[@]}"; do
25+
for i in "${!words[@]}"; do
26+
word="${words[i]}"
1427
case "$skip" in
1528
"") ;;
1629
groupsource)
@@ -23,7 +36,13 @@ _clush()
2336
esac
2437
case "$word" in
2538
"") ;;
26-
--) return;;
39+
--)
40+
i=$((i+1)) # command from next word!
41+
_clush_command_or_file
42+
return
43+
;;
44+
-c|--copy|--rcopy) mode=copy;;
45+
-w|-g|--group) target_set=1; skip=any;;
2746
# no-arg options
2847
--version|-h|--help|-n|--nostdin|-a|--all|-q|--quiet|\
2948
-v|--verbose|-d|--debug) ;;
@@ -34,7 +53,10 @@ _clush()
3453
# options with = included in word
3554
--*=*) ;;
3655
-*) skip=any;;
37-
*) return;; # was non-option
56+
*)
57+
# likely non-option, continue file or command completion from here
58+
_clush_command_or_file
59+
return;;
3860
esac
3961
done
4062

@@ -54,6 +76,7 @@ _clush()
5476
if [ "$prev" = "-w" ]; then
5577
compopts="@*" # include all nodes
5678
fi
79+
# shellcheck disable=SC2086 ## $compopts expanded on purpose
5780
options="$(cluset ${groupsource:+-s "$groupsource"} --completion $compopts)"
5881
if [ -n "$cleangroup" ]; then
5982
options=${options//@"$groupsource":/@}
@@ -75,17 +98,28 @@ _clush()
7598
;;
7699
# no-arg options
77100
--version|-h|--help|-n|--nostdin|-a|--all|-q|--quiet|\
78-
-v|--verbose|-d|--debug) ;;
79-
# any other option: just ignore.
101+
-v|--verbose|-d|--debug|-c|--copy|--rcopy) ;;
102+
# any other option: ignore next word (likely argument)
80103
-*)
81104
return;;
82105
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]*)')"
106+
# new option or no option:
107+
if [ -z "$options" ]; then
108+
case "$cur" in
109+
-*)
110+
# starts with dash - get all options from help text...
111+
options="$(clush --help | grep -oP -- '(?<=[ \t])(-[a-z]|--[^= \t]*)')"
112+
;;
113+
*)
114+
# otherwise complete command or file if appropriate and stop here
115+
_clush_command_or_file
116+
return
117+
esac
118+
fi
85119

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

0 commit comments

Comments
 (0)