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