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