commit fd45bc8caba2b7f40bdb64aec4c997cc9849fff6
parent 6291256868f033cae7c3ef2b30406a2c17090046
Author: phanium <91544758+phanen@users.noreply.github.com>
Date: Wed, 28 Jan 2026 06:59:36 +0800
fix: lsp.enable() don't work correctly inside FileType event #37538
Problem:
Two cases lsp.enable() won't work in the first FileType event
1. lsp.enable luals inside FileType or ftplugin/lua.lua, then:
```
nvim a.lua
```
2. lsp.enable luals inside FileType or ftplugin/lua.lua, then:
```
nvim -> :edit a.lua -> :mksession! | restart +qa! so Session.vim
```
Solution:
Currently `v:vim_did_enter` is used to detected two cases:
1. "maunally enabled" (lsp.enable() or `:lsp enable`)
2. "inside FileType event"
To detect 2. correctly we use did_filetype().
Diffstat:
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
@@ -590,7 +590,7 @@ function lsp.enable(name, enable)
-- Ensure any pre-existing buffers start/stop their LSP clients.
if enable ~= false then
- if vim.v.vim_did_enter == 1 and next(lsp._enabled_configs) then
+ if (vim.v.vim_did_enter == 1 or vim.fn.did_filetype() == 1) and next(lsp._enabled_configs) then
vim.cmd.doautoall('nvim.lsp.enable FileType')
end
else
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
@@ -6874,6 +6874,40 @@ describe('LSP', function()
)
end)
+ it('in first FileType event (on startup)', function()
+ local tmp = tmpname()
+ write_file(tmp, string.dump(create_server_definition))
+ n.clear({
+ args = {
+ '--cmd',
+ string.format([[lua assert(loadfile(%q))()]], tmp),
+ '--cmd',
+ [[lua _G.server = _G._create_server({ handlers = {initialize = function(_, _, callback) callback(nil, {capabilities = {}}) end} })]],
+ '--cmd',
+ [[lua vim.lsp.config('foo', { cmd = _G.server.cmd, filetypes = { 'foo' }, root_markers = { '.foorc' } })]],
+ '--cmd',
+ [[au FileType * ++once lua vim.lsp.enable('foo')]],
+ '-c',
+ 'set ft=foo',
+ },
+ })
+
+ eq(
+ { 1, 'foo' },
+ exec_lua(function()
+ local foos = vim.lsp.get_clients({ bufnr = 0 })
+ return { #foos, (foos[1] or {}).name }
+ end)
+ )
+ exec_lua([[vim.lsp.enable('foo', false)]])
+ eq(
+ 0,
+ exec_lua(function()
+ return #vim.lsp.get_clients({ bufnr = 0 })
+ end)
+ )
+ end)
+
it('does not attach to buffers more than once if no root_dir', function()
exec_lua(create_server_definition)