dotfiles

*nix config files
git clone git://git.pyratebeard.net/dotfiles.git
Log | Files | Refs | README

_hub (5187B)


      1 #compdef hub
      2 
      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.
      8 #
      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.
     13 
     14 (( $+functions[__hub_setup_zsh_fns] )) ||
     15 __hub_setup_zsh_fns () {
     16   (( $+functions[_git-alias] )) ||
     17   _git-alias () {
     18     _arguments \
     19       '-s[output shell script suitable for eval]' \
     20       '1::shell:(zsh bash csh)'
     21   }
     22 
     23   (( $+functions[_git-browse] )) ||
     24   _git-browse () {
     25     _arguments \
     26       '-u[output the URL]' \
     27       '2::subpage:(wiki commits issues)'
     28   }
     29 
     30   (( $+functions[_git-compare] )) ||
     31   _git-compare () {
     32     _arguments \
     33       '-u[output the URL]' \
     34       ':[start...]end range:'
     35   }
     36 
     37   (( $+functions[_git-create] )) ||
     38   _git-create () {
     39     _arguments \
     40       '::name (REPOSITORY or ORGANIZATION/REPOSITORY):' \
     41       '-p[make repository private]' \
     42       '-d[description]:description' \
     43       '-h[home page]:repository home page URL:_urls'
     44   }
     45 
     46   (( $+functions[_git-fork] )) ||
     47   _git-fork () {
     48     _arguments \
     49       '--no-remote[do not add a remote for the new fork]'
     50   }
     51 
     52   (( $+functions[_git-pull-request] )) ||
     53   _git-pull-request () {
     54     _arguments \
     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"):' \
     58       - set1 \
     59         '-m[message]' \
     60         '-F[file]' \
     61       - set2 \
     62         '-i[issue]:issue number:' \
     63       - set3 \
     64         '::issue-url:_urls'
     65   }
     66 
     67   # stash the "real" command for later
     68   functions[_hub_orig_git_commands]=$functions[_git_commands]
     69 
     70   # Replace it with our own wrapper.
     71   declare -f _git_commands >& /dev/null && unfunction _git_commands
     72   _git_commands () {
     73     local ret=1
     74     # call the original routine
     75     _call_function ret _hub_orig_git_commands
     76 
     77     # Effectively "append" our hub commands to the behavior of the original
     78     # _git_commands function.  Using this wrapper function approach ensures
     79     # that we only offer the user the hub subcommands when the user is
     80     # actually trying to complete subcommands.
     81     hub_commands=(
     82       alias:'show shell instructions for wrapping git'
     83       pull-request:'open a pull request on GitHub'
     84       fork:'fork origin repo on GitHub'
     85       create:'create new repo on GitHub for the current project'
     86       browse:'browse the project on GitHub'
     87       compare:'open GitHub compare view'
     88       ci-status:'lookup commit in GitHub Status API'
     89     )
     90     _describe -t hub-commands 'hub command' hub_commands && ret=0
     91 
     92     return ret
     93   }
     94 }
     95 
     96 (( $+functions[__hub_setup_bash_fns] )) ||
     97 __hub_setup_bash_fns () {
     98   # TODO more bash-style fns needed here to complete subcommand args.  They take
     99   # the form "_git_CMD" where "CMD" is something like "pull-request".
    100 
    101   # Duplicate and rename the 'list_all_commands' function
    102   eval "$(declare -f __git_list_all_commands | \
    103         sed 's/__git_list_all_commands/__git_list_all_commands_without_hub/')"
    104 
    105   # Wrap the 'list_all_commands' function with extra hub commands
    106   __git_list_all_commands() {
    107     cat <<-EOF
    108 alias
    109 pull-request
    110 fork
    111 create
    112 browse
    113 compare
    114 ci-status
    115 EOF
    116     __git_list_all_commands_without_hub
    117   }
    118 
    119   # Ensure cached commands are cleared
    120   __git_all_commands=""
    121 }
    122 
    123 # redefine _hub to a much smaller function in the steady state
    124 _hub () {
    125   # only attempt to intercept the normal "_git" helper functions once
    126   (( $+__hub_func_replacement_done )) ||
    127     () {
    128       # At this stage in the shell's execution the "_git" function has not yet
    129       # been autoloaded, so the "_git_commands" or "__git_list_all_commands"
    130       # functions will not be defined.  Call it now (with a bogus no-op service
    131       # to prevent premature completion) so that we can wrap them.
    132       if declare -f _git >& /dev/null ; then
    133         _hub_noop () { __hub_zsh_provided=1 }       # zsh-provided will call this one
    134         __hub_noop_main () { __hub_git_provided=1 } # git-provided will call this one
    135         local service=hub_noop
    136         _git
    137         unfunction _hub_noop
    138         unfunction __hub_noop_main
    139         service=git
    140       fi
    141 
    142       if (( $__hub_zsh_provided )) ; then
    143         __hub_setup_zsh_fns
    144       elif (( $__hub_git_provided )) ; then
    145         __hub_setup_bash_fns
    146       fi
    147 
    148       __hub_func_replacement_done=1
    149     }
    150 
    151   # Now perform the actual completion, allowing the "_git" function to call our
    152   # replacement "_git_commands" function as needed.  Both versions expect
    153   # service=git or they will call nonexistent routines or end up in an infinite
    154   # loop.
    155   service=git
    156   declare -f _git >& /dev/null && _git
    157 }
    158 
    159 # make sure we actually attempt to complete on the first "tab" from the user
    160 _hub