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