-
Notifications
You must be signed in to change notification settings - Fork 374
Expand file tree
/
Copy pathtestMathBashCompletionScript().bash
More file actions
278 lines (247 loc) · 8.73 KB
/
testMathBashCompletionScript().bash
File metadata and controls
278 lines (247 loc) · 8.73 KB
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#!/bin/bash
__math_cursor_index_in_current_word() {
local remaining="${COMP_LINE}"
local word
for word in "${COMP_WORDS[@]::COMP_CWORD}"; do
remaining="${remaining##*([[:space:]])"${word}"*([[:space:]])}"
done
local -ir index="$((COMP_POINT - ${#COMP_LINE} + ${#remaining}))"
if [[ "${index}" -le 0 ]]; then
printf 0
else
printf %s "${index}"
fi
}
# positional arguments:
#
# - 1: the current (sub)command's count of positional arguments
#
# required variables:
#
# - flags: the flags that the current (sub)command can accept
# - options: the options that the current (sub)command can accept
# - positional_number: value ignored
# - unparsed_words: unparsed words from the current command line
#
# modified variables:
#
# - flags: remove flags for this (sub)command that are already on the command line
# - options: remove options for this (sub)command that are already on the command line
# - positional_number: set to the current positional number
# - unparsed_words: remove all flags, options, and option values for this (sub)command
__math_offer_flags_options() {
local -ir positional_count="${1}"
positional_number=0
local was_flag_option_terminator_seen=false
local is_parsing_option_value=false
local -ar unparsed_word_indices=("${!unparsed_words[@]}")
local -i word_index
for word_index in "${unparsed_word_indices[@]}"; do
if "${is_parsing_option_value}"; then
# This word is an option value:
# Reset marker for next word iff not currently the last word
[[ "${word_index}" -ne "${unparsed_word_indices[${#unparsed_word_indices[@]} - 1]}" ]] && is_parsing_option_value=false
unset "unparsed_words[${word_index}]"
# Do not process this word as a flag or an option
continue
fi
local word="${unparsed_words["${word_index}"]}"
if ! "${was_flag_option_terminator_seen}"; then
case "${word}" in
--)
unset "unparsed_words[${word_index}]"
# by itself -- is a flag/option terminator, but if it is the last word, it is the start of a completion
if [[ "${word_index}" -ne "${unparsed_word_indices[${#unparsed_word_indices[@]} - 1]}" ]]; then
was_flag_option_terminator_seen=true
fi
continue
;;
-*)
# ${word} is a flag or an option
# If ${word} is an option, mark that the next word to be parsed is an option value
local option
for option in "${options[@]}"; do
[[ "${word}" = "${option}" ]] && is_parsing_option_value=true && break
done
# Remove ${word} from ${flags} or ${options} so it isn't offered again
local not_found=true
local -i index
for index in "${!flags[@]}"; do
if [[ "${flags[${index}]}" = "${word}" ]]; then
unset "flags[${index}]"
flags=("${flags[@]}")
not_found=false
break
fi
done
if "${not_found}"; then
for index in "${!options[@]}"; do
if [[ "${options[${index}]}" = "${word}" ]]; then
unset "options[${index}]"
options=("${options[@]}")
break
fi
done
fi
unset "unparsed_words[${word_index}]"
continue
;;
esac
fi
# ${word} is neither a flag, nor an option, nor an option value
if [[ "${positional_number}" -lt "${positional_count}" ]]; then
# ${word} is a positional
((positional_number++))
unset "unparsed_words[${word_index}]"
else
if [[ -z "${word}" ]]; then
# Could be completing a flag, option, or subcommand
positional_number=-1
else
# ${word} is a subcommand or invalid, so stop processing this (sub)command
positional_number=-2
fi
break
fi
done
unparsed_words=("${unparsed_words[@]}")
if\
! "${was_flag_option_terminator_seen}"\
&& ! "${is_parsing_option_value}"\
&& [[ ("${cur}" = -* && "${positional_number}" -ge 0) || "${positional_number}" -eq -1 ]]
then
COMPREPLY+=($(compgen -W "${flags[*]} ${options[*]}" -- "${cur}"))
fi
}
__math_add_completions() {
local completion
while IFS='' read -r completion; do
COMPREPLY+=("${completion}")
done < <(IFS=$'\n' compgen "${@}" -- "${cur}")
}
__math_custom_complete() {
if [[ -n "${cur}" || -z ${COMP_WORDS[${COMP_CWORD}]} || "${COMP_LINE:${COMP_POINT}:1}" != ' ' ]]; then
local -ar words=("${COMP_WORDS[@]}")
else
local -ar words=("${COMP_WORDS[@]::${COMP_CWORD}}" '' "${COMP_WORDS[@]:${COMP_CWORD}}")
fi
"${COMP_WORDS[0]}" "${@}" "${words[@]}"
}
_math() {
trap "$(shopt -p);$(shopt -po)" RETURN
shopt -s extglob
set +o history +o posix
local -xr SAP_SHELL=bash
local -x SAP_SHELL_VERSION
SAP_SHELL_VERSION="$(IFS='.';printf %s "${BASH_VERSINFO[*]}")"
local -r SAP_SHELL_VERSION
local -r cur="${2}"
local -r prev="${3}"
local -i positional_number
local -a unparsed_words=("${COMP_WORDS[@]:1:${COMP_CWORD}}")
local -a flags=(--version -h --help)
local -a options=()
__math_offer_flags_options 0
# Offer subcommand / subcommand argument completions
local -r subcommand="${unparsed_words[0]}"
unset 'unparsed_words[0]'
unparsed_words=("${unparsed_words[@]}")
case "${subcommand}" in
add|multiply|stats|help)
# Offer subcommand argument completions
"_math_${subcommand}"
;;
*)
# Offer subcommand completions
COMPREPLY+=($(compgen -W 'add multiply stats help' -- "${cur}"))
;;
esac
}
_math_add() {
flags=(--hex-output -x --version -h --help)
options=()
__math_offer_flags_options 1
}
_math_multiply() {
flags=(--hex-output -x --version -h --help)
options=()
__math_offer_flags_options 1
}
_math_stats() {
flags=(--version -h --help)
options=()
__math_offer_flags_options 0
# Offer subcommand / subcommand argument completions
local -r subcommand="${unparsed_words[0]}"
unset 'unparsed_words[0]'
unparsed_words=("${unparsed_words[@]}")
case "${subcommand}" in
average|stdev|quantiles)
# Offer subcommand argument completions
"_math_stats_${subcommand}"
;;
*)
# Offer subcommand completions
COMPREPLY+=($(compgen -W 'average stdev quantiles' -- "${cur}"))
;;
esac
}
_math_stats_average() {
flags=(--version -h --help)
options=(--kind)
__math_offer_flags_options 1
# Offer option value completions
case "${prev}" in
'--kind')
__math_add_completions -W 'mean'$'\n''median'$'\n''mode'
return
;;
esac
}
_math_stats_stdev() {
flags=(--version -h --help)
options=()
__math_offer_flags_options 1
}
_math_stats_quantiles() {
flags=(--version -h --help)
options=(--file --one-of-four --custom-arg --custom-deprecated-arg --shell --custom --custom-deprecated)
__math_offer_flags_options 1
# Offer option value completions
case "${prev}" in
'--file')
__math_add_completions -o plusdirs -fX '!*.@(txt|md)'
return
;;
'--one-of-four')
__math_add_completions -W 'alphabet'$'\n''alligator'$'\n''branch'$'\n''braggart'
return
;;
'--custom-arg')
__math_add_completions -W "$(__math_custom_complete ---completion stats quantiles -- --custom-arg "${COMP_CWORD}" "$(__math_cursor_index_in_current_word)")"
return
;;
'--custom-deprecated-arg')
__math_add_completions -W "$(__math_custom_complete ---completion stats quantiles -- --custom-deprecated-arg)"
return
;;
'--shell')
__math_add_completions -W "$(eval 'head -100 '\''/usr/share/dict/words'\'' | tail -50')"
return
;;
'--custom')
__math_add_completions -W "$(__math_custom_complete ---completion stats quantiles -- --custom "${COMP_CWORD}" "$(__math_cursor_index_in_current_word)")"
return
;;
'--custom-deprecated')
__math_add_completions -W "$(__math_custom_complete ---completion stats quantiles -- --custom-deprecated)"
return
;;
esac
}
_math_help() {
flags=(--version)
options=()
__math_offer_flags_options 1
}
complete -o filenames -F _math math