Simplify subcommand option parsing by moving it out of the loop
[tig] / contrib / tig-completion.bash
CommitLineData
d195d49e
JF
1##
2# bash completion support for tig
3#
4# Copyright (C) 2007 Jonas fonseca
5# Copyright (C) 2006,2007 Shawn Pearce
6#
7# Based git's git-completion.sh: http://repo.or.cz/w/git/fastimport.git
8#
9# The contained completion routines provide support for completing:
10#
11# *) local and remote branch names
12# *) local and remote tag names
13# *) tig 'subcommands'
14# *) tree paths within 'ref:path/to/file' expressions
15#
16# To use these routines:
17#
18# 1) Copy this file to somewhere (e.g. ~/.tig-completion.sh).
19# 2) Added the following line to your .bashrc:
20# source ~/.tig-completion.sh
21#
22# 3) You may want to make sure the git executable is available
23# in your PATH before this script is sourced, as some caching
24# is performed while the script loads. If git isn't found
25# at source time then all lookups will be done on demand,
26# which may be slightly slower.
27#
28
29__tigdir ()
30{
31 if [ -z "$1" ]; then
32 if [ -n "$__git_dir" ]; then
33 echo "$__git_dir"
34 elif [ -d .git ]; then
35 echo .git
36 else
37 git rev-parse --git-dir 2>/dev/null
38 fi
39 elif [ -d "$1/.git" ]; then
40 echo "$1/.git"
41 else
42 echo "$1"
43 fi
44}
45
77452abc 46_tigcomp ()
d195d49e
JF
47{
48 local all c s=$'\n' IFS=' '$'\t'$'\n'
49 local cur="${COMP_WORDS[COMP_CWORD]}"
50 if [ $# -gt 2 ]; then
51 cur="$3"
52 fi
53 for c in $1; do
54 case "$c$4" in
55 --*=*) all="$all$c$4$s" ;;
56 *.) all="$all$c$4$s" ;;
57 *) all="$all$c$4 $s" ;;
58 esac
59 done
60 IFS=$s
61 COMPREPLY=($(compgen -P "$2" -W "$all" -- "$cur"))
62 return
63}
64
65__tig_refs ()
66{
67 local cmd i is_hash=y dir="$(__tigdir "$1")"
68 if [ -d "$dir" ]; then
69 if [ -e "$dir/HEAD" ]; then echo HEAD; fi
70 for i in $(git --git-dir="$dir" \
71 for-each-ref --format='%(refname)' \
72 refs/tags refs/heads refs/remotes); do
73 case "$i" in
74 refs/tags/*) echo "${i#refs/tags/}" ;;
75 refs/heads/*) echo "${i#refs/heads/}" ;;
76 refs/remotes/*) echo "${i#refs/remotes/}" ;;
77 *) echo "$i" ;;
78 esac
79 done
80 return
81 fi
82 for i in $(git-ls-remote "$dir" 2>/dev/null); do
83 case "$is_hash,$i" in
84 y,*) is_hash=n ;;
85 n,*^{}) is_hash=y ;;
86 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
87 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
88 n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
89 n,*) is_hash=y; echo "$i" ;;
90 esac
91 done
92}
93
94__tig_complete_file ()
95{
96 local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
97 case "$cur" in
98 ?*:*)
99 ref="${cur%%:*}"
100 cur="${cur#*:}"
101 case "$cur" in
102 ?*/*)
103 pfx="${cur%/*}"
104 cur="${cur##*/}"
105 ls="$ref:$pfx"
106 pfx="$pfx/"
107 ;;
108 *)
109 ls="$ref"
110 ;;
111 esac
112 COMPREPLY=($(compgen -P "$pfx" \
113 -W "$(git --git-dir="$(__tigdir)" ls-tree "$ls" \
114 | sed '/^100... blob /s,^.* ,,
115 /^040000 tree /{
116 s,^.* ,,
117 s,$,/,
118 }
119 s/^.* //')" \
120 -- "$cur"))
121 ;;
122 *)
77452abc 123 _tigcomp "$(__tig_refs)"
d195d49e
JF
124 ;;
125 esac
126}
127
128__tig_complete_revlist ()
129{
130 local pfx cur="${COMP_WORDS[COMP_CWORD]}"
131 case "$cur" in
132 *...*)
133 pfx="${cur%...*}..."
134 cur="${cur#*...}"
77452abc 135 _tigcomp "$(__tig_refs)" "$pfx" "$cur"
d195d49e
JF
136 ;;
137 *..*)
138 pfx="${cur%..*}.."
139 cur="${cur#*..}"
77452abc 140 _tigcomp "$(__tig_refs)" "$pfx" "$cur"
d195d49e
JF
141 ;;
142 *.)
77452abc 143 _tigcomp "$cur."
d195d49e
JF
144 ;;
145 *)
77452abc 146 _tigcomp "$(__tig_refs)"
d195d49e
JF
147 ;;
148 esac
149}
150
77452abc 151_tig_options ()
d195d49e
JF
152{
153 local cur="${COMP_WORDS[COMP_CWORD]}"
154 case "$cur" in
155 --pretty=*)
77452abc 156 _tigcomp "
d195d49e
JF
157 oneline short medium full fuller email raw
158 " "" "${cur##--pretty=}"
159 return
160 ;;
161 --*)
77452abc 162 _tigcomp "
d195d49e
JF
163 --max-count= --max-age= --since= --after=
164 --min-age= --before= --until=
165 --root --not --topo-order --date-order
166 --no-merges
167 --abbrev-commit --abbrev=
168 --relative-date
169 --author= --committer= --grep=
170 --all-match
171 --pretty= --name-status --name-only
172 --not --all
77452abc 173 --help --version
d195d49e
JF
174 "
175 return
176 ;;
77452abc
JF
177 -*)
178 _tigcomp "-v -h"
179 return
180 ;;
d195d49e
JF
181 esac
182 __tig_complete_revlist
183}
184
185_tig_show ()
186{
187 local cur="${COMP_WORDS[COMP_CWORD]}"
188 case "$cur" in
189 --pretty=*)
77452abc 190 _tigcomp "
d195d49e
JF
191 oneline short medium full fuller email raw
192 " "" "${cur##--pretty=}"
193 return
194 ;;
195 --*)
77452abc 196 _tigcomp "--pretty="
d195d49e
JF
197 return
198 ;;
199 esac
200 __tig_complete_file
201}
202
203_tig ()
204{
205 local i c=1 command __tig_dir
206
207 while [ $c -lt $COMP_CWORD ]; do
208 i="${COMP_WORDS[c]}"
209 case "$i" in
210 --) command="log"; break;;
211 -*) ;;
212 *) command="$i"; break ;;
213 esac
214 c=$((++c))
215 done
216
217 if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
218 case "${COMP_WORDS[COMP_CWORD]}" in
219 --*=*) COMPREPLY=() ;;
77452abc
JF
220 -*) _tig_options ;;
221 *) _tigcomp "status show $(__tig_refs)" ;;
d195d49e
JF
222 esac
223 return
224 fi
225
226 case "$command" in
d195d49e 227 show) _tig_show ;;
77452abc
JF
228 status) ;;
229 *) _tigcomp "
d195d49e
JF
230 $(__tig_complete_file)
231 $(__tig_refs)
232 " ;;
233 esac
234}
235
236complete -o default -o nospace -F _tig tig
237
238# The following are necessary only for Cygwin, and only are needed
239# when the user has tab-completed the executable name and consequently
240# included the '.exe' suffix.
241if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
242complete -o default -o nospace -F _tig tig.exe
243fi