mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
feat(lsp): return resolved config for vim.lsp.config[name]
Allows to retrieve the configuration as it will be used by `lsp.enable` - including the parts merged from `*` and rtp. This is useful for explicit startup control (`vim.lsp.start(vim.lsp.config[name])`) Closes https://github.com/neovim/neovim/issues/31640
This commit is contained in:

committed by
Mathias Fußenegger

parent
1877cd5fcd
commit
e00cd1ab40
@@ -420,9 +420,33 @@ lsp.config = setmetatable({ _configs = {} }, {
|
|||||||
--- @return vim.lsp.Config
|
--- @return vim.lsp.Config
|
||||||
__index = function(self, name)
|
__index = function(self, name)
|
||||||
validate('name', name, 'string')
|
validate('name', name, 'string')
|
||||||
invalidate_enabled_config(name)
|
|
||||||
|
local rconfig = lsp._enabled_configs[name] or {}
|
||||||
self._configs[name] = self._configs[name] or {}
|
self._configs[name] = self._configs[name] or {}
|
||||||
return self._configs[name]
|
|
||||||
|
if not rconfig.resolved_config then
|
||||||
|
-- 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
|
||||||
|
for _, v in ipairs(api.nvim_get_runtime_file(('lsp/%s.lua'):format(name), true)) do
|
||||||
|
local config = assert(loadfile(v))() ---@type any?
|
||||||
|
if type(config) == 'table' then
|
||||||
|
rtp_config = vim.tbl_deep_extend('force', rtp_config, config)
|
||||||
|
else
|
||||||
|
log.warn(string.format('%s does not return a table, ignoring', v))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
rconfig.resolved_config = vim.tbl_deep_extend(
|
||||||
|
'force',
|
||||||
|
lsp.config._configs['*'] or {},
|
||||||
|
rtp_config,
|
||||||
|
lsp.config._configs[name] or {}
|
||||||
|
)
|
||||||
|
rconfig.resolved_config.name = name
|
||||||
|
end
|
||||||
|
|
||||||
|
return rconfig.resolved_config
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--- @param self vim.lsp.config
|
--- @param self vim.lsp.config
|
||||||
@@ -446,44 +470,6 @@ lsp.config = setmetatable({ _configs = {} }, {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
--- @private
|
|
||||||
--- @param name string
|
|
||||||
--- @return vim.lsp.Config
|
|
||||||
function lsp._resolve_config(name)
|
|
||||||
local econfig = lsp._enabled_configs[name] or {}
|
|
||||||
|
|
||||||
if not econfig.resolved_config then
|
|
||||||
-- 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
|
|
||||||
for _, v in ipairs(api.nvim_get_runtime_file(('lsp/%s.lua'):format(name), true)) do
|
|
||||||
local config = assert(loadfile(v))() ---@type any?
|
|
||||||
if type(config) == 'table' then
|
|
||||||
rtp_config = vim.tbl_deep_extend('force', rtp_config, config)
|
|
||||||
else
|
|
||||||
log.warn(string.format('%s does not return a table, ignoring', v))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local config = vim.tbl_deep_extend(
|
|
||||||
'force',
|
|
||||||
lsp.config._configs['*'] or {},
|
|
||||||
rtp_config,
|
|
||||||
lsp.config._configs[name] or {}
|
|
||||||
)
|
|
||||||
|
|
||||||
config.name = name
|
|
||||||
|
|
||||||
validate('cmd', config.cmd, { 'function', 'table' })
|
|
||||||
validate('cmd', config.reuse_client, 'function', true)
|
|
||||||
-- All other fields are validated in client.create
|
|
||||||
|
|
||||||
econfig.resolved_config = config
|
|
||||||
end
|
|
||||||
|
|
||||||
return assert(econfig.resolved_config)
|
|
||||||
end
|
|
||||||
|
|
||||||
local lsp_enable_autocmd_id --- @type integer?
|
local lsp_enable_autocmd_id --- @type integer?
|
||||||
|
|
||||||
--- @param bufnr integer
|
--- @param bufnr integer
|
||||||
@@ -514,7 +500,9 @@ local function lsp_enable_callback(bufnr)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for name in vim.spairs(lsp._enabled_configs) do
|
for name in vim.spairs(lsp._enabled_configs) do
|
||||||
local config = lsp._resolve_config(name)
|
local config = lsp.config[name]
|
||||||
|
validate('cmd', config.cmd, { 'function', 'table' })
|
||||||
|
validate('cmd', config.reuse_client, 'function', true)
|
||||||
|
|
||||||
if can_start(config) then
|
if can_start(config) then
|
||||||
-- Deepcopy config so changes done in the client
|
-- Deepcopy config so changes done in the client
|
||||||
@@ -522,6 +510,7 @@ local function lsp_enable_callback(bufnr)
|
|||||||
config = vim.deepcopy(config)
|
config = vim.deepcopy(config)
|
||||||
|
|
||||||
if type(config.root_dir) == 'function' then
|
if type(config.root_dir) == 'function' then
|
||||||
|
---@param root_dir string
|
||||||
config.root_dir(function(root_dir)
|
config.root_dir(function(root_dir)
|
||||||
config.root_dir = root_dir
|
config.root_dir = root_dir
|
||||||
start(config)
|
start(config)
|
||||||
|
@@ -184,7 +184,7 @@ local function check_enabled_configs()
|
|||||||
vim.health.start('vim.lsp: Enabled Configurations')
|
vim.health.start('vim.lsp: Enabled Configurations')
|
||||||
|
|
||||||
for name in vim.spairs(vim.lsp._enabled_configs) do
|
for name in vim.spairs(vim.lsp._enabled_configs) do
|
||||||
local config = vim.lsp._resolve_config(name)
|
local config = vim.lsp.config[name]
|
||||||
local text = {} --- @type string[]
|
local text = {} --- @type string[]
|
||||||
text[#text + 1] = ('%s:'):format(name)
|
text[#text + 1] = ('%s:'):format(name)
|
||||||
for k, v in
|
for k, v in
|
||||||
|
@@ -6147,7 +6147,7 @@ describe('LSP', function()
|
|||||||
vim.lsp.config('*', { root_markers = { '.git' } })
|
vim.lsp.config('*', { root_markers = { '.git' } })
|
||||||
vim.lsp.config('foo', { cmd = { 'foo' } })
|
vim.lsp.config('foo', { cmd = { 'foo' } })
|
||||||
|
|
||||||
return vim.lsp._resolve_config('foo')
|
return vim.lsp.config['foo']
|
||||||
end)
|
end)
|
||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
|
Reference in New Issue
Block a user