tig-2.1.1
[tig.git] / contrib / tig-completion.bash
blob67303ec0a7cd3677e5e8f54d9493e3ac4c65bd35
1 ##
2 # bash completion support for tig
4 # Copyright (C) 2007-2010 Jonas fonseca
5 # Copyright (C) 2006,2007 Shawn Pearce
7 # Based git's git-completion.sh: http://repo.or.cz/w/git/fastimport.git
9 # The contained completion routines provide support for completing:
11 # *) local and remote branch names
12 # *) local and remote tag names
13 # *) tig 'subcommands'
14 # *) tree paths within 'ref:path/to/file' expressions
16 # To use these routines:
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
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.
29 __tigdir ()
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
39 elif [ -d "$1/.git" ]; then
40 echo "$1/.git"
41 else
42 echo "$1"
46 _tigcomp ()
48 local all c s=$'\n' IFS=' '$'\t'$'\n'
49 local cur="${COMP_WORDS[COMP_CWORD]}"
50 if [ $# -gt 2 ]; then
51 cur="$3"
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
65 __tig_refs ()
67 local cmd i is_hash=y dir="$(__tigdir "$1")"
68 if [ -d "$dir" ]; then
69 for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
70 if [ -e "$dir/$i" ]; then echo $i; fi
71 done
72 for i in $(git --git-dir="$dir" \
73 for-each-ref --format='%(refname)' \
74 refs/tags refs/heads refs/remotes); do
75 case "$i" in
76 refs/tags/*) echo "${i#refs/tags/}" ;;
77 refs/heads/*) echo "${i#refs/heads/}" ;;
78 refs/remotes/*) echo "${i#refs/remotes/}" ;;
79 *) echo "$i" ;;
80 esac
81 done
82 return
84 for i in $(git-ls-remote "$dir" 2>/dev/null); do
85 case "$is_hash,$i" in
86 y,*) is_hash=n ;;
87 n,*^{}) is_hash=y ;;
88 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
89 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
90 n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
91 n,*) is_hash=y; echo "$i" ;;
92 esac
93 done
96 __tig_complete_file ()
98 local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
99 case "$cur" in
100 ?*:*)
101 ref="${cur%%:*}"
102 cur="${cur#*:}"
103 case "$cur" in
104 ?*/*)
105 pfx="${cur%/*}"
106 cur="${cur##*/}"
107 ls="$ref:$pfx"
108 pfx="$pfx/"
111 ls="$ref"
113 esac
114 COMPREPLY=($(compgen -P "$pfx" \
115 -W "$(git --git-dir="$(__tigdir)" ls-tree "$ls" \
116 | sed '/^100... blob /s,^.* ,,
117 /^040000 tree /{
118 s,^.* ,,
119 s,$,/,
121 s/^.* //')" \
122 -- "$cur"))
125 _tigcomp "$(__tig_refs)"
127 esac
130 __tig_complete_revlist ()
132 local pfx cur="${COMP_WORDS[COMP_CWORD]}"
133 case "$cur" in
134 *...*)
135 pfx="${cur%...*}..."
136 cur="${cur#*...}"
137 _tigcomp "$(__tig_refs)" "$pfx" "$cur"
139 *..*)
140 pfx="${cur%..*}.."
141 cur="${cur#*..}"
142 _tigcomp "$(__tig_refs)" "$pfx" "$cur"
145 _tigcomp "$cur."
148 _tigcomp "$(__tig_refs)"
150 esac
153 _tig_options ()
155 local cur="${COMP_WORDS[COMP_CWORD]}"
156 case "$cur" in
157 --pretty=*)
158 _tigcomp "
159 oneline short medium full fuller email raw
160 " "" "${cur##--pretty=}"
161 return
163 --*)
164 _tigcomp "
165 --max-count= --max-age= --since= --after=
166 --min-age= --before= --until=
167 --root --not --topo-order --date-order
168 --no-merges
169 --abbrev-commit --abbrev=
170 --relative-date
171 --author= --committer= --grep=
172 --all-match
173 --pretty= --name-status --name-only
174 --not --all
175 --help --version
177 return
180 _tigcomp "-v -h"
181 return
183 esac
184 __tig_complete_revlist
187 _tig_blame ()
189 local reply="" ref=HEAD cur="${COMP_WORDS[COMP_CWORD]}" p=""
190 local pfx=$(git rev-parse --show-prefix 2>/dev/null)
192 if test "$COMP_CWORD" -lt 3; then
193 _tigcomp "$(__tig_refs)"
194 else
195 ref="${COMP_WORDS[2]}"
198 case "$cur" in
199 */) p=${cur%/} ;;
200 */*) p=${cur%/*} ;;
201 *) p= ;;
202 esac
204 i=${#COMPREPLY[@]}
205 local IFS=$'\n'
206 for c in $(git --git-dir="$(__tigdir)" ls-tree "$ref:$pfx$p" 2>/dev/null |
207 sed -n '/^100... blob /{
208 s,^.* ,,
209 s,$, ,
212 /^040000 tree /{
213 s,^.* ,,
214 s,$,/,
218 c="${p:+$p/}$c"
219 if [[ "$c" == "$cur"* ]]; then
220 COMPREPLY[i++]=$c
222 done
225 _tig_show ()
227 local cur="${COMP_WORDS[COMP_CWORD]}"
228 case "$cur" in
229 --pretty=*)
230 _tigcomp "
231 oneline short medium full fuller email raw
232 " "" "${cur##--pretty=}"
233 return
235 --*)
236 _tigcomp "--pretty="
237 return
239 esac
240 __tig_complete_file
243 _tig ()
245 local i c=1 command __tig_dir
247 while [ $c -lt $COMP_CWORD ]; do
248 i="${COMP_WORDS[c]}"
249 case "$i" in
250 --) command="log"; break;;
251 -*) ;;
252 *) command="$i"; break ;;
253 esac
254 c=$((++c))
255 done
257 if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
258 case "${COMP_WORDS[COMP_CWORD]}" in
259 --*=*) COMPREPLY=() ;;
260 -*) _tig_options ;;
261 *) _tigcomp "blame status show log stash grep $(__tig_refs)" ;;
262 esac
263 return
266 case "$command" in
267 blame) _tig_blame ;;
268 show) _tig_show ;;
269 status) ;;
270 *) _tigcomp "
271 $(__tig_complete_file)
272 $(__tig_refs)
273 " ;;
274 esac
277 # Detect if current shell is ZSH, and if so, load this file in bash
278 # compatibility mode.
279 if [ -n "$ZSH_VERSION" ]; then
280 autoload bashcompinit
281 bashcompinit
284 complete -o default -o nospace -F _tig tig
286 # The following are necessary only for Cygwin, and only are needed
287 # when the user has tab-completed the executable name and consequently
288 # included the '.exe' suffix.
289 if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
290 complete -o default -o nospace -F _tig tig.exe