Zsh completions learn stg float --noapply
[stgit.git] / completion / stgit.zsh
blobdd55e2797737049d5696a9f4075e7afcbf051cda
1 #compdef stg
3 # This script implements zsh completions for StGit (stg).
5 # To use these completions, copy to a directory in $fpath as _stgit.
6 # For example:
8 # $ mkdir ~/.zsh.d
9 # $ cp completion/stgit.zsh ~/.zsh.d/_stgit
10 # $ $EDITOR ~/.zshrc
12 # fpath=("$HOME/.zsh.d" $fpath)
13 # autoload -U compinit
16 _stg-branch() {
17 __stg_add_args_help
18 subcmd_args+=(
19 - group-list
20 '--list[list branches]'
21 - group-switch
22 '--merge[merge worktree changes into other branch]'
23 ':branch:__stg_branch_stgit'
24 - group-create
25 '--create[create and switch to new branch]'
26 ':new-branch:'
27 ':committish:'
28 - group-clone
29 '--clone[clone current branch to new branch]'
30 ':new-branch:'
31 - group-rename
32 '(-r --rename)'{-r,--rename}'[rename existing branch]'
33 ':branch:__stg_branch_stgit'
34 ':new-branch:'
35 - group-protect
36 '(-p --protect)'{-p,--protect}'[prevent stg from modifying branch]'
37 ':branch:__stg_branch_stgit'
38 - group-unprotect
39 '(-u --unprotect)'{-u,--unprotect}'[allow stg to modify branch]'
40 ':branch:__stg_branch_stgit'
41 - group-delete
42 '--delete[delete branch]'
43 '--force[force delete when series is non-empty]'
44 ':branch:__stg_branch_stgit'
45 - group-cleanup
46 '--cleanup[cleanup stg metadata for branch]'
47 '--force[force cleanup when series is non-empty]'
48 ':branch:__stg_branch_stgit'
49 - group-description
50 '(-d --description)'{-d,--description}'[set branch description]:description'
51 ':branch:__stg_branch_stgit'
53 _arguments -s -S $subcmd_args
56 _stg-clean() {
57 __stg_add_args_help
58 subcmd_args+=(
59 '(-a --applied)'{-a,--applied}'[delete empty applied patches]'
60 '(-u --unapplied)'{-u,--unapplied}'[delete empty unapplied patches]'
62 _arguments -s -S $subcmd_args
65 _stg-clone() {
66 __stg_add_args_help
67 subcmd_args+=(
68 ':repository:'
69 ': :_directories'
71 _arguments -s $subcmd_args
74 _stg-commit() {
75 __stg_add_args_help
76 subcmd_args+=(
77 - group-all
78 '(-a --all)'{-a,--all}'[commit all unapplied patches]'
79 - group-number
80 '(-n --number)'{-n+,--number=}'[commit specified number of patches]:number'
81 - group-patches
82 '*:applied patches:__stg_patches_applied'
84 _arguments -s -S $subcmd_args
87 _stg-delete() {
88 __stg_add_args_help
89 __stg_add_args_branch
90 subcmd_args+=(
91 '--spill[spill patch contents to worktree and index]'
92 - group-top
93 '(-t --top)'{-t,--top}'[delete top patch]'
94 - group-patchnames
95 '*:patches:__stg_patches_all'
97 _arguments -s -S $subcmd_args
100 _stg-diff() {
101 __stg_add_args_help
102 __stg_add_args_diffopts
103 subcmd_args+=(
104 '(-r --range)'{-r,--range=}'[show diff between revisions]: :__stg_patches_all'
105 '(-s --stat)'{-s,--stat}'[show stat instead of diff]'
106 '*:files:__stg_changed_files'
108 _arguments -s -S $subcmd_args
111 _stg-edit() {
112 __stg_add_args_help
113 __stg_add_args_author
114 __stg_add_args_diffopts
115 __stg_add_args_edit
116 __stg_add_args_hook
117 __stg_add_args_savetemplate
118 __stg_add_args_sign
119 subcmd_args+=(
120 '(-d --diff)'{-d,--diff}'[edit patch diff]'
121 '(-t --set-tree)'{-t,--set-tree=}'[set git tree of patch]:treeish'
122 ':patch:__stg_patches_all'
124 __stg_add_args_message
125 _arguments -s -S $subcmd_args
128 _stg-export() {
129 __stg_add_args_help
130 __stg_add_args_branch
131 __stg_add_args_diffopts
132 subcmd_args+=(
133 '(-d --dir)'{-d,--dir}'[export patches to directory]: :_directories'
134 '(-n --numbered)'{-n,--numbered}'[prefix patch names with order numbers]'
135 '(-s --stdout)'{-s,--stdout}'[dump patches to standard output]'
136 '(-t --template)'{-t,--template=}'[use template file]: :_files'
137 '*:patches:__stg_patches_unhidden'
138 + '(suffix)'
139 '(-e --extension)'{-e,--extension=}'[extension to append to patch names]:extension'
140 '(-p --patch)'{-p,--patch}'[append .patch to patch names]'
142 _arguments -s -S $subcmd_args
145 _stg-files() {
146 __stg_add_args_help
147 __stg_add_args_diffopts
148 subcmd_args+=(
149 '--bare[bare file names]'
150 '(-s --stat)'{-s,--stat}'[show diff stat]'
151 ':patches:__stg_patches_all'
153 _arguments -s -S $subcmd_args
156 _stg-float() {
157 __stg_add_args_help
158 __stg_add_args_keep
159 subcmd_args+=(
160 '--noapply[Reorder patches by floating without applying]'
161 '(-s --series)'{-s,--series=}'[arrange according to series file]: :_files'
162 '*:patches:__stg_patches_all'
164 _arguments -s -S $subcmd_args
167 _stg-fold() {
168 __stg_add_args_help
169 subcmd_args+=(
170 '(-b --base)'{-b,--base=}'[apply on base commit instead of HEAD]:commit'
171 '(-p --strip)'{-p+,--strip=}'[remove N leading directories from diff paths]:num'
172 '-C=[ensure N lines of surrounding context for each change]:num'
173 '--reject[leave rejected hunks in .rej files]'
174 ':file:_files'
176 _arguments -s -S $subcmd_args
179 _stg-goto() {
180 __stg_add_args_help
181 __stg_add_args_keep
182 __stg_add_args_merged
183 subcmd_args+=(
184 ':patches:__stg_patches_all'
186 _arguments -s -S $subcmd_args
189 _stg-help() {
190 _arguments -s ':commands:__stg_subcommands'
193 _stg-hide() {
194 __stg_add_args_help
195 __stg_add_args_branch
196 subcmd_args+=(
197 ':patches:__stg_patches_unhidden'
199 _arguments -s -S $subcmd_args
202 _stg-id() {
203 __stg_add_args_help
204 subcmd_args+=(
205 ':references:__stg_patches_all'
207 _arguments -s -S $subcmd_args
210 _stg-import() {
211 __stg_add_args_help
212 __stg_add_args_author
213 __stg_add_args_edit
214 __stg_add_args_sign
215 subcmd_args+=(
216 '(-n --name)'{-n,--name}'[name for imported patch]'
217 '(-p --strip)'{-p+,--strip=}'[remove N leading directories from diff paths]:num'
218 '(-t --stripname)'{-t,--stripname}'[strip number and extension from patch name]'
219 '-C=[ensure N lines of surrounding context for each change]:num'
220 '(-i --ignore)'{-i,--ignore}'[ingore applied patches in series]'
221 '--replace[replace unapplied patches in series]'
222 '--reject[leave rejected hunks in .rej files]'
223 '--keep-cr[do not remove CR from email lines ending with CRLF]'
224 '(-d --showdiff)'{-d,--showdiff}'[show patch content in editor buffer]'
225 ':file:_files'
226 + '(source)'
227 '(-m --mail)'{-m,--mail}'[import from standard email file]'
228 '(-M --mbox)'{-M,--mbox}'[import from mbox file]'
229 '(-s --series)'{-s,--series}'[import from series file]'
230 '(-u --url)'{-u,--url}'[import patch from URL]'
232 _arguments -s -S $subcmd_args
235 _stg-init() {
236 __stg_add_args_help
237 _arguments -s $subcmd_args
240 _stg-log() {
241 __stg_add_args_help
242 __stg_add_args_branch
243 subcmd_args+=(
244 '--clear[clear log history]'
245 '(-d --diff)'{-d,--diff}'[show refresh diffs]'
246 '(-f --full)'{-f,--full}'[show full commit ids]'
247 '(-g --graphical)'{-g,--graphical}'[show log in gitk]'
248 '(-n --number)'{-n+,--number=}'[limit to number of commits]'
249 '*:patches:__stg_patches_all'
251 _arguments -s -S $subcmd_args
254 _stg-mail() {
255 __stg_add_args_help
256 __stg_add_args_branch
257 __stg_add_args_diffopts
258 subcmd_args+=(
259 '--to=[add address to To: list]:address'
260 '--cc=[add address to Cc: list]:address'
261 '--bcc=[add address to Bcc: list]:address'
262 '--auto[automatically cc patch signers]'
263 '--no-thread[do not send subsequent messages as replies]'
264 '--unrelated[send patches without sequence numbers]'
265 '(-v --version)'{-v,--version=}'[add version to subject prefix]:version'
266 '--prefix=[add prefix to subject]:prefix'
267 '(-c --cover)'{-c,--cover=}'[cover message file]: :_files'
268 '(-e --edit-cover)'{-e,--edit-cover}'[edit cover message before sending]'
269 '(-E --edit-patches)'{-E,--edit-patches}'[edit patches before sending]'
270 '(-s --sleep)'{-s,--sleep=}'[seconds to sleep between sending emails]:seconds'
271 '--in-reply-to=[reply reference id]:refid'
272 '--domain=[domain to use for message ID]:domain'
273 '(-u --user)'{-u,--user=}'[username for SMTP authentication]:user'
274 '(-p --password)'{-p,--password=}'[password for SMTP authentication]:password'
275 '(-T --smtp-tls)'{-t,--smtp-tls}'[use TLS for SMTP authentication]'
276 + '(send-method)'
277 '--git[use `git send-email`]'
278 '(-m --mbox)'{-m,--mbox}'[generate mbox file instead of sending]'
279 '--smtp-server=[server or command for sending email]'
280 + '(attachment)'
281 '--attach[send patch as attachment]'
282 '--attach-inline[send patch as inline attachment]'
283 '(-t --template)'{-t,--template=}'[message template file]: :_files'
284 + '(patches)'
285 '(-a --all)'{-a,--all}'[email all applied patches]'
286 '*:patches:__stg_patches_all'
288 _arguments -s -S $subcmd_args
291 _stg-new() {
292 __stg_add_args_help
293 __stg_add_args_author
294 __stg_add_args_sign
295 __stg_add_args_hook
296 __stg_add_args_savetemplate
297 subcmd_args+=(
298 '(-v --verbose)'{-v,--verbose}'[show diff of file changes]'
299 ':: :_guard "([^-]?#|)" name'
301 __stg_add_args_message
302 _arguments -s -S $subcmd_args
305 _stg-next() {
306 __stg_add_args_help
307 __stg_add_args_branch
308 _arguments -s -S $subcmd_args
311 _stg-patches() {
312 __stg_add_args_help
313 __stg_add_args_branch
314 __stg_add_args_diffopts
315 subcmd_args+=(
316 '(-d --diff)'{-d,--diff}'[show diffs of given files]'
317 '*:files:__stg_files_known'
319 _arguments -s -S $subcmd_args
322 _stg-pick() {
323 # TODO: complete --parent commit id
324 __stg_add_args_help
325 subcmd_args+=(
326 '(-n --name)'{-n,--name=}'[name for picked patch]:name'
327 '(-B --ref-branch)'{-B,--ref-branch=}'[pick patches from branch]: :__stg_branch_stgit'
328 '(-r --revert)'{-r,--revert}'[revert given commit object]'
329 '(-p --parent=)'{-p,--parent}'[use commit id as parent]:commit'
330 '(-x --expose)'{-x,--expose}'[append imported commit id to patch log]'
331 '--unapplied[keep patch unapplied]'
332 '*'{-f,--file=}'[only fold given file]: :_files'
333 '*:patches:__stg_patches_refbranch'
334 + '(mode)'
335 '--fold[fold the commit into current patch]'
336 '--update[fold limited to current patch files]'
338 _arguments -s -S $subcmd_args
341 _stg-pop() {
342 __stg_add_args_help
343 __stg_add_args_keep
344 subcmd_args+=(
345 '(-s --spill)'{-s,--spill}'[pop a patch keeping its modifications in the tree]'
346 - group-number
347 '(-n --number)'{-n+,--number=}'[push specified number of patches]:number'
348 - group-all
349 '(-a --all)'{-a,--all}'[push all unapplied patches]'
350 - group-patches
351 '*:applied patches:__stg_patches_applied'
353 _arguments -s -S $subcmd_args
356 _stg-prev() {
357 __stg_add_args_help
358 __stg_add_args_branch
359 _arguments -s -S $subcmd_args
362 _stg-pull() {
363 __stg_add_args_help
364 __stg_add_args_merged
365 subcmd_args+=(
366 '(-n --nopush)'{-n,--nopush}'[do not push patches after rebasing]'
367 ':repository:__stg_remotes'
369 _arguments -s -S $subcmd_args
372 _stg-push() {
373 __stg_add_args_help
374 __stg_add_args_keep
375 __stg_add_args_merged
376 subcmd_args+=(
377 '--reverse[push patches in reverse order]'
378 '--set-tree[push patch with the original tree]'
379 - group-all
380 '(-a --all)'{-a,--all}'[push all unapplied patches]'
381 - group-number
382 '(-n --number)'{-n+,--number=}'[push specified number of patches]:number'
383 - group-patches
384 '*:unapplied patches:__stg_patches_unapplied'
386 _arguments -s -S $subcmd_args
389 _stg-rebase() {
390 __stg_add_args_help
391 __stg_add_args_merged
392 subcmd_args+=(
393 '(-n --nopush)'{-n,--nopush}'[do not push patches after rebasing]'
394 ':new-base-id:__stg_heads'
396 _arguments -s -S $subcmd_args
399 _stg-redo() {
400 __stg_add_args_help
401 subcmd_args+=(
402 '--hard[discard changes in index/worktree]'
403 '(-n --number)'{-n+,--number=}'[number of undos to redo]:number'
405 _arguments -s -S $subcmd_args
408 _stg-refresh() {
409 __stg_add_args_help
410 __stg_add_args_author
411 __stg_add_args_edit
412 __stg_add_args_hook
413 __stg_add_args_sign
414 __stg_add_args_diffopts
415 subcmd_args+=(
416 '(-a --annotate)'{-a,--annotate=}'[annotate patch log entry]:note'
417 '(-d --diff)'{-d,--diff}'[show diff when editing patch message]'
418 '(-F --force)'{-F,--force}'[force refresh even if index is dirty]'
419 '(-i --index)'{-i,--index}'[refresh from index instead of worktree]'
420 '(-p --patch)'{-p,--patch=}'[refresh patch other than top patch]: :__stg_patches_applied'
421 '--spill[Spill patch contents to worktree and index, and erase patch content]'
422 + '(update-files)'
423 '(-u --update)'{-u,--update}'[only update current patch files]'
424 '*:files:__stg_changed_files'
425 + '(submodules)'
426 '(-s --submodules)'{-s,--submodules}'[include submodules in refresh]'
427 '--no-submodules[exclude submodules from refresh]'
429 __stg_add_args_message
430 _arguments -s -S $subcmd_args
433 _stg-rename() {
434 __stg_add_args_help
435 __stg_add_args_branch
436 subcmd_args+=(
437 ':old-patch:__stg_patches_all'
439 _arguments -s -S $subcmd_args
442 _stg-repair() {
443 __stg_add_args_help
444 _arguments -s $subcmd_args
447 _stg-reset() {
448 __stg_add_args_help
449 subcmd_args+=(
450 '--hard[discard changes in index/worktree]'
451 ':state:'
452 '*:patches:__stg_patches_all'
454 _arguments -s -S $subcmd_args
457 _stg-series() {
458 __stg_add_args_help
459 __stg_add_args_branch
460 subcmd_args+=(
461 '--author[show the author name for each patch]'
462 '(-c --count)'{-c,--count}'[print number of patches]'
463 '(-d --description)'{-d,--description}'[show short descriptions]'
464 '--no-description[do not show patch descriptions]'
465 '(-e --empty)'{-e,--empty}'[identify empty patches]'
466 '(-m --missing)'{-m,--missing=}'[show patches from branch missing in current]: :__stg_branch_stgit'
467 '--noprefix[do not show the patch status prefix]'
468 '(-s --short)'{-s,--short}'[list just patches around the topmost patch]'
469 '--showbranch[show branch name of listed patches]'
470 - group-ahu
471 '(-A --applied)'{-A,--applied}'[show applied patches]'
472 '(-H --hidden)'{-H,--hidden}'[show hidden patches]'
473 '(-U --unapplied)'{-U,--unapplied}'[show unapplied patches]'
474 - group-all
475 '(-a --all)'{-a,--all}'[show all patches including hidden]'
476 - group-patches
477 ':patches:__stg_patches_all'
479 _arguments -s -S $subcmd_args
482 _stg-show() {
483 __stg_add_args_help
484 __stg_add_args_branch
485 __stg_add_args_diffopts
486 subcmd_args+=(
487 '(-s --stat)'{-s,--stat}'[show diff stat]'
488 '*:patches:__stg_patches_all'
489 + '(patch-selection)'
490 '(-a --applied)'{-a,--applied}'[show applied patches]'
491 '(-u --unapplied)'{-u,--unapplied}'[show unapplied patches]'
493 _arguments -s -S $subcmd_args
496 _stg-sink() {
497 __stg_add_args_help
498 __stg_add_args_keep
499 subcmd_args+=(
500 '(-n --nopush)'{-n,--nopush}'[do not push patches after sinking]'
501 '(-t --to)'{-t,--to=}'[sink patches below target patch]: :__stg_patches_applied'
502 ':patches:__stg_patches_all'
504 _arguments -s -S $subcmd_args
507 _stg-squash() {
508 __stg_add_args_help
509 __stg_add_args_hook
510 __stg_add_args_savetemplate
511 subcmd_args+=(
512 '(-n --name)'{-n,--name=}'[name for squashed patch]: :__stg_patches_all'
513 '*:patches:__stg_patches_all_allow_dups'
515 __stg_add_args_message
516 _arguments -s -S $subcmd_args
519 _stg-sync() {
520 __stg_add_args_help
521 subcmd_args+=(
522 + '(patches)'
523 '(-a --all)'{-a,--all}'[synchronize all applied patches]'
524 '*:patches:__stg_patches_refbranch'
525 + '(source)'
526 '(-B --ref-branch)'{-B,--ref-branch}'[synchronize patches with branch]: :__stg_branch_stgit'
527 '(-s --series)'{-s,--series=}'[synchronize patches with series]: :_files'
529 _arguments -s -S $subcmd_args
532 _stg-top() {
533 __stg_add_args_help
534 __stg_add_args_branch
535 _arguments -s -S $subcmd_args
538 _stg-uncommit() {
539 __stg_add_args_help
540 subcmd_args+=(
541 - group-number
542 '(-n --number)'{-n+,--number=}'[push specified number of patches]:number'
543 ':prefix:'
544 - group-to
545 '(-t --to)'{-t,--to=}'[uncommit to the specified commit]:commit'
546 '(-x --exclusive)'{-x,--exclusive}'[exclude the commit specified by --to]'
547 - group-names
548 '*: :_guard "([^-]?#|)" names'
550 _arguments -s -S $subcmd_args
553 _stg-undo() {
554 __stg_add_args_help
555 subcmd_args+=(
556 '--hard[discard changes in index/worktree]'
557 '(-n --number)'{-n+,--number=}'[number commands to undo]:number'
559 _arguments -s -S $subcmd_args
562 _stg-unhide() {
563 __stg_add_args_help
564 __stg_add_args_branch
565 subcmd_args+=(
566 ':patches:__stg_patches_hidden'
568 _arguments -s -S $subcmd_args
571 __stg_add_args_author() {
572 subcmd_args+=(
573 '--author=[set author details]'
574 '--authdate=[set author date]:date'
575 '--authemail=[set author email]:email'
576 '--authname=[set author name]:name'
580 __stg_add_args_branch() {
581 subcmd_args+=(
582 '(-b --branch)'{-b,--branch=}'[specify another branch]: :__stg_branch_stgit'
586 __stg_add_args_diffopts() {
587 # TODO: complete diff-opts values (with separators?)
588 subcmd_args+=(
589 '(-O --diff-opts)'{-O+,--diff-opts=}'[extra options for git diff]:opts'
593 __stg_add_args_edit() {
594 subcmd_args+=(
595 '(-e --edit)'{-e,--edit}'[invoke interactive editor]'
599 __stg_add_args_help() {
600 subcmd_args+=(
601 '(- *)'{-h,--help}'[show help message and exit]'
605 __stg_add_args_hook() {
606 subcmd_args+=(
607 '--no-verify[disable commit-msg hook]'
611 __stg_add_args_keep() {
612 subcmd_args+=(
613 '(-k --keep)'{-k,--keep}'[keep local changes]'
617 __stg_add_args_merged() {
618 subcmd_args+=(
619 '(-m --merged)'{-m,--merged}'[check for patches merged upstream]'
623 __stg_add_args_message() {
624 subcmd_args+=(
625 + '(message)'
626 '(-f --file)'{-f,--file=}'[use message file instead of invoking editor]: :_files'
627 '(-m --message)'{-m,--message=}'[specify message instead of invoking editor]:message'
631 __stg_add_args_savetemplate() {
632 subcmd_args+=(
633 '--save-template=[save message template to file and exit]: :_files'
637 __stg_add_args_sign() {
638 subcmd_args+=(
639 '--ack[add Acked-by trailer]'
640 '--ack-by[add Acked-by trailer]:value'
641 '--review[add Reviewed-by trailer]'
642 '--review-by[add Reviewed-by trailer]:value'
643 '--sign[add Signed-off-by trailer]'
644 '--sign-by[add Signed-off-by trailer]:value'
648 __stg_heads () {
649 _alternative 'heads-local::__stg_heads_local' 'heads-remote::__stg_heads_remote'
652 __stg_heads_local () {
653 local f gitdir
654 declare -a heads
656 heads=(${(f)"$(_call_program headrefs git for-each-ref --format='"%(refname:short)"' refs/heads 2>/dev/null)"})
657 gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null)
658 if __stg_git_command_successful $pipestatus; then
659 for f in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
660 [[ -f $gitdir/$f ]] && heads+=$f
661 done
662 [[ -f $gitdir/refs/stash ]] && heads+=stash
663 [[ -f $gitdir/refs/bisect/bad ]] && heads+=bisect/bad
666 __stg_git_describe_commit heads heads-local "local head" "$@"
669 __stg_heads_remote () {
670 declare -a heads
672 heads=(${(f)"$(_call_program headrefs git for-each-ref --format='"%(refname:short)"' refs/remotes 2>/dev/null)"})
674 __stg_git_describe_commit heads heads-remote "remote head" "$@"
677 __stg_git_command_successful () {
678 if (( ${#*:#0} > 0 )); then
679 _message 'not a git repository'
680 return 1
682 return 0
685 __stg_git_describe_commit () {
686 __stg_git_describe_branch $1 $2 $3 -M 'r:|/=* r:|=*' "${(@)argv[4,-1]}"
689 __stg_git_describe_branch () {
690 local __commits_in=$1
691 local __tag=$2
692 local __desc=$3
693 shift 3
695 integer maxverbose
696 if zstyle -s :completion:$curcontext: max-verbose maxverbose &&
697 (( ${compstate[nmatches]} <= maxverbose )); then
698 local __c
699 local -a __commits
700 for __c in ${(P)__commits_in}; do
701 __commits+=("${__c}:${$(_call_program describe git rev-list -1 --oneline $__c)//:/\\:}")
702 done
703 _describe -t $__tag $__desc __commits "$@"
704 else
705 local expl
706 _wanted $__tag expl $__desc compadd "$@" -a - $__commits_in
710 __stg_branch_stgit() {
711 declare -a stg_branches
712 stg_branches=(
713 ${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/stacks 2>/dev/null)"}#refs/stacks/}
715 local expl
716 _wanted -V branches expl "branch" compadd $stg_branches
719 __stg_files_relative() {
720 local prefix
721 prefix=$(_call_program gitprefix git rev-parse --show-prefix 2>/dev/null)
722 if (( $#prefix == 0 )); then
723 print $1
724 return
727 local file
728 local -a files
730 files=()
731 # Collapse "//" and "/./" into "/". Strip any remaining "/." and "/".
732 for file in ${${${${${(0)1}//\/\///}//\/.\///}%/.}%/}; do
733 integer i n
734 (( n = $#file > $#prefix ? $#file : $#prefix ))
735 for (( i = 1; i <= n; i++ )); do
736 if [[ $file[i] != $prefix[i] ]]; then
737 while (( i > 0 )) && [[ $file[i-1] != / ]]; do
738 (( i-- ))
739 done
740 break
742 done
744 files+=${(l@${#prefix[i,-1]//[^\/]}*3@@../@)}${file[i,-1]}
745 done
747 print ${(pj:\0:)files}
750 __stg_diff-index_files () {
751 local tree=$1 description=$2 tag=$3; shift 3
752 local files expl
754 # $tree needs to be escaped for _call_program; matters for $tree = "HEAD^"
755 files=$(_call_program files git diff-index -z --name-only --no-color --cached ${(q)tree} 2>/dev/null)
756 __stg_git_command_successful $pipestatus || return 1
757 files=(${(0)"$(__stg_files_relative $files)"})
758 __stg_git_command_successful $pipestatus || return 1
760 _wanted $tag expl $description _multi_parts $@ - / files
763 __stg_changed-in-index_files () {
764 __stg_diff-index_files HEAD 'changed in index file' changed-in-index-files "$@"
767 __stg_changed-in-working-tree_files () {
768 local files expl
770 files=$(_call_program changed-in-working-tree-files git diff -z --name-only --no-color 2>/dev/null)
771 __stg_git_command_successful $pipestatus || return 1
772 files=(${(0)"$(__stg_files_relative $files)"})
773 __stg_git_command_successful $pipestatus || return 1
775 _wanted changed-in-working-tree-files expl 'changed in working tree file' _multi_parts $@ -f - / files
778 __stg_changed_files () {
779 _alternative \
780 'changed-in-index-files::__stg_changed-in-index_files' \
781 'changed-in-working-tree-files::__stg_changed-in-working-tree_files'
784 __stg_files_known() {
785 declare -a known_files
786 known_files=(
787 ${(f)"$(_call_program known-files git ls-files 2>/dev/null)"}
789 local expl
790 _wanted -V known-files expl "known files" _multi_parts - / known_files
793 __stg_get_branch_opt() {
794 local short long i
795 short=${1:-'-b'}
796 long=${2:-'--branch'}
797 i=${words[(I)$short|$long(=*|)]}
798 case ${words[i]} in
799 $short|$long)
800 if (( i < $#words )); then
801 echo "--branch=${words[i + 1]}"
805 echo "--branch=${words[i]#*=}"
807 esac
810 __stg_want_patches() {
811 declare -a patches
812 local expl
813 patches=(
814 ${(f)"$(_call_program want-patches stg series --no-description --noprefix $@ 2>/dev/null)"}
816 _wanted -V all expl "patch" compadd ${patches:|words}
820 __stg_patches_all() {
821 __stg_want_patches $(__stg_get_branch_opt) --all
824 __stg_patches_all_allow_dups() {
825 declare -a patches
826 local expl branch_opt
827 branch_opt=$(__stg_get_branch_opt)
828 patches=(
829 ${(f)"$(_call_program all-patches stg series $branch_opt --no-description --noprefix --all 2>/dev/null)"}
831 _wanted -V all expl "patch" compadd ${patches}
834 __stg_patches_applied() {
835 __stg_want_patches $(__stg_get_branch_opt) --applied
838 __stg_patches_hidden() {
839 __stg_want_patches $(__stg_get_branch_opt) --hidden
842 __stg_patches_unapplied() {
843 __stg_want_patches $(__stg_get_branch_opt) --unapplied
846 __stg_patches_unhidden() {
847 __stg_want_patches $(__stg_get_branch_opt) --applied --unapplied
850 __stg_patches_refbranch() {
851 __stg_want_patches $(__stg_get_branch_opt -B --ref-branch) --all
854 __stg_remotes() {
855 local remotes expl
856 remotes=(${(f)"$(_call_program remotes git remote 2>/dev/null)"})
857 _wanted remotes expl remote compadd "$@" -a - remotes
860 __stg_subcommands() {
861 _describe -t commands 'stgit command' _stg_cmds
864 __stg_caching_policy() {
865 [[ =$service -nt $1 ]]
868 _stgit() {
869 local curcontext="$curcontext" state line expl ret=1
870 typeset -A opt_args
872 # Special cases for git aliases
873 case "$words[2]" in
874 (add|mv|rm|status)
875 words[1]=git
877 (resolved)
878 words[1]=git
879 words[2]=add
881 esac
882 if [ "$words[1]" = git ]; then
883 _normal && ret=0
884 return ret
887 local update_policy
888 zstyle -s ":completion:*:*:stg:*" cache-policy update_policy
889 if [[ -z "$update_policy" ]]; then
890 zstyle ":completion:*:*:stg:*" cache-policy __stg_caching_policy
893 _arguments -C -A "-*" \
894 '(-)--help[print help information]' \
895 '(*)--version[display version information]' \
896 '1: :->command' \
897 '*:: :->args' && ret=0
899 if [[ -n $state ]] && (( ! $+_stg_cmds )); then
900 typeset -a _stg_cmds
901 if _cache_invalid stg-cmds || ! _retrieve_cache stg-cmds; then
902 _stg_cmds=(
903 ${${${(M)${(f)"$(stg help 2> /dev/null)"}## *}# }/#(#b)([^[:space:]]##)[[:space:]]##(*)/$match[1]:$match[2]}
905 if (( $? == 0 )); then
906 _store_cache stg-cmds _stg_cmds
907 else
908 unset _stg_cmds
913 case $state in
914 (command)
915 __stg_subcommands && ret=0
917 (args)
918 local -a subcmd_args
919 local subcmd=$words[1]
920 curcontext="${curcontext%:*:*}:stg-$subcmd:"
921 if ! _call_function ret _stg-$subcmd; then
922 _message "unknown sub-command: $subcmd"
925 esac
927 return ret
930 _stgit "$@"