使用裸 git 存储库自动完成 Zsh 文件

aaa*_*aaa 2 zsh git autocomplete

我的 .zshrc 中有这个:

# command completion
autoload -Uz compinit
compinit
Run Code Online (Sandbox Code Playgroud)

通常让我通过选项卡浏览命令、参数和文件。

但对于git --git-dir=<the path> --work-tree="$HOME"(通常是别名)它仅适用于子命令(如添加和推送)和参数,不适用于文件。我希望它也能处理文件。

我尝试将其放入脚本中,如下所示:

#!/usr/bin/env sh

git --git-dir=<the path> --work-tree="$HOME" "$@"
Run Code Online (Sandbox Code Playgroud)

它适用于文件,但子命令和参数会中断。

谢谢。

Gil*_*il' 5

如果--git-dir出现在命令行上,如果您的 zsh 足够新(\xe2\x89\xa55.3),则完成代码会识别它并在查找要完成的内容时考虑它。它通过将参数作为--git-dir环境变量传递来实现这一点GIT_DIR。例如,要在 后补全远程名称git fetch,zsh 运行git remote。之后git --git-dir=/some/where,zsh在环境中git remote运行。GIT_DIR=/some/where所以这部分确实有效。

\n\n

不幸的是,从当前的 zsh 版本(5.7.1+)开始,它传递了未扩展的参数。因此,如果您写类似的内容git --git-dir=~/repositories/foo.git,zsh 会通过GIT_DIR=~/repositories/foo.git,但不会GIT_DIR=/home/aaa/repositories/foo.git

\n\n

zsh 补全代码没有对--work-tree.

\n\n

我认为您可以通过编辑文件并替换行来解决扩展问题--git-dir并添加支持--git-worktree_git

\n\n
        (( $+opt_args[--git-dir] )) && local -x GIT_DIR=$opt_args[--git-dir]\n
Run Code Online (Sandbox Code Playgroud)\n\n

经过

\n\n
        (( $+opt_args[--git-dir] )) && local -x GIT_DIR=${(e)~opt_args[--git-dir]}\n        (( $+opt_args[--work-tree] )) && local -x GIT_WORKTREE=${(e)~opt_args[--work-tree]}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我还没有测试过这个。

\n\n

我没有足够的动力发帖到 zsh 邮件列表,但请这样做:这个(或者它的工作版本,如果它不起作用)将是一个有用的补丁。

\n\n

如果您将--git-dir--work-tree放在别名中,这是透明的:zsh 在完成之前扩展别名(假设您没有关闭该选项complete_aliases)。如果你把它们放在一个函数或脚本中,这是不透明的:zsh不会看到它们,甚至不会知道函数或脚本调用了git,除非你告诉它。

\n\n

如果您无法让此补丁发挥作用,或者您不想维护自己的 版本_git,则可以通过使用包装 git 的自定义完成函数定义自定义命令来解决此问题。

\n\n
gitx () {\n  git --git-dir=/some/where --work-tree=/else/where "$@"\n}\n_gitx () {\n  local -x GIT_DIR=/some/where GIT_WORKTREE=/else/where\n  _git "$@"\n}\ncompdef _gitx gitx\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您有多个包装器,则每个包装器都需要一个完成函数。或者,您可以向完成函数添加一些逻辑来确定要使用的GIT_DIR和的值GIT_WORKTREE。函数的名称位于$service.

\n