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