如果我有一个可执行文件 - 例如~/bin/stuff
在 my 中PATH
,我可以在 my 中定义它.zshrc
,使其首先自动完成文本文件作为我的命令的参数:
zstyle ':completion:*:*:stuff:*' file-patterns '*.txt:all-files' '*:all-files'
但是,如果stuff
是别名(例如)alias stuff=less
,那么它就不再起作用了,并且 zsh 只是假装它应该自动完成所有文件,因为这是默认设置。
我看过这里的文档 -Zsh补全系统除了谈论如何扩展别名之外,没有发现任何其他内容 - 这不是我想要的。
我思考这是因为文档说参数模式zstyle
是':completion:*:*:-command-:*:commands'
的参数模式,但这是否意味着第四部分必须是命令而不是一个别名。我一直认为它们在 zsh 中或多或少是可以互换的。
我的意思是我可以创建一堆单行可执行文件,其中只有我的别名,后跟"$@"
- 但事实并非如此优雅的。
答案1
stuff
假设在这两种情况下标签都被捣碎了
% ls
bar foo.txt
% whence stuff
% alias stuff=less
% zstyle ':completion:*:*:stuff:*' file-patterns '*.txt:all-files'
% stuff
bar foo.txt
相关旋钮zshoptions(1)
是
COMPLETE_ALIASES
Prevents aliases on the command line from being internally sub-
stituted before completion is attempted. The effect is to make
the alias a distinct command for completion purposes.
所以
% setopt COMPLETE_ALIASES
% stuff foo.txt
否则别名已经是别的东西了。
为了检查副作用,我们应该确认此更改不会破坏没有完成或样式配置的别名的完成,
% setopt COMPLETE_ALIASES
% whence foo
% unfunction _foo
unfunction: no such hash table element: _foo
% alias foo=ls
% foo (eval):1: command not found: _foo
因此,使用COMPLETE_ALIASES
set 时,您可能需要为每个别名设置完成,或者列出或以其他方式在适当的位置包含别名,compdef
例如
% compdef _ls foo
% foo
...
另一方面,我确实发现exec
包装器非常优雅,因为与 shell 别名不同,它们可以通过exec(3)
或system(3)
不需要加载相当大的 shell 来调用,也可以通过交互式 shell 配置污染本应是简单的系统调用。