Teach bash to complete branch names in some places.
[stgit] / contrib / stgit-completion.bash
1 # bash completion support for StGIT -*- shell-script -*-
2 #
3 # Copyright (C) 2006, Karl Hasselström <kha@treskal.com>
4 # Based on git-completion.sh
5 #
6 # To use these routines:
7 #
8 # 1. Copy this file to somewhere (e.g. ~/.stgit-completion.bash).
9 #
10 # 2. Add the following line to your .bashrc:
11 # . ~/.stgit-completion.bash
12
13 _stg_commands="
14 add
15 applied
16 assimilate
17 branch
18 bury
19 delete
20 diff
21 clean
22 clone
23 commit
24 cp
25 export
26 files
27 float
28 fold
29 goto
30 hide
31 id
32 import
33 init
34 log
35 mail
36 new
37 patches
38 pick
39 pop
40 pull
41 push
42 rebase
43 refresh
44 rename
45 resolved
46 rm
47 series
48 show
49 status
50 sync
51 top
52 unapplied
53 uncommit
54 unhide
55 "
56
57 # The path to .git, or empty if we're not in a repository.
58 _gitdir ()
59 {
60 echo "$(git rev-parse --git-dir 2>/dev/null)"
61 }
62
63 # Name of the current branch, or empty if there isn't one.
64 _current_branch ()
65 {
66 local b=$(git symbolic-ref HEAD 2>/dev/null)
67 echo ${b#refs/heads/}
68 }
69
70 # List of all applied patches.
71 _applied_patches ()
72 {
73 local g=$(_gitdir)
74 [ "$g" ] && cat "$g/patches/$(_current_branch)/applied"
75 }
76
77 # List of all unapplied patches.
78 _unapplied_patches ()
79 {
80 local g=$(_gitdir)
81 [ "$g" ] && cat "$g/patches/$(_current_branch)/unapplied"
82 }
83
84 # List of all patches.
85 _all_patches ()
86 {
87 local b=$(_current_branch)
88 local g=$(_gitdir)
89 [ "$g" ] && cat "$g/patches/$b/applied" "$g/patches/$b/unapplied"
90 }
91
92 # List of all patches except the current patch.
93 _all_other_patches ()
94 {
95 local b=$(_current_branch)
96 local g=$(_gitdir)
97 [ "$g" ] && cat "$g/patches/$b/applied" "$g/patches/$b/unapplied" \
98 | grep -v "^$(cat $g/patches/$b/current 2> /dev/null)$"
99 }
100
101 _all_branches ()
102 {
103 local g=$(_gitdir)
104 [ "$g" ] && (cd .git/patches/ && echo *)
105 }
106
107 # List the command options
108 _cmd_options ()
109 {
110 stg $1 --help 2>/dev/null | grep -e " --[A-Za-z]" | sed -e "s/.*\(--[^ =]\+\).*/\1/"
111 }
112
113 # Generate completions for patches and patch ranges from the given
114 # patch list function, and options from the given list.
115 _complete_patch_range ()
116 {
117 local patchlist="$1" options="$2"
118 local pfx cur="${COMP_WORDS[COMP_CWORD]}"
119 case "$cur" in
120 *..*)
121 pfx="${cur%..*}.."
122 cur="${cur#*..}"
123 COMPREPLY=($(compgen -P "$pfx" -W "$($patchlist)" -- "$cur"))
124 ;;
125 *)
126 COMPREPLY=($(compgen -W "$options $($patchlist)" -- "$cur"))
127 ;;
128 esac
129 }
130
131 _complete_patch_range_options ()
132 {
133 local patchlist="$1" options="$2" patch_options="$3"
134 local prev="${COMP_WORDS[COMP_CWORD-1]}"
135 local cur="${COMP_WORDS[COMP_CWORD]}"
136 local popt
137 for popt in $patch_options; do
138 if [ $prev == $popt ]; then
139 _complete_patch_range $patchlist
140 return
141 fi
142 done
143 COMPREPLY=($(compgen -W "$options" -- "$cur"))
144 }
145
146 _complete_branch ()
147 {
148 COMPREPLY=($(compgen -W "$(_cmd_options $1) $($2)" -- "${COMP_WORDS[COMP_CWORD]}"))
149 }
150
151 # Generate completions for options from the given list.
152 _complete_options ()
153 {
154 local options="$1"
155 COMPREPLY=($(compgen -W "$options" -- "${COMP_WORDS[COMP_CWORD]}"))
156 }
157
158 _stg_common ()
159 {
160 _complete_options "$(_cmd_options $1)"
161 }
162
163 _stg_patches ()
164 {
165 _complete_patch_range "$2" "$(_cmd_options $1)"
166 }
167
168 _stg_patches_options ()
169 {
170 _complete_patch_range_options "$2" "$(_cmd_options $1)" "$3"
171 }
172
173 _stg_help ()
174 {
175 _complete_options "$_stg_commands"
176 }
177
178 _stg ()
179 {
180 local i c=1 command
181
182 while [ $c -lt $COMP_CWORD ]; do
183 if [ $c == 1 ]; then
184 command="${COMP_WORDS[c]}"
185 fi
186 c=$((++c))
187 done
188
189 # Complete name of subcommand.
190 if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
191 COMPREPLY=($(compgen \
192 -W "--help --version copyright help $_stg_commands" \
193 -- "${COMP_WORDS[COMP_CWORD]}"))
194 return;
195 fi
196
197 # Complete arguments to subcommands.
198 case "$command" in
199 # generic commands
200 help) _stg_help ;;
201 # repository commands
202 id) _stg_patches $command _all_patches ;;
203 # stack commands
204 bury) _stg_patches $command _all_patches ;;
205 float) _stg_patches $command _all_patches ;;
206 goto) _stg_patches $command _all_other_patches ;;
207 hide) _stg_patches $command _all_patches ;;
208 pop) _stg_patches $command _applied_patches ;;
209 push) _stg_patches $command _unapplied_patches ;;
210 series) _stg_patches $command _all_patches ;;
211 unhide) _stg_patches $command _all_patches ;;
212 # patch commands
213 delete) _stg_patches $command _all_patches ;;
214 export) _stg_patches $command _applied_patches ;;
215 files) _stg_patches $command _all_patches ;;
216 log) _stg_patches $command _all_patches ;;
217 mail) _stg_patches $command _all_patches ;;
218 pick) _stg_patches $command _unapplied_patches ;;
219 refresh)_stg_patches_options $command _applied_patches "-p --patch" ;;
220 rename) _stg_patches $command _all_patches ;;
221 show) _stg_patches $command _all_patches ;;
222 sync) _stg_patches $command _applied_patches ;;
223 # working-copy commands
224 diff) _stg_patches_options $command _applied_patches "-r --range" ;;
225 # commands that usually raher accept branches
226 branch) _complete_branch $command _all_branches ;;
227 rebase) _complete_branch $command _all_branches ;;
228 # all the other commands
229 *) _stg_common $command ;;
230 esac
231 }
232
233 complete -o default -F _stg stg