任何人都知道如何对 zsh 做同样的事情?
5 回答
zstyle :completion::complete:git-checkout:argument-rest:headrefs command "git for-each-ref --format='%(refname)' refs/heads 2>/dev/null"
解释:
如果您在当前上下文中按 TAB (而不是按) ,键入git checkout <Control-x><h>
调用_complete_help
会公开 zsh 完成系统如何操作的内部结构。<Control-x><h>
从这里可以看出zsh会调用该__git_heads
函数来完成git分支头的名称。如果然后键入which __git_heads
,您可以看到这些分支头名称是通过以下方式获得的:
_call_program headrefs git for-each-ref --format='"%(refname)"' refs/heads refs/remotes 2>/dev/null
幸运的是,_call_program
它专门设计用于允许用户更改默认行为。所以上面的zstyle
命令指示 zsh 使用替代git for-each-ref ...
调用而不是内置的调用,你可以看到在上面的调用中,我删除了refs/remotes
参数。的第一个参数zstyle
是完成上下文,这里它的意思是“headrefs
当用户完成参数时,完成系统请求完成标签的完成git checkout
。所以这zstyle
只会影响git checkout
,而不影响任何其他git
子命令。
通过键入git checkout <Ctrl-X><H>
,您会看到一堆标签,其中一些似乎相关的是:
$ git checkout
tags in context :completion::complete:git-checkout:argument-rest:
remote-branch-names-noprefix (__git_describe_branch __git_describe_commit __git_remote_branch_names_noprefix _git-checkout _git)
heads-remote (__git_describe_branch __git_describe_commit __git_heads_remote __git_heads __git_commits __git_tree_ishs _git-checkout _git)
[...]
乍一看,我们需要改变remote-branch-names-noprefix
's 的行为以停止提供不带前缀的远程分支名称。
要仔细检查,让我们看看这些标签与哪些条目相关联,使用:
$ zstyle ':completion:*' group-name ''
$ zstyle ':completion:*' format 'Completing "%d":'
$ git checkout T<Tab>
Completing "remote branch name":
T3522-plugins_and_stuff T7482
Completing "local head":
T7626-async
在上面标签名称后面的括号中,有一串命令会导致为该标签生成自动完成条目。在remote-branch-names-noprefix
's 链中,您可以看到__git_remote_branch_names_noprefix
哪些似乎相关。看看/usr/share/zsh/functions/Completion/Unix/_git
:
(( $+functions[__git_remote_branch_names_noprefix] )) ||
__git_remote_branch_names_noprefix () {
declare -a heads
branch_names=(${${${${(f)"$(_call_program remote-branch-refs-noprefix git for-each-ref --format='"%(refname)"' refs/remotes 2>/dev/null)"}#refs/remotes/}#*/}:#HEAD})
__git_command_successful $pipestatus || return 1
__git_describe_commit branch_names remote-branch-names-noprefix 'remote branch name' "$@"
}
您可以看到如何_call_program
用于定义remote-branch-refs-noprefix
. 我们想在git-checkout
's 的情况下改变这个定义。通过将其替换为“echo”,它将停止提供自动完成条目:
zstyle ':completion::complete:git-checkout:argument-rest:remote-branch-refs-noprefix' command "echo"
看来__git_heads
现在只检查本地分支,而是调用完成文件__git_refs
。
我通过将此补丁应用到 来破解它git-completion.bash
,它由 zsh_git
命令代理:
--- git-completion.bash.old 2015-04-02 16:09:38.000000000 -0700
+++ git-completion.bash 2015-04-02 16:10:24.000000000 -0700
@@ -1032,13 +1032,7 @@
"
;;
*)
- # check if --track, --no-track, or --no-guess was specified
- # if so, disable DWIM mode
- local flags="--track --no-track --no-guess" track=1
- if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
- track=''
- fi
- __gitcomp_nl "$(__git_refs '' $track)"
+ __gitcomp_nl "$(__git_heads)"
;;
esac
}
这不是一个完美的解决方案,但它适用于我的用例,并且可以立即完成而不是 10 秒。
没有一个答案不帮助我。尝试这个:
$ git checkout <Ctrl+X><H>
tags in context :completion::complete:git::
argument-rest (_arguments _git)
tags in context :completion::complete:git-checkout::
argument-rest options (_arguments _git-checkout _call_function _git)
tags in context :completion::complete:git-checkout:argument-rest:
remote branches tree-ishs modified-files (_alternative _git-checkout _call_function _git)
remote-branch-names-noprefix (__git_remote_branch_names_noprefix _alternative _git-checkout _call_function _git)
heads commit-tags commit-objects (_alternative __git_commits __git_tree_ishs _alternative _git-checkout _call_function _git)
heads-local (__git_heads_local __git_heads _alternative __git_commits __git_tree_ishs _alternative _git-checkout _call_function _git)
commit-tags (__git_tags_of_type __git_commit_tags _alternative __git_commits __git_tree_ishs _alternative _git-checkout _call_function _git)
modified-files (__git_files __git_modified_files _alternative _git-checkout _call_function _git)
你可以在这个输出函数中找到,它会为命令生成完成。您可以在.zshrc
. 把它放在配置文件的最顶部:
__git_heads_remote() {}
之后,您将不会在完成时看到远程磁头。您可以对任何功能执行此操作。
git checkout
您可以通过将此行添加到.zshrc
文件中来禁用自动完成功能:
compdef -d git checkout