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