Neovim 0.7.0启动时nvim-cmp失效 手动重载配置后恢复正常
这个故障本质是配置执行时机不匹配,和cmp配置写法本身无关——启动流程中执行cmp配置时,插件依赖未完成初始化,配置未被实际挂载;手动执行:luafile %时Neovim已完成全量启动,所有插件已载入运行时路径,配置自然生效。
排查点1:包管理器加载时序问题
如果使用Packer作为插件管理器,常规写法中require "user.plugins"仅调用packer.startup()注册插件清单,不会在require执行阶段立刻将插件注入Neovim runtimepath,而是等VimEnter事件触发后才完成插件路径加载。
此时紧接其后执行require "user.cmp"会出现两类异常:
pcall(require, "cmp")执行时cmp尚未加入runtimepath,直接命中return分支,整个cmp配置文件直接退出,完全没有执行配置逻辑- 即使cmp模块被找到,关联补全源(cmp-nvim-lsp、cmp-buffer、cmp-path等)尚未完成注册,
cmp.setup()中配置的触发规则、补全源列表不会被识别,补全功能无法触发
修复方式
调整cmp配置的加载时机,等VimEnter事件触发、所有插件完成加载后再执行cmp配置:
将init.lua中原有的require "user.cmp"替换为以下代码:
vim.api.nvim_create_autocmd("VimEnter", { callback = function() require "user.cmp" end, once = true, })
如果使用Lazy.nvim作为包管理器,直接将cmp配置写入插件spec的config字段即可,不要在外部单独require cmp配置文件,避免加载时机提前。
排查点2:后续配置覆盖cmp设置
检查user.lsp、user.autopairs两个在cmp之后加载的文件,是否存在重复调用cmp.setup()、重置cmp全局配置的代码:
- 旧版本nvim-autopairs的cmp集成代码存在直接调用
cmp.setup({})的写法,如果没有合并原有配置,会直接清空之前写入的补全映射、源规则 - 部分LSP配置片段会调用
cmp.setup.buffer({enabled = false})做缓冲区级配置,若执行时机异常会被应用到全局,导致补全全局失效
验证方式
在cmp.lua末尾添加一行日志:
print("[debug] cmp config loaded", vim.fn.localtime())
在user.lsp、user.autopairs的末尾各添加一行日志:
print("[debug] after module load, cmp global enabled:", require("cmp").get_config().enabled)
启动Neovim后查看消息区输出,如果cmp配置加载完成后,cmp全局enabled状态变为false,即可确认是后续模块覆盖了配置,删除对应重置逻辑,改用cmp.setup.filetype()或配置合并的方式编写集成代码即可。
快速定位技巧
启动Neovim后直接执行命令:lua print(package.loaded.cmp == nil),如果返回true,即可直接确认是加载时机问题——启动阶段cmp模块根本未被加载,你的cmp配置文件直接走了提前return的分支,没有执行任何配置逻辑,直到手动重载配置时cmp已经完成加载,配置才正常生效。
内容的提问来源于stack exchange,提问作者Mike

