mirror of
https://github.com/neovim/neovim.git
synced 2025-09-14 23:38:17 +00:00
fix(lsp): misleading logs in non-applicable filetypes #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.
This commit is contained in:
@@ -426,16 +426,21 @@ local function validate_config(config)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- @param bufnr integer
|
--- @param bufnr integer
|
||||||
--- @param name string
|
|
||||||
--- @param config vim.lsp.Config
|
--- @param config vim.lsp.Config
|
||||||
local function can_start(bufnr, name, config)
|
--- @param logging boolean
|
||||||
local config_ok, err = pcall(validate_config, config)
|
local function can_start(bufnr, config, logging)
|
||||||
if not config_ok then
|
if
|
||||||
log.error(('cannot start %s due to config error: %s'):format(name, err))
|
type(config.filetypes) == 'table'
|
||||||
|
and not vim.tbl_contains(config.filetypes, vim.bo[bufnr].filetype)
|
||||||
|
then
|
||||||
return false
|
return false
|
||||||
end
|
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
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -462,9 +467,7 @@ local function lsp_enable_callback(bufnr)
|
|||||||
-- Stop any clients that no longer apply to this buffer.
|
-- Stop any clients that no longer apply to this buffer.
|
||||||
local clients = lsp.get_clients({ bufnr = bufnr, _uninitialized = true })
|
local clients = lsp.get_clients({ bufnr = bufnr, _uninitialized = true })
|
||||||
for _, client in ipairs(clients) do
|
for _, client in ipairs(clients) do
|
||||||
if
|
if lsp.is_enabled(client.name) and not can_start(bufnr, lsp.config[client.name], false) then
|
||||||
lsp.is_enabled(client.name) and not can_start(bufnr, client.name, lsp.config[client.name])
|
|
||||||
then
|
|
||||||
lsp.buf_detach_client(bufnr, client.id)
|
lsp.buf_detach_client(bufnr, client.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -472,7 +475,7 @@ local function lsp_enable_callback(bufnr)
|
|||||||
-- Start any clients that apply to this buffer.
|
-- Start any clients that apply to this buffer.
|
||||||
for name in vim.spairs(lsp._enabled_configs) do
|
for name in vim.spairs(lsp._enabled_configs) do
|
||||||
local config = lsp.config[name]
|
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
|
-- Deepcopy config so changes done in the client
|
||||||
-- do not propagate back to the enabled configs.
|
-- do not propagate back to the enabled configs.
|
||||||
config = vim.deepcopy(config)
|
config = vim.deepcopy(config)
|
||||||
|
@@ -3,7 +3,6 @@ local n = require('test.functional.testnvim')()
|
|||||||
|
|
||||||
local t_lsp = require('test.functional.plugin.lsp.testutil')
|
local t_lsp = require('test.functional.plugin.lsp.testutil')
|
||||||
|
|
||||||
local assert_log = t.assert_log
|
|
||||||
local buf_lines = n.buf_lines
|
local buf_lines = n.buf_lines
|
||||||
local command = n.command
|
local command = n.command
|
||||||
local dedent = t.dedent
|
local dedent = t.dedent
|
||||||
@@ -278,7 +277,7 @@ describe('LSP', function()
|
|||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(101, code, 'exit code') -- See fake-lsp-server.lua
|
eq(101, code, 'exit code') -- See fake-lsp-server.lua
|
||||||
eq(0, signal, 'exit signal')
|
eq(0, signal, 'exit signal')
|
||||||
assert_log(
|
t.assert_log(
|
||||||
pesc([[assert_eq failed: left == "\"shutdown\"", right == "\"test\""]]),
|
pesc([[assert_eq failed: left == "\"shutdown\"", right == "\"test\""]]),
|
||||||
fake_lsp_logfile
|
fake_lsp_logfile
|
||||||
)
|
)
|
||||||
@@ -6799,6 +6798,7 @@ describe('LSP', function()
|
|||||||
it('validates config on attach', function()
|
it('validates config on attach', function()
|
||||||
local tmp1 = t.tmpname(true)
|
local tmp1 = t.tmpname(true)
|
||||||
exec_lua(function()
|
exec_lua(function()
|
||||||
|
vim.fn.writefile({ '' }, fake_lsp_logfile)
|
||||||
vim.lsp.log._set_filename(fake_lsp_logfile)
|
vim.lsp.log._set_filename(fake_lsp_logfile)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -6808,22 +6808,32 @@ describe('LSP', function()
|
|||||||
vim.lsp.config('foo', cfg)
|
vim.lsp.config('foo', cfg)
|
||||||
vim.lsp.enable('foo')
|
vim.lsp.enable('foo')
|
||||||
vim.cmd.edit(assert(tmp1))
|
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'
|
vim.bo.filetype = 'foo'
|
||||||
end)
|
end)
|
||||||
|
|
||||||
retry(nil, 1000, function()
|
retry(nil, 1000, function()
|
||||||
assert_log(err, fake_lsp_logfile)
|
t.assert_log(err, fake_lsp_logfile)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
test_cfg({
|
test_cfg({
|
||||||
|
filetypes = { 'foo' },
|
||||||
cmd = { 'lolling' },
|
cmd = { 'lolling' },
|
||||||
}, 'cannot start foo due to config error: .* lolling is not executable')
|
}, 'invalid "foo" config: .* lolling is not executable')
|
||||||
|
|
||||||
test_cfg({
|
test_cfg({
|
||||||
cmd = { 'cat' },
|
cmd = { 'cat' },
|
||||||
filetypes = true,
|
filetypes = true,
|
||||||
}, 'cannot start foo due to config error: .* filetypes: expected table, got boolean')
|
}, 'invalid "foo" config: .* filetypes: expected table, got boolean')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('does not start without workspace if workspace_required=true', function()
|
it('does not start without workspace if workspace_required=true', function()
|
||||||
|
Reference in New Issue
Block a user