1# bash completion for git-bug -*- shell-script -*-
2
3__git-bug_debug()
4{
5 if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
6 echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
7 fi
8}
9
10# Homebrew on Macs have version 1.3 of bash-completion which doesn't include
11# _init_completion. This is a very minimal version of that function.
12__git-bug_init_completion()
13{
14 COMPREPLY=()
15 _get_comp_words_by_ref "$@" cur prev words cword
16}
17
18__git-bug_index_of_word()
19{
20 local w word=$1
21 shift
22 index=0
23 for w in "$@"; do
24 [[ $w = "$word" ]] && return
25 index=$((index+1))
26 done
27 index=-1
28}
29
30__git-bug_contains_word()
31{
32 local w word=$1; shift
33 for w in "$@"; do
34 [[ $w = "$word" ]] && return
35 done
36 return 1
37}
38
39__git-bug_handle_reply()
40{
41 __git-bug_debug "${FUNCNAME[0]}"
42 case $cur in
43 -*)
44 if [[ $(type -t compopt) = "builtin" ]]; then
45 compopt -o nospace
46 fi
47 local allflags
48 if [ ${#must_have_one_flag[@]} -ne 0 ]; then
49 allflags=("${must_have_one_flag[@]}")
50 else
51 allflags=("${flags[*]} ${two_word_flags[*]}")
52 fi
53 COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") )
54 if [[ $(type -t compopt) = "builtin" ]]; then
55 [[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace
56 fi
57
58 # complete after --flag=abc
59 if [[ $cur == *=* ]]; then
60 if [[ $(type -t compopt) = "builtin" ]]; then
61 compopt +o nospace
62 fi
63
64 local index flag
65 flag="${cur%=*}"
66 __git-bug_index_of_word "${flag}" "${flags_with_completion[@]}"
67 COMPREPLY=()
68 if [[ ${index} -ge 0 ]]; then
69 PREFIX=""
70 cur="${cur#*=}"
71 ${flags_completion[${index}]}
72 if [ -n "${ZSH_VERSION}" ]; then
73 # zsh completion needs --flag= prefix
74 eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
75 fi
76 fi
77 fi
78 return 0;
79 ;;
80 esac
81
82 # check if we are handling a flag with special work handling
83 local index
84 __git-bug_index_of_word "${prev}" "${flags_with_completion[@]}"
85 if [[ ${index} -ge 0 ]]; then
86 ${flags_completion[${index}]}
87 return
88 fi
89
90 # we are parsing a flag and don't have a special handler, no completion
91 if [[ ${cur} != "${words[cword]}" ]]; then
92 return
93 fi
94
95 local completions
96 completions=("${commands[@]}")
97 if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then
98 completions=("${must_have_one_noun[@]}")
99 fi
100 if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then
101 completions+=("${must_have_one_flag[@]}")
102 fi
103 COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") )
104
105 if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then
106 COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") )
107 fi
108
109 if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
110 declare -F __custom_func >/dev/null && __custom_func
111 fi
112
113 # available in bash-completion >= 2, not always present on macOS
114 if declare -F __ltrim_colon_completions >/dev/null; then
115 __ltrim_colon_completions "$cur"
116 fi
117
118 # If there is only 1 completion and it is a flag with an = it will be completed
119 # but we don't want a space after the =
120 if [[ "${#COMPREPLY[@]}" -eq "1" ]] && [[ $(type -t compopt) = "builtin" ]] && [[ "${COMPREPLY[0]}" == --*= ]]; then
121 compopt -o nospace
122 fi
123}
124
125# The arguments should be in the form "ext1|ext2|extn"
126__git-bug_handle_filename_extension_flag()
127{
128 local ext="$1"
129 _filedir "@(${ext})"
130}
131
132__git-bug_handle_subdirs_in_dir_flag()
133{
134 local dir="$1"
135 pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
136}
137
138__git-bug_handle_flag()
139{
140 __git-bug_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
141
142 # if a command required a flag, and we found it, unset must_have_one_flag()
143 local flagname=${words[c]}
144 local flagvalue
145 # if the word contained an =
146 if [[ ${words[c]} == *"="* ]]; then
147 flagvalue=${flagname#*=} # take in as flagvalue after the =
148 flagname=${flagname%=*} # strip everything after the =
149 flagname="${flagname}=" # but put the = back
150 fi
151 __git-bug_debug "${FUNCNAME[0]}: looking for ${flagname}"
152 if __git-bug_contains_word "${flagname}" "${must_have_one_flag[@]}"; then
153 must_have_one_flag=()
154 fi
155
156 # if you set a flag which only applies to this command, don't show subcommands
157 if __git-bug_contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
158 commands=()
159 fi
160
161 # keep flag value with flagname as flaghash
162 # flaghash variable is an associative array which is only supported in bash > 3.
163 if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
164 if [ -n "${flagvalue}" ] ; then
165 flaghash[${flagname}]=${flagvalue}
166 elif [ -n "${words[ $((c+1)) ]}" ] ; then
167 flaghash[${flagname}]=${words[ $((c+1)) ]}
168 else
169 flaghash[${flagname}]="true" # pad "true" for bool flag
170 fi
171 fi
172
173 # skip the argument to a two word flag
174 if __git-bug_contains_word "${words[c]}" "${two_word_flags[@]}"; then
175 c=$((c+1))
176 # if we are looking for a flags value, don't show commands
177 if [[ $c -eq $cword ]]; then
178 commands=()
179 fi
180 fi
181
182 c=$((c+1))
183
184}
185
186__git-bug_handle_noun()
187{
188 __git-bug_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
189
190 if __git-bug_contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
191 must_have_one_noun=()
192 elif __git-bug_contains_word "${words[c]}" "${noun_aliases[@]}"; then
193 must_have_one_noun=()
194 fi
195
196 nouns+=("${words[c]}")
197 c=$((c+1))
198}
199
200__git-bug_handle_command()
201{
202 __git-bug_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
203
204 local next_command
205 if [[ -n ${last_command} ]]; then
206 next_command="_${last_command}_${words[c]//:/__}"
207 else
208 if [[ $c -eq 0 ]]; then
209 next_command="_git-bug_root_command"
210 else
211 next_command="_${words[c]//:/__}"
212 fi
213 fi
214 c=$((c+1))
215 __git-bug_debug "${FUNCNAME[0]}: looking for ${next_command}"
216 declare -F "$next_command" >/dev/null && $next_command
217}
218
219__git-bug_handle_word()
220{
221 if [[ $c -ge $cword ]]; then
222 __git-bug_handle_reply
223 return
224 fi
225 __git-bug_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
226 if [[ "${words[c]}" == -* ]]; then
227 __git-bug_handle_flag
228 elif __git-bug_contains_word "${words[c]}" "${commands[@]}"; then
229 __git-bug_handle_command
230 elif [[ $c -eq 0 ]]; then
231 __git-bug_handle_command
232 elif __git-bug_contains_word "${words[c]}" "${command_aliases[@]}"; then
233 # aliashash variable is an associative array which is only supported in bash > 3.
234 if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
235 words[c]=${aliashash[${words[c]}]}
236 __git-bug_handle_command
237 else
238 __git-bug_handle_noun
239 fi
240 else
241 __git-bug_handle_noun
242 fi
243 __git-bug_handle_word
244}
245
246
247_git_bug() {
248 __start_git-bug "$@"
249}
250
251_git-bug_close()
252{
253 last_command="git-bug_close"
254
255 command_aliases=()
256
257 commands=()
258
259 flags=()
260 two_word_flags=()
261 local_nonpersistent_flags=()
262 flags_with_completion=()
263 flags_completion=()
264
265
266 must_have_one_flag=()
267 must_have_one_noun=()
268 noun_aliases=()
269}
270
271_git-bug_commands()
272{
273 last_command="git-bug_commands"
274
275 command_aliases=()
276
277 commands=()
278
279 flags=()
280 two_word_flags=()
281 local_nonpersistent_flags=()
282 flags_with_completion=()
283 flags_completion=()
284
285 flags+=("--pretty")
286 flags+=("-p")
287 local_nonpersistent_flags+=("--pretty")
288
289 must_have_one_flag=()
290 must_have_one_noun=()
291 noun_aliases=()
292}
293
294_git-bug_comment()
295{
296 last_command="git-bug_comment"
297
298 command_aliases=()
299
300 commands=()
301
302 flags=()
303 two_word_flags=()
304 local_nonpersistent_flags=()
305 flags_with_completion=()
306 flags_completion=()
307
308 flags+=("--file=")
309 two_word_flags+=("-F")
310 local_nonpersistent_flags+=("--file=")
311 flags+=("--message=")
312 two_word_flags+=("-m")
313 local_nonpersistent_flags+=("--message=")
314
315 must_have_one_flag=()
316 must_have_one_noun=()
317 noun_aliases=()
318}
319
320_git-bug_label()
321{
322 last_command="git-bug_label"
323
324 command_aliases=()
325
326 commands=()
327
328 flags=()
329 two_word_flags=()
330 local_nonpersistent_flags=()
331 flags_with_completion=()
332 flags_completion=()
333
334 flags+=("--remove")
335 flags+=("-r")
336 local_nonpersistent_flags+=("--remove")
337
338 must_have_one_flag=()
339 must_have_one_noun=()
340 noun_aliases=()
341}
342
343_git-bug_ls()
344{
345 last_command="git-bug_ls"
346
347 command_aliases=()
348
349 commands=()
350
351 flags=()
352 two_word_flags=()
353 local_nonpersistent_flags=()
354 flags_with_completion=()
355 flags_completion=()
356
357
358 must_have_one_flag=()
359 must_have_one_noun=()
360 noun_aliases=()
361}
362
363_git-bug_new()
364{
365 last_command="git-bug_new"
366
367 command_aliases=()
368
369 commands=()
370
371 flags=()
372 two_word_flags=()
373 local_nonpersistent_flags=()
374 flags_with_completion=()
375 flags_completion=()
376
377 flags+=("--file=")
378 two_word_flags+=("-F")
379 local_nonpersistent_flags+=("--file=")
380 flags+=("--message=")
381 two_word_flags+=("-m")
382 local_nonpersistent_flags+=("--message=")
383 flags+=("--title=")
384 two_word_flags+=("-t")
385 local_nonpersistent_flags+=("--title=")
386
387 must_have_one_flag=()
388 must_have_one_noun=()
389 noun_aliases=()
390}
391
392_git-bug_open()
393{
394 last_command="git-bug_open"
395
396 command_aliases=()
397
398 commands=()
399
400 flags=()
401 two_word_flags=()
402 local_nonpersistent_flags=()
403 flags_with_completion=()
404 flags_completion=()
405
406
407 must_have_one_flag=()
408 must_have_one_noun=()
409 noun_aliases=()
410}
411
412_git-bug_pull()
413{
414 last_command="git-bug_pull"
415
416 command_aliases=()
417
418 commands=()
419
420 flags=()
421 two_word_flags=()
422 local_nonpersistent_flags=()
423 flags_with_completion=()
424 flags_completion=()
425
426
427 must_have_one_flag=()
428 must_have_one_noun=()
429 noun_aliases=()
430}
431
432_git-bug_push()
433{
434 last_command="git-bug_push"
435
436 command_aliases=()
437
438 commands=()
439
440 flags=()
441 two_word_flags=()
442 local_nonpersistent_flags=()
443 flags_with_completion=()
444 flags_completion=()
445
446
447 must_have_one_flag=()
448 must_have_one_noun=()
449 noun_aliases=()
450}
451
452_git-bug_show()
453{
454 last_command="git-bug_show"
455
456 command_aliases=()
457
458 commands=()
459
460 flags=()
461 two_word_flags=()
462 local_nonpersistent_flags=()
463 flags_with_completion=()
464 flags_completion=()
465
466
467 must_have_one_flag=()
468 must_have_one_noun=()
469 noun_aliases=()
470}
471
472_git-bug_termui()
473{
474 last_command="git-bug_termui"
475
476 command_aliases=()
477
478 commands=()
479
480 flags=()
481 two_word_flags=()
482 local_nonpersistent_flags=()
483 flags_with_completion=()
484 flags_completion=()
485
486
487 must_have_one_flag=()
488 must_have_one_noun=()
489 noun_aliases=()
490}
491
492_git-bug_webui()
493{
494 last_command="git-bug_webui"
495
496 command_aliases=()
497
498 commands=()
499
500 flags=()
501 two_word_flags=()
502 local_nonpersistent_flags=()
503 flags_with_completion=()
504 flags_completion=()
505
506 flags+=("--port=")
507 two_word_flags+=("-p")
508 local_nonpersistent_flags+=("--port=")
509
510 must_have_one_flag=()
511 must_have_one_noun=()
512 noun_aliases=()
513}
514
515_git-bug_root_command()
516{
517 last_command="git-bug"
518
519 command_aliases=()
520
521 commands=()
522 commands+=("close")
523 commands+=("commands")
524 commands+=("comment")
525 commands+=("label")
526 commands+=("ls")
527 commands+=("new")
528 commands+=("open")
529 commands+=("pull")
530 commands+=("push")
531 commands+=("show")
532 commands+=("termui")
533 commands+=("webui")
534
535 flags=()
536 two_word_flags=()
537 local_nonpersistent_flags=()
538 flags_with_completion=()
539 flags_completion=()
540
541
542 must_have_one_flag=()
543 must_have_one_noun=()
544 noun_aliases=()
545}
546
547__start_git-bug()
548{
549 local cur prev words cword
550 declare -A flaghash 2>/dev/null || :
551 declare -A aliashash 2>/dev/null || :
552 if declare -F _init_completion >/dev/null 2>&1; then
553 _init_completion -s || return
554 else
555 __git-bug_init_completion -n "=" || return
556 fi
557
558 local c=0
559 local flags=()
560 local two_word_flags=()
561 local local_nonpersistent_flags=()
562 local flags_with_completion=()
563 local flags_completion=()
564 local commands=("git-bug")
565 local must_have_one_flag=()
566 local must_have_one_noun=()
567 local last_command
568 local nouns=()
569
570 __git-bug_handle_word
571}
572
573if [[ $(type -t compopt) = "builtin" ]]; then
574 complete -o default -F __start_git-bug git-bug
575else
576 complete -o default -o nospace -F __start_git-bug git-bug
577fi
578
579# ex: ts=4 sw=4 et filetype=sh