Don't use patches/<branch>/current
[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 # List the command options
102 _cmd_options ()
103 {
104 stg $1 --help 2>/dev/null | grep -e " --[A-Za-z]" | sed -e "s/.*\(--[^ =]\+\).*/\1/"
105 }
106
107 # Generate completions for patches and patch ranges from the given
108 # patch list function, and options from the given list.
109 _complete_patch_range ()
110 {
111 local patchlist="$1" options="$2"
112 local pfx cur="${COMP_WORDS[COMP_CWORD]}"
113 case "$cur" in
114 *..*)
115 pfx="${cur%..*}.."
116 cur="${cur#*..}"
117 COMPREPLY=($(compgen -P "$pfx" -W "$($patchlist)" -- "$cur"))
118 ;;
119 *)
120 COMPREPLY=($(compgen -W "$options $($patchlist)" -- "$cur"))
121 ;;
122 esac
123 }
124
125 _complete_patch_range_options ()
126 {
127 local patchlist="$1" options="$2" patch_options="$3"
128 local prev="${COMP_WORDS[COMP_CWORD-1]}"
129 local cur="${COMP_WORDS[COMP_CWORD]}"
130 local popt
131 for popt in $patch_options; do
132 if [ $prev == $popt ]; then
133 _complete_patch_range $patchlist
134 return
135 fi
136 done
137 COMPREPLY=($(compgen -W "$options" -- "$cur"))
138 }
139
140 # Generate completions for options from the given list.
141 _complete_options ()
142 {
143 local options="$1"
144 COMPREPLY=($(compgen -W "$options" -- "${COMP_WORDS[COMP_CWORD]}"))
145 }
146
147 _stg_common ()
148 {
149 _complete_options "$(_cmd_options $1)"
150 }
151
152 _stg_patches ()
153 {
154 _complete_patch_range "$2" "$(_cmd_options $1)"
155 }
156
157 _stg_patches_options ()
158 {
159 _complete_patch_range_options "$2" "$(_cmd_options $1)" "$3"
160 }
161
162 _stg_help ()
163 {
164 _complete_options "$_stg_commands"
165 }
166
167 _stg ()
168 {
169 local i c=1 command
170
171 while [ $c -lt $COMP_CWORD ]; do
172 if [ $c == 1 ]; then
173 command="${COMP_WORDS[c]}"
174 fi
175 c=$((++c))
176 done
177
178 # Complete name of subcommand.
179 if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
180 COMPREPLY=($(compgen \
181 -W "--help --version copyright help $_stg_commands" \
182 -- "${COMP_WORDS[COMP_CWORD]}"))
183 return;
184 fi
185
186 # Complete arguments to subcommands.
187 case "$command" in
188 # generic commands
189 help) _stg_help ;;
190 # repository commands
191 id) _stg_patches $command _all_patches ;;
192 # stack commands
193 bury) _stg_patches $command _all_patches ;;
194 float) _stg_patches $command _all_patches ;;
195 goto) _stg_patches $command _all_other_patches ;;
196 hide) _stg_patches $command _all_patches ;;
197 pop) _stg_patches $command _applied_patches ;;
198 push) _stg_patches $command _unapplied_patches ;;
199 series) _stg_patches $command _all_patches ;;
200 unhide) _stg_patches $command _all_patches ;;
201 # patch commands
202 delete) _stg_patches $command _all_patches ;;
203 export) _stg_patches $command _applied_patches ;;
204 files) _stg_patches $command _all_patches ;;
205 log) _stg_patches $command _all_patches ;;
206 mail) _stg_patches $command _all_patches ;;
207 pick) _stg_patches $command _unapplied_patches ;;
208 refresh)_stg_patches_options $command _applied_patches "-p --patch" ;;
209 rename) _stg_patches $command _all_patches ;;
210 show) _stg_patches $command _all_patches ;;
211 sync) _stg_patches $command _applied_patches ;;
212 # working-copy commands
213 diff) _stg_patches_options $command _applied_patches "-r --range" ;;
214 # all the other commands
215 *) _stg_common $command ;;
216 esac
217 }
218
219 complete -o default -F _stg stg