-
Notifications
You must be signed in to change notification settings - Fork 66
/
gi-completion.sh
126 lines (113 loc) · 3.78 KB
/
gi-completion.sh
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
#!/usr/bin/env bash
# shellcheck disable=SC2207
#
# Shellcheck ignore list:
# - SC2207: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
# Rationale: Required for compgen idiomatic use
#
# (C) Copyright 2018, 2019 Diomidis Spinellis
#
# This file is part of gi, the Git-based issue management system.
#
# gi is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# gi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with gi. If not, see <http://www.gnu.org/licenses/>.
#
# Autocompletes the gi subcommand sequence.
# Arguments: the current word
_gi_autocomplete_subcommand()
{
local IFS=$'\n' command_regex='^\s{3}([a-z]+)\s.*'
# parse help information for sub commands
while read -r line; do
# match only the command lines a.k.a. "gi <subcommand>: command help"
if [[ $line =~ $command_regex ]]; then
COMPREPLY+=($(compgen -W "${BASH_REMATCH[1]}" -- "$1"))
fi
done <<< "$(git issue help 2>/dev/null)"
}
# Autocompletes the gi subcommands' argument sequence.
# Arguments: the subcommand, the current word
_gi_autocomplete_subcommand_argument()
{
case $1 in
show | comment | tag | assign | attach | watcher | weight | create)
# list all issues
list_args="-a"
;;
edit | close | milestone | duedate | timeestimate | timespent)
# list only open issues
list_args=""
;;
*)
# stop completion for the rest of the sub-commands
return
esac
local IFS=$'\n' desc sha cmd gi_list
while read -r line; do
# shellcheck disable=SC2001
# SC2001: See if you can use ${variable//search/replace} instead.
# Rationale: Can't, because it doesn't handle \n
desc=($(echo "$line" | sed 's/ /\n/'))
cmd=$(compgen -W "${desc[0]}" -- "$2")
if [ -n "$cmd" ]; then
# Store the matching issues along with their description
gi_list+=($(printf '%*s' "-$COLUMNS" "$cmd - ${desc[1]}"))
fi
done <<< "$(git issue list "$list_args" 2>/dev/null)"
if [[ ${#gi_list[@]} == 1 ]]; then
# If only one match, autocomplete the sha without the description
sha="${gi_list[0]/%\ */}"
COMPREPLY+=($(compgen -W "$sha"))
else
# Display the whole sha list along with the descriptions
COMPREPLY+=("${gi_list[@]}")
fi
}
# Handles auto-completion of the gi executable.
_gi_autocomplete()
{
local word="${COMP_WORDS[COMP_CWORD]}"
local basecmd=${COMP_WORDS[0]}
local baseidx="-1"
if [ "$basecmd" = "gi" ]; then
baseidx="1"
else
basecmd="${COMP_WORDS[1]}"
if [ "$basecmd" = "issue" ]; then
baseidx="2"
else
baseidx="-1"
fi
fi
if [ "$COMP_CWORD" -ge "$baseidx" ]; then
if [ "$COMP_CWORD" -eq "$baseidx" ]; then
_gi_autocomplete_subcommand "$word"
else
local subcmd="${COMP_WORDS[$baseidx]}"
local prev_word="${COMP_WORDS[COMP_CWORD-1]}"
# completion is only implemented directly after a subcommand or after a
# subcommand's flag, that is at maximum two positions further
local max_pos=$(( "$baseidx" + "2" ))
# stop completion if we already passed the hash argument
[ "$COMP_CWORD" -gt "$max_pos" ] && return
[ "$COMP_CWORD" -eq "$max_pos" ] && [[ $prev_word != -* ]] && return
_gi_autocomplete_subcommand_argument "$subcmd" "$word"
fi
else
__git_wrap__gitk_main
fi
}
_git_issue() {
_gi_autocomplete
}
complete -F _gi_autocomplete gi