diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2016-09-09 01:34:45 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2016-09-09 01:37:10 +1200 |
commit | 89ccc114cbbee7e9d2a42498408b2b82e8ff4b08 (patch) | |
tree | ce9b7a9848ed98c6a34f5edc7c98373154b49a6e /bash/bash_completion.d/git.bash | |
parent | Correct ref matching in Git completion (diff) | |
download | dotfiles-89ccc114cbbee7e9d2a42498408b2b82e8ff4b08.tar.gz dotfiles-89ccc114cbbee7e9d2a42498408b2b82e8ff4b08.zip |
Further refinements/extensions to Git completion
Diffstat (limited to 'bash/bash_completion.d/git.bash')
-rw-r--r-- | bash/bash_completion.d/git.bash | 189 |
1 files changed, 131 insertions, 58 deletions
diff --git a/bash/bash_completion.d/git.bash b/bash/bash_completion.d/git.bash index d974f655..798f04e8 100644 --- a/bash/bash_completion.d/git.bash +++ b/bash/bash_completion.d/git.bash @@ -1,5 +1,92 @@ # Some simple completion for Git _git() { + + # Subcommands for this function to stack words onto COMPREPLY; if the first + # argument is not given, the rest of the function is reached + case $1 in + + # No argument; continue normal completion + '') ;; + + # Symbolic references, remote or local + refs) + local ref + while IFS= read -r ref ; do + [[ -n $ref ]] || continue + ref=${ref#refs/*/} + case $ref in + "${COMP_WORDS[COMP_CWORD]}"*) + COMPREPLY[${#COMPREPLY[@]}]=$ref + ;; + esac + done < <(git for-each-ref \ + --format '%(refname)' \ + 2>/dev/null) + return + ;; + + # Remote names + remotes) + local remote + while IFS= read -r remote ; do + case $remote in + '') continue ;; + "${COMP_WORDS[COMP_CWORD]}"*) + COMPREPLY[${#COMPREPLY[@]}]=$remote + ;; + esac + done < <(git remote 2>/dev/null) + return + ;; + + # Git aliases + aliases) + local alias + while IFS= read -r alias ; do + alias=${alias#alias.} + alias=${alias%% *} + case $alias in + '') continue ;; + "${COMP_WORDS[COMP_CWORD]}"*) + COMPREPLY[${#COMPREPLY[@]}]=$alias + ;; + esac + done < <(git config \ + --get-regexp '^alias\.' \ + 2>/dev/null) + return + ;; + + # Git subcommands + subcommands) + local execpath + execpath=$(git --exec-path) || return + local path + for path in "$execpath"/git-"${COMP_WORDS[COMP_CWORD]}"* ; do + [[ -f $path ]] || continue + [[ -x $path ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=${path#"$execpath"/git-} + done + return + ;; + + # Untracked files + untracked_files) + local file + while IFS= read -rd '' file ; do + [[ -n $file ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$file + done < <(git ls-files \ + --directory \ + --exclude-standard \ + --no-empty-directory \ + --others \ + -z \ + -- "${COMP_WORDS[COMP_CWORD]}"'*' \ + 2>/dev/null) + return + ;; + esac # Try to find the index of the Git subcommand local -i sci i @@ -20,16 +107,10 @@ _git() { esac done - # Complete initial subcommand - if ((sci == COMP_CWORD)) || [[ ${COMP_WORDS[sci]} == 'help' ]] ; then - local ep - ep=$(git --exec-path) || return - local path - for path in "$ep"/git-"${COMP_WORDS[COMP_CWORD]}"* ; do - [[ -f $path ]] || continue - [[ -x $path ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=${path#"$ep"/git-} - done + # Complete initial subcommand or alias + if ((sci == COMP_CWORD)) ; then + _git subcommands + _git aliases return fi @@ -38,61 +119,53 @@ _git() { # Complete with untracked, unignored files add) - local file - while IFS= read -rd '' file ; do - [[ -n $file ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$file - done < <(git ls-files \ - --directory \ - --exclude-standard \ - --no-empty-directory \ - --others \ - -z \ - -- "${COMP_WORDS[COMP_CWORD]}"'*' \ - 2>/dev/null) + _git untracked_files + return + ;; + + # Help on real subcommands (not aliases) + help) + _git subcommands + return ;; # Complete with remote subcommands and then remote names remote) local word - while IFS= read -r word ; do - [[ -n $word ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$word - done < <( - if ((COMP_CWORD - sci > 1)) ; then - git remote 2>/dev/null - else - compgen -W ' - add - get-url - prune - remove - rename - set-branches - set-head - set-url - show - update - ' -- "${COMP_WORDS[COMP_CWORD]}" - fi - ) + if ((CWORD == 1)) ; then + while IFS= read -r word ; do + [[ -n $word ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$word + done < <(compgen -W ' + add + get-url + prune + remove + rename + set-branches + set-head + set-url + show + update + ' -- "${COMP_WORDS[COMP_CWORD]}") + else + _git remotes + fi + return ;; - # Complete with ref names - *) - local ref - while IFS= read -r ref ; do - [[ -n $ref ]] || continue - ref=${ref#refs/*/} - case $ref in - "${COMP_WORDS[COMP_CWORD]}"*) - COMPREPLY[${#COMPREPLY[@]}]=$ref - ;; - esac - done < <(git for-each-ref \ - --format '%(refname)' \ - 2>/dev/null) - return + # Complete with remotes and then refs + fetch|pull|push) + if ((CWORD == 1)) ; then + _git remotes + else + _git refs + fi + ;; + + # Commands for which I'm likely to want a ref + branch|checkout|merge|rebase|tag) + _git refs ;; esac } |