comparison contrib/bash_completion @ 2041:077a2da7f1de

bash_completion: completion for commands provided by extensions Make the bash_completion function call _hg_cmd_$cmd to generate completion candidates for $cmd if that function exists. Add basic completion functions for: - mq: - qpop - qpush - qdelete - qsave - qcommit - strip - hbisect: - bisect - patchbomb: - email - gpg: - sign
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
date Mon, 03 Apr 2006 14:56:00 +0200
parents 0c438fd25e6e
children c995d68333cf
comparison
equal deleted inserted replaced
2040:cd7711268774 2041:077a2da7f1de
1 # bash completion for the Mercurial distributed SCM
2
3 # Docs:
4 #
5 # If you source this file from your .bashrc, bash should be able to
6 # complete a command line that uses hg with all the available commands
7 # and options and sometimes even arguments.
8 #
9 # Mercurial allows you to define additional commands through extensions.
10 # Bash should be able to automatically figure out the name of these new
11 # commands and their options. If you also want to tell it how to
12 # complete non-option arguments, see below for how to define an
13 # _hg_cmd_foo function.
14 #
15 #
16 # Notes about completion for specific commands:
17 #
18 # - the completion function for the email command from the patchbomb
19 # extension will try to call _hg_emails to get a list of e-mail
20 # addresses. It's up to the user to define this function. For
21 # example, put the addresses of the lists that you usually patchbomb
22 # in ~/.patchbomb-to and the addresses that you usually use to send
23 # the patchbombs in ~/.patchbomb-from and use something like this:
24 #
25 # _hg_emails()
26 # {
27 # if [ -r ~/.patchbomb-$1 ]; then
28 # cat ~/.patchbomb-$1
29 # fi
30 # }
31 #
32 #
33 # Writing completion functions for additional commands:
34 #
35 # If it exists, the function _hg_cmd_foo will be called without
36 # arguments to generate the completion candidates for the hg command
37 # "foo".
38 #
39 # In addition to the regular completion variables provided by bash,
40 # the following variables are also set:
41 # - $hg - the hg program being used (e.g. /usr/bin/hg)
42 # - $cmd - the name of the hg command being completed
43 # - $cmd_index - the index of $cmd in $COMP_WORDS
44 # - $cur - the current argument being completed
45 # - $prev - the argument before $cur
46 # - $global_args - "|"-separated list of global options that accept
47 # an argument (e.g. '--cwd|-R|--repository')
48 # - $canonical - 1 if we canonicalized $cmd before calling the function
49 # 0 otherwise
50 #
51
1 shopt -s extglob 52 shopt -s extglob
2 53
3 _hg_commands() 54 _hg_commands()
4 { 55 {
5 local commands 56 local commands
52 echo $(($count - 1)) 103 echo $(($count - 1))
53 } 104 }
54 105
55 _hg() 106 _hg()
56 { 107 {
57 local cur prev cmd opts i 108 local cur prev cmd cmd_index opts i
58 # global options that receive an argument 109 # global options that receive an argument
59 local global_args='--cwd|-R|--repository' 110 local global_args='--cwd|-R|--repository'
60 local hg="$1" 111 local hg="$1"
61 112
62 COMPREPLY=() 113 COMPREPLY=()
68 # receives an argument) 119 # receives an argument)
69 for ((i=1; $i<=$COMP_CWORD; i++)); do 120 for ((i=1; $i<=$COMP_CWORD; i++)); do
70 if [[ ${COMP_WORDS[i]} != -* ]]; then 121 if [[ ${COMP_WORDS[i]} != -* ]]; then
71 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then 122 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
72 cmd="${COMP_WORDS[i]}" 123 cmd="${COMP_WORDS[i]}"
124 cmd_index=$i
73 break 125 break
74 fi 126 fi
75 fi 127 fi
76 done 128 done
77 129
118 _hg_command_specific 170 _hg_command_specific
119 } 171 }
120 172
121 _hg_command_specific() 173 _hg_command_specific()
122 { 174 {
175 if [ "$(type -t "_hg_cmd_$cmd")" = function ]; then
176 "_hg_cmd_$cmd"
177 return 0
178 fi
179
123 if [ "$cmd" != status ] && [ "$prev" = -r ] || [ "$prev" == --rev ]; then 180 if [ "$cmd" != status ] && [ "$prev" = -r ] || [ "$prev" == --rev ]; then
124 if [ $canonical = 1 ]; then 181 if [ $canonical = 1 ]; then
125 _hg_tags 182 _hg_tags
126 return 0 183 return 0
127 elif [[ status != "$cmd"* ]]; then 184 elif [[ status != "$cmd"* ]]; then
185 return 0 242 return 0
186 } 243 }
187 244
188 complete -o bashdefault -o default -F _hg hg 2>/dev/null \ 245 complete -o bashdefault -o default -F _hg hg 2>/dev/null \
189 || complete -o default -F _hg hg 246 || complete -o default -F _hg hg
247
248
249 # Completion for commands provided by extensions
250
251 # mq
252 _hg_ext_mq_patchlist()
253 {
254 local patches=$("$hg" $1 2>/dev/null)
255 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$patches' -- "$cur"))
256 }
257
258 _hg_ext_mq_queues()
259 {
260 local root=$("$hg" root 2>/dev/null)
261 local n
262 for n in $(cd "$root"/.hg && compgen -d -- "$cur"); do
263 # I think we're usually not interested in the regular "patches" queue
264 # so just filter it.
265 if [ "$n" != patches ] && [ -e "$root/.hg/$n/series" ]; then
266 COMPREPLY=(${COMPREPLY[@]:-} "$n")
267 fi
268 done
269 }
270
271 _hg_cmd_qpop()
272 {
273 if [[ "$prev" = @(-n|--name) ]]; then
274 _hg_ext_mq_queues
275 return
276 fi
277 _hg_ext_mq_patchlist qapplied
278 }
279
280 _hg_cmd_qpush()
281 {
282 if [[ "$prev" = @(-n|--name) ]]; then
283 _hg_ext_mq_queues
284 return
285 fi
286 _hg_ext_mq_patchlist qunapplied
287 }
288
289 _hg_cmd_qdelete()
290 {
291 _hg_ext_mq_patchlist qseries
292 }
293
294 _hg_cmd_qsave()
295 {
296 if [[ "$prev" = @(-n|--name) ]]; then
297 _hg_ext_mq_queues
298 return
299 fi
300 }
301
302 _hg_cmd_strip()
303 {
304 _hg_tags
305 }
306
307 _hg_cmd_qcommit()
308 {
309 local root=$("$hg" root 2>/dev/null)
310 # this is run in a sub-shell, so we can't use _hg_status
311 local files=$(cd "$root/.hg/patches" 2>/dev/null &&
312 "$hg" status -nmar 2>/dev/null)
313 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
314 }
315
316
317 # hbisect
318 _hg_cmd_bisect()
319 {
320 local i subcmd
321
322 # find the sub-command
323 for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do
324 if [[ ${COMP_WORDS[i]} != -* ]]; then
325 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
326 subcmd="${COMP_WORDS[i]}"
327 break
328 fi
329 fi
330 done
331
332 if [ -z "$subcmd" ] || [ $COMP_CWORD -eq $i ] || [ "$subcmd" = help ]; then
333 COMPREPLY=(${COMPREPLY[@]:-}
334 $(compgen -W 'bad good help init next reset' -- "$cur"))
335 return
336 fi
337
338 case "$subcmd" in
339 good|bad)
340 _hg_tags
341 ;;
342 esac
343
344 return
345 }
346
347
348 # patchbomb
349 _hg_cmd_email()
350 {
351 case "$prev" in
352 -c|--cc|-t|--to|-f|--from)
353 # we need an e-mail address. let the user provide a function
354 # to get them
355 if [ "$(type -t _hg_emails)" = function ]; then
356 local arg=to
357 if [[ "$prev" == @(-f|--from) ]]; then
358 arg=from
359 fi
360 local addresses=$(_hg_emails $arg)
361 COMPREPLY=(${COMPREPLY[@]:-}
362 $(compgen -W '$addresses' -- "$cur"))
363 fi
364 return
365 ;;
366 -m|--mbox)
367 # fallback to standard filename completion
368 return
369 ;;
370 -s|--subject)
371 # free form string
372 return
373 ;;
374 esac
375
376 _hg_tags
377 return
378 }
379
380
381 # gpg
382 _hg_cmd_sign()
383 {
384 _hg_tags
385 }