mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
fix(lsp): better handling of "*" configs
Problem: If a config name contains "*" it causes rtp discovery of `lsp/` to consider the `*` as a wildcard and could lead to strange and unintended behaviour. For example, accessing the `'*'` config from a `lsp/` file would cause an infinite loop. Solution: - Explicitly disallow a config name from containing wildcards, with the exception of `'*'`. - When Resolving `'*'` config, skip the rtp step.
This commit is contained in:
committed by
Lewis Russell
parent
04901f4ee7
commit
2ee896201c
@ -377,6 +377,19 @@ local function invalidate_enabled_config(name)
|
||||
end
|
||||
end
|
||||
|
||||
--- @param name any
|
||||
local function validate_config_name(name)
|
||||
validate('name', name, function(value)
|
||||
if type(value) ~= 'string' then
|
||||
return false
|
||||
end
|
||||
if value ~= '*' and value:match('%*') then
|
||||
return false, 'LSP config name cannot contain wildcard ("*")'
|
||||
end
|
||||
return true
|
||||
end, 'non-wildcard string')
|
||||
end
|
||||
|
||||
--- @nodoc
|
||||
--- @class vim.lsp.config
|
||||
--- @field [string] vim.lsp.Config
|
||||
@ -386,11 +399,16 @@ lsp.config = setmetatable({ _configs = {} }, {
|
||||
--- @param name string
|
||||
--- @return vim.lsp.Config
|
||||
__index = function(self, name)
|
||||
validate('name', name, 'string')
|
||||
validate_config_name(name)
|
||||
|
||||
local rconfig = lsp._enabled_configs[name] or {}
|
||||
|
||||
if not rconfig.resolved_config then
|
||||
if name == '*' then
|
||||
rconfig.resolved_config = lsp.config._configs['*'] or {}
|
||||
return rconfig.resolved_config
|
||||
end
|
||||
|
||||
-- Resolve configs from lsp/*.lua
|
||||
-- Calls to vim.lsp.config in lsp/* have a lower precedence than calls from other sites.
|
||||
local rtp_config --- @type vim.lsp.Config?
|
||||
@ -400,12 +418,12 @@ lsp.config = setmetatable({ _configs = {} }, {
|
||||
--- @type vim.lsp.Config?
|
||||
rtp_config = vim.tbl_deep_extend('force', rtp_config or {}, config)
|
||||
else
|
||||
log.warn(string.format('%s does not return a table, ignoring', v))
|
||||
log.warn(('%s does not return a table, ignoring'):format(v))
|
||||
end
|
||||
end
|
||||
|
||||
if not rtp_config and not self._configs[name] then
|
||||
log.warn(string.format('%s does not have a configuration', name))
|
||||
log.warn(('%s does not have a configuration'):format(name))
|
||||
return
|
||||
end
|
||||
|
||||
@ -425,7 +443,7 @@ lsp.config = setmetatable({ _configs = {} }, {
|
||||
--- @param name string
|
||||
--- @param cfg vim.lsp.Config
|
||||
__newindex = function(self, name, cfg)
|
||||
validate('name', name, 'string')
|
||||
validate_config_name(name)
|
||||
validate('cfg', cfg, 'table')
|
||||
invalidate_enabled_config(name)
|
||||
self._configs[name] = cfg
|
||||
@ -435,7 +453,7 @@ lsp.config = setmetatable({ _configs = {} }, {
|
||||
--- @param name string
|
||||
--- @param cfg vim.lsp.Config
|
||||
__call = function(self, name, cfg)
|
||||
validate('name', name, 'string')
|
||||
validate_config_name(name)
|
||||
validate('cfg', cfg, 'table')
|
||||
invalidate_enabled_config(name)
|
||||
self[name] = vim.tbl_deep_extend('force', self._configs[name] or {}, cfg)
|
||||
|
@ -6449,5 +6449,36 @@ describe('LSP', function()
|
||||
end)
|
||||
)
|
||||
end)
|
||||
|
||||
it('does not allow wildcards in config name', function()
|
||||
local err =
|
||||
'.../lsp.lua:0: name: expected non%-wildcard string, got foo%*%. Info: LSP config name cannot contain wildcard %("%*"%)'
|
||||
|
||||
matches(
|
||||
err,
|
||||
pcall_err(exec_lua, function()
|
||||
local _ = vim.lsp.config['foo*']
|
||||
end)
|
||||
)
|
||||
|
||||
matches(
|
||||
err,
|
||||
pcall_err(exec_lua, function()
|
||||
vim.lsp.config['foo*'] = {}
|
||||
end)
|
||||
)
|
||||
|
||||
matches(
|
||||
err,
|
||||
pcall_err(exec_lua, function()
|
||||
vim.lsp.config('foo*', {})
|
||||
end)
|
||||
)
|
||||
|
||||
-- Exception for '*'
|
||||
pcall(exec_lua, function()
|
||||
vim.lsp.config('*', {})
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
Reference in New Issue
Block a user