Subversion Repositories configs

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 - 1
# bash completion for the Mercurial distributed SCM
2
 
3
# Docs:
4
#
5
# If you source this file from your .bashrc, bash should be able to
6
# complete a command line that uses hg with all the available commands
7
# and options and sometimes even arguments.
8
#
9
# Mercurial allows you to define additional commands through extensions.
10
# Bash should be able to automatically figure out the name of these new
11
# commands and their options.  See below for how to define _hg_opt_foo
12
# and _hg_cmd_foo functions to fine-tune the completion for option and
13
# non-option arguments, respectively.
14
#
15
#
16
# Notes about completion for specific commands:
17
#
18
# - the completion function for the email command from the patchbomb
19
#   extension will try to call _hg_emails to get a list of e-mail
20
#   addresses.  It's up to the user to define this function.  For
21
#   example, put the addresses of the lists that you usually patchbomb
22
#   in ~/.patchbomb-to and the addresses that you usually use to send
23
#   the patchbombs in ~/.patchbomb-from and use something like this:
24
#
25
#      _hg_emails()
26
#      {
27
#          if [ -r ~/.patchbomb-$1 ]; then
28
#              cat ~/.patchbomb-$1
29
#          fi
30
#      }
31
#
32
#
33
# Writing completion functions for additional commands:
34
#
35
# If it exists, the function _hg_cmd_foo will be called without
36
# arguments to generate the completion candidates for the hg command
37
# "foo".  If the command receives some arguments that aren't options
38
# even though they start with a "-", you can define a function called
39
# _hg_opt_foo to generate the completion candidates.  If _hg_opt_foo
40
# doesn't return 0, regular completion for options is attempted.
41
#
42
# In addition to the regular completion variables provided by bash,
43
# the following variables are also set:
44
# - $hg - the hg program being used (e.g. /usr/bin/hg)
45
# - $cmd - the name of the hg command being completed
46
# - $cmd_index - the index of $cmd in $COMP_WORDS
47
# - $cur - the current argument being completed
48
# - $prev - the argument before $cur
49
# - $global_args - "|"-separated list of global options that accept
50
#                  an argument (e.g. '--cwd|-R|--repository')
51
# - $canonical - 1 if we canonicalized $cmd before calling the function
52
#                0 otherwise
53
#
54
 
55
shopt -s extglob
56
 
57
_hg_commands()
58
{
59
    local commands
60
    commands="$("$hg" debugcomplete "$cur" 2>/dev/null)" || commands=""
61
    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$commands' -- "$cur"))
62
}
63
 
64
_hg_paths()
65
{
66
    local paths="$("$hg" paths 2>/dev/null | sed -e 's/ = .*$//')"
67
    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$paths' -- "$cur"))
68
}
69
 
70
_hg_repos()
71
{
72
    local i
73
    for i in $(compgen -d -- "$cur"); do
74
	test ! -d "$i"/.hg || COMPREPLY=(${COMPREPLY[@]:-} "$i")
75
    done
76
}
77
 
78
_hg_status()
79
{
80
    local files="$("$hg" status -n$1 . 2>/dev/null)"
81
    local IFS=$'\n'
82
    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
83
}
84
 
85
_hg_tags()
86
{
87
    local tags="$("$hg" tags -q 2>/dev/null)"
88
    local IFS=$'\n'
89
    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$tags' -- "$cur"))
90
}
91
 
92
_hg_branches()
93
{
94
    local branches="$("$hg" branches -q 2>/dev/null)"
95
    local IFS=$'\n'
96
    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$branches' -- "$cur"))
97
}
98
 
99
# this is "kind of" ugly...
100
_hg_count_non_option()
101
{
102
    local i count=0
103
    local filters="$1"
104
 
105
    for ((i=1; $i<=$COMP_CWORD; i++)); do
106
	if [[ "${COMP_WORDS[i]}" != -* ]]; then
107
	    if [[ ${COMP_WORDS[i-1]} == @($filters|$global_args) ]]; then
108
		continue
109
	    fi
110
	    count=$(($count + 1))
111
	fi
112
    done
113
 
114
    echo $(($count - 1))
115
}
116
 
117
_hg()
118
{
119
    local cur prev cmd cmd_index opts i
120
    # global options that receive an argument
121
    local global_args='--cwd|-R|--repository'
122
    local hg="$1"
123
    local canonical=0
124
 
125
    COMPREPLY=()
126
    cur="$2"
127
    prev="$3"
128
 
129
    # searching for the command
130
    # (first non-option argument that doesn't follow a global option that
131
    #  receives an argument)
132
    for ((i=1; $i<=$COMP_CWORD; i++)); do
133
	if [[ ${COMP_WORDS[i]} != -* ]]; then
134
	    if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
135
		cmd="${COMP_WORDS[i]}"
136
		cmd_index=$i
137
		break
138
	    fi
139
	fi
140
    done
141
 
142
    if [[ "$cur" == -* ]]; then
143
	if [ "$(type -t "_hg_opt_$cmd")" = function ] && "_hg_opt_$cmd"; then
144
	    return
145
	fi
146
 
147
	opts=$("$hg" debugcomplete --options "$cmd" 2>/dev/null)
148
 
149
	COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur"))
150
	return
151
    fi
152
 
153
    # global options
154
    case "$prev" in
155
	-R|--repository)
156
	    _hg_paths
157
	    _hg_repos
158
	    return
159
	;;
160
	--cwd)
161
	    # Stick with default bash completion
162
	    return
163
	;;
164
    esac
165
 
166
    if [ -z "$cmd" ] || [ $COMP_CWORD -eq $i ]; then
167
	_hg_commands
168
	return
169
    fi
170
 
171
    # try to generate completion candidates for whatever command the user typed
172
    local help
173
    if _hg_command_specific; then
174
	return
175
    fi
176
 
177
    # canonicalize the command name and try again
178
    help=$("$hg" help "$cmd" 2>/dev/null)
179
    if [ $? -ne 0 ]; then
180
	# Probably either the command doesn't exist or it's ambiguous
181
	return
182
    fi
183
    cmd=${help#hg }
184
    cmd=${cmd%%[$' \n']*}
185
    canonical=1
186
    _hg_command_specific
187
}
188
 
189
_hg_command_specific()
190
{
191
    if [ "$(type -t "_hg_cmd_$cmd")" = function ]; then
192
	"_hg_cmd_$cmd"
193
	return 0
194
    fi
195
 
196
    if [ "$cmd" != status ] && [ "$prev" = -r ] || [ "$prev" == --rev ]; then
197
	if [ $canonical = 1 ]; then
198
	    _hg_tags
199
	    _hg_branches
200
	    return 0
201
	elif [[ status != "$cmd"* ]]; then
202
	    _hg_tags
203
	    _hg_branches
204
	    return 0
205
	else
206
	    return 1
207
	fi
208
    fi
209
 
210
    case "$cmd" in
211
	help)
212
	    _hg_commands
213
	;;
214
	export)
215
	    if _hg_ext_mq_patchlist qapplied && [ "${COMPREPLY[*]}" ]; then
216
		return 0
217
	    fi
218
	    _hg_tags
219
	    _hg_branches
220
	;;
221
	manifest|update)
222
	    _hg_tags
223
	    _hg_branches
224
	;;
225
	pull|push|outgoing|incoming)
226
	    _hg_paths
227
	    _hg_repos
228
	;;
229
	paths)
230
	    _hg_paths
231
	;;
232
	add)
233
	    _hg_status "u"
234
	;;
235
	merge)
236
	    _hg_tags
237
	    _hg_branches
238
	;;
239
	commit)
240
	    _hg_status "mar"
241
	;;
242
	remove)
243
	    _hg_status "d"
244
	;;
245
	forget)
246
	    _hg_status "a"
247
	;;
248
	diff)
249
	    _hg_status "mar"
250
	;;
251
	revert)
252
	    _hg_status "mard"
253
	;;
254
	clone)
255
	    local count=$(_hg_count_non_option)
256
	    if [ $count = 1 ]; then
257
		_hg_paths
258
	    fi
259
	    _hg_repos
260
	;;
261
	debugindex|debugindexdot)
262
	    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.i" -- "$cur"))
263
	;;
264
	debugdata)
265
	    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.d" -- "$cur"))
266
	;;
267
	*)
268
	    return 1
269
	;;
270
    esac
271
 
272
    return 0
273
}
274
 
275
complete -o bashdefault -o default -F _hg hg 2>/dev/null \
276
    || complete -o default -F _hg hg
277
 
278
 
279
# Completion for commands provided by extensions
280
 
281
# bookmarks
282
_hg_bookmarks()
283
{
284
    local bookmarks="$("$hg" bookmarks --quiet 2>/dev/null )"
285
    local IFS=$'\n'
286
    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$bookmarks' -- "$cur"))
287
}
288
 
289
_hg_cmd_bookmarks()
290
{
291
    if [[ "$prev" = @(-d|--delete|-m|--rename) ]]; then
292
        _hg_bookmarks
293
        return
294
    fi
295
}
296
 
297
# mq
298
_hg_ext_mq_patchlist()
299
{
300
    local patches
301
    patches=$("$hg" $1 2>/dev/null)
302
    if [ $? -eq 0 ] && [ "$patches" ]; then
303
	COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$patches' -- "$cur"))
304
	return 0
305
    fi
306
    return 1
307
}
308
 
309
_hg_ext_mq_queues()
310
{
311
    local root=$("$hg" root 2>/dev/null)
312
    local n
313
    for n in $(cd "$root"/.hg && compgen -d -- "$cur"); do
314
	# I think we're usually not interested in the regular "patches" queue
315
	# so just filter it.
316
	if [ "$n" != patches ] && [ -e "$root/.hg/$n/series" ]; then
317
	    COMPREPLY=(${COMPREPLY[@]:-} "$n")
318
	fi
319
    done
320
}
321
 
322
_hg_cmd_qpop()
323
{
324
    if [[ "$prev" = @(-n|--name) ]]; then
325
	_hg_ext_mq_queues
326
	return
327
    fi
328
    _hg_ext_mq_patchlist qapplied
329
}
330
 
331
_hg_cmd_qpush()
332
{
333
    if [[ "$prev" = @(-n|--name) ]]; then
334
	_hg_ext_mq_queues
335
	return
336
    fi
337
    _hg_ext_mq_patchlist qunapplied
338
}
339
 
340
_hg_cmd_qgoto()
341
{
342
    if [[ "$prev" = @(-n|--name) ]]; then
343
	_hg_ext_mq_queues
344
	return
345
    fi
346
    _hg_ext_mq_patchlist qseries
347
}
348
 
349
_hg_cmd_qdelete()
350
{
351
    local qcmd=qunapplied
352
    if [[ "$prev" = @(-r|--rev) ]]; then
353
	qcmd=qapplied
354
    fi
355
    _hg_ext_mq_patchlist $qcmd
356
}
357
 
358
_hg_cmd_qfinish()
359
{
360
    if [[ "$prev" = @(-a|--applied) ]]; then
361
	return
362
    fi
363
    _hg_ext_mq_patchlist qapplied
364
}
365
 
366
_hg_cmd_qsave()
367
{
368
    if [[ "$prev" = @(-n|--name) ]]; then
369
	_hg_ext_mq_queues
370
	return
371
    fi
372
}
373
 
374
_hg_cmd_strip()
375
{
376
    _hg_tags
377
    _hg_branches
378
}
379
 
380
_hg_cmd_qcommit()
381
{
382
    local root=$("$hg" root 2>/dev/null)
383
    # this is run in a sub-shell, so we can't use _hg_status
384
    local files=$(cd "$root/.hg/patches" 2>/dev/null &&
385
                  "$hg" status -nmar 2>/dev/null)
386
    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
387
}
388
 
389
_hg_cmd_qfold()
390
{
391
    _hg_ext_mq_patchlist qunapplied
392
}
393
 
394
_hg_cmd_qrename()
395
{
396
    _hg_ext_mq_patchlist qseries
397
}
398
 
399
_hg_cmd_qheader()
400
{
401
    _hg_ext_mq_patchlist qseries
402
}
403
 
404
_hg_cmd_qclone()
405
{
406
    local count=$(_hg_count_non_option)
407
    if [ $count = 1 ]; then
408
	_hg_paths
409
    fi
410
    _hg_repos
411
}
412
 
413
_hg_ext_mq_guards()
414
{
415
    "$hg" qselect --series 2>/dev/null | sed -e 's/^.//'
416
}
417
 
418
_hg_cmd_qselect()
419
{
420
    local guards=$(_hg_ext_mq_guards)
421
    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$guards' -- "$cur"))
422
}
423
 
424
_hg_cmd_qguard()
425
{
426
    local prefix=''
427
 
428
    if [[ "$cur" == +* ]]; then
429
	prefix=+
430
    elif [[ "$cur" == -* ]]; then
431
	prefix=-
432
    fi
433
    local ncur=${cur#[-+]}
434
 
435
    if ! [ "$prefix" ]; then
436
	_hg_ext_mq_patchlist qseries
437
	return
438
    fi
439
 
440
    local guards=$(_hg_ext_mq_guards)
441
    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -P $prefix -W '$guards' -- "$ncur"))
442
}
443
 
444
_hg_opt_qguard()
445
{
446
    local i
447
    for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do
448
	if [[ ${COMP_WORDS[i]} != -* ]]; then
449
	    if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
450
		_hg_cmd_qguard
451
		return 0
452
	    fi
453
	elif [ "${COMP_WORDS[i]}" = -- ]; then
454
	    _hg_cmd_qguard
455
	    return 0
456
	fi
457
    done
458
    return 1
459
}
460
 
461
 
462
# hbisect
463
_hg_cmd_bisect()
464
{
465
    local i subcmd
466
 
467
    # find the sub-command
468
    for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do
469
	if [[ ${COMP_WORDS[i]} != -* ]]; then
470
	    if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
471
		subcmd="${COMP_WORDS[i]}"
472
		break
473
	    fi
474
	fi
475
    done
476
 
477
    if [ -z "$subcmd" ] || [ $COMP_CWORD -eq $i ] || [ "$subcmd" = help ]; then
478
	COMPREPLY=(${COMPREPLY[@]:-}
479
		   $(compgen -W 'bad good help init next reset' -- "$cur"))
480
	return
481
    fi
482
 
483
    case "$subcmd" in
484
	good|bad)
485
	    _hg_tags
486
	    _hg_branches
487
	    ;;
488
    esac
489
 
490
    return
491
}
492
 
493
 
494
# patchbomb
495
_hg_cmd_email()
496
{
497
    case "$prev" in
498
	-c|--cc|-t|--to|-f|--from|--bcc)
499
	    # we need an e-mail address. let the user provide a function
500
	    # to get them
501
	    if [ "$(type -t _hg_emails)" = function ]; then
502
		local arg=to
503
		if [[ "$prev" == @(-f|--from) ]]; then
504
		    arg=from
505
		fi
506
		local addresses=$(_hg_emails $arg)
507
		COMPREPLY=(${COMPREPLY[@]:-}
508
			   $(compgen -W '$addresses' -- "$cur"))
509
	    fi
510
	    return
511
	    ;;
512
	-m|--mbox)
513
	    # fallback to standard filename completion
514
	    return
515
	    ;;
516
	-s|--subject)
517
	    # free form string
518
	    return
519
	    ;;
520
    esac
521
 
522
    _hg_tags
523
    _hg_branches
524
    return
525
}
526
 
527
 
528
# gpg
529
_hg_cmd_sign()
530
{
531
    _hg_tags
532
    _hg_branches
533
}
534
 
535
 
536
# transplant
537
_hg_cmd_transplant()
538
{
539
    case "$prev" in
540
	-s|--source)
541
	    _hg_paths
542
	    _hg_repos
543
	    return
544
	    ;;
545
	--filter)
546
	    # standard filename completion
547
	    return
548
	    ;;
549
    esac
550
 
551
    # all other transplant options values and command parameters are revisions
552
    _hg_tags
553
    _hg_branches
554
    return
555
}
556
 
557
# shelve
558
_hg_shelves()
559
{
560
    local shelves="$("$hg" unshelve -l . 2>/dev/null)"
561
    local IFS=$'\n'
562
    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$shelves' -- "$cur"))
563
}
564
 
565
_hg_cmd_shelve()
566
{
567
    _hg_status "mard"
568
}
569
 
570
_hg_cmd_unshelve()
571
{
572
    _hg_shelves
573
}