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