chiark / gitweb /
Complete patch names after a patch (range) option
[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     export
24     files
25     float
26     fold
27     goto
28     id
29     import
30     init
31     log
32     mail
33     new
34     patches
35     pick
36     pop
37     pull
38     push
39     refresh
40     rename
41     resolved
42     rm
43     series
44     show
45     status
46     top
47     unapplied
48     uncommit
49 "
50
51 # The path to .git, or empty if we're not in a repository.
52 _gitdir ()
53 {
54     echo "$(git rev-parse --git-dir 2>/dev/null)"
55 }
56
57 # Name of the current branch, or empty if there isn't one.
58 _current_branch ()
59 {
60     local b=$(git symbolic-ref HEAD 2>/dev/null)
61     echo ${b#refs/heads/}
62 }
63
64 # List of all applied patches.
65 _applied_patches ()
66 {
67     local g=$(_gitdir)
68     [ "$g" ] && cat "$g/patches/$(_current_branch)/applied"
69 }
70
71 # List of all unapplied patches.
72 _unapplied_patches ()
73 {
74     local g=$(_gitdir)
75     [ "$g" ] && cat "$g/patches/$(_current_branch)/unapplied"
76 }
77
78 # List of all patches.
79 _all_patches ()
80 {
81     local b=$(_current_branch)
82     local g=$(_gitdir)
83     [ "$g" ] && cat "$g/patches/$b/applied" "$g/patches/$b/unapplied"
84 }
85
86 # List of all patches except the current patch.
87 _all_other_patches ()
88 {
89     local b=$(_current_branch)
90     local g=$(_gitdir)
91     [ "$g" ] && cat "$g/patches/$b/applied" "$g/patches/$b/unapplied" \
92         | grep -v "^$(< $g/patches/$b/current)$"
93 }
94
95 # List the command options
96 _cmd_options ()
97 {
98     stg $1 --help | grep -e " --[A-Za-z]" | sed -e "s/.*\(--[^ =]\+\).*/\1/"
99 }
100
101 # Generate completions for patches and patch ranges from the given
102 # patch list function, and options from the given list.
103 _complete_patch_range ()
104 {
105     local patchlist="$1" options="$2"
106     local pfx cur="${COMP_WORDS[COMP_CWORD]}"
107     case "$cur" in
108         *..*)
109             pfx="${cur%..*}.."
110             cur="${cur#*..}"
111             COMPREPLY=($(compgen -P "$pfx" -W "$($patchlist)" -- "$cur"))
112             ;;
113         *)
114             COMPREPLY=($(compgen -W "$options $($patchlist)" -- "$cur"))
115             ;;
116     esac
117 }
118
119 _complete_patch_range_options ()
120 {
121     local patchlist="$1" options="$2" patch_options="$3"
122     local prev="${COMP_WORDS[COMP_CWORD-1]}"
123     local cur="${COMP_WORDS[COMP_CWORD]}"
124     local popt
125     for popt in $patch_options; do
126         if [ $prev == $popt ]; then
127             _complete_patch_range $patchlist
128             return
129         fi
130     done
131     COMPREPLY=($(compgen -W "$options" -- "$cur"))
132 }
133
134 # Generate completions for options from the given list.
135 _complete_options ()
136 {
137     local options="$1"
138     COMPREPLY=($(compgen -W "$options" -- "${COMP_WORDS[COMP_CWORD]}"))
139 }
140
141 _stg_common ()
142 {
143     _complete_options "$(_cmd_options $1)"
144 }
145
146 _stg_patches ()
147 {
148     _complete_patch_range "$2" "$(_cmd_options $1)"
149 }
150
151 _stg_patches_options ()
152 {
153     _complete_patch_range_options "$2" "$(_cmd_options $1)" "$3"
154 }
155
156 _stg_help ()
157 {
158     _complete_options "$_stg_commands"
159 }
160
161 _stg ()
162 {
163     local i c=1 command
164
165     while [ $c -lt $COMP_CWORD ]; do
166         if [ $c == 1 ]; then
167             command="${COMP_WORDS[c]}"
168         fi
169         c=$((++c))
170     done
171
172     # Complete name of subcommand.
173     if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
174         COMPREPLY=($(compgen \
175             -W "--help --version copyright help $_stg_commands" \
176             -- "${COMP_WORDS[COMP_CWORD]}"))
177         return;
178     fi
179
180     # Complete arguments to subcommands.
181     case "$command" in
182         # generic commands
183         help)   _stg_help ;;
184         # repository commands
185         id)     _stg_patches $command _all_patches ;;
186         # stack commands
187         float)  _stg_patches $command _all_patches ;;
188         goto)   _stg_patches $command _all_other_patches ;;
189         pop)    _stg_patches $command _applied_patches ;;
190         push)   _stg_patches $command _unapplied_patches ;;
191         # patch commands
192         delete) _stg_patches $command _all_patches ;;
193         export) _stg_patches_options $command _applied_patches "-r --range" ;;
194         files)  _stg_patches $command _all_patches ;;
195         log)    _stg_patches $command _all_patches ;;
196         mail)   _stg_patches $command _applied_patches ;;
197         pick)   _stg_patches $command _unapplied_patches ;;
198         refresh)_stg_patches_options $command _applied_patches "-p --patch" ;;
199         rename) _stg_patches $command _all_patches ;;
200         show)   _stg_patches $command _all_patches ;;
201         # working-copy commands
202         diff)   _stg_patches_options $command _applied_patches "-r --range" ;;
203         # all the other commands
204         *)      _stg_common $command ;;
205     esac
206 }
207
208 complete -o default -F _stg stg