I recently upgraded my laptop and have been making sure my developer workflow is how I'm used to. Everything has been working fine except Git tab autocompletion.
Normally I can type git che
then hit tab and it will autocomplete to git checkout
.
For whatever reason, on my new laptop, it does not do that. Now it will list every option that starts with "che" (check-attr, check-ignore, cherry, cherry-pick, etc.)
I've read a bunch but can't seem to figure what is (a) causing this (b) how to change it.
Specs: Laptop - Macbook Pro M1 Shell - zsh
Note: I think it may have to do with Zsh's tab-completion library but not sure how to change it.
I've read documentation and updated zshrc files
Added and removed:
autoload -Uz compinit && compinit
CodePudding user response:
Interesting question! I looked into it and here is what I found:
There are two separate zsh completion systems for git:
The one that ships with git (https://github.com/git/git/blob/master/contrib/completion/git-completion.zsh), which, as shown in the docs you linked, offers the completion system you have, based on any available git binaries.
The one that ships with zsh (https://github.com/zsh-users/zsh/blob/master/Completion/Unix/Command/_git), which is much more complex, as well as apparently more context-aware.
Starting a new zsh session with an empty zshrc
(zsh -d -f -i
) we see this:
josh% autoload -Uz compinit && compinit
josh% git che<TAB>
check-attr -- display gitattributes information
check-ignore -- debug gitignore/exclude files
check-mailmap -- show canonical names and email addresses of contacts
check-ref-format -- ensure that a reference name is well formed
checkout -- checkout branch or paths to working tree
checkout-index -- copy files from index to working directory
cherry -- find commits not merged upstream
cherry-pick -- apply changes introduced by some existing commits
Then after loading the other completion system (I'll discuss how exactly to do this next):
josh% git che<TAB>
becomes
josh% git checkout
So how do we switch? The way I do it is via the OMZ plugin gitfast. I don't actually (heaven forbid) use OMZ, but just clone the plugin and source it to my fpath in zshrc
with fpath=( $XDG_CONFIG_HOME/ohmyzsh/plugins/gitfast $fpath )
But it looks like a more direct way would be to follow the instructions in _git
in that repo:
# The recommended way to install this script is to make a copy of it as a
# file named '_git' inside any directory in your fpath.
#
# For example, create a directory '~/.zsh/', copy this file to '~/.zsh/_git',
# and then add the following to your ~/.zshrc file:
#
# fpath=(~/.zsh $fpath)
#
# You need git's bash completion script installed. By default bash-completion's
# location will be used (e.g. pkg-config --variable=completionsdir bash-completion).
#
# If your bash completion script is somewhere else, you can specify the
# location in your ~/.zshrc:
#
# zstyle ':completion:*:*:git:*' script ~/.git-completion.bash