From fd45bc8caba2b7f40bdb64aec4c997cc9849fff6 Mon Sep 17 00:00:00 2001 From: phanium <91544758+phanen@users.noreply.github.com> Date: Wed, 28 Jan 2026 06:59:36 +0800 Subject: [PATCH] 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(). --- runtime/lua/vim/lsp.lua | 2 +- test/functional/plugin/lsp_spec.lua | 34 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index a464ed47df..db17f992ba 100644 --- 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 index 02a843bac8..829e756588 100644 --- 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)