问题 在Zsh中禁用远程分支的自动完成?


这与。有关 在Git Bash中禁用远程分支的自动完成?

任何人都知道如何使用zsh做同样的事情?


9710
2017-08-29 09:56


起源



答案:


zstyle :completion::complete:git-checkout:argument-rest:headrefs command "git for-each-ref --format='%(refname)' refs/heads 2>/dev/null"

说明:

打字 git checkout <Control-x><h> 所调用 _complete_help 这揭示了如果你在当前环境中按下TAB而不是按下,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 子命令。


9
2018-06-16 12:21



如何将远程和本地分成自动完成中的两个独立部分?例如。我很想拥有特殊的头脑(HEAD, ORIG_HEAD, FETCH_HEAD等),然后是本地分支机构,然后是远程分支机构。对我来说,如何做到这一点并不明显。如果很容易扩展你的答案,那就会膨胀。如果没有,我会打开一个新问题。 - Bo Jeanes
有 大概 一种方法 - 毕竟,有一个分组机制(搜索 group-name 和 group-order 在手册中)但我不知道如何将各种头分成这些组 - 所以可能值得一个单独的问题。 - Adam Spiers


答案:


zstyle :completion::complete:git-checkout:argument-rest:headrefs command "git for-each-ref --format='%(refname)' refs/heads 2>/dev/null"

说明:

打字 git checkout <Control-x><h> 所调用 _complete_help 这揭示了如果你在当前环境中按下TAB而不是按下,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 子命令。


9
2018-06-16 12:21



如何将远程和本地分成自动完成中的两个独立部分?例如。我很想拥有特殊的头脑(HEAD, ORIG_HEAD, FETCH_HEAD等),然后是本地分支机构,然后是远程分支机构。对我来说,如何做到这一点并不明显。如果很容易扩展你的答案,那就会膨胀。如果没有,我会打开一个新问题。 - Bo Jeanes
有 大概 一种方法 - 毕竟,有一个分组机制(搜索 group-name 和 group-order 在手册中)但我不知道如何将各种头分成这些组 - 所以可能值得一个单独的问题。 - Adam Spiers


看起来 __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秒。


1
2018-04-02 23:14





通过打字 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停止提供没有前缀的远程分支名称的行为。

要仔细检查,让我们看看这些标签与哪些条目相关联,使用:

$ 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你能看到的链条 __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的情况。通过将其替换为“echo”,它将停止提供自动完成条目:

zstyle ':completion::complete:git-checkout:argument-rest:remote-branch-refs-noprefix' command "echo"

1
2017-11-29 15:56





没有人回答不帮助我。尝试这个:

$ 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() {}

之后,您将无法在完成时看到远程头部。您可以为任何功能执行此操作。


0
2018-03-27 08:39





您可以禁用自动完成功能 git checkout 将此行添加到您的 .zshrc 文件:

compdef -d git checkout

-1
2017-08-29 13:17



我一直在寻找一种避免自动完成远程分支的方法。我想要自动完成本地分支机构。 - Galder Zamarreño
@GalderZamarreño害怕超出我的zsh知识的范围;可能会尝试zsh列表;他们似乎是有帮助的人。 - Christopher