git 自定义子命令的 bash 补全?

usr*_*etc 4 git bash-completion git-completion

假设我有一个git-cc可执行文件PATH。如果git-cc支持--help,那么很容易提供足够的完成

complete -F _longopt git-cc
Run Code Online (Sandbox Code Playgroud)

这样就$ git-cc --<TAB>完成了(根据帮助输出)。但git cc --<TAB>不会完成(即使它运行良好)。更重要的是,如果我为自定义子命令创建 git 别名,例如cc-sensible-defaults = cc --opt1 ...,那也不起作用,在这种情况下,简单地删除空格(git-cc而不是git cc)不是一个选项。

该怎么办?我尝试过使用__git_complete [git-]cc _longopt,但各种组合都没有起到任何作用。它似乎是为了完成 bash 别名(如gl = git-log),而不是子命令。正如预期的那样, git/git-completion.bash中的介绍不是很有帮助,包含令人困惑的内容

# If you have a command that is not part of git, but you would still
# like completion, you can use __git_complete:
#
#   __git_complete gl git_log
#
# Or if it's a main command (i.e. git or gitk):
#
#   __git_complete gk gitk
Run Code Online (Sandbox Code Playgroud)

(WTH 是 _git_log?他们的意思是 _git_log,这确实是一个函数?这是某种约定吗?)

Kam*_*Cuk 6

更新:

\n
\n

对我来说,这个解决方案只是<tab>每次都列出所有替代方案,没有完成,为什么?我尝试过_git_jump() { COMPREPLY=(diff merge grep); }git jump d<tab>但输出只是列出:diff grep merge \xe2\x80\x93\xc2\xa0\nMoberg

\n
\n

您要做的就是从COMPREPLY单词中删除,以便只$cur留下以 开头的单词。如果你给出 3,bash 将显示列表。如果你减少COMPREPLY=(diff)那么 Bash 会自动完成。

\n

受到https://github.com/git/git/blob/master/contrib/completion/git-completion.bash#L2445的启发的启发,以下内容效果很好:

\n
_git_jump() { __gitcomp "diff merge grep" "" "$cur"; }\n
Run Code Online (Sandbox Code Playgroud)\n

或者我认为最好自己编写类似的代码,而不是依赖git

\n
_git_jump() { COMPREPLY=( $(compgen -W "diff merge grep" -- "${COMP_WORDS[COMP_CWORD]}") ); }\n
Run Code Online (Sandbox Code Playgroud)\n

对我来说https://devmanual.gentoo.org/tasks-reference/completion/index.html是最好的介绍如何做到这一点。

\n
\n
\n

该怎么办?

\n
\n

只需定义一个以前导进行编译的函数_git_

\n
# you should rather use COMPREPLY+=(..) or call `__gitcomp` to append\n$ _git_cc() { COMPREPLY=(-a -b); }\n$ git cc <tab>\n-a  -b  \n$ git cc -\n
Run Code Online (Sandbox Code Playgroud)\n

请参阅__git_complete_command

\n
__git_complete_command () {\n    local command="$1"\n    local completion_func="_git_${command//-/_}"\n    ...\n    if __git_have_func $completion_func\n        then\n            $completion_func\n            return 0\n
Run Code Online (Sandbox Code Playgroud)\n
\n

我尝试过使用 __git_complete

\n
\n

据我了解__git_complete恰恰相反 - 你需要一个像 git 子命令一样完整的正常命令。例如:

\n
$ _git_cc() { COMPREPLY=(-a -b); }\n$ alias mycommand=\'git cc\'\n$ __git_complete mycommand git_cc                  # or __git_complete mycommand _git_cc\n$ mycommand <tab>\n-a  -b  \n$ mycommand -\n
Run Code Online (Sandbox Code Playgroud)\n
\n

_git_log 是什么?

\n
\n

_git_log是一个生成补全的函数git log

\n
\n

他们的意思是 _git_log 吗?它确实是一个函数?

\n
\n

是的。请参阅__git_complete_main测试是否存在带有后缀或的函数_

\n
\n

这是某种惯例吗?)

\n
\n

是的。

\n