使用下面的代码,一切都按预期进行:
当我书写
c
并按下TAB
按键时,我会按正确的顺序获得适当的完成。当我书写
./
并按下TAB
按键时,我得到了标签的完成executables
。
# Always use menu selection when using unambiguous completions.
zstyle ':completion:*:*:*:*:*' menu 'select'
# Show only completions.
zstyle ':completion:*:*:*:*:*' completer _complete
# Group name becomes the name of the matching tag.
zstyle ':completion:*:*:*:*:*' group-name ''
# Configure the order of tag matching as well as their descriptions.
zstyle -e ':completion:*:*:-command-:*:*' tag-order '
reply=(
"executables:Executables:Executables
builtins:Builtins:Builtins
commands:Commands:Commands
aliases:Aliases:Aliases
functions:Functions:Functions
parameters:Variables:Variables
reserved-words:Keywords:Keywords"
)
'
# Configure the order in which completion groups will be shown.
zstyle ':completion:*:*:-command-:*:*' group-order 'Executables' 'Builtins' 'Commands' 'Aliases' 'Functions' 'Variables' 'Keywords'
# Configure the format for each group/tag description.
zstyle ':completion:*:*:*:*:descriptions' format $'%{\e[0;38;2;0;0;0;48;2;200;150;0m%} %d %{\e[0;38;2;200;150;0;48;2;0;0;0m%}%{\e[0m%}'
# Initialize completion system.
autoload -Uz compinit && compinit
但是,如果我指定的标签没有产生任何完成,那么也会尝试其他标签。
functions
证明这一点的最简单方法是从样式中排除标签tag-order
:
zstyle -e ':completion:*:*:-command-:*:*' tag-order '
reply=(
"executables:Executables:Executables
builtins:Builtins:Builtins
commands:Commands:Commands
aliases:Aliases:Aliases
parameters:Variables:Variables
reserved-words:Keywords:Keywords"
)
'
然后创建两个具有唯一前缀的函数:
function unique_prefix_A() { }
function unique_prefix_B() { }
现在,当我输入unique_prefix_
并按下TAB
按键时,我并不期望看到任何内容,因为标签functions
已从 中删除tag-order
。
但是,由于Executables
、Builtins
、Commands
、Aliases
和没有提供任何补全,因此默认情况下将尝试匹配其他标签(即排除的标签),以尝试提供任何补全。 Variables
Keywords
zsh
functions
因此,将建议 以下功能unique_prefix_A
和:unique_prefix_B
我不喜欢这种行为并且想要将搜索限制在明确指定的标签内。
手册标签顺序风格表明了一个简单的解决方案:
- 如果任何值仅由连字符组成,则仅生成其他值中指定的标签。通常,如果指定的标签无法生成任何匹配项,则最后尝试所有未明确选择的标签。这意味着仅由单个连字符组成的单个值会关闭完成。
应用解决方案:
# Configure the order of tag matching as well as their descriptions.
zstyle -e ':completion:*:*:-command-:*:*' tag-order '
reply=(
"executables:Executables:Executables
builtins:Builtins:Builtins
commands:Commands:Commands
aliases:Aliases:Aliases
functions:Functions:Functions
parameters:Variables:Variables
reserved-words:Keywords:Keywords"
"-"
)
'
当前行为是:
当我书写
c
并按下TAB
按键时,我会按正确的顺序获得适当的完成。)
当我书写
./
并按下TAB
按键时,我什么也没得到。
为什么现在只有executables
标签不起作用?
我该如何修复它并获得所需的行为?
答案1
在这种情况下,标签会调用。然后调用executable
更多,因此有必要指定这些_files -g '*(-*)
_files
_tags
完成函数中隐式指定的标签, 也。
zstyle -e ':completion:*:*:-command-:*:*' tag-order '
reply=(
"executables:Executables:Executables
builtins:Builtins:Builtins
commands:Commands:Commands
aliases:Aliases:Aliases
functions:Functions:Functions
parameters:Variables:Variables
reserved-words:Keywords:Keywords
globbed-files directories"
"-"
)
'
在这种情况下,添加globbed-files
以下内容会很有用:directories
% ls -al
total 80
drwxr-xr-x 3 t t 4096 May 18 08:27 .
drwxrwxrwt 16 root root 69632 May 18 15:27 ..
drwxr-xr-x 2 t t 4096 May 18 08:27 directory
-rwxr-xr-x 1 t t 0 May 18 08:27 executable-file
-rw-r--r-- 1 t t 0 May 18 08:27 test
% ./<TAB>
Executables
directory/ executable-file*
但在上述设置中,目录和本地可执行文件将进入同一个“可执行”组。如果我们想让“目录”进入其他组,我们可以指定file-patterns
直接使用它像这样:
zstyle ':completion:*:*:-command-:*:*' file-patterns \
'*(#q-*):executables:Executables *(-/):directories:Directories'
zstyle -e ':completion:*:*:-command-:*:*' tag-order '
reply=(
"executables:Executables:Executables
builtins:Builtins:Builtins
commands:Commands:Commands
aliases:Aliases:Aliases
functions:Functions:Functions
parameters:Variables:Variables
reserved-words:Keywords:Keywords
directories:Directories"
-
)
'
在下面的例子中,“目录”和“可执行文件”位于分开的组中:
% ls -al
total 80
drwxr-xr-x 3 t t 4096 May 18 08:27 .
drwxrwxrwt 15 root root 69632 May 18 15:24 ..
drwxr-xr-x 2 t t 4096 May 18 08:27 directory
-rwxr-xr-x 1 t t 0 May 18 08:27 executable-file
-rw-r--r-- 1 t t 0 May 18 08:27 test
% ./<TAB>
Executables
executable-file*
Directories
directory/
以下是最终的最小 .zshrc 示例:
autoload -Uz compinit && compinit
zstyle ':completion:*:*:*:*:*' group-name ''
zstyle ':completion:*:descriptions' format '%B%F{black}%d%f%b'
zstyle ':completion:*:*:*:*:*' menu 'select'
# This comment out block is just for a reminder of my answer's first half.
# zstyle -e ':completion:*:*:-command-:*:*' tag-order '
# reply=(
# "executables:Executables:Executables
# builtins:Builtins:Builtins
# commands:Commands:Commands
# aliases:Aliases:Aliases
# functions:Functions:Functions
# parameters:Variables:Variables
# reserved-words:Keywords:Keywords
# globbed-files directories"
# "-"
# )
# '
zstyle ':completion:*:*:-command-:*:*' file-patterns \
'*(#q-*):executables:Executables *(-/):directories:Directories'
zstyle -e ':completion:*:*:-command-:*:*' tag-order '
reply=(
"executables:Executables:Executables
builtins:Builtins:Builtins
commands:Commands:Commands
aliases:Aliases:Aliases
functions:Functions:Functions
parameters:Variables:Variables
reserved-words:Keywords:Keywords
directories:Directories"
-
)
'
更新:注释掉不必要的块。
答案2
我认为问题不仅在于(连字符),还在于您对自动完成规则的了解程度。
我进行了一些测试,例如删除“变量”从订单标签并在 shell 中创建(TEST、LOLO)。
此后,我尝试了自动完成功能,希望看不到任何内容,但它们却在“变量”中列出并显示为“参数”。
这种行为让我思考 UDEV 以及某些系统如何针对某些行为要求非常具体的规则。
您的标签匹配组正常且按预期工作(在 ./ 场景中),但有一件事需要执行:
./<TAB>
而完全不同的事情是自动完成如下内容:
unique_prefix<TAB>
因此,无论您在这些组中添加多少连字符,它都不会起作用,因为它是不同的规则执行。
我没有处理这个问题,而是搜索了一个例子来避免特定的功能,这个代码片段工作得很好(检查来源):
这些功能的一个用途是多次尝试一个标签,每次尝试时设置不同的其他样式,但仍使用所有其他标签而不必重复所有标签。例如,要使命令位置中的函数名称补全在第一次尝试补全时忽略所有以下划线开头的补全函数:
(我已将其更改为匹配所有功能):
ignored-patterns ’_*’
为了这:
ignored-patterns ’*’
在本规则中:
zstyle ’:completion:*:*:-command-:*:*’ tag-order \
’functions:-non-comp *’ functions
zstyle ’:completion:*:functions-non-comp’ \
ignored-patterns ’*’
当我尝试自动完成时:unique_prefix(什么都没有发生)并且./执行效果良好。
因此,答案是:您需要针对每种不同的情况制定特定的规则,记住任何模式都可以根据您定义的规则进行不同的解释。