我已经阅读了一些关于zsh补全的指南,但仍感到困惑。在我们的开发环境中,我们有一个名为git new-branch
的自定义Git命令。 我想在键入git ne
和Tab后,让zsh自动补全它。我该怎么做?
我已经阅读了一些关于zsh补全的指南,但仍感到困惑。在我们的开发环境中,我们有一个名为git new-branch
的自定义Git命令。 我想在键入git ne
和Tab后,让zsh自动补全它。我该怎么做?
默认的 git 自动补全可以扩展:
比如说你有自己的 git 子命令(当你运行 "git foo" 时,git 将运行一个名为“git-foo”的程序),你希望 "git f" 自动补全这个子命令的名称。你可以通过用户命令样式将该子命令知名于自动补全:
% zstyle ':completion:*:*:git:*' user-commands foo:'description for foo'
`user-commands' 是一个列表样式,所以您可以在其中添加任意数量的程序。 :description 部分是可选的,因此您可以像这样添加 $path 中的所有 git-* 程序:
那就是,只需要添加。
% 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年第二季度)中,您有一个新的选择,这不仅适用于zsh:命令行完成机制(位于contrib/
中)已经学会为"git $command
"加载自定义完成文件,其中$command
是用户在使用更新版本的bash时在$PATH上拥有的自定义"git-$command
"。
请看 提交 085e2ee(2018年4月29日)由Florian Gamböck (FloGa
)。
(在提交fb3a0ca中由Junio C Hamano -- gitster
--合并,于2018年5月23日)
这是 Git 2.18 提出的方法:completion: load completion file for external subcommand
Adding external subcommands to Git is as easy as to put an executable file
git-foo
intoPATH
.
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 agit subcommand
.For example, look at https://bugs.gentoo.org/544722.
To give a short summary: The populargit-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.
我认为最简单的方法是使用由 bash-completion v1.90 定义的函数,即 _completion_loader。
它会负责加载正确的脚本(如果有的话)。
之后,git 完成脚本会像往常一样工作。_completion_loader 是在 2011 年 提交 20c05b43 的
scop/bash-completion
(bash 的可编程完成函数)中引入的,因此即使在旧的 LTS 发行版中也应该可用。
该函数不仅在默认路径 /usr/share/bash-completion/completions 中搜索外部完成脚本,还通过 $XDG_DATA_HOME 在用户的主目录中以及通过 $BASH_COMPLETION_USER_DIR 在用户指定的目录中搜索。
事实证明,有两个不同的完成函数:
- 一个随zsh一起提供,和
- 另一个随Git一起提供。
univerio补充道:
- 由zsh提供的函数是Debian(以及Ubuntu、Mint等)的默认值,并且
- 由git提供的函数是macOS上安装homebrew的git的默认值。
非常令人困惑。不确定哪一个更好。
这个特定答案仅适用于由Git提供的函数,而被接受的答案仅适用于由zsh提供的函数。
/usr/share/bash-completion/completions
。请参见下面的答案。 - VonC