##// END OF EJS Templates
bash_completion: untabify
Sean Farley -
r20123:f16240c8 default
parent child Browse files
Show More
@@ -1,587 +1,587
1 1 # bash completion for the Mercurial distributed SCM -*- sh -*-
2 2
3 3 # Docs:
4 4 #
5 5 # If you source this file from your .bashrc, bash should be able to
6 6 # complete a command line that uses hg with all the available commands
7 7 # and options and sometimes even arguments.
8 8 #
9 9 # Mercurial allows you to define additional commands through extensions.
10 10 # Bash should be able to automatically figure out the name of these new
11 11 # commands and their options. See below for how to define _hg_opt_foo
12 12 # and _hg_cmd_foo functions to fine-tune the completion for option and
13 13 # non-option arguments, respectively.
14 14 #
15 15 #
16 16 # Notes about completion for specific commands:
17 17 #
18 18 # - the completion function for the email command from the patchbomb
19 19 # extension will try to call _hg_emails to get a list of e-mail
20 20 # addresses. It's up to the user to define this function. For
21 21 # example, put the addresses of the lists that you usually patchbomb
22 22 # in ~/.patchbomb-to and the addresses that you usually use to send
23 23 # the patchbombs in ~/.patchbomb-from and use something like this:
24 24 #
25 25 # _hg_emails()
26 26 # {
27 27 # if [ -r ~/.patchbomb-$1 ]; then
28 28 # cat ~/.patchbomb-$1
29 29 # fi
30 30 # }
31 31 #
32 32 #
33 33 # Writing completion functions for additional commands:
34 34 #
35 35 # If it exists, the function _hg_cmd_foo will be called without
36 36 # arguments to generate the completion candidates for the hg command
37 37 # "foo". If the command receives some arguments that aren't options
38 38 # even though they start with a "-", you can define a function called
39 39 # _hg_opt_foo to generate the completion candidates. If _hg_opt_foo
40 40 # doesn't return 0, regular completion for options is attempted.
41 41 #
42 42 # In addition to the regular completion variables provided by bash,
43 43 # the following variables are also set:
44 44 # - $hg - the hg program being used (e.g. /usr/bin/hg)
45 45 # - $cmd - the name of the hg command being completed
46 46 # - $cmd_index - the index of $cmd in $COMP_WORDS
47 47 # - $cur - the current argument being completed
48 48 # - $prev - the argument before $cur
49 49 # - $global_args - "|"-separated list of global options that accept
50 50 # an argument (e.g. '--cwd|-R|--repository')
51 51 # - $canonical - 1 if we canonicalized $cmd before calling the function
52 52 # 0 otherwise
53 53 #
54 54
55 55 shopt -s extglob
56 56
57 57 _hg_cmd()
58 58 {
59 59 HGPLAIN=1 "$hg" "$@" 2>/dev/null
60 60 }
61 61
62 62 _hg_commands()
63 63 {
64 64 local commands
65 65 commands="$(HGPLAINEXCEPT=alias _hg_cmd debugcomplete "$cur")" || commands=""
66 66 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$commands' -- "$cur"))
67 67 }
68 68
69 69 _hg_paths()
70 70 {
71 71 local paths="$(_hg_cmd paths -q)"
72 72 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$paths' -- "$cur"))
73 73 }
74 74
75 75 _hg_repos()
76 76 {
77 77 local i
78 78 for i in $(compgen -d -- "$cur"); do
79 test ! -d "$i"/.hg || COMPREPLY=(${COMPREPLY[@]:-} "$i")
79 test ! -d "$i"/.hg || COMPREPLY=(${COMPREPLY[@]:-} "$i")
80 80 done
81 81 }
82 82
83 83 _hg_debugpathcomplete()
84 84 {
85 85 local files="$(_hg_cmd debugpathcomplete $1 "$cur")"
86 86 local IFS=$'\n'
87 87 compopt -o filenames 2>/dev/null
88 88 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
89 89 }
90 90
91 91 _hg_status()
92 92 {
93 93 local files="$(_hg_cmd status -n$1 "glob:$cur**")"
94 94 local IFS=$'\n'
95 95 compopt -o filenames 2>/dev/null
96 96 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
97 97 }
98 98
99 99 _hg_bookmarks()
100 100 {
101 101 local bookmarks="$(_hg_cmd bookmarks -q)"
102 102 local IFS=$'\n'
103 103 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$bookmarks' -- "$cur"))
104 104 }
105 105
106 106 _hg_labels()
107 107 {
108 108 local labels="$(_hg_cmd debuglabelcomplete "$cur")"
109 109 local IFS=$'\n'
110 110 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$labels' -- "$cur"))
111 111 }
112 112
113 113 # this is "kind of" ugly...
114 114 _hg_count_non_option()
115 115 {
116 116 local i count=0
117 117 local filters="$1"
118 118
119 119 for ((i=1; $i<=$COMP_CWORD; i++)); do
120 if [[ "${COMP_WORDS[i]}" != -* ]]; then
121 if [[ ${COMP_WORDS[i-1]} == @($filters|$global_args) ]]; then
122 continue
123 fi
124 count=$(($count + 1))
125 fi
120 if [[ "${COMP_WORDS[i]}" != -* ]]; then
121 if [[ ${COMP_WORDS[i-1]} == @($filters|$global_args) ]]; then
122 continue
123 fi
124 count=$(($count + 1))
125 fi
126 126 done
127 127
128 128 echo $(($count - 1))
129 129 }
130 130
131 131 _hg()
132 132 {
133 133 local cur prev cmd cmd_index opts i
134 134 # global options that receive an argument
135 135 local global_args='--cwd|-R|--repository'
136 136 local hg="$1"
137 137 local canonical=0
138 138
139 139 COMPREPLY=()
140 140 cur="$2"
141 141 prev="$3"
142 142
143 143 # searching for the command
144 144 # (first non-option argument that doesn't follow a global option that
145 145 # receives an argument)
146 146 for ((i=1; $i<=$COMP_CWORD; i++)); do
147 if [[ ${COMP_WORDS[i]} != -* ]]; then
148 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
149 cmd="${COMP_WORDS[i]}"
150 cmd_index=$i
151 break
152 fi
153 fi
147 if [[ ${COMP_WORDS[i]} != -* ]]; then
148 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
149 cmd="${COMP_WORDS[i]}"
150 cmd_index=$i
151 break
152 fi
153 fi
154 154 done
155 155
156 156 if [[ "$cur" == -* ]]; then
157 if [ "$(type -t "_hg_opt_$cmd")" = function ] && "_hg_opt_$cmd"; then
158 return
159 fi
157 if [ "$(type -t "_hg_opt_$cmd")" = function ] && "_hg_opt_$cmd"; then
158 return
159 fi
160 160
161 opts=$(_hg_cmd debugcomplete --options "$cmd")
161 opts=$(_hg_cmd debugcomplete --options "$cmd")
162 162
163 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur"))
164 return
163 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur"))
164 return
165 165 fi
166 166
167 167 # global options
168 168 case "$prev" in
169 -R|--repository)
170 _hg_paths
171 _hg_repos
172 return
173 ;;
174 --cwd)
175 # Stick with default bash completion
176 return
177 ;;
169 -R|--repository)
170 _hg_paths
171 _hg_repos
172 return
173 ;;
174 --cwd)
175 # Stick with default bash completion
176 return
177 ;;
178 178 esac
179 179
180 180 if [ -z "$cmd" ] || [ $COMP_CWORD -eq $i ]; then
181 _hg_commands
182 return
181 _hg_commands
182 return
183 183 fi
184 184
185 185 # try to generate completion candidates for whatever command the user typed
186 186 local help
187 187 if _hg_command_specific; then
188 return
188 return
189 189 fi
190 190
191 191 # canonicalize the command name and try again
192 192 help=$(_hg_cmd help "$cmd")
193 193 if [ $? -ne 0 ]; then
194 # Probably either the command doesn't exist or it's ambiguous
195 return
194 # Probably either the command doesn't exist or it's ambiguous
195 return
196 196 fi
197 197 cmd=${help#hg }
198 198 cmd=${cmd%%[$' \n']*}
199 199 canonical=1
200 200 _hg_command_specific
201 201 }
202 202
203 203 _hg_command_specific()
204 204 {
205 205 if [ "$(type -t "_hg_cmd_$cmd")" = function ]; then
206 "_hg_cmd_$cmd"
207 return 0
206 "_hg_cmd_$cmd"
207 return 0
208 208 fi
209 209
210 210 if [ "$cmd" != status ] && [ "$prev" = -r ] || [ "$prev" == --rev ]; then
211 if [ $canonical = 1 ]; then
212 _hg_labels
213 return 0
214 elif [[ status != "$cmd"* ]]; then
211 if [ $canonical = 1 ]; then
212 _hg_labels
213 return 0
214 elif [[ status != "$cmd"* ]]; then
215 215 _hg_labels
216 return 0
217 else
218 return 1
219 fi
216 return 0
217 else
218 return 1
219 fi
220 220 fi
221 221
222 222 case "$cmd" in
223 help)
224 _hg_commands
225 ;;
226 export)
227 if _hg_ext_mq_patchlist qapplied && [ "${COMPREPLY[*]}" ]; then
228 return 0
229 fi
230 _hg_labels
231 ;;
232 manifest|update|up|checkout|co)
233 _hg_labels
234 ;;
235 pull|push|outgoing|incoming)
236 _hg_paths
237 _hg_repos
238 ;;
239 paths)
240 _hg_paths
241 ;;
242 add)
243 _hg_status "u"
244 ;;
245 merge)
246 _hg_labels
247 ;;
248 commit|ci|record)
249 _hg_status "mar"
250 ;;
251 remove|rm)
252 _hg_debugpathcomplete -n
253 ;;
254 forget)
255 _hg_debugpathcomplete -fa
256 ;;
257 diff)
258 _hg_status "mar"
259 ;;
260 revert)
261 _hg_debugpathcomplete
262 ;;
263 clone)
264 local count=$(_hg_count_non_option)
265 if [ $count = 1 ]; then
266 _hg_paths
267 fi
268 _hg_repos
269 ;;
270 debugindex|debugindexdot)
271 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.i" -- "$cur"))
272 ;;
273 debugdata)
274 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.d" -- "$cur"))
275 ;;
276 *)
277 return 1
278 ;;
223 help)
224 _hg_commands
225 ;;
226 export)
227 if _hg_ext_mq_patchlist qapplied && [ "${COMPREPLY[*]}" ]; then
228 return 0
229 fi
230 _hg_labels
231 ;;
232 manifest|update|up|checkout|co)
233 _hg_labels
234 ;;
235 pull|push|outgoing|incoming)
236 _hg_paths
237 _hg_repos
238 ;;
239 paths)
240 _hg_paths
241 ;;
242 add)
243 _hg_status "u"
244 ;;
245 merge)
246 _hg_labels
247 ;;
248 commit|ci|record)
249 _hg_status "mar"
250 ;;
251 remove|rm)
252 _hg_debugpathcomplete -n
253 ;;
254 forget)
255 _hg_debugpathcomplete -fa
256 ;;
257 diff)
258 _hg_status "mar"
259 ;;
260 revert)
261 _hg_debugpathcomplete
262 ;;
263 clone)
264 local count=$(_hg_count_non_option)
265 if [ $count = 1 ]; then
266 _hg_paths
267 fi
268 _hg_repos
269 ;;
270 debugindex|debugindexdot)
271 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.i" -- "$cur"))
272 ;;
273 debugdata)
274 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.d" -- "$cur"))
275 ;;
276 *)
277 return 1
278 ;;
279 279 esac
280 280
281 281 return 0
282 282 }
283 283
284 284 complete -o bashdefault -o default -F _hg hg \
285 285 || complete -o default -F _hg hg
286 286
287 287
288 288 # Completion for commands provided by extensions
289 289
290 290 # bookmarks
291 291 _hg_cmd_bookmarks()
292 292 {
293 293 if [[ "$prev" = @(-d|--delete|-m|--rename) ]]; then
294 294 _hg_bookmarks
295 295 return
296 296 fi
297 297 }
298 298
299 299 # mq
300 300 _hg_ext_mq_patchlist()
301 301 {
302 302 local patches
303 303 patches=$(_hg_cmd $1)
304 304 if [ $? -eq 0 ] && [ "$patches" ]; then
305 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$patches' -- "$cur"))
306 return 0
305 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$patches' -- "$cur"))
306 return 0
307 307 fi
308 308 return 1
309 309 }
310 310
311 311 _hg_ext_mq_queues()
312 312 {
313 313 local root=$(_hg_cmd root)
314 314 local n
315 315 for n in $(cd "$root"/.hg && compgen -d -- "$cur"); do
316 # I think we're usually not interested in the regular "patches" queue
317 # so just filter it.
318 if [ "$n" != patches ] && [ -e "$root/.hg/$n/series" ]; then
319 COMPREPLY=(${COMPREPLY[@]:-} "$n")
320 fi
316 # I think we're usually not interested in the regular "patches" queue
317 # so just filter it.
318 if [ "$n" != patches ] && [ -e "$root/.hg/$n/series" ]; then
319 COMPREPLY=(${COMPREPLY[@]:-} "$n")
320 fi
321 321 done
322 322 }
323 323
324 324 _hg_cmd_qpop()
325 325 {
326 326 if [[ "$prev" = @(-n|--name) ]]; then
327 _hg_ext_mq_queues
328 return
327 _hg_ext_mq_queues
328 return
329 329 fi
330 330 _hg_ext_mq_patchlist qapplied
331 331 }
332 332
333 333 _hg_cmd_qpush()
334 334 {
335 335 if [[ "$prev" = @(-n|--name) ]]; then
336 _hg_ext_mq_queues
337 return
336 _hg_ext_mq_queues
337 return
338 338 fi
339 339 _hg_ext_mq_patchlist qunapplied
340 340 }
341 341
342 342 _hg_cmd_qgoto()
343 343 {
344 344 if [[ "$prev" = @(-n|--name) ]]; then
345 _hg_ext_mq_queues
346 return
345 _hg_ext_mq_queues
346 return
347 347 fi
348 348 _hg_ext_mq_patchlist qseries
349 349 }
350 350
351 351 _hg_cmd_qdelete()
352 352 {
353 353 local qcmd=qunapplied
354 354 if [[ "$prev" = @(-r|--rev) ]]; then
355 qcmd=qapplied
355 qcmd=qapplied
356 356 fi
357 357 _hg_ext_mq_patchlist $qcmd
358 358 }
359 359
360 360 _hg_cmd_qfinish()
361 361 {
362 362 if [[ "$prev" = @(-a|--applied) ]]; then
363 return
363 return
364 364 fi
365 365 _hg_ext_mq_patchlist qapplied
366 366 }
367 367
368 368 _hg_cmd_qsave()
369 369 {
370 370 if [[ "$prev" = @(-n|--name) ]]; then
371 _hg_ext_mq_queues
372 return
371 _hg_ext_mq_queues
372 return
373 373 fi
374 374 }
375 375
376 376 _hg_cmd_rebase() {
377 377 if [[ "$prev" = @(-s|--source|-d|--dest|-b|--base|-r|--rev) ]]; then
378 378 _hg_labels
379 379 return
380 380 fi
381 381 }
382 382
383 383 _hg_cmd_strip()
384 384 {
385 385 _hg_labels
386 386 }
387 387
388 388 _hg_cmd_qcommit()
389 389 {
390 390 local root=$(_hg_cmd root)
391 391 # this is run in a sub-shell, so we can't use _hg_status
392 392 local files=$(cd "$root/.hg/patches" && _hg_cmd status -nmar)
393 393 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
394 394 }
395 395
396 396 _hg_cmd_qfold()
397 397 {
398 398 _hg_ext_mq_patchlist qunapplied
399 399 }
400 400
401 401 _hg_cmd_qrename()
402 402 {
403 403 _hg_ext_mq_patchlist qseries
404 404 }
405 405
406 406 _hg_cmd_qheader()
407 407 {
408 408 _hg_ext_mq_patchlist qseries
409 409 }
410 410
411 411 _hg_cmd_qclone()
412 412 {
413 413 local count=$(_hg_count_non_option)
414 414 if [ $count = 1 ]; then
415 _hg_paths
415 _hg_paths
416 416 fi
417 417 _hg_repos
418 418 }
419 419
420 420 _hg_ext_mq_guards()
421 421 {
422 422 _hg_cmd qselect --series | sed -e 's/^.//'
423 423 }
424 424
425 425 _hg_cmd_qselect()
426 426 {
427 427 local guards=$(_hg_ext_mq_guards)
428 428 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$guards' -- "$cur"))
429 429 }
430 430
431 431 _hg_cmd_qguard()
432 432 {
433 433 local prefix=''
434 434
435 435 if [[ "$cur" == +* ]]; then
436 prefix=+
436 prefix=+
437 437 elif [[ "$cur" == -* ]]; then
438 prefix=-
438 prefix=-
439 439 fi
440 440 local ncur=${cur#[-+]}
441 441
442 442 if ! [ "$prefix" ]; then
443 _hg_ext_mq_patchlist qseries
444 return
443 _hg_ext_mq_patchlist qseries
444 return
445 445 fi
446 446
447 447 local guards=$(_hg_ext_mq_guards)
448 448 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -P $prefix -W '$guards' -- "$ncur"))
449 449 }
450 450
451 451 _hg_opt_qguard()
452 452 {
453 453 local i
454 454 for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do
455 if [[ ${COMP_WORDS[i]} != -* ]]; then
456 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
457 _hg_cmd_qguard
458 return 0
459 fi
460 elif [ "${COMP_WORDS[i]}" = -- ]; then
461 _hg_cmd_qguard
462 return 0
463 fi
455 if [[ ${COMP_WORDS[i]} != -* ]]; then
456 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
457 _hg_cmd_qguard
458 return 0
459 fi
460 elif [ "${COMP_WORDS[i]}" = -- ]; then
461 _hg_cmd_qguard
462 return 0
463 fi
464 464 done
465 465 return 1
466 466 }
467 467
468 468 _hg_cmd_qqueue()
469 469 {
470 470 local q
471 471 local queues
472 472 local opts="--list --create --rename --delete --purge"
473 473
474 474 queues=$( _hg_cmd qqueue --quiet )
475 475
476 476 COMPREPLY=( $( compgen -W "${opts} ${queues}" "${cur}" ) )
477 477 }
478 478
479 479
480 480 # hbisect
481 481 _hg_cmd_bisect()
482 482 {
483 483 local i subcmd
484 484
485 485 # find the sub-command
486 486 for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do
487 if [[ ${COMP_WORDS[i]} != -* ]]; then
488 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
489 subcmd="${COMP_WORDS[i]}"
490 break
491 fi
492 fi
487 if [[ ${COMP_WORDS[i]} != -* ]]; then
488 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
489 subcmd="${COMP_WORDS[i]}"
490 break
491 fi
492 fi
493 493 done
494 494
495 495 if [ -z "$subcmd" ] || [ $COMP_CWORD -eq $i ] || [ "$subcmd" = help ]; then
496 COMPREPLY=(${COMPREPLY[@]:-}
497 $(compgen -W 'bad good help init next reset' -- "$cur"))
498 return
496 COMPREPLY=(${COMPREPLY[@]:-}
497 $(compgen -W 'bad good help init next reset' -- "$cur"))
498 return
499 499 fi
500 500
501 501 case "$subcmd" in
502 good|bad)
503 _hg_labels
504 ;;
502 good|bad)
503 _hg_labels
504 ;;
505 505 esac
506 506
507 507 return
508 508 }
509 509
510 510
511 511 # patchbomb
512 512 _hg_cmd_email()
513 513 {
514 514 case "$prev" in
515 -c|--cc|-t|--to|-f|--from|--bcc)
516 # we need an e-mail address. let the user provide a function
517 # to get them
518 if [ "$(type -t _hg_emails)" = function ]; then
519 local arg=to
520 if [[ "$prev" == @(-f|--from) ]]; then
521 arg=from
522 fi
523 local addresses=$(_hg_emails $arg)
524 COMPREPLY=(${COMPREPLY[@]:-}
525 $(compgen -W '$addresses' -- "$cur"))
526 fi
527 return
528 ;;
529 -m|--mbox)
530 # fallback to standard filename completion
531 return
532 ;;
533 -s|--subject)
534 # free form string
535 return
536 ;;
515 -c|--cc|-t|--to|-f|--from|--bcc)
516 # we need an e-mail address. let the user provide a function
517 # to get them
518 if [ "$(type -t _hg_emails)" = function ]; then
519 local arg=to
520 if [[ "$prev" == @(-f|--from) ]]; then
521 arg=from
522 fi
523 local addresses=$(_hg_emails $arg)
524 COMPREPLY=(${COMPREPLY[@]:-}
525 $(compgen -W '$addresses' -- "$cur"))
526 fi
527 return
528 ;;
529 -m|--mbox)
530 # fallback to standard filename completion
531 return
532 ;;
533 -s|--subject)
534 # free form string
535 return
536 ;;
537 537 esac
538 538
539 539 _hg_labels
540 540 return
541 541 }
542 542
543 543
544 544 # gpg
545 545 _hg_cmd_sign()
546 546 {
547 547 _hg_labels
548 548 }
549 549
550 550
551 551 # transplant
552 552 _hg_cmd_transplant()
553 553 {
554 554 case "$prev" in
555 -s|--source)
556 _hg_paths
557 _hg_repos
558 return
559 ;;
560 --filter)
561 # standard filename completion
562 return
563 ;;
555 -s|--source)
556 _hg_paths
557 _hg_repos
558 return
559 ;;
560 --filter)
561 # standard filename completion
562 return
563 ;;
564 564 esac
565 565
566 566 # all other transplant options values and command parameters are revisions
567 567 _hg_labels
568 568 return
569 569 }
570 570
571 571 # shelve
572 572 _hg_shelves()
573 573 {
574 574 local shelves="$(_hg_cmd unshelve -l .)"
575 575 local IFS=$'\n'
576 576 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$shelves' -- "$cur"))
577 577 }
578 578
579 579 _hg_cmd_shelve()
580 580 {
581 581 _hg_status "mard"
582 582 }
583 583
584 584 _hg_cmd_unshelve()
585 585 {
586 586 _hg_shelves
587 587 }
General Comments 0
You need to be logged in to leave comments. Login now