##// END OF EJS Templates
bash_completion: add -l|--list support for shelve...
Sean Farley -
r21719:28ecdf3f default
parent child Browse files
Show More
@@ -1,642 +1,642
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 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 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
88 88 }
89 89
90 90 _hg_status()
91 91 {
92 92 local files="$(_hg_cmd status -n$1 "glob:$cur**")"
93 93 local IFS=$'\n'
94 94 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
95 95 }
96 96
97 97 _hg_branches()
98 98 {
99 99 local branches="$(_hg_cmd branches -q)"
100 100 local IFS=$'\n'
101 101 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$branches' -- "$cur"))
102 102 }
103 103
104 104 _hg_bookmarks()
105 105 {
106 106 local bookmarks="$(_hg_cmd bookmarks -q)"
107 107 local IFS=$'\n'
108 108 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$bookmarks' -- "$cur"))
109 109 }
110 110
111 111 _hg_labels()
112 112 {
113 113 local labels="$(_hg_cmd debuglabelcomplete "$cur")"
114 114 local IFS=$'\n'
115 115 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$labels' -- "$cur"))
116 116 }
117 117
118 118 # this is "kind of" ugly...
119 119 _hg_count_non_option()
120 120 {
121 121 local i count=0
122 122 local filters="$1"
123 123
124 124 for ((i=1; $i<=$COMP_CWORD; i++)); do
125 125 if [[ "${COMP_WORDS[i]}" != -* ]]; then
126 126 if [[ ${COMP_WORDS[i-1]} == @($filters|$global_args) ]]; then
127 127 continue
128 128 fi
129 129 count=$(($count + 1))
130 130 fi
131 131 done
132 132
133 133 echo $(($count - 1))
134 134 }
135 135
136 136 _hg_fix_wordlist()
137 137 {
138 138 local LASTCHAR=' '
139 139 if [ ${#COMPREPLY[@]} = 1 ]; then
140 140 [ -d "$COMPREPLY" ] && LASTCHAR=/
141 141 COMPREPLY=$(printf %q%s "$COMPREPLY" "$LASTCHAR")
142 142 else
143 143 for ((i=0; i < ${#COMPREPLY[@]}; i++)); do
144 144 [ -d "${COMPREPLY[$i]}" ] && COMPREPLY[$i]=${COMPREPLY[$i]}/
145 145 done
146 146 fi
147 147 }
148 148
149 149 _hg()
150 150 {
151 151 local cur prev cmd cmd_index opts i aliashg
152 152 # global options that receive an argument
153 153 local global_args='--cwd|-R|--repository'
154 154 local hg="$1"
155 155 local canonical=0
156 156
157 157 aliashg=$(alias $hg 2>/dev/null)
158 158 if [[ -n "$aliashg" ]]; then
159 159 aliashg=${aliashg#"alias $hg='"}
160 160 aliashg=${aliashg%"'"}
161 161 hg=$aliashg
162 162 fi
163 163
164 164 COMPREPLY=()
165 165 cur="$2"
166 166 prev="$3"
167 167
168 168 # searching for the command
169 169 # (first non-option argument that doesn't follow a global option that
170 170 # receives an argument)
171 171 for ((i=1; $i<=$COMP_CWORD; i++)); do
172 172 if [[ ${COMP_WORDS[i]} != -* ]]; then
173 173 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
174 174 cmd="${COMP_WORDS[i]}"
175 175 cmd_index=$i
176 176 break
177 177 fi
178 178 fi
179 179 done
180 180
181 181 if [[ "$cur" == -* ]]; then
182 182 if [ "$(type -t "_hg_opt_$cmd")" = function ] && "_hg_opt_$cmd"; then
183 183 _hg_fix_wordlist
184 184 return
185 185 fi
186 186
187 187 opts=$(_hg_cmd debugcomplete --options "$cmd")
188 188
189 189 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur"))
190 190 _hg_fix_wordlist
191 191 return
192 192 fi
193 193
194 194 # global options
195 195 case "$prev" in
196 196 -R|--repository)
197 197 _hg_paths
198 198 _hg_repos
199 199 _hg_fix_wordlist
200 200 return
201 201 ;;
202 202 --cwd)
203 203 # Stick with default bash completion
204 204 _hg_fix_wordlist
205 205 return
206 206 ;;
207 207 esac
208 208
209 209 if [ -z "$cmd" ] || [ $COMP_CWORD -eq $i ]; then
210 210 _hg_commands
211 211 _hg_fix_wordlist
212 212 return
213 213 fi
214 214
215 215 # try to generate completion candidates for whatever command the user typed
216 216 local help
217 217 if _hg_command_specific; then
218 218 _hg_fix_wordlist
219 219 return
220 220 fi
221 221
222 222 # canonicalize the command name and try again
223 223 help=$(_hg_cmd help "$cmd")
224 224 if [ $? -ne 0 ]; then
225 225 # Probably either the command doesn't exist or it's ambiguous
226 226 return
227 227 fi
228 228 cmd=${help#hg }
229 229 cmd=${cmd%%[$' \n']*}
230 230 canonical=1
231 231 _hg_command_specific
232 232 _hg_fix_wordlist
233 233 }
234 234
235 235 _hg_command_specific()
236 236 {
237 237 if [ "$(type -t "_hg_cmd_$cmd")" = function ]; then
238 238 "_hg_cmd_$cmd"
239 239 return 0
240 240 fi
241 241
242 242 if [ "$cmd" != status ]; then
243 243 case "$prev" in
244 244 -r|--rev)
245 245 if [[ $canonical = 1 || status != "$cmd"* ]]; then
246 246 _hg_labels
247 247 return 0
248 248 fi
249 249 return 1
250 250 ;;
251 251 -B|--bookmark)
252 252 if [[ $canonical = 1 || status != "$cmd"* ]]; then
253 253 _hg_bookmarks
254 254 return 0
255 255 fi
256 256 return 1
257 257 ;;
258 258 -b|--branch)
259 259 if [[ $canonical = 1 || status != "$cmd"* ]]; then
260 260 _hg_branches
261 261 return 0
262 262 fi
263 263 return 1
264 264 ;;
265 265 esac
266 266 fi
267 267
268 268 local aliascmd=$(_hg_cmd showconfig alias.$cmd | awk '{print $1}')
269 269 [ -n "$aliascmd" ] && cmd=$aliascmd
270 270
271 271 case "$cmd" in
272 272 help)
273 273 _hg_commands
274 274 ;;
275 275 export)
276 276 if _hg_ext_mq_patchlist qapplied && [ "${COMPREPLY[*]}" ]; then
277 277 return 0
278 278 fi
279 279 _hg_labels
280 280 ;;
281 281 manifest|update|up|checkout|co)
282 282 _hg_labels
283 283 ;;
284 284 pull|push|outgoing|incoming)
285 285 _hg_paths
286 286 _hg_repos
287 287 ;;
288 288 paths)
289 289 _hg_paths
290 290 ;;
291 291 add)
292 292 _hg_status "u"
293 293 ;;
294 294 merge)
295 295 _hg_labels
296 296 ;;
297 297 commit|ci|record)
298 298 _hg_status "mar"
299 299 ;;
300 300 remove|rm)
301 301 _hg_debugpathcomplete -n
302 302 ;;
303 303 forget)
304 304 _hg_debugpathcomplete -fa
305 305 ;;
306 306 diff)
307 307 _hg_status "mar"
308 308 ;;
309 309 revert)
310 310 _hg_debugpathcomplete
311 311 ;;
312 312 clone)
313 313 local count=$(_hg_count_non_option)
314 314 if [ $count = 1 ]; then
315 315 _hg_paths
316 316 fi
317 317 _hg_repos
318 318 ;;
319 319 debugindex|debugindexdot)
320 320 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.i" -- "$cur"))
321 321 ;;
322 322 debugdata)
323 323 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.d" -- "$cur"))
324 324 ;;
325 325 *)
326 326 return 1
327 327 ;;
328 328 esac
329 329
330 330 return 0
331 331 }
332 332
333 333 complete -o bashdefault -o default -o nospace -F _hg hg \
334 334 || complete -o default -o nospace -F _hg hg
335 335
336 336
337 337 # Completion for commands provided by extensions
338 338
339 339 # bookmarks
340 340 _hg_cmd_bookmarks()
341 341 {
342 342 _hg_bookmarks
343 343 return
344 344 }
345 345
346 346 # mq
347 347 _hg_ext_mq_patchlist()
348 348 {
349 349 local patches
350 350 patches=$(_hg_cmd $1)
351 351 if [ $? -eq 0 ] && [ "$patches" ]; then
352 352 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$patches' -- "$cur"))
353 353 return 0
354 354 fi
355 355 return 1
356 356 }
357 357
358 358 _hg_ext_mq_queues()
359 359 {
360 360 local root=$(_hg_cmd root)
361 361 local n
362 362 for n in $(cd "$root"/.hg && compgen -d -- "$cur"); do
363 363 # I think we're usually not interested in the regular "patches" queue
364 364 # so just filter it.
365 365 if [ "$n" != patches ] && [ -e "$root/.hg/$n/series" ]; then
366 366 COMPREPLY=(${COMPREPLY[@]:-} "$n")
367 367 fi
368 368 done
369 369 }
370 370
371 371 _hg_cmd_qpop()
372 372 {
373 373 if [[ "$prev" = @(-n|--name) ]]; then
374 374 _hg_ext_mq_queues
375 375 return
376 376 fi
377 377 _hg_ext_mq_patchlist qapplied
378 378 }
379 379
380 380 _hg_cmd_qpush()
381 381 {
382 382 if [[ "$prev" = @(-n|--name) ]]; then
383 383 _hg_ext_mq_queues
384 384 return
385 385 fi
386 386 _hg_ext_mq_patchlist qunapplied
387 387 }
388 388
389 389 _hg_cmd_qgoto()
390 390 {
391 391 if [[ "$prev" = @(-n|--name) ]]; then
392 392 _hg_ext_mq_queues
393 393 return
394 394 fi
395 395 _hg_ext_mq_patchlist qseries
396 396 }
397 397
398 398 _hg_cmd_qdelete()
399 399 {
400 400 local qcmd=qunapplied
401 401 if [[ "$prev" = @(-r|--rev) ]]; then
402 402 qcmd=qapplied
403 403 fi
404 404 _hg_ext_mq_patchlist $qcmd
405 405 }
406 406
407 407 _hg_cmd_qfinish()
408 408 {
409 409 if [[ "$prev" = @(-a|--applied) ]]; then
410 410 return
411 411 fi
412 412 _hg_ext_mq_patchlist qapplied
413 413 }
414 414
415 415 _hg_cmd_qsave()
416 416 {
417 417 if [[ "$prev" = @(-n|--name) ]]; then
418 418 _hg_ext_mq_queues
419 419 return
420 420 fi
421 421 }
422 422
423 423 _hg_cmd_rebase() {
424 424 if [[ "$prev" = @(-s|--source|-d|--dest|-b|--base|-r|--rev) ]]; then
425 425 _hg_labels
426 426 return
427 427 fi
428 428 }
429 429
430 430 _hg_cmd_strip()
431 431 {
432 432 if [[ "$prev" = @(-B|--bookmark) ]]; then
433 433 _hg_bookmarks
434 434 return
435 435 fi
436 436 _hg_labels
437 437 }
438 438
439 439 _hg_cmd_qcommit()
440 440 {
441 441 local root=$(_hg_cmd root)
442 442 # this is run in a sub-shell, so we can't use _hg_status
443 443 local files=$(cd "$root/.hg/patches" && _hg_cmd status -nmar)
444 444 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
445 445 }
446 446
447 447 _hg_cmd_qfold()
448 448 {
449 449 _hg_ext_mq_patchlist qunapplied
450 450 }
451 451
452 452 _hg_cmd_qrename()
453 453 {
454 454 _hg_ext_mq_patchlist qseries
455 455 }
456 456
457 457 _hg_cmd_qheader()
458 458 {
459 459 _hg_ext_mq_patchlist qseries
460 460 }
461 461
462 462 _hg_cmd_qclone()
463 463 {
464 464 local count=$(_hg_count_non_option)
465 465 if [ $count = 1 ]; then
466 466 _hg_paths
467 467 fi
468 468 _hg_repos
469 469 }
470 470
471 471 _hg_ext_mq_guards()
472 472 {
473 473 _hg_cmd qselect --series | sed -e 's/^.//'
474 474 }
475 475
476 476 _hg_cmd_qselect()
477 477 {
478 478 local guards=$(_hg_ext_mq_guards)
479 479 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$guards' -- "$cur"))
480 480 }
481 481
482 482 _hg_cmd_qguard()
483 483 {
484 484 local prefix=''
485 485
486 486 if [[ "$cur" == +* ]]; then
487 487 prefix=+
488 488 elif [[ "$cur" == -* ]]; then
489 489 prefix=-
490 490 fi
491 491 local ncur=${cur#[-+]}
492 492
493 493 if ! [ "$prefix" ]; then
494 494 _hg_ext_mq_patchlist qseries
495 495 return
496 496 fi
497 497
498 498 local guards=$(_hg_ext_mq_guards)
499 499 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -P $prefix -W '$guards' -- "$ncur"))
500 500 }
501 501
502 502 _hg_opt_qguard()
503 503 {
504 504 local i
505 505 for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do
506 506 if [[ ${COMP_WORDS[i]} != -* ]]; then
507 507 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
508 508 _hg_cmd_qguard
509 509 return 0
510 510 fi
511 511 elif [ "${COMP_WORDS[i]}" = -- ]; then
512 512 _hg_cmd_qguard
513 513 return 0
514 514 fi
515 515 done
516 516 return 1
517 517 }
518 518
519 519 _hg_cmd_qqueue()
520 520 {
521 521 local q
522 522 local queues
523 523 local opts="--list --create --rename --delete --purge"
524 524
525 525 queues=$( _hg_cmd qqueue --quiet )
526 526
527 527 COMPREPLY=( $( compgen -W "${opts} ${queues}" "${cur}" ) )
528 528 }
529 529
530 530
531 531 # hbisect
532 532 _hg_cmd_bisect()
533 533 {
534 534 local i subcmd
535 535
536 536 # find the sub-command
537 537 for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do
538 538 if [[ ${COMP_WORDS[i]} != -* ]]; then
539 539 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
540 540 subcmd="${COMP_WORDS[i]}"
541 541 break
542 542 fi
543 543 fi
544 544 done
545 545
546 546 if [ -z "$subcmd" ] || [ $COMP_CWORD -eq $i ] || [ "$subcmd" = help ]; then
547 547 COMPREPLY=(${COMPREPLY[@]:-}
548 548 $(compgen -W 'bad good help init next reset' -- "$cur"))
549 549 return
550 550 fi
551 551
552 552 case "$subcmd" in
553 553 good|bad)
554 554 _hg_labels
555 555 ;;
556 556 esac
557 557
558 558 return
559 559 }
560 560
561 561
562 562 # patchbomb
563 563 _hg_cmd_email()
564 564 {
565 565 case "$prev" in
566 566 -c|--cc|-t|--to|-f|--from|--bcc)
567 567 # we need an e-mail address. let the user provide a function
568 568 # to get them
569 569 if [ "$(type -t _hg_emails)" = function ]; then
570 570 local arg=to
571 571 if [[ "$prev" == @(-f|--from) ]]; then
572 572 arg=from
573 573 fi
574 574 local addresses=$(_hg_emails $arg)
575 575 COMPREPLY=(${COMPREPLY[@]:-}
576 576 $(compgen -W '$addresses' -- "$cur"))
577 577 fi
578 578 return
579 579 ;;
580 580 -m|--mbox)
581 581 # fallback to standard filename completion
582 582 return
583 583 ;;
584 584 -s|--subject)
585 585 # free form string
586 586 return
587 587 ;;
588 588 esac
589 589
590 590 _hg_labels
591 591 return
592 592 }
593 593
594 594
595 595 # gpg
596 596 _hg_cmd_sign()
597 597 {
598 598 _hg_labels
599 599 }
600 600
601 601
602 602 # transplant
603 603 _hg_cmd_transplant()
604 604 {
605 605 case "$prev" in
606 606 -s|--source)
607 607 _hg_paths
608 608 _hg_repos
609 609 return
610 610 ;;
611 611 --filter)
612 612 # standard filename completion
613 613 return
614 614 ;;
615 615 esac
616 616
617 617 # all other transplant options values and command parameters are revisions
618 618 _hg_labels
619 619 return
620 620 }
621 621
622 622 # shelve
623 623 _hg_shelves()
624 624 {
625 625 local shelves="$(_hg_cmd shelve -ql)"
626 626 local IFS=$'\n'
627 627 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$shelves' -- "$cur"))
628 628 }
629 629
630 630 _hg_cmd_shelve()
631 631 {
632 if [[ "$prev" = @(-d|--delete) ]]; then
632 if [[ "$prev" = @(-d|--delete|-l|--list) ]]; then
633 633 _hg_shelves
634 634 else
635 635 _hg_status "mard"
636 636 fi
637 637 }
638 638
639 639 _hg_cmd_unshelve()
640 640 {
641 641 _hg_shelves
642 642 }
General Comments 0
You need to be logged in to leave comments. Login now