7ae9e6a8bb03bbcc3766ea3f3e5369881d4f3b23
[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 delete
19 diff
20 clean
21 clone
22 commit
23 cp
24 export
25 files
26 float
27 fold
28 goto
29 hide
30 id
31 import
32 init
33 log
34 mail
35 new
36 patches
37 pick
38 pop
39 pull
40 push
41 rebase
42 refresh
43 rename
44 resolved
45 rm
46 series
47 show
48 sink
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 applied patches.
85 _hidden_patches ()
86 {
87 local g=$(_gitdir)
88 [ "$g" ] && cat "$g/patches/$(_current_branch)/hidden"
89 }
90
91 # List of all patches.
92 _all_patches ()
93 {
94 local b=$(_current_branch)
95 local g=$(_gitdir)
96 [ "$g" ] && cat "$g/patches/$b/applied" "$g/patches/$b/unapplied"
97 }
98
99 # List of all patches except the current patch.
100 _all_other_patches ()
101 {
102 local b=$(_current_branch)
103 local g=$(_gitdir)
104 [ "$g" ] && cat "$g/patches/$b/applied" "$g/patches/$b/unapplied" \
105 | grep -v "^$(cat $g/patches/$b/current 2> /dev/null)$"
106 }
107
108 _all_branches ()
109 {
110 local g=$(_gitdir)
111 [ "$g" ] && (cd $g/patches/ && echo *)
112 }
113
114 _conflicting_files ()
115 {
116 local g=$(_gitdir)
117 [ "$g" ] && stg status --conflict
118 }
119
120 _dirty_files ()
121 {
122 local g=$(_gitdir)
123 [ "$g" ] && stg status --modified --new --deleted
124 }
125
126 _unknown_files ()
127 {
128 local g=$(_gitdir)
129 [ "$g" ] && stg status --unknown
130 }
131
132 _known_files ()
133 {
134 local g=$(_gitdir)
135 [ "$g" ] && git ls-files
136 }
137
138 # List the command options
139 _cmd_options ()
140 {
141 stg $1 --help 2>/dev/null | grep -e " --[A-Za-z]" | sed -e "s/.*\(--[^ =]\+\).*/\1/"
142 }
143
144 # Generate completions for patches and patch ranges from the given
145 # patch list function, and options from the given list.
146 _complete_patch_range ()
147 {
148 local patchlist="$1" options="$2"
149 local pfx cur="${COMP_WORDS[COMP_CWORD]}"
150 case "$cur" in
151 *..*)
152 pfx="${cur%..*}.."
153 cur="${cur#*..}"
154 COMPREPLY=($(compgen -P "$pfx" -W "$($patchlist)" -- "$cur"))
155 ;;
156 *)
157 COMPREPLY=($(compgen -W "$options $($patchlist)" -- "$cur"))
158 ;;
159 esac
160 }
161
162 _complete_patch_range_options ()
163 {
164 local patchlist="$1" options="$2" patch_options="$3"
165 local prev="${COMP_WORDS[COMP_CWORD-1]}"
166 local cur="${COMP_WORDS[COMP_CWORD]}"
167 local popt
168 for popt in $patch_options; do
169 if [ $prev == $popt ]; then
170 _complete_patch_range $patchlist
171 return
172 fi
173 done
174 COMPREPLY=($(compgen -W "$options" -- "$cur"))
175 }
176
177 _complete_branch ()
178 {
179 COMPREPLY=($(compgen -W "$(_cmd_options $1) $($2)" -- "${COMP_WORDS[COMP_CWORD]}"))
180 }
181
182 # Generate completions for options from the given list.
183 _complete_options ()
184 {
185 local options="$1"
186 COMPREPLY=($(compgen -W "$options" -- "${COMP_WORDS[COMP_CWORD]}"))
187 }
188
189 _complete_files ()
190 {
191 COMPREPLY=($(compgen -W "$(_cmd_options $1) $2" -- "${COMP_WORDS[COMP_CWORD]}"))
192 }
193
194 _stg_common ()
195 {
196 _complete_options "$(_cmd_options $1)"
197 }
198
199 _stg_patches ()
200 {
201 _complete_patch_range "$2" "$(_cmd_options $1)"
202 }
203
204 _stg_patches_options ()
205 {
206 _complete_patch_range_options "$2" "$(_cmd_options $1)" "$3"
207 }
208
209 _stg_help ()
210 {
211 _complete_options "$_stg_commands"
212 }
213
214 _stg ()
215 {
216 local i c=1 command
217
218 while [ $c -lt $COMP_CWORD ]; do
219 if [ $c == 1 ]; then
220 command="${COMP_WORDS[c]}"
221 fi
222 c=$((++c))
223 done
224
225 # Complete name of subcommand.
226 if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
227 COMPREPLY=($(compgen \
228 -W "--help --version copyright help $_stg_commands" \
229 -- "${COMP_WORDS[COMP_CWORD]}"))
230 return;
231 fi
232
233 # Complete arguments to subcommands.
234 case "$command" in
235 # generic commands
236 help) _stg_help ;;
237 # repository commands
238 id) _stg_patches $command _all_patches ;;
239 # stack commands
240 float) _stg_patches $command _all_patches ;;
241 goto) _stg_patches $command _all_other_patches ;;
242 hide) _stg_patches $command _unapplied_patches ;;
243 pop) _stg_patches $command _applied_patches ;;
244 push) _stg_patches $command _unapplied_patches ;;
245 series) _stg_patches $command _all_patches ;;
246 sink) _stg_patches $command _all_patches ;;
247 unhide) _stg_patches $command _hidden_patches ;;
248 # patch commands
249 delete) _stg_patches $command _all_patches ;;
250 export) _stg_patches $command _applied_patches ;;
251 files) _stg_patches $command _all_patches ;;
252 log) _stg_patches $command _all_patches ;;
253 mail) _stg_patches $command _all_patches ;;
254 pick) _stg_patches $command _unapplied_patches ;;
255 # refresh)_stg_patches_options $command _applied_patches "-p --patch" ;;
256 refresh) _complete_files $command "$(_dirty_files)" ;;
257 rename) _stg_patches $command _all_patches ;;
258 show) _stg_patches $command _all_patches ;;
259 sync) _stg_patches $command _applied_patches ;;
260 # working-copy commands
261 diff) _stg_patches_options $command _applied_patches "-r --range" ;;
262 resolved) _complete_files $command "$(_conflicting_files)" ;;
263 add) _complete_files $command "$(_unknown_files)" ;;
264 # rm) _complete_files $command "$(_known_files)" ;;
265 # commands that usually raher accept branches
266 branch) _complete_branch $command _all_branches ;;
267 rebase) _complete_branch $command _all_branches ;;
268 # all the other commands
269 *) _stg_common $command ;;
270 esac
271 }
272
273 complete -o default -F _stg stg