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