diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index dc09cdde5c..4967aefd6d 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -426,16 +426,21 @@ local function validate_config(config) end --- @param bufnr integer ---- @param name string --- @param config vim.lsp.Config -local function can_start(bufnr, name, config) - local config_ok, err = pcall(validate_config, config) - if not config_ok then - log.error(('cannot start %s due to config error: %s'):format(name, err)) +--- @param logging boolean +local function can_start(bufnr, config, logging) + if + type(config.filetypes) == 'table' + and not vim.tbl_contains(config.filetypes, vim.bo[bufnr].filetype) + then return false end - if config.filetypes and not vim.tbl_contains(config.filetypes, vim.bo[bufnr].filetype) then + local config_ok, err = pcall(validate_config, config) + if not config_ok then + if logging then + log.error(('invalid "%s" config: %s'):format(config.name, err)) + end return false end @@ -462,9 +467,7 @@ local function lsp_enable_callback(bufnr) -- Stop any clients that no longer apply to this buffer. local clients = lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) for _, client in ipairs(clients) do - if - lsp.is_enabled(client.name) and not can_start(bufnr, client.name, lsp.config[client.name]) - then + if lsp.is_enabled(client.name) and not can_start(bufnr, lsp.config[client.name], false) then lsp.buf_detach_client(bufnr, client.id) end end @@ -472,7 +475,7 @@ local function lsp_enable_callback(bufnr) -- Start any clients that apply to this buffer. for name in vim.spairs(lsp._enabled_configs) do local config = lsp.config[name] - if config and can_start(bufnr, name, config) then + if config and can_start(bufnr, config, true) then -- Deepcopy config so changes done in the client -- do not propagate back to the enabled configs. config = vim.deepcopy(config) diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index cccbbbbda5..993308c033 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -3,7 +3,6 @@ local n = require('test.functional.testnvim')() local t_lsp = require('test.functional.plugin.lsp.testutil') -local assert_log = t.assert_log local buf_lines = n.buf_lines local command = n.command local dedent = t.dedent @@ -278,7 +277,7 @@ describe('LSP', function() on_exit = function(code, signal) eq(101, code, 'exit code') -- See fake-lsp-server.lua eq(0, signal, 'exit signal') - assert_log( + t.assert_log( pesc([[assert_eq failed: left == "\"shutdown\"", right == "\"test\""]]), fake_lsp_logfile ) @@ -6799,6 +6798,7 @@ describe('LSP', function() it('validates config on attach', function() local tmp1 = t.tmpname(true) exec_lua(function() + vim.fn.writefile({ '' }, fake_lsp_logfile) vim.lsp.log._set_filename(fake_lsp_logfile) end) @@ -6808,22 +6808,32 @@ describe('LSP', function() vim.lsp.config('foo', cfg) vim.lsp.enable('foo') vim.cmd.edit(assert(tmp1)) + vim.bo.filetype = 'non.applicable.filetype' + end) + + -- Assert NO log for non-applicable 'filetype'. #35737 + if type(cfg.filetypes) == 'table' then + t.assert_nolog(err, fake_lsp_logfile) + end + + exec_lua(function() vim.bo.filetype = 'foo' end) retry(nil, 1000, function() - assert_log(err, fake_lsp_logfile) + t.assert_log(err, fake_lsp_logfile) end) end test_cfg({ + filetypes = { 'foo' }, cmd = { 'lolling' }, - }, 'cannot start foo due to config error: .* lolling is not executable') + }, 'invalid "foo" config: .* lolling is not executable') test_cfg({ cmd = { 'cat' }, filetypes = true, - }, 'cannot start foo due to config error: .* filetypes: expected table, got boolean') + }, 'invalid "foo" config: .* filetypes: expected table, got boolean') end) it('does not start without workspace if workspace_required=true', function()