如何修复纯 zsh 中 make target 补全失效?
结论
调整 zsh-autocomplete 和补全系统的加载顺序:保留 Homebrew 补全目录的 FPATH 设置,将它放在 zsh-autocomplete 之前,并删除手动调用的 compinit。该插件的安装说明要求从 .zshrc 中移除 compinit 调用;Homebrew 补全目录也要在补全系统初始化前加入搜索路径。zsh-autocomplete 安装说明 Homebrew zsh-completions 说明
配置可以写成:
if type brew &>/dev/null; then
FPATH="$(brew --prefix)/share/zsh-completions:$FPATH"
fi
source /opt/homebrew/share/zsh-autocomplete/zsh-autocomplete.plugin.zsh
source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh
source /opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
重新打开终端,或运行 exec zsh,然后进入包含 Makefile、makefile 或 GNUmakefile 的目录,测试 make <TAB>。
为什么只看到目录
你的配置先运行了 compinit,之后才加载 zsh-autocomplete。这不符合插件文档给出的配置方式:插件负责配置 zsh completion,因此文档要求删除手动的 compinit 调用。Homebrew 的 zsh-completions 路径也应在插件初始化前加入 FPATH,让补全系统初始化时能找到其中的函数。
MAKEFILE 和 MAKEFILE_LIST 通常是 Makefile 中使用的变量,不是 zsh 判断当前目录是否存在 Makefile 的标记。因此,这个判断无法可靠地决定是否加载插件。可以直接加载插件,或使用明确的 shell 配置条件。
检查补全函数和 Makefile
如果调整后仍然只出现目录,可以在 zsh 中检查 _make 是否存在:
whence -v _make
然后确认当前目录中有 zsh 能识别的 Makefile 文件名。zsh 的 _make 补全函数会检查 GNUmakefile、makefile 和 Makefile,并从文件中解析 target。如果文件使用了其他名称,可以用 make -f 文件名 指定。_make 补全函数
如果找不到 _make,先确认 Homebrew 补全路径存在,并且已在加载 zsh-autocomplete 前加入 FPATH。如果 _make 存在但没有出现 target,再检查 Makefile 是否在当前目录、文件名是否符合上述规则,以及 target 是否由 Makefile 动态生成。动态 target 的处理方式取决于 Makefile 的写法,现有配置不足以判断具体情况。
注意
starship、zoxide 和 fzf 的初始化与 make target 补全解析属于不同配置。排查时,先确认 _make 和 Makefile 是否能被识别。zsh-autocomplete 文档还提示,其他插件可能覆盖快捷键或补全行为;如果调整加载顺序后仍有异常,可以暂时注释其他插件,逐项排查。
备注:内容仅供参考。
