aboutsummaryrefslogtreecommitdiff
path: root/bash/bash_completion.d
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2016-09-09 01:34:45 +1200
committerTom Ryder <tom@sanctum.geek.nz>2016-09-09 01:37:10 +1200
commit89ccc114cbbee7e9d2a42498408b2b82e8ff4b08 (patch)
treece9b7a9848ed98c6a34f5edc7c98373154b49a6e /bash/bash_completion.d
parentCorrect ref matching in Git completion (diff)
downloaddotfiles-89ccc114cbbee7e9d2a42498408b2b82e8ff4b08.tar.gz
dotfiles-89ccc114cbbee7e9d2a42498408b2b82e8ff4b08.zip
Further refinements/extensions to Git completion
Diffstat (limited to 'bash/bash_completion.d')
-rw-r--r--bash/bash_completion.d/git.bash189
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
}