如何将自定义 git 命令添加到 zsh 补全?

How to add custom git command to zsh completion?

我已经阅读了一些关于 zsh 完成的指南,但我仍然感到困惑。在我们的开发环境中,我们有一个名为 git new-branch 的自定义 Git 命令。我希望 zsh 在键入 git neTab 后自动完​​成它。我该怎么做?

默认git完成is extendible:

Say you got your own git sub-commands (git will run a program `git-foo' when you run "git foo") and you want "git f" to complete that sub commands name for you. You can make that sub-command known to the completion via the user-command style:

% zstyle ':completion:*:*:git:*' user-commands foo:'description for foo'

`user-commands' is a list style, so you can add any number of programs there. The :description part is optional, so you could add all git-* programs from your $path like this:

% zstyle ':completion:*:*:git:*' user-commands ${${(M)${(k)commands}:#git-*}/git-/}

即加

即可
zstyle ':completion:*:*:git:*' user-commands new-branch:'custom new branch function'

给你的 zshrc.

如果您也想处理自定义命令的参数,那么使用自定义 compdef 文件是更好的解决方案。上面引用的文件也有一些详细信息:只需创建一个定义 git-<yourcommand> 函数的标准定义文件,默认 git 完成将在需要时自动使用它。

使用 Git 2.18(2018 年第 2 季度),你有一个新的可能性,它不仅适用于 zsh:命令行完成机制(在 contrib/ 中)学会了加载 “git $command”的自定义完成文件,其中 $command 是 最终用户在使用时在 $PATH 上的自定义“git-$command” bash.

的较新版本

参见 commit 085e2ee (29 Apr 2018) by Florian Gamböck (FloGa)
(由 Junio C Hamano -- gitster -- in commit fb3a0ca 合并,2018 年 5 月 23 日)

completion: load completion file for external subcommand

Adding external subcommands to Git is as easy as to put an executable file git-foo into PATH.
Packaging such subcommands for a Linux distribution can be achieved by unpacking the executable into /usr/bin of the user's system.
Adding system-wide completion scripts for new subcommands, however, can be a bit tricky.

Since bash-completion started to use dynamical loading of completion scripts since v1.90 (preview of v2.0), it is no longer sufficient to drop a completion script of a subcommand into the standard completions path, /usr/share/bash-completion/completions, since this script will not be loaded if called as a git subcommand.

For example, look at https://bugs.gentoo.org/544722.
To give a short summary: The popular git-flow subcommand provides a completion script, which gets installed as /usr/share/bash-completion/completions/git-flow.

If you now type into a Bash shell:

git flow <TAB>

You will not get any completions, because bash-completion only loads completions for git and git has no idea that git-flow is defined in another file.
You have to load this script manually or trigger the dynamic loader with:

`git-flow <TAB>` # Please notice the dash instead of whitespace

This will not complete anything either, because it only defines a Bash function, without generating completions.
But now the correct completion script has been loaded and the first command can use the completions.

So, the goal is now to teach the git completion script to consider the possibility of external completion scripts for subcommands, but of course without breaking current workflows.

怎么样?这就是 Git 2.18 提出的:

I think the easiest method is to use a function that was defined by bash-completion v1.90, namely _completion_loader.
It will take care of loading the correct script if present.
Afterwards, the git completion script behaves as usual.

_completion_loader was introduced in commit 20c05b43 of scop/bash-completion (the programmable completion functions for bash) back in 2011, so it should be available in even older LTS distributions.
This function searches for external completion scripts not only in the default path /usr/share/bash-completion/completions, but also in the user's home directory via $XDG_DATA_HOME and in a user specified directory via $BASH_COMPLETION_USER_DIR.


univerio adds :

It turns out that there are two different completion functions:

univerio 添加:

  • The zsh-provided function is the default on Debian (and Ubuntu, Mint, etc), and
  • the git-provided function is the default on homebrew-installed git on macOS.

Super confusing. Not sure which one is better.

This particular answer works only for the git-provided function, while the accepted answer works only for the zsh-provided function.