Skip to content

Commit 1590ccd

Browse files
committed
Improved bash completion, parses help.
1 parent 862687f commit 1590ccd

File tree

1 file changed

+94
-50
lines changed

1 file changed

+94
-50
lines changed

dev/generate-completion-scripts.pl

Lines changed: 94 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -99,65 +99,109 @@
9999
my %IS_AN_ALIAS = map { $_ => 1 } map { @$_ } values %OPTION_ALIASES;
100100

101101
my $BASH_TEMPLATE = <<'END_TEMPLATE';
102-
declare -g -a _ack_options
103-
declare -g -a _ack_types=()
102+
_ack() {
103+
local cur prev prog split=false
104+
cur=$(_get_cword "=")
105+
prev="${COMP_WORDS[COMP_CWORD-1]}"
106+
prog="${COMP_WORDS[0]}"
107+
COMPREPLY=()
104108
105-
_ack_options=(
106-
[% FOREACH option IN options -%]
107-
"[% option -%]" \
108-
[% END -%]
109-
)
110-
111-
function __setup_ack() {
112-
local type
113-
114-
while read LINE; do
115-
case $LINE in
116-
--*)
117-
type="${LINE%% *}"
118-
type=${type/--\[no\]/}
119-
_ack_options[ ${#_ack_options[@]} ]="--$type"
120-
_ack_options[ ${#_ack_options[@]} ]="--no$type"
121-
_ack_types[ ${#_ack_types[@]} ]="$type"
122-
;;
123-
esac
124-
done < <(ack --help-types)
125-
}
126-
__setup_ack
127-
unset -f __setup_ack
109+
_expand || return 0
128110
129-
function _ack_complete() {
130-
local current_word
131-
local pattern
111+
# Once user writes '--', just file completion after PATTERN
112+
[ "$prev" = "--" ] && return 0
113+
for word in ${COMP_WORDS[@]}; do
114+
[ "$word" = "$prev" ] && break
115+
[ "$word" = "--" ] && _filedir && return 0
116+
done
132117
133-
current_word=${COMP_WORDS[$COMP_CWORD]}
134-
135-
if [[ "$current_word" == -* ]]; then
136-
pattern="${current_word}*"
137-
for option in ${_ack_options[@]}; do
138-
if [[ "$option" == $pattern ]]; then
139-
COMPREPLY[ ${#COMPREPLY[@]} ]=$option
118+
local opts types
119+
if [ "${__COMP_CACHE_ACK}x" = "x" ]; then
120+
for i in $("$prog" --help); do
121+
i=${i%%=*}
122+
if [ "${i:0:6}" = '--[no]' ]; then
123+
i="${i#--\[no\]}"
124+
opts="$opts --no$i --$i"
125+
elif [[ "$i" =~ ^-[a-zA-Z0-9?-]+,? ]]; then
126+
opts="$opts ${i//[\[.,\'\"]}"
127+
fi
128+
done
129+
for t in $("$prog" --help-types); do
130+
if [ "${t:0:6}" = '--[no]' ]; then
131+
t="${t#--\[no\]}"
132+
opts="$opts --no$t --$t"
133+
types="$types no$t $t"
140134
fi
141135
done
136+
__COMP_CACHE_ACK=( "$opts" "$types" )
137+
export __COMP_CACHE_ACK
142138
else
143-
local previous_word
144-
previous_word=${COMP_WORDS[$(( $COMP_CWORD - 1 ))]}
145-
if [[ "$previous_word" == "=" ]]; then
146-
previous_word=${COMP_WORDS[$(( $COMP_CWORD - 2 ))]}
147-
fi
148-
149-
if [ "$previous_word" == '--type' -o "$previous_word" == '--notype' ]; then
150-
pattern="${current_word}*"
151-
for type in ${_ack_types[@]}; do
152-
if [[ "$type" == $pattern ]]; then
153-
COMPREPLY[ ${#COMPREPLY[@]} ]=$type
154-
fi
155-
done
156-
fi
139+
opts="${__COMP_CACHE_ACK[0]}"
140+
types="${__COMP_CACHE_ACK[1]}"
157141
fi
142+
143+
_split_longopt && split=true
144+
145+
case "${prev}" in
146+
# directory completion
147+
--ignore-dir*)
148+
_filedir -d
149+
return 0
150+
;;
151+
# file completion
152+
--ackrc|--files-from)
153+
_filedir
154+
return 0
155+
;;
156+
# command completion
157+
--pager)
158+
COMPREPLY=( $(compgen -c -- "${cur}") )
159+
return 0
160+
;;
161+
# search type completion
162+
--type)
163+
COMPREPLY=( $(compgen -W "${types}" -- "${cur}") )
164+
return 0
165+
;;
166+
# color completion
167+
--color-*)
168+
local colors="
169+
black on_black
170+
blue on_blue
171+
cyan on_cyan
172+
green on_green
173+
magenta on_magenta
174+
red on_red
175+
white on_white
176+
yellow on_yellow
177+
"
178+
COMPREPLY=( $(compgen -W "${colors}" -- "${cur}") )
179+
return 0
180+
;;
181+
# require args, no completion
182+
-[ABCGgm]|--*context|--color|--colour|--ignore-file|\
183+
--lines|--match|--max-count|--output|--type-*)
184+
return 0
185+
;;
186+
esac
187+
188+
$split && return 0
189+
190+
case "${cur}" in
191+
-*)
192+
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
193+
return 0
194+
;;
195+
*)
196+
_filedir
197+
return 0
198+
;;
199+
esac
158200
}
159201
160-
complete -o default -F _ack_complete ack ack2 ack-grep
202+
for i in "ack" "ack2" "ack-grep" "ack-standalone"; do
203+
have "$i" && complete -F _ack ${nospace} "$i"
204+
done
161205
END_TEMPLATE
162206

163207
my $ZSH_TEMPLATE = <<'END_TEMPLATE';

0 commit comments

Comments
 (0)