-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathclush
141 lines (135 loc) · 3.41 KB
/
clush
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# clush bash completion
#
# to install in /usr/share/bash-completion/completions/ or ~/.local/share/bash-completion/completions/
_clush_command_or_file() {
# undo our nospace setting...
compopt +o nospace
# complete either files (copy mode) or commands (if target set)
case "$target_set,$mode" in
*,copy)
# available since bash-completion 2.12
if declare -F _comp_compgen_filedir >/dev/null; then
_comp_compgen_filedir
else
_filedir
fi
;;
1,command)
# available since bash-completion 2.12
if declare -F _comp_command_offset >/dev/null; then
_comp_command_offset "$i"
else
_command_offset "$i"
fi
;;
esac
}
_clush()
{
# shellcheck disable=SC2034 # set/used by _init_completion
local cur prev words cword split
local i word options="" compopts="" skip=argv0 groupsource="" cleangroup=""
local mode=command target_set=""
_init_completion -s -n : || return
# stop parsing if there had been any non-option before (or --)
for i in "${!words[@]}"; do
word="${words[i]}"
case "$skip" in
"") ;;
groupsource)
groupsource="$word"
;& # fallthrough
*)
skip=""
continue
;;
esac
case "$word" in
"") ;;
--)
i=$((i+1)) # command from next word!
_clush_command_or_file
return
;;
-c|--copy|--rcopy) mode=copy;;
-w|-g|--group) target_set=1; skip=any;;
# no-arg options
--version|-h|--help|-n|--nostdin|-a|--all|-q|--quiet|\
-v|--verbose|-d|--debug) ;;
# get source separately...
--groupsource=*) groupsource="${word#*=}";;
-s|--groupsource) skip=groupsource;;
# assume all the rest as options...
# options with = included in word
--*=*) ;;
-*) skip=any;;
*)
# likely non-option, in copy mode options like -w can come
# later so just skip, otherwise likely start of command
[ "$mode" = copy ] && continue
_clush_command_or_file
return;;
esac
done
case "$prev" in
-w|-x|-g|--group|-X)
case "$cur" in
*:*)
groupsource="${cur%%:*}"
groupsource="${groupsource#@}"
;;
*)
if [ -n "$groupsource" ]; then
cleangroup=1
fi
;;
esac
if [ "$prev" = "-w" ]; then
compopts="@*" # include all nodes
fi
# shellcheck disable=SC2086 ## $compopts expanded on purpose
options="$(cluset ${groupsource:+-s "$groupsource"} --completion $compopts)"
if [ -n "$cleangroup" ]; then
options=${options//@"$groupsource":/@}
fi
case "$prev" in
-g|--group|-X)
options=${options//@/}
;;
esac
;;
-s|--groupsource)
options=$(cluset --groupsources --quiet)
;;
--color)
options="never always auto"
;;
-R|--worker)
options="ssh exec rsh"
;;
# no-arg options
--version|-h|--help|-n|--nostdin|-a|--all|-q|--quiet|\
-v|--verbose|-d|--debug|-c|--copy|--rcopy) ;;
# any other option: ignore next word (likely argument)
-*)
return;;
esac
# new option or no option:
if [ -z "$options" ]; then
case "$cur" in
-*)
# starts with dash - get all options from help text...
options="$(clush --help | grep -oP -- '(?<=[ \t])(-[a-z]|--[^= \t]*)')"
;;
*)
# otherwise complete command or file if appropriate and stop here
_clush_command_or_file
return
esac
fi
# append space for everything that doesn't end in `:` (likely a groupsource)
mapfile -t COMPREPLY < <(compgen -W "$options" -- "$cur" | sed -e 's/[^:]$/& /')
# remove the prefix from COMPREPLY if $cur contains colons and
# COMP_WORDBREAKS splits on colons...
__ltrim_colon_completions "$cur"
} && complete -o nospace -F _clush "${BASH_SOURCE##*/}"