github.com/echohead/hub@v2.2.1+incompatible/etc/hub.bash_completion.sh (about)

     1  # hub tab-completion script for bash.
     2  # This script complements the completion script that ships with git.
     3  
     4  # Check that git tab completion is available
     5  if declare -F _git > /dev/null; then
     6    # Duplicate and rename the 'list_all_commands' function
     7    eval "$(declare -f __git_list_all_commands | \
     8          sed 's/__git_list_all_commands/__git_list_all_commands_without_hub/')"
     9  
    10    # Wrap the 'list_all_commands' function with extra hub commands
    11    __git_list_all_commands() {
    12      cat <<-EOF
    13  alias
    14  pull-request
    15  fork
    16  create
    17  browse
    18  compare
    19  ci-status
    20  EOF
    21      __git_list_all_commands_without_hub
    22    }
    23  
    24    # Ensure cached commands are cleared
    25    __git_all_commands=""
    26  
    27    ##########################
    28    # hub command completions
    29    ##########################
    30  
    31    # hub alias [-s] [SHELL]
    32    _git_alias() {
    33      local i c=2 s=-s sh shells="bash zsh sh ksh csh fish"
    34      while [ $c -lt $cword ]; do
    35        i="${words[c]}"
    36        case "$i" in
    37          -s)
    38            unset s
    39            ;;
    40          *)
    41            for sh in $shells; do
    42              if [ "$sh" = "$i" ]; then
    43                unset shells
    44                break
    45              fi
    46            done
    47            ;;
    48        esac
    49        ((c++))
    50      done
    51      __gitcomp "$s $shells"
    52    }
    53  
    54    # hub browse [-u] [--|[USER/]REPOSITORY] [SUBPAGE]
    55    _git_browse() {
    56      local i c=2 u=-u repo subpage
    57      local subpages_="commits issues tree wiki pulls branches stargazers
    58        contributors network network/ graphs graphs/"
    59      local subpages_network="members"
    60      local subpages_graphs="commit-activity code-frequency punch-card"
    61      while [ $c -lt $cword ]; do
    62        i="${words[c]}"
    63        case "$i" in
    64          -u)
    65            unset u
    66            ;;
    67          *)
    68            if [ -z "$repo" ]; then
    69              repo=$i
    70            else
    71              subpage=$i
    72            fi
    73            ;;
    74        esac
    75        ((c++))
    76      done
    77      if [ -z "$repo" ]; then
    78        __gitcomp "$u -- $(__hub_github_repos '\p')"
    79      elif [ -z "$subpage" ]; then
    80        case "$cur" in
    81          */*)
    82            local pfx="${cur%/*}" cur_="${cur#*/}"
    83            local subpages_var="subpages_$pfx"
    84            __gitcomp "${!subpages_var}" "$pfx/" "$cur_"
    85            ;;
    86          *)
    87            __gitcomp "$u ${subpages_}"
    88            ;;
    89        esac
    90      else
    91        __gitcomp "$u"
    92      fi
    93    }
    94  
    95    # hub compare [-u] [USER[/REPOSITORY]] [[START...]END]
    96    _git_compare() {
    97      local i c=$((cword - 1)) u=-u user remote owner repo arg_repo rev
    98      while [ $c -gt 1 ]; do
    99        i="${words[c]}"
   100        case "$i" in
   101          -u)
   102            unset u
   103            ;;
   104          *)
   105            if [ -z "$rev" ]; then
   106              # Even though the logic below is able to complete both user/repo
   107              # and revision in the right place, when there is only one argument
   108              # (other than -u) in the command, that argument will be taken as
   109              # revision. For example:
   110              # $ hub compare -u upstream
   111              # > https://github.com/USER/REPO/compare/upstream
   112              if __hub_github_repos '\p' | grep -Eqx "^$i(/[^/]+)?"; then
   113                arg_repo=$i
   114              else
   115                rev=$i
   116              fi
   117            elif [ -z "$arg_repo" ]; then
   118              arg_repo=$i
   119            fi
   120            ;;
   121        esac
   122        ((c--))
   123      done
   124  
   125      # Here we want to find out the git remote name of user/repo, in order to
   126      # generate an appropriate revision list
   127      if [ -z "$arg_repo" ]; then
   128        user=$(__hub_github_user)
   129        if [ -z "$user" ]; then
   130          for i in $(__hub_github_repos); do
   131            remote=${i%%:*}
   132            repo=${i#*:}
   133            if [ "$remote" = origin ]; then
   134              break
   135            fi
   136          done
   137        else
   138          for i in $(__hub_github_repos); do
   139            remote=${i%%:*}
   140            repo=${i#*:}
   141            owner=${repo%%/*}
   142            if [ "$user" = "$owner" ]; then
   143              break
   144            fi
   145          done
   146        fi
   147      else
   148        for i in $(__hub_github_repos); do
   149          remote=${i%%:*}
   150          repo=${i#*:}
   151          owner=${repo%%/*}
   152          case "$arg_repo" in
   153            "$repo"|"$owner")
   154              break
   155              ;;
   156          esac
   157        done
   158      fi
   159  
   160      local pfx cur_="$cur"
   161      case "$cur_" in
   162        *..*)
   163          pfx="${cur_%%..*}..."
   164          cur_="${cur_##*..}"
   165          __gitcomp_nl "$(__hub_revlist $remote)" "$pfx" "$cur_"
   166          ;;
   167        *)
   168          if [ -z "${arg_repo}${rev}" ]; then
   169            __gitcomp "$u $(__hub_github_repos '\o\n\p') $(__hub_revlist $remote)"
   170          elif [ -z "$rev" ]; then
   171            __gitcomp "$u $(__hub_revlist $remote)"
   172          else
   173            __gitcomp "$u"
   174          fi
   175          ;;
   176      esac
   177    }
   178  
   179    # hub create [NAME] [-p] [-d DESCRIPTION] [-h HOMEPAGE]
   180    _git_create() {
   181      local i c=2 name repo flags="-p -d -h"
   182      while [ $c -lt $cword ]; do
   183        i="${words[c]}"
   184        case "$i" in
   185          -d|-h)
   186            ((c++))
   187            flags=${flags/$i/}
   188            ;;
   189          -p)
   190            flags=${flags/$i/}
   191            ;;
   192          *)
   193            name=$i
   194            ;;
   195        esac
   196        ((c++))
   197      done
   198      if [ -z "$name" ]; then
   199        repo=$(basename "$(pwd)")
   200      fi
   201      case "$prev" in
   202        -d|-h)
   203          COMPREPLY=()
   204          ;;
   205        -p|*)
   206          __gitcomp "$repo $flags"
   207          ;;
   208      esac
   209    }
   210  
   211    # hub fork [--no-remote]
   212    _git_fork() {
   213      local i c=2 remote=yes
   214      while [ $c -lt $cword ]; do
   215        i="${words[c]}"
   216        case "$i" in
   217          --no-remote)
   218            unset remote
   219            ;;
   220        esac
   221        ((c++))
   222      done
   223      if [ -n "$remote" ]; then
   224        __gitcomp "--no-remote"
   225      fi
   226    }
   227  
   228    # hub pull-request [-f] [-m <MESSAGE>|-F <FILE>|-i <ISSUE>|<ISSUE-URL>] [-b <BASE>] [-h <HEAD>]
   229    _git_pull_request() {
   230      local i c=2 flags="-f -m -F -i -b -h"
   231      while [ $c -lt $cword ]; do
   232        i="${words[c]}"
   233        case "$i" in
   234          -m|-F|-i|-b|-h)
   235            ((c++))
   236            flags=${flags/$i/}
   237            ;;
   238          -f)
   239            flags=${flags/$i/}
   240            ;;
   241        esac
   242        ((c++))
   243      done
   244      case "$prev" in
   245        -i)
   246          COMPREPLY=()
   247          ;;
   248        -b|-h)
   249          # (Doesn't seem to need this...)
   250          # Uncomment the following line when 'owner/repo:[TAB]' misbehaved
   251          #_get_comp_words_by_ref -n : cur
   252          __gitcomp_nl "$(__hub_heads)"
   253          # __ltrim_colon_completions "$cur"
   254          ;;
   255        -F)
   256          COMPREPLY=( "$cur"* )
   257          ;;
   258        -f|*)
   259          __gitcomp "$flags"
   260          ;;
   261      esac
   262    }
   263  
   264    ###################
   265    # Helper functions
   266    ###################
   267  
   268    # __hub_github_user [HOST]
   269    # Return $GITHUB_USER or the default github user defined in hub config
   270    # HOST - Host to be looked-up in hub config. Default is "github.com"
   271    __hub_github_user() {
   272      if [ -n "$GITHUB_USER" ]; then
   273        echo $GITHUB_USER
   274        return
   275      fi
   276      local line h k v host=${1:-github.com} config=${HUB_CONFIG:-~/.config/hub}
   277      if [ -f "$config" ]; then
   278        while read line; do
   279          if [ "$line" = "---" ]; then
   280            continue
   281          fi
   282          k=${line%%:*}
   283          v=${line#*:}
   284          if [ -z "$v" ]; then
   285            if [ "$h" = "$host" ]; then
   286              break
   287            fi
   288            h=$k
   289            continue
   290          fi
   291          k=${k#* }
   292          v=${v#* }
   293          if [ "$h" = "$host" ] && [ "$k" = "user" ]; then
   294            echo "$v"
   295            break
   296          fi
   297        done < "$config"
   298      fi
   299    }
   300  
   301    # __hub_github_repos [FORMAT]
   302    # List all github hosted repository
   303    # FORMAT - Format string contains multiple of these:
   304    #   \m  remote
   305    #   \p  owner/repo
   306    #   \o  owner
   307    #   escaped characters (\n, \t ...etc) work
   308    # If omitted, prints all github repos in the format of "remote:owner/repo"
   309    __hub_github_repos() {
   310      local f format=$1
   311      if [ -z "$(__gitdir)" ]; then
   312        return
   313      fi
   314      if [ -z "$format" ]; then
   315        format='\1:\2'
   316      else
   317        format=${format//\m/\1}
   318        format=${format//\p/\2}
   319        format=${format//\o/\3}
   320      fi
   321      command git config --get-regexp 'remote\.[^.]*\.url' |
   322      grep -E ' ((https?|git)://|git@)github\.com[:/][^:/]+/[^/]+$' |
   323      sed -E 's#^remote\.([^.]+)\.url +.+[:/](([^/]+)/[^.]+)(\.git)?$#'"$format"'#'
   324    }
   325  
   326    # __hub_heads
   327    # List all local "branch", and remote "owner/repo:branch"
   328    __hub_heads() {
   329      local i remote repo branch dir=$(__gitdir)
   330      if [ -d "$dir" ]; then
   331        command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
   332          "refs/heads/"
   333        for i in $(__hub_github_repos); do
   334          remote=${i%%:*}
   335          repo=${i#*:}
   336          command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
   337            "refs/remotes/${remote}/" | while read branch; do
   338            echo "${repo}:${branch#${remote}/}"
   339          done
   340        done
   341      fi
   342    }
   343  
   344    # __hub_revlist [REMOTE]
   345    # List all tags, and branches under REMOTE, without the "remote/" prefix
   346    # REMOTE - Remote name to search branches from. Default is "origin"
   347    __hub_revlist() {
   348      local i remote=${1:-origin} dir=$(__gitdir)
   349      if [ -d "$dir" ]; then
   350        command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
   351          "refs/remotes/${remote}/" | while read i; do
   352          echo "${i#${remote}/}"
   353        done
   354        command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
   355          "refs/tags/"
   356      fi
   357    }
   358  
   359    # Enable completion for hub even when not using the alias
   360    complete -o bashdefault -o default -o nospace -F _git hub 2>/dev/null \
   361      || complete -o default -o nospace -F _git hub
   362  fi