我为命令编写了一个简单的完成脚本cheat
,以便cheat
在提示时使用 zsh 时自动完成参数。
(显然)这需要以 compinit / compsys 兼容的方式进行设置:
文件:~/system/dev_resources/zsh_comp/_cheat
#compdef cheat
[bulk of code...]
# make call into compsys to provide completion!
_describe 'values' comp_cands_arr
通过以下方式使用 zsh 脚本~/.zshrc
:
fpath=(~/system/dev_resources/zsh_comp $fpath)
autoload -U ~/system/dev_resources/zsh_comp/*(:t)
完成脚本工作正常 - 没有问题。
现在我只想通过zstyle
内置引用和配置这个完成脚本。
这完成系统配置zsh 中的部分康普系统文档告诉我们:
当在命令行上的某个位置尝试完成时,完成系统开始构建上下文 [...]
字段始终按顺序排列
。
:完成:函数:完成者:命令:参数:标签
和
[completer] 当前活动的完成符,不带前导下划线且其他下划线转换为连字符的函数名称。 “完成者”全面控制完成的执行方式;
我的问题是,我的 zsh 完成脚本是否_cheat
被视为上下文字符串中的“完成者”?即这是否正确/适用?
:completion:function:cheat:command:argument:tag
^^^^^
它似乎适用,但同时该_cheat
脚本并不是正式定义为 shell 函数,它只是一个松散的命令集合......
答案1
你的_cheat
文件做定义一个名为 的函数_cheat
。您可以通过显示函数的代码 ( echo $functions[_cheat]
) 来验证这一点。当一个函数是自动加载从文件中,该文件包含函数的代码,就好像在_cheat () {
文件内容之前和}
文件内容之后一样。 (Zsh 还支持“ksh 式”自动加载,其中文件必须包含函数定义以及对函数本身的调用。)
神奇的第一行#compdef
当完成系统初始化时在文件中找到$fpath
相当于调用compdef _cheat cheat
其中_cheat
是文件的名称(和自动加载函数)并且cheat
是该函数要使用的命令的名称。该关联被记录在_comps
关联数组( $_comps[cheat]=_cheat
)中。
该completer
领域在zstyle
上下文字符串是删除了前导下划线的完成函数的名称。
答案2
在回答问题时
我的 zsh 完成脚本 _cheat 是否被视为上下文字符串中的“完成者”?
答案似乎是不
如果您使用ESC2, CTRL+ x,h来转储 zsh 的完成上下文
% cheat b
tags in context :completion::complete:cheat::
values (_describe _cheat)
您可以看到 zsh 认为第三个/完成者位置属于完成者“完成”,并且cheat
被分配了第四个或command
位置。
重要的是,这是命令cheat
(实际的可执行程序)而不是完成函数_cheat
,完成函数_cheat
是 zsh 内置函数定义的值zstyle
。