##// END OF EJS Templates
bash_completion: match more narrowly...
Bryan O'Sullivan -
r18767:69e4787b default
parent child Browse files
Show More
@@ -1,600 +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 local files="$(_hg_cmd status -n$1 .)"
85 local files="$(_hg_cmd status -n$1 "glob:$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_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 389 _hg_cmd_rebase() {
390 390 if [[ "$prev" = @(-s|--source|-d|--dest|-b|--base|-r|--rev) ]]; then
391 391 _hg_labels
392 392 return
393 393 fi
394 394 }
395 395
396 396 _hg_cmd_strip()
397 397 {
398 398 _hg_labels
399 399 }
400 400
401 401 _hg_cmd_qcommit()
402 402 {
403 403 local root=$(_hg_cmd root)
404 404 # this is run in a sub-shell, so we can't use _hg_status
405 405 local files=$(cd "$root/.hg/patches" && _hg_cmd status -nmar)
406 406 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
407 407 }
408 408
409 409 _hg_cmd_qfold()
410 410 {
411 411 _hg_ext_mq_patchlist qunapplied
412 412 }
413 413
414 414 _hg_cmd_qrename()
415 415 {
416 416 _hg_ext_mq_patchlist qseries
417 417 }
418 418
419 419 _hg_cmd_qheader()
420 420 {
421 421 _hg_ext_mq_patchlist qseries
422 422 }
423 423
424 424 _hg_cmd_qclone()
425 425 {
426 426 local count=$(_hg_count_non_option)
427 427 if [ $count = 1 ]; then
428 428 _hg_paths
429 429 fi
430 430 _hg_repos
431 431 }
432 432
433 433 _hg_ext_mq_guards()
434 434 {
435 435 _hg_cmd qselect --series | sed -e 's/^.//'
436 436 }
437 437
438 438 _hg_cmd_qselect()
439 439 {
440 440 local guards=$(_hg_ext_mq_guards)
441 441 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$guards' -- "$cur"))
442 442 }
443 443
444 444 _hg_cmd_qguard()
445 445 {
446 446 local prefix=''
447 447
448 448 if [[ "$cur" == +* ]]; then
449 449 prefix=+
450 450 elif [[ "$cur" == -* ]]; then
451 451 prefix=-
452 452 fi
453 453 local ncur=${cur#[-+]}
454 454
455 455 if ! [ "$prefix" ]; then
456 456 _hg_ext_mq_patchlist qseries
457 457 return
458 458 fi
459 459
460 460 local guards=$(_hg_ext_mq_guards)
461 461 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -P $prefix -W '$guards' -- "$ncur"))
462 462 }
463 463
464 464 _hg_opt_qguard()
465 465 {
466 466 local i
467 467 for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do
468 468 if [[ ${COMP_WORDS[i]} != -* ]]; then
469 469 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
470 470 _hg_cmd_qguard
471 471 return 0
472 472 fi
473 473 elif [ "${COMP_WORDS[i]}" = -- ]; then
474 474 _hg_cmd_qguard
475 475 return 0
476 476 fi
477 477 done
478 478 return 1
479 479 }
480 480
481 481 _hg_cmd_qqueue()
482 482 {
483 483 local q
484 484 local queues
485 485 local opts="--list --create --rename --delete --purge"
486 486
487 487 queues=$( _hg_cmd qqueue --quiet )
488 488
489 489 COMPREPLY=( $( compgen -W "${opts} ${queues}" "${cur}" ) )
490 490 }
491 491
492 492
493 493 # hbisect
494 494 _hg_cmd_bisect()
495 495 {
496 496 local i subcmd
497 497
498 498 # find the sub-command
499 499 for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do
500 500 if [[ ${COMP_WORDS[i]} != -* ]]; then
501 501 if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
502 502 subcmd="${COMP_WORDS[i]}"
503 503 break
504 504 fi
505 505 fi
506 506 done
507 507
508 508 if [ -z "$subcmd" ] || [ $COMP_CWORD -eq $i ] || [ "$subcmd" = help ]; then
509 509 COMPREPLY=(${COMPREPLY[@]:-}
510 510 $(compgen -W 'bad good help init next reset' -- "$cur"))
511 511 return
512 512 fi
513 513
514 514 case "$subcmd" in
515 515 good|bad)
516 516 _hg_labels
517 517 ;;
518 518 esac
519 519
520 520 return
521 521 }
522 522
523 523
524 524 # patchbomb
525 525 _hg_cmd_email()
526 526 {
527 527 case "$prev" in
528 528 -c|--cc|-t|--to|-f|--from|--bcc)
529 529 # we need an e-mail address. let the user provide a function
530 530 # to get them
531 531 if [ "$(type -t _hg_emails)" = function ]; then
532 532 local arg=to
533 533 if [[ "$prev" == @(-f|--from) ]]; then
534 534 arg=from
535 535 fi
536 536 local addresses=$(_hg_emails $arg)
537 537 COMPREPLY=(${COMPREPLY[@]:-}
538 538 $(compgen -W '$addresses' -- "$cur"))
539 539 fi
540 540 return
541 541 ;;
542 542 -m|--mbox)
543 543 # fallback to standard filename completion
544 544 return
545 545 ;;
546 546 -s|--subject)
547 547 # free form string
548 548 return
549 549 ;;
550 550 esac
551 551
552 552 _hg_labels
553 553 return
554 554 }
555 555
556 556
557 557 # gpg
558 558 _hg_cmd_sign()
559 559 {
560 560 _hg_labels
561 561 }
562 562
563 563
564 564 # transplant
565 565 _hg_cmd_transplant()
566 566 {
567 567 case "$prev" in
568 568 -s|--source)
569 569 _hg_paths
570 570 _hg_repos
571 571 return
572 572 ;;
573 573 --filter)
574 574 # standard filename completion
575 575 return
576 576 ;;
577 577 esac
578 578
579 579 # all other transplant options values and command parameters are revisions
580 580 _hg_labels
581 581 return
582 582 }
583 583
584 584 # shelve
585 585 _hg_shelves()
586 586 {
587 587 local shelves="$(_hg_cmd unshelve -l .)"
588 588 local IFS=$'\n'
589 589 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$shelves' -- "$cur"))
590 590 }
591 591
592 592 _hg_cmd_shelve()
593 593 {
594 594 _hg_status "mard"
595 595 }
596 596
597 597 _hg_cmd_unshelve()
598 598 {
599 599 _hg_shelves
600 600 }
General Comments 0
You need to be logged in to leave comments. Login now