在 zsh 中,我试图了解哪些命令具有现有的完成功能,以便我可以为没有的命令编写完成功能。
有没有办法列出 zsh 将完成的命令而不需要 grep 完成文件?例如,是否有一个内置命令可以列出它们?
已知完成的列表存储在关联数组
_comps
中。命令名称和其他完成上下文用作 _comps
的键,而相应的完成功能则存储为值。
您可以使用以下命令获取具有关联完成的命令的完整列表:
for command completion in ${(kv)_comps:#-*(-|-,*)}
do
printf "%-32s %s\n" $command $completion
done | sort
for command completion in LIST; COMMAND
会迭代 LIST
,同时在每次迭代中获取两个元素 command
和 completion
,并为它们运行 COMMAND
。这也是 for
循环的缩写形式,不需要 do
和 done
。${(kv)ASSOC_ARRAY}
将关联数组 ASSOC_ARRAY
扩展为空格分隔的键值对列表。所以它是一个“key1 value1 key2 value2 key3 value3 …”的交替列表,由 for
循环的两个参数占用。 $ASSOC_ARRAY
只会扩展为值列表。${ASSOC_ARRAY:#PATTERN}
从其扩展中过滤掉 ASSOC_ARRAY
的所有元素,其中键与 PATTERN
匹配。-*(-|-,*)
匹配所有特殊上下文的名称,例如 -math-
、-parameter-
或 -value-,NAME,COMMAND
。它还会过滤任何与 -*-
或 -*-,*
匹配的命令名称(如果此类命令在您的系统上有完成功能)。 (为了确定,你可以省略模式过滤器)printf "%-32s %s\n" $command $completion
进行格式化输出,以便您获得一个漂亮的表格。 $command
打印代替 %-32s
,并左对齐 (-
) 填充至 32 个字符。打印 $completion
代替 %s
。| sort
:关联数组是无序的,因此循环的输出需要经过sort
才能得到有序列表。我发现 @adaephon 提供的代码未对齐,并且此代码效果更好。
for command in ${(k)_comps}; do
completions=${_comps[$command]}
printf "%-32s %s\n" $command $completions
done