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