zshrc: Using "emulate -L"s in functions where needed
[grml-etc-core.git] / etc / zsh / completion.d / _hg
1 #compdef hg
2
3 # Zsh completion script for mercurial.  Rename this file to _hg and copy
4 # it into your zsh function path (/usr/share/zsh/site-functions for
5 # instance)
6 #
7 # Copyright (C) 2005 Steve Borho
8 #
9 # This is free software; you can redistribute it and/or modify it under
10 # the terms of the GNU General Public License as published by the Free
11 # Software Foundation; either version 2 of the License, or (at your
12 # option) any later version.
13 #
14
15 local curcontext="$curcontext" state line
16 typeset -A opt_args
17 local subcmds repos tags newFiles addedFiles includeExclude commitMessage
18
19 _mq_state () {
20   case "$state" in
21     (qapplied)
22       compadd $(hg qapplied)
23     ;;
24     (qunapplied)
25       compadd $(hg qunapplied)
26     ;;
27   esac
28 }
29
30 tags=($(hg tags 2> /dev/null | sed -e 's/[0-9]*:[a-f0-9]\{40\}$//; s/ *$//'))
31 subcmds=($(hg -v help | sed -e '1,/^list of commands:/d' \
32       -e '/^global options:/,$d' -e '/^ [^ ]/!d; s/[,:].*//g;'))
33
34 # A lot of commands have these arguments
35 includeExclude=(
36         '*-I-[include names matching the given patterns]:dir:_files -W $(hg root) -/'
37         '*--include-[include names matching the given patterns]:dir:_files -W $(hg root) -/'
38         '*-X-[exclude names matching the given patterns]:dir:_files -W $(hg root) -/'
39         '*--exclude-[exclude names matching the given patterns]:dir:_files -W $(hg root) -/')
40
41 commitMessage=(
42         '(-m --message -l --logfile --edit)-e[edit commit message]'
43         '(-m --message -l --logfile -e)--edit[edit commit message]'
44         '(-e --edit -l --logfile --message)-m[use <text> as commit message]:message:'
45         '(-e --edit -l --logfile -m)--message[use <text> as commit message]:message:'
46         '(-e --edit -m --message --logfile)-l[read the commit message from <file>]:log file:_files'
47         '(-e --edit -m --message -l)--logfile[read the commit message from <file>]:log file:_files')
48
49 if [[ $service == "hg" ]]; then
50     _arguments -C -A "-*" \
51     '(--repository)-R[repository root directory]:root:_files -/' \
52     '(-R)--repository[repository root directory]:root:_files -/' \
53     '--cwd[change working directory]:new working directory:_files -/' \
54     '(--noninteractive)-y[do not prompt, assume yes for any required answers]' \
55     '(-y)--noninteractive[do not prompt, assume yes for any required answers]' \
56     '(--verbose)-v[enable additional output]' \
57     '(-v)--verbose[enable additional output]' \
58     '(--quiet)-q[suppress output]' \
59     '(-q)--quiet[suppress output]' \
60     '(--help)-h[display help and exit]' \
61     '(-h)--help[display help and exit]' \
62     '--debug[debug mode]' \
63     '--debugger[start debugger]' \
64     '--traceback[print traceback on exception]' \
65     '--time[time how long the command takes]' \
66     '--profile[profile]' \
67     '--version[output version information and exit]' \
68     '*::command:->subcmd' && return 0
69
70     if (( CURRENT == 1 )); then
71         _wanted commands expl 'hg command' compadd -a subcmds
72         return
73     fi
74     service="$words[1]"
75     curcontext="${curcontext%:*}=$service:"
76 fi
77
78 case $service in
79     (add)
80         newFiles=(${(ps:\0:)"$(hg status -0un .)"})
81         _arguments $includeExclude \
82         '*:file:->unknown'
83         _wanted files expl 'unknown files' compadd -a newFiles
84     ;;
85
86     (addremove)
87         _arguments $includeExclude \
88         '*:directories:_files -/'  # assume they want to add/remove a dir
89     ;;
90
91     (forget)
92         addedFiles=(${(ps:\0:)"$(hg status -0an .)"})
93         _arguments $includeExclude  \
94         '*:file:->added'
95         _wanted files expl 'newly added files' compadd -a addedFiles
96     ;;
97
98     (remove|rm)
99         _arguments $includeExclude \
100         '*:file:_files'
101     ;;
102
103     (copy|cp)
104         _arguments $includeExclude \
105         '(--after)-A[record a copy that has already occurred]' \
106         '(-A)--after[record a copy that has already occurred]' \
107         '(--force)-f[forcibly copy over an existing managed file]' \
108         '(-f)--force[forcibly copy over an existing managed file]' \
109         '(--parents)-p[append source path to dest]' \
110         '(-p)--parents[append source path to dest]' \
111         '*:files:_files'
112     ;;
113
114     (rename|mv)
115         if (( CURRENT == 2 )); then
116             _arguments $includeExclude \
117             '(--after)-A[record a rename that has already occurred]' \
118             '(-A)--after[record a rename that has already occurred]' \
119             '(--force)-f[replace destination if it exists]' \
120             '(-F)--force[replace destination if it exists]' \
121             '(--parents)-p[append source path to dest]' \
122             '(-p)--parents[append source path to dest]' \
123             '*:files:_files'
124         else
125             _arguments '*:destination:_files'
126         fi
127     ;;
128
129     (diff)
130         _arguments $includeExclude \
131         '*-r[revision]:revision:($tags)' \
132         '*--rev[revision]:revision:($tags)' \
133         '(--text)-a[treat all files as text]' \
134         '(-a)--text[treat all files as text]' \
135         '*:file:_files'
136     ;;
137
138     (status|st)
139         _arguments $includeExclude \
140         '(--no-status)-n[hide status prefix]' \
141         '(-n)--no-status[hide status prefix]' \
142         '(--print0)-0[end filenames with NUL, for use with xargs]' \
143         '(-0)--print0[end filenames with NUL, for use with xargs]' \
144         '(--modified)-m[show only modified files]' \
145         '(-m)--modified[show only modified files]' \
146         '(--added)-a[show only added files]' \
147         '(-a)--added[show only added files]' \
148         '(--removed)-r[show only removed files]' \
149         '(-r)--removed[show only removed files]' \
150         '(--unknown)-u[show only unknown files]' \
151         '(-u)--unknown[show only unknown files]' \
152         '*:search pattern, then files:_files'
153     ;;
154
155     (revert)
156         addedFiles=(${(ps:\0:)"$(hg status -0amrn .)"})
157         _arguments \
158         '(--rev)-r[revision to revert to]:revision:($tags)' \
159         '(-r)--rev[revision to revert to]:revision:($tags)' \
160         '(--nonrecursive)-n[do not recurse into subdirectories]' \
161         '(-n)--nonrecursive[do not recurse into subdirectories]' \
162         '*:file:->modified'
163         _wanted files expl 'mofified files' compadd -a addedFiles
164     ;;
165
166     (commit|ci)
167         addedFiles=(${(ps:\0:)"$(hg status -0amrn .)"})
168         _arguments $includeExclude \
169         '(--addremove)-A[run addremove during commit]' \
170         '(-A)--addremove[run addremove during commit]' \
171         '(--message)-m[use <txt> as commit message]:string:' \
172         '(-m)--message[use <txt> as commit message]:string:' \
173         '(--logfile)-l[read commit message from <file>]:.log file:_file -g \*.txt' \
174         '(-l)--logfile[read commit message from <file>]:.log file:_file -g \*.txt' \
175         '(--date)-d[record datecode as commit date]:date code:' \
176         '(-d)--date[record datecode as commit date]:date code:' \
177         '(--user)-u[record user as commiter]:user:' \
178         '(-u)--user[record user as commiter]:user:' \
179         '*:file:->modified'
180         _wanted files expl 'mofified files' compadd -a addedFiles
181     ;;
182
183     (cat)
184         _arguments $includeExclude \
185         '(--output)-o[print output to file with formatted name]:filespec:' \
186         '(-o)--output[print output to file with formatted name]:filespec:' \
187         '(--rev)-r[revision]:revision:($tags)' \
188         '(-r)--rev[revision]:revision:($tags)' \
189         '*:file:_files'
190     ;;
191
192     (annotate)
193         _arguments $includeExclude \
194         '(--rev)-r[annotate the specified revision]:revision:($tags)' \
195         '(-r)--rev[annotate the specified revision]:revision:($tags)' \
196         '(--text)-a[treat all files as text]' \
197         '(-a)--text[treat all files as text]' \
198         '(--user)-u[list the author]' \
199         '(-u)--user[list the author]' \
200         '(--changeset)-c[list the changeset]' \
201         '(-c)--changeset[list the changeset]' \
202         '(--number)-n[list the revision number (default)]' \
203         '(-n)--number[list the revision number (default)]' \
204         '*:files:_files'
205     ;;
206
207     (grep)
208         _arguments $includeExclude \
209         '*-r[search in given revision range]:revision:($tags)' \
210         '*--rev[search in given revision range]:revision:($tags)' \
211         '--all[print all revisions with matches]' \
212         '(-print0)-0[end filenames with NUL, for use with xargs]' \
213         '(-0)--print0[end filenames with NUL, for use with xargs]' \
214         '(--ignore-case)-i[ignore case when matching]' \
215         '(-i)--ignore-case[ignore case when matching]' \
216         '(--files-with-matches)-l[print names of files and revs that match]' \
217         '(-l)--files-with-matches[print names of files and revs that match]' \
218         '(--line-number)-n[print matching line numbers]' \
219         '(-n)--line-number[print matching line numbers]' \
220         '(--user)-u[print user who committed change]' \
221         '(-u)--user[print user who committed change]' \
222         '*:search pattern:'
223     ;;
224
225     (locate)
226         _arguments $includeExclude \
227         '(--rev)-r[search repository as it stood at revision]:revision:($tags)' \
228         '(-r)--rev[search repository as it stood at revision]:revision:($tags)' \
229         '(--print0)-0[end filenames with NUL, for use with xargs]' \
230         '(-0)--print0[end filenames with NUL, for use with xargs]' \
231         '(--fullpath)-f[print complete paths]' \
232         '(-f)--fullpath[print complete paths]' \
233         '*:search pattern:'
234     ;;
235
236     (log|history)
237         _arguments $includeExclude \
238         '*-r[show the specified revision or range]:revision:($tags)' \
239         '*--rev[show the specified revision or range]:revision:($tags)' \
240         '(--no-merges -M --only-merges)-m[show only merge revisions]' \
241         '(--no-merges -M -m)--only-merges[show only merge revisions]' \
242         '(--only-merges -m --no-merges)-M[do not show merge revisions]' \
243         '(--only-merges -m -M)--no-merges[do not show merge revisions]' \
244         '(--keyword)-k[search for a keyword]:keyword:' \
245         '(-k)--keyword[search for a keyword]:keyword:' \
246         '(--branch)-b[show branches]' \
247         '(-b)--branch[show branches]' \
248         '(--patch)-p[show patch]' \
249         '(-p)--patch[show patch]' \
250         '*:file:_files'
251     ;;
252
253     (update|checkout|co)
254         _arguments \
255         '(--branch)-b[checkout the head of a specific branch]' \
256         '(-b)--branch[checkout the head of a specific branch]' \
257         '(-C --clean --merge)-m[allow merging of branches]' \
258         '(-C --clean -m)--merge[allow merging of branches]' \
259         '(-m --merge --clean)-C[overwrite locally modified files]' \
260         '(-m --merge -C)--clean[overwrite locally modified files]' \
261         '*:revision or tag:($tags)'
262     ;;
263
264     (tag)
265         _arguments \
266         '(--local)-l[make the tag local]' \
267         '(-l)--local[make the tag local]' \
268         '(--message)-m[message for tag commit log entry]:string:' \
269         '(-m)--message[message for tag commit log entry]:string:' \
270         '(--date)-d[record datecode as commit date]:date code:' \
271         '(-d)--date[record datecode as commit date]:date code:' \
272         '(--user)-u[record user as commiter]:user:' \
273         '(-u)--user[record user as commiter]:user:' \
274         '*:name, then revision:($tags)'
275     ;;
276
277     (clone)
278         if (( CURRENT == 2 )); then
279             repos=( $(hg paths | sed -e 's/^.*= //') )
280             _arguments \
281             '(--no-update)-U[do not update the new working directory]' \
282             '(-U)--no-update[do not update the new working directory]' \
283             '(--ssh)-e[specify ssh command to use]:string:' \
284             '(-e)--ssh[specify ssh command to use]:string:' \
285             '--pull[use pull protocol to copy metadata]' \
286             '--remotecmd[specify hg command to run on the remote side]:remote hg:' \
287             '*:local repo:_files -/'
288             _wanted source expl 'source repository' compadd -a repos
289         elif (( CURRENT == 3 )); then
290             _arguments '*:dest repo:_files -/'
291         fi
292     ;;
293
294     (rawcommit)
295         _arguments \
296         '(--parent)-p[parent revision]:revision:($tags)' \
297         '(-p)--parent[parent revision]:revision:($tags)' \
298         '(--date)-d[record datecode as commit date]:date code:' \
299         '(-d)--date[record datecode as commit date]:date code:' \
300         '(--user)-u[record user as commiter]:user:' \
301         '(-u)--user[record user as commiter]:user:' \
302         '(--message)-m[use <txt> as commit message]:string:' \
303         '(-m)--message[use <txt> as commit message]:string:' \
304         '(--logfile)-l[read commit message from <file>]:.log file:_file -g \*.txt' \
305         '(-l)--logfile[read commit message from <file>]:.log file:_file -g \*.txt' \
306         '(--files)-F[file list]:file list:_files' \
307         '(-F)--files[file list]:file list:_files' \
308         '*:files to commit:_files'
309     ;;
310
311     (bundle)
312         if (( CURRENT == 2 )); then
313             _arguments '*:changegroup file:_files -g \*.hg'
314         elif (( CURRENT == 3 )); then
315             _arguments '*:other repo:_files -/'
316         fi
317     ;;
318
319     (unbundle)
320         _arguments '*:changegroup .hg file:_files -g \*.hg'
321     ;;
322
323     (incoming)
324         _arguments \
325         '(--patch)-p[show patch]' \
326         '(-p)--patch[show patch]' \
327         '(--no-merges)-M[do not show merge revisions]' \
328         '(-M)--no-merges[do not show merge revisions]' \
329         '(--newest-first)-n[show newest record first]' \
330         '(-n)--newest-first[show newest record first]' \
331         '*:mercurial repository:_files -/'
332     ;;
333
334     (import|patch)
335         _arguments \
336         '(--strip)-p[directory strip option for patch (default: 1)]:count:' \
337         '(-p)--strip[directory strip option for patch (default: 1)]:count:' \
338         '(--force)-f[skip check for outstanding uncommitted changes]' \
339         '(-f)--force[skip check for outstanding uncommitted changes]' \
340         '(--base)-b[base directory to read patches from]:file:_files -W $(hg root) -/' \
341         '(-b)--base[base directory to read patches from]:file:_files -W $(hg root) -/' \
342         '*:patch file:_files'
343     ;;
344
345     (pull)
346         repos=( $(hg paths | sed -e 's/^.*= //') )
347         _arguments \
348         '(--update)-u[update working directory to tip after pull]' \
349         '(-u)--update[update working directory to tip after pull]' \
350         '(--ssh)-e[specify ssh command to use]:ssh command:' \
351         '(-e)--ssh[specify ssh command to use]:ssh command:' \
352         '--remotecmd[specify hg command to run on the remote side]:remote hg:' \
353         '*:local repo:_files -/'
354         _wanted source expl 'source repository' compadd -a repos
355     ;;
356
357     (outgoing)
358         _arguments \
359         '(--patch)-p[show patch]' \
360         '(-p)--patch[show patch]' \
361         '(--no-merges)-M[do not show merge revisions]' \
362         '(-M)--no-merges[do not show merge revisions]' \
363         '(--newest-first)-n[show newest record first]' \
364         '(-n)--newest-first[show newest record first]' \
365         '*:local repo:_files -/'
366         _wanted source expl 'source repository' compadd -a repos
367     ;;
368
369     (export)
370         _arguments \
371         '(--outout)-o[print output to file with formatted name]:filespec:' \
372         '(-o)--output[print output to file with formatted name]:filespec:' \
373         '(--text)-a[treat all files as text]' \
374         '(-a)--text[treat all files as text]' \
375         '*:revision:->revs'
376         _wanted revs expl 'revision or tag' compadd -a tags
377     ;;
378
379     (push)
380         repos=( $(hg paths | sed -e 's/^.*= //') )
381         _arguments \
382         '(--force)-f[force push]' \
383         '(-f)--force[force push]' \
384         '(--ssh)-e[specify ssh command to use]:ssh command:' \
385         '(-e)--ssh[specify ssh command to use]:ssh command:' \
386         '--remotecmd[specify hg command to run on the remote side]:remote hg:' \
387         '*:local repo:_files -/'
388         _wanted source expl 'source repository' compadd -a repos
389     ;;
390
391     (serve)
392         _arguments \
393         '(--accesslog)-A[name of access log file]:log file:_files' \
394         '(-A)--accesslog[name of access log file]:log file:_files' \
395         '(--errorlog)-E[name of error log file]:log file:_files' \
396         '(-E)--errorlog[name of error log file]:log file:_files' \
397         '(--port)-p[listen port]:listen port:' \
398         '(-p)--port[listen port]:listen port:' \
399         '(--address)-a[interface address]:interface address:' \
400         '(-a)--address[interface address]:interface address:' \
401         '(--name)-n[name to show in web pages]:repository name:' \
402         '(-n)--name[name to show in web pages]:repository name:' \
403         '(--templates)-t[web template directory]:template dir:_files -/' \
404         '(-t)--templates[web template directory]:template dir:_files -/' \
405         '--style[web template style]:style' \
406         '--stdio[for remote clients]' \
407         '(--ipv6)-6[use IPv6 in addition to IPv4]' \
408         '(-6)--ipv6[use IPv6 in addition to IPv4]'
409     ;;
410
411     (help)
412         _wanted commands expl 'hg command' compadd -a subcmds
413     ;;
414
415     (heads)
416         _arguments \
417         '(--branches)-b[find branch info]' \
418         '(-b)--branches[find branch info]'
419     ;;
420
421     (paths)
422         _arguments '*:symbolic name:(default default-push)'
423     ;;
424
425     (init)
426         _arguments '*:new repo directory:_files -/'
427     ;;
428
429     (manifest)
430         _arguments '*:revision:($tags)'
431     ;;
432
433     (parents)
434         _arguments '*:revision:($tags)'
435     ;;
436
437     (identify|recover|root|undo|view|verify|version|ct|tags)
438         # no arguments for these commands
439     ;;
440
441     # MQ commands
442     (qdel*|qrm|qrem*)
443         _arguments \
444             {-k,--keep}'[keep patch file]' \
445             {-r,--rev}'[revision]:applied patch:->qapplied' \
446             '*:unapplied patches:->qunapplied'
447         _mq_state
448     ;;
449
450     (qnew)
451         _arguments $commitMessage \
452             {-f,--force}'[import uncommitted changes into patch]' \
453             ':patch name:'
454     ;;
455
456     (qpo*)
457         applied=( $(hg qapplied) )
458         _arguments \
459             (1){-a,--all}'[pop all patches]' \
460             {-f,--force}'[forget any local changes]' \
461             ':applied patch:->qapplied'
462         _mq_state
463     ;;
464
465     (qpu*)
466         _arguments \
467             (1){-a,--all}'[apply all patches]' \
468             {-f,--force}'[apply if the patch has rejects]' \
469             ':unapplied patch:->qunapplied'
470         _mq_state
471     ;;
472     (qref*)
473         _arguments $commitMessage $includeExclude \
474             {-g,--git}'[use git extended diff format]' \
475             {-s,--short}'[short refresh]'
476     ;;
477
478     (*)
479         _message "unknown hg command completion: $service"
480     ;;
481 esac