chiark / gitweb /
Rename "stg assimilate" to "stg repair"
[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 _applied_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