1
1
# clush bash completion
2
2
#
3
3
# 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
+
4
29
_clush()
5
30
{
6
31
# shellcheck disable=SC2034 # set/used by _init_completion
7
32
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=""
9
35
10
36
_init_completion -s -n : || return
11
37
12
38
# 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]}"
14
41
case "$skip" in
15
42
"") ;;
16
43
groupsource)
@@ -23,7 +50,13 @@ _clush()
23
50
esac
24
51
case "$word" in
25
52
"") ;;
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;;
27
60
# no-arg options
28
61
--version|-h|--help|-n|--nostdin|-a|--all|-q|--quiet|\
29
62
-v|--verbose|-d|--debug) ;;
@@ -34,7 +67,12 @@ _clush()
34
67
# options with = included in word
35
68
--*=*) ;;
36
69
-*) 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;;
38
76
esac
39
77
done
40
78
@@ -54,6 +92,7 @@ _clush()
54
92
if [ "$prev" = "-w" ]; then
55
93
compopts="@*" # include all nodes
56
94
fi
95
+ # shellcheck disable=SC2086 ## $compopts expanded on purpose
57
96
options="$(cluset ${groupsource:+-s "$groupsource"} --completion $compopts)"
58
97
if [ -n "$cleangroup" ]; then
59
98
options=${options//@"$groupsource":/@}
@@ -75,17 +114,28 @@ _clush()
75
114
;;
76
115
# no-arg options
77
116
--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)
80
119
-*)
81
120
return;;
82
121
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
85
135
86
136
# append space for everything that doesn't end in `:` (likely a groupsource)
87
137
mapfile -t COMPREPLY < <(compgen -W "$options" -- "$cur" | sed -e 's/[^:]$/& /')
88
138
# remove the prefix from COMPREPLY if $cur contains colons and
89
139
# COMP_WORDBREAKS splits on colons...
90
140
__ltrim_colon_completions "$cur"
91
- } && complete -o nospace -F _clush ${BASH_SOURCE##*/}
141
+ } && complete -o nospace -F _clush " ${BASH_SOURCE##*/}"
0 commit comments