3 # Zsh will source this file when attempting to autoload the "_hub" function,
4 # typically on the first attempt to complete the hub command. We define two new
5 # setup helper routines (one for the zsh-distributed version, one for the
6 # git-distributed, bash-based version). Then we redefine the "_hub" function to
7 # call "_git" after some other interception.
9 # This is pretty fragile, if you think about it. Any number of implementation
10 # changes in the "_git" scripts could cause problems down the road. It would be
11 # better if the stock git completions were just a bit more permissive about how
12 # it allowed third-party commands to be added.
14 (( $+functions[__hub_setup_zsh_fns] )) ||
15 __hub_setup_zsh_fns () {
16 (( $+functions[_git-alias] )) ||
19 '-s[output shell script suitable for eval]' \
20 '1::shell:(zsh bash csh)'
23 (( $+functions[_git-browse] )) ||
26 '-u[output the URL]' \
27 '2::subpage:(wiki commits issues)'
30 (( $+functions[_git-compare] )) ||
33 '-u[output the URL]' \
34 ':[start...]end range:'
37 (( $+functions[_git-create] )) ||
40 '::name (REPOSITORY or ORGANIZATION/REPOSITORY):' \
41 '-p[make repository private]' \
42 '-d[description]:description' \
43 '-h[home page]:repository home page URL:_urls'
46 (( $+functions[_git-fork] )) ||
49 '--no-remote[do not add a remote for the new fork]'
52 (( $+functions[_git-pull-request] )) ||
53 _git-pull-request () {
55 '-f[force (skip check for local commits)]' \
56 '-b[base]:base ("branch", "owner\:branch", "owner/repo\:branch"):' \
57 '-h[head]:head ("branch", "owner\:branch", "owner/repo\:branch"):' \
61 '--no-edit[use first commit message for pull request title/description]' \
66 '-i[issue]:issue number:' \
71 # stash the "real" command for later
72 functions[_hub_orig_git_commands]=$functions[_git_commands]
74 # Replace it with our own wrapper.
75 declare -f _git_commands >& /dev/null && unfunction _git_commands
78 # call the original routine
79 _call_function ret _hub_orig_git_commands
81 # Effectively "append" our hub commands to the behavior of the original
82 # _git_commands function. Using this wrapper function approach ensures
83 # that we only offer the user the hub subcommands when the user is
84 # actually trying to complete subcommands.
86 alias:'show shell instructions for wrapping git'
87 pull-request:'open a pull request on GitHub'
88 pr:'list or checkout a GitHub pull request'
89 issue:'list or create a GitHub issue'
90 release:'list or create a GitHub release'
91 fork:'fork origin repo on GitHub'
92 create:'create new repo on GitHub for the current project'
93 delete:'delete a GitHub repo'
94 browse:'browse the project on GitHub'
95 compare:'open GitHub compare view'
96 ci-status:'show status of GitHub checks for a commit'
97 sync:'update local branches from upstream'
99 _describe -t hub-commands 'hub command' hub_commands && ret=0
105 (( $+functions[__hub_setup_bash_fns] )) ||
106 __hub_setup_bash_fns () {
107 # TODO more bash-style fns needed here to complete subcommand args. They take
108 # the form "_git_CMD" where "CMD" is something like "pull-request".
110 # Duplicate and rename the 'list_all_commands' function
111 eval "$(declare -f __git_list_all_commands | \
112 sed 's/__git_list_all_commands/__git_list_all_commands_without_hub/')"
114 # Wrap the 'list_all_commands' function with extra hub commands
115 __git_list_all_commands() {
130 __git_list_all_commands_without_hub
133 # Ensure cached commands are cleared
134 __git_all_commands=""
137 # redefine _hub to a much smaller function in the steady state
139 # only attempt to intercept the normal "_git" helper functions once
140 (( $+__hub_func_replacement_done )) ||
142 # At this stage in the shell's execution the "_git" function has not yet
143 # been autoloaded, so the "_git_commands" or "__git_list_all_commands"
144 # functions will not be defined. Call it now (with a bogus no-op service
145 # to prevent premature completion) so that we can wrap them.
146 if declare -f _git >& /dev/null ; then
147 _hub_noop () { __hub_zsh_provided=1 } # zsh-provided will call this one
148 __hub_noop_main () { __hub_git_provided=1 } # git-provided will call this one
149 local service=hub_noop
152 unfunction __hub_noop_main
156 if (( $__hub_zsh_provided )) ; then
158 elif (( $__hub_git_provided )) ; then
162 __hub_func_replacement_done=1
165 # Now perform the actual completion, allowing the "_git" function to call our
166 # replacement "_git_commands" function as needed. Both versions expect
167 # service=git or they will call nonexistent routines or end up in an infinite
170 declare -f _git >& /dev/null && _git
173 # make sure we actually attempt to complete on the first "tab" from the user