在 zsh 中的 $PATH 缓存中重建自动完成索引(或任何名称)和二进制文件

phu*_*ehe 91 zsh autocomplete

安装新软件后,使用 zsh 已打开的终端将不知道新命令,也无法为这些命令生成自动完成。显然打开一个新终端可以解决这个问题,但是可以重建索引(或任何你称之为的东西)以便自动完成可以在旧终端上工作吗?

我试过了,compinit但这没有帮助。另外,有没有一种不依赖于shell的方法?很高兴有一种方法来验证答案(除了卸载并重新安装它)。

我的意思是在输入命令名称的几个字符后,我可以按Tab,然后zsh应该做剩下的工作来调出全名。

Gil*_*il' 88

要重建可执行命令的缓存,请使用rehashhash -rf

确保您没有取消设置该hash_list_all选项(它会导致更少的磁盘访问,但会降低缓存更新的频率)。

如果您不想输入命令,您可以通过将以下行放入~/.zshrc¹来告诉 zsh 在完成时不要信任其缓存:

zstyle ":completion:*:commands" rehash 1
Run Code Online (Sandbox Code Playgroud)

有性能成本,但在今天的典型桌面设置中可以忽略不计。(如果您使用的$PATH是 NFS 或 RAM 不足的系统,则不会。)

zstyle命令本身是在记录zshmodule手册页。样式值记录在zshcompsyszshcompwid手册页中,或者您可以阅读源代码(此处为_command_names函数的源代码)。如果你想要一些可读的文档……如果你找到了一些,请告诉我!

¹需要 zsh?4.3.3,谢谢Chris Johnsen

  • 任何一个 rehash 咒语都应该在之前完全散列的 shell 中启用“新命令”的命令名称完成。设置PATH(或路径)也会引起rehash;因此`PATH="$PATH"` 也可以完成这项工作。`HASH_LIST_ALL` 在我的文档中显示为默认值。 (3认同)

Chr*_*sen 16

如果您在获取新命令的“参数补全”时遇到问题,那么compinit可能是您需要的命令,但是它有一个缓存机制可能会导致您的问题。

我的版本 (4.3.10) 的文档说compinit使用缓存的“转储文件”.zcompdump来存储已编译的完成函数以加速后续调用。它仅在注意到完成文件(fpath#compdef …或开头的元素文件#autoload …)数量发生变化时才使转储文件无效。大概安装新软件会改变此类完成文件的数量(假设它还在正确的位置安装了zsh自动完成文件),所以我希望一个普通compinit的工作。如果您遇到它不起作用的情况,您可能需要绕过或手动使转储文件无效。

要跳过使用转储文件,请使用compinit -D; 这只会影响当前的外壳。

要重建转储文件,请将其删除并重新运行compinit

rm -i ${ZDOTDIR:-${HOME:?No ZDOTDIR or HOME}}/.zcompdump &&
compinit
Run Code Online (Sandbox Code Playgroud)

这将影响当前的 shell、运行 plain 的现有 shellcompinit以及任何未来的 shell。


小智 9

我发现,在处理/开发存在于文件中的完成时,#compdef _foo foo我需要在每次编辑时使用:

unfunction _foo && compinit
Run Code Online (Sandbox Code Playgroud)

以查看更新后的foo命令完成更新后的更改。