Skip to content

Commit 4910aeb

Browse files
justinmkdundargoc
authored andcommitted
fix(lsp): misleading logs in non-applicable filetypes neovim#35749
Problem: LSP logs show misleading "cannot start" messages when editing a filetype NOT listed in the `config.filetypes` field. [ERROR][2025-09-13 18:55:56] …/runtime//lua/vim/lsp/log.lua:151 "cannot start cssls due to config error: …/runtime//lua/vim/lsp.lua:423: cmd: expected expected function or table with executable command, got table: 0x0104701b18. Info: vscode-css-language-server is not executable" Solution: - `can_start`: check `config.filetypes` before checking the rest of the config.
1 parent 9304f48 commit 4910aeb

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

runtime/lua/vim/lsp.lua

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -426,16 +426,21 @@ local function validate_config(config)
426426
end
427427

428428
--- @param bufnr integer
429-
--- @param name string
430429
--- @param config vim.lsp.Config
431-
local function can_start(bufnr, name, config)
432-
local config_ok, err = pcall(validate_config, config)
433-
if not config_ok then
434-
log.error(('cannot start %s due to config error: %s'):format(name, err))
430+
--- @param logging boolean
431+
local function can_start(bufnr, config, logging)
432+
if
433+
type(config.filetypes) == 'table'
434+
and not vim.tbl_contains(config.filetypes, vim.bo[bufnr].filetype)
435+
then
435436
return false
436437
end
437438

438-
if config.filetypes and not vim.tbl_contains(config.filetypes, vim.bo[bufnr].filetype) then
439+
local config_ok, err = pcall(validate_config, config)
440+
if not config_ok then
441+
if logging then
442+
log.error(('invalid "%s" config: %s'):format(config.name, err))
443+
end
439444
return false
440445
end
441446

@@ -462,17 +467,15 @@ local function lsp_enable_callback(bufnr)
462467
-- Stop any clients that no longer apply to this buffer.
463468
local clients = lsp.get_clients({ bufnr = bufnr, _uninitialized = true })
464469
for _, client in ipairs(clients) do
465-
if
466-
lsp.is_enabled(client.name) and not can_start(bufnr, client.name, lsp.config[client.name])
467-
then
470+
if lsp.is_enabled(client.name) and not can_start(bufnr, lsp.config[client.name], false) then
468471
lsp.buf_detach_client(bufnr, client.id)
469472
end
470473
end
471474

472475
-- Start any clients that apply to this buffer.
473476
for name in vim.spairs(lsp._enabled_configs) do
474477
local config = lsp.config[name]
475-
if config and can_start(bufnr, name, config) then
478+
if config and can_start(bufnr, config, true) then
476479
-- Deepcopy config so changes done in the client
477480
-- do not propagate back to the enabled configs.
478481
config = vim.deepcopy(config)

test/functional/plugin/lsp_spec.lua

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ local n = require('test.functional.testnvim')()
33

44
local t_lsp = require('test.functional.plugin.lsp.testutil')
55

6-
local assert_log = t.assert_log
76
local buf_lines = n.buf_lines
87
local command = n.command
98
local dedent = t.dedent
@@ -278,7 +277,7 @@ describe('LSP', function()
278277
on_exit = function(code, signal)
279278
eq(101, code, 'exit code') -- See fake-lsp-server.lua
280279
eq(0, signal, 'exit signal')
281-
assert_log(
280+
t.assert_log(
282281
pesc([[assert_eq failed: left == "\"shutdown\"", right == "\"test\""]]),
283282
fake_lsp_logfile
284283
)
@@ -6799,6 +6798,7 @@ describe('LSP', function()
67996798
it('validates config on attach', function()
68006799
local tmp1 = t.tmpname(true)
68016800
exec_lua(function()
6801+
vim.fn.writefile({ '' }, fake_lsp_logfile)
68026802
vim.lsp.log._set_filename(fake_lsp_logfile)
68036803
end)
68046804

@@ -6808,22 +6808,32 @@ describe('LSP', function()
68086808
vim.lsp.config('foo', cfg)
68096809
vim.lsp.enable('foo')
68106810
vim.cmd.edit(assert(tmp1))
6811+
vim.bo.filetype = 'non.applicable.filetype'
6812+
end)
6813+
6814+
-- Assert NO log for non-applicable 'filetype'. #35737
6815+
if type(cfg.filetypes) == 'table' then
6816+
t.assert_nolog(err, fake_lsp_logfile)
6817+
end
6818+
6819+
exec_lua(function()
68116820
vim.bo.filetype = 'foo'
68126821
end)
68136822

68146823
retry(nil, 1000, function()
6815-
assert_log(err, fake_lsp_logfile)
6824+
t.assert_log(err, fake_lsp_logfile)
68166825
end)
68176826
end
68186827

68196828
test_cfg({
6829+
filetypes = { 'foo' },
68206830
cmd = { 'lolling' },
6821-
}, 'cannot start foo due to config error: .* lolling is not executable')
6831+
}, 'invalid "foo" config: .* lolling is not executable')
68226832

68236833
test_cfg({
68246834
cmd = { 'cat' },
68256835
filetypes = true,
6826-
}, 'cannot start foo due to config error: .* filetypes: expected table, got boolean')
6836+
}, 'invalid "foo" config: .* filetypes: expected table, got boolean')
68276837
end)
68286838

68296839
it('does not start without workspace if workspace_required=true', function()

0 commit comments

Comments
 (0)