Merge branch 'bc/svn-hash-oid-fix'
[git] / contrib / completion / git-completion.zsh
1 #compdef git gitk
2
3 # zsh completion wrapper for git
4 #
5 # Copyright (c) 2012-2013 Felipe Contreras <felipe.contreras@gmail.com>
6 #
7 # You need git's bash completion script installed somewhere, by default it
8 # would be the location bash-completion uses.
9 #
10 # If your script is somewhere else, you can configure it on your ~/.zshrc:
11 #
12 #  zstyle ':completion:*:*:git:*' script ~/.git-completion.bash
13 #
14 # The recommended way to install this script is to make a copy of it in
15 # ~/.zsh/ directory as ~/.zsh/git-completion.zsh and then add the following
16 # to your ~/.zshrc file:
17 #
18 #  fpath=(~/.zsh $fpath)
19 #  autoload -Uz compinit && compinit
20
21 complete ()
22 {
23         # do nothing
24         return 0
25 }
26
27 zstyle -T ':completion:*:*:git:*' tag-order && \
28         zstyle ':completion:*:*:git:*' tag-order 'common-commands'
29
30 zstyle -s ":completion:*:*:git:*" script script
31 if [ -z "$script" ]; then
32         local -a locations
33         local e
34         locations=(
35                 $(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
36                 '/etc/bash_completion.d/git' # fedora, old debian
37                 '/usr/share/bash-completion/completions/git' # arch, ubuntu, new debian
38                 '/usr/share/bash-completion/git' # gentoo
39                 )
40         for e in $locations; do
41                 test -f $e && script="$e" && break
42         done
43 fi
44 GIT_SOURCING_ZSH_COMPLETION=y . "$script"
45
46 __gitcomp ()
47 {
48         emulate -L zsh
49
50         local cur_="${3-$cur}"
51
52         case "$cur_" in
53         --*=)
54                 ;;
55         *)
56                 local c IFS=$' \t\n'
57                 local -a array
58                 for c in ${=1}; do
59                         c="$c${4-}"
60                         case $c in
61                         --*=*|*.) ;;
62                         *) c="$c " ;;
63                         esac
64                         array+=("$c")
65                 done
66                 compset -P '*[=:]'
67                 compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
68                 ;;
69         esac
70 }
71
72 __gitcomp_direct ()
73 {
74         emulate -L zsh
75
76         local IFS=$'\n'
77         compset -P '*[=:]'
78         compadd -Q -- ${=1} && _ret=0
79 }
80
81 __gitcomp_nl ()
82 {
83         emulate -L zsh
84
85         local IFS=$'\n'
86         compset -P '*[=:]'
87         compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
88 }
89
90 __gitcomp_nl_append ()
91 {
92         emulate -L zsh
93
94         local IFS=$'\n'
95         compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
96 }
97
98 __gitcomp_file_direct ()
99 {
100         emulate -L zsh
101
102         local IFS=$'\n'
103         compset -P '*[=:]'
104         compadd -f -- ${=1} && _ret=0
105 }
106
107 __gitcomp_file ()
108 {
109         emulate -L zsh
110
111         local IFS=$'\n'
112         compset -P '*[=:]'
113         compadd -p "${2-}" -f -- ${=1} && _ret=0
114 }
115
116 __git_zsh_bash_func ()
117 {
118         emulate -L ksh
119
120         local command=$1
121
122         local completion_func="_git_${command//-/_}"
123         declare -f $completion_func >/dev/null && $completion_func && return
124
125         local expansion=$(__git_aliased_command "$command")
126         if [ -n "$expansion" ]; then
127                 words[1]=$expansion
128                 completion_func="_git_${expansion//-/_}"
129                 declare -f $completion_func >/dev/null && $completion_func
130         fi
131 }
132
133 __git_zsh_cmd_common ()
134 {
135         local -a list
136         list=(
137         add:'add file contents to the index'
138         bisect:'find by binary search the change that introduced a bug'
139         branch:'list, create, or delete branches'
140         checkout:'checkout a branch or paths to the working tree'
141         clone:'clone a repository into a new directory'
142         commit:'record changes to the repository'
143         diff:'show changes between commits, commit and working tree, etc'
144         fetch:'download objects and refs from another repository'
145         grep:'print lines matching a pattern'
146         init:'create an empty Git repository or reinitialize an existing one'
147         log:'show commit logs'
148         merge:'join two or more development histories together'
149         mv:'move or rename a file, a directory, or a symlink'
150         pull:'fetch from and merge with another repository or a local branch'
151         push:'update remote refs along with associated objects'
152         rebase:'forward-port local commits to the updated upstream head'
153         reset:'reset current HEAD to the specified state'
154         restore:'restore working tree files'
155         rm:'remove files from the working tree and from the index'
156         show:'show various types of objects'
157         status:'show the working tree status'
158         switch:'switch branches'
159         tag:'create, list, delete or verify a tag object signed with GPG')
160         _describe -t common-commands 'common commands' list && _ret=0
161 }
162
163 __git_zsh_cmd_alias ()
164 {
165         local -a list
166         list=(${${${(0)"$(git config -z --get-regexp '^alias\.')"}#alias.}%$'\n'*})
167         _describe -t alias-commands 'aliases' list $* && _ret=0
168 }
169
170 __git_zsh_cmd_all ()
171 {
172         local -a list
173         emulate ksh -c __git_compute_all_commands
174         list=( ${=__git_all_commands} )
175         _describe -t all-commands 'all commands' list && _ret=0
176 }
177
178 __git_zsh_main ()
179 {
180         local curcontext="$curcontext" state state_descr line
181         typeset -A opt_args
182         local -a orig_words
183
184         orig_words=( ${words[@]} )
185
186         _arguments -C \
187                 '(-p --paginate --no-pager)'{-p,--paginate}'[pipe all output into ''less'']' \
188                 '(-p --paginate)--no-pager[do not pipe git output into a pager]' \
189                 '--git-dir=-[set the path to the repository]: :_directories' \
190                 '--bare[treat the repository as a bare repository]' \
191                 '(- :)--version[prints the git suite version]' \
192                 '--exec-path=-[path to where your core git programs are installed]:: :_directories' \
193                 '--html-path[print the path where git''s HTML documentation is installed]' \
194                 '--info-path[print the path where the Info files are installed]' \
195                 '--man-path[print the manpath (see `man(1)`) for the man pages]' \
196                 '--work-tree=-[set the path to the working tree]: :_directories' \
197                 '--namespace=-[set the git namespace]' \
198                 '--no-replace-objects[do not use replacement refs to replace git objects]' \
199                 '(- :)--help[prints the synopsis and a list of the most commonly used commands]: :->arg' \
200                 '(-): :->command' \
201                 '(-)*:: :->arg' && return
202
203         case $state in
204         (command)
205                 _alternative \
206                          'alias-commands:alias:__git_zsh_cmd_alias' \
207                          'common-commands:common:__git_zsh_cmd_common' \
208                          'all-commands:all:__git_zsh_cmd_all' && _ret=0
209                 ;;
210         (arg)
211                 local command="${words[1]}" __git_dir
212
213                 if (( $+opt_args[--bare] )); then
214                         __git_dir='.'
215                 else
216                         __git_dir=${opt_args[--git-dir]}
217                 fi
218
219                 (( $+opt_args[--help] )) && command='help'
220
221                 words=( ${orig_words[@]} )
222
223                 __git_zsh_bash_func $command
224                 ;;
225         esac
226 }
227
228 _git ()
229 {
230         local _ret=1
231         local cur cword prev
232
233         cur=${words[CURRENT]}
234         prev=${words[CURRENT-1]}
235         let cword=CURRENT-1
236
237         if (( $+functions[__${service}_zsh_main] )); then
238                 __${service}_zsh_main
239         else
240                 emulate ksh -c __${service}_main
241         fi
242
243         let _ret && _default && _ret=0
244         return _ret
245 }
246
247 _git