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