mirror of
https://github.com/neovim/neovim.git
synced 2026-08-27 09:31:47 +00:00
feat(lsp): vim.lsp.get_configs() #37237
Problem: No way to iterate configs. Users need to reach for `vim.lsp.config._configs`, an internal interface. Solution: Provide vim.lsp.get_configs(). Also indirectly improves :lsp enable/disable completion by discarding invalid configs from completion.
This commit is contained in:
@@ -1153,6 +1153,23 @@ get_clients({filter}) *vim.lsp.get_clients()*
|
|||||||
Return: ~
|
Return: ~
|
||||||
(`vim.lsp.Client[]`) List of |vim.lsp.Client| objects
|
(`vim.lsp.Client[]`) List of |vim.lsp.Client| objects
|
||||||
|
|
||||||
|
get_configs({filter}) *vim.lsp.get_configs()*
|
||||||
|
Get LSP configs.
|
||||||
|
|
||||||
|
Note: Will eagerly evaluate config files in `'runtimepath'` if necessary.
|
||||||
|
|
||||||
|
Parameters: ~
|
||||||
|
• {filter} (`table?`) Key-value pairs used to filter the returned
|
||||||
|
configs.
|
||||||
|
• {enabled}? (`boolean`) If true, only return enabled
|
||||||
|
configs. If false, only return configs that aren't
|
||||||
|
enabled.
|
||||||
|
• {filetype}? (`string`) Only return configs which attach to
|
||||||
|
the given filetype.
|
||||||
|
|
||||||
|
Return: ~
|
||||||
|
(`vim.lsp.Config[]`) List of |vim.lsp.Config| objects
|
||||||
|
|
||||||
is_enabled({name}) *vim.lsp.is_enabled()*
|
is_enabled({name}) *vim.lsp.is_enabled()*
|
||||||
Checks if the given LSP config is enabled (globally, not per-buffer).
|
Checks if the given LSP config is enabled (globally, not per-buffer).
|
||||||
|
|
||||||
|
|||||||
@@ -330,6 +330,7 @@ LSP
|
|||||||
• Support for `workspace/codeLens/refresh`:
|
• Support for `workspace/codeLens/refresh`:
|
||||||
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#codeLens_refresh
|
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#codeLens_refresh
|
||||||
• |gx| opens `textDocument/documentLink` items found at cursor.
|
• |gx| opens `textDocument/documentLink` items found at cursor.
|
||||||
|
• |vim.lsp.get_configs()| can get all LSP configs matching certain conditions.
|
||||||
|
|
||||||
LUA
|
LUA
|
||||||
|
|
||||||
|
|||||||
@@ -19,45 +19,22 @@ local function get_client_names()
|
|||||||
:totable()
|
:totable()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @return string[]
|
--- @param filter vim.lsp.get_configs.Filter
|
||||||
local function get_config_names()
|
|
||||||
local config_names = vim
|
|
||||||
.iter(api.nvim_get_runtime_file('lsp/*.lua', true))
|
|
||||||
--- @param path string
|
|
||||||
:map(function(path)
|
|
||||||
local file_name = path:match('[^/]*.lua$')
|
|
||||||
return file_name:sub(0, #file_name - 4)
|
|
||||||
end)
|
|
||||||
:totable()
|
|
||||||
|
|
||||||
--- @diagnostic disable-next-line
|
|
||||||
vim.list_extend(config_names, vim.tbl_keys(lsp.config._configs))
|
|
||||||
|
|
||||||
return vim
|
|
||||||
.iter(config_names)
|
|
||||||
:unique()
|
|
||||||
--- @param name string
|
|
||||||
:filter(function(name)
|
|
||||||
return name ~= '*'
|
|
||||||
end)
|
|
||||||
:totable()
|
|
||||||
end
|
|
||||||
|
|
||||||
--- @param filter fun(string):boolean
|
|
||||||
--- @return fun():string[]
|
--- @return fun():string[]
|
||||||
local function filtered_config_names(filter)
|
local function filtered_config_names(filter)
|
||||||
return function()
|
return function()
|
||||||
return vim.iter(get_config_names()):filter(filter):totable()
|
return vim
|
||||||
|
.iter(lsp.get_configs(filter))
|
||||||
|
:map(function(config)
|
||||||
|
return config.name
|
||||||
|
end)
|
||||||
|
:totable()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local complete_args = {
|
local complete_args = {
|
||||||
enable = filtered_config_names(function(name)
|
enable = filtered_config_names { enabled = false },
|
||||||
return not lsp.is_enabled(name)
|
disable = filtered_config_names { enabled = true },
|
||||||
end),
|
|
||||||
disable = filtered_config_names(function(name)
|
|
||||||
return lsp.is_enabled(name)
|
|
||||||
end),
|
|
||||||
restart = get_client_names,
|
restart = get_client_names,
|
||||||
stop = get_client_names,
|
stop = get_client_names,
|
||||||
}
|
}
|
||||||
@@ -79,17 +56,10 @@ local function ex_lsp_enable(config_names)
|
|||||||
-- Default to enabling all clients matching the filetype of the current buffer.
|
-- Default to enabling all clients matching the filetype of the current buffer.
|
||||||
if #config_names == 0 then
|
if #config_names == 0 then
|
||||||
local filetype = vim.bo.filetype
|
local filetype = vim.bo.filetype
|
||||||
for _, name in ipairs(get_config_names()) do
|
for _, config in ipairs(lsp.get_configs()) do
|
||||||
local success, result = pcall(function()
|
local filetypes = config.filetypes
|
||||||
return lsp.config[name]
|
if filetypes == nil or vim.list_contains(filetypes, filetype) then
|
||||||
end)
|
table.insert(config_names, config.name)
|
||||||
if success then
|
|
||||||
local filetypes = result.filetypes
|
|
||||||
if filetypes == nil or vim.list_contains(filetypes, filetype) then
|
|
||||||
table.insert(config_names, name)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
echo_err(result --[[@as string]])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if #config_names == 0 then
|
if #config_names == 0 then
|
||||||
|
|||||||
@@ -387,6 +387,76 @@ lsp.config = setmetatable({ _configs = {} }, {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
--- @return string[]
|
||||||
|
local function get_config_names()
|
||||||
|
local config_names = vim
|
||||||
|
.iter(api.nvim_get_runtime_file('lsp/*.lua', true))
|
||||||
|
--- @param path string
|
||||||
|
:map(function(path)
|
||||||
|
local file_name = path:match('[^/]*.lua$')
|
||||||
|
return file_name:sub(0, #file_name - 4)
|
||||||
|
end)
|
||||||
|
:totable()
|
||||||
|
|
||||||
|
vim.list_extend(config_names, vim.tbl_keys(lsp.config._configs))
|
||||||
|
|
||||||
|
return vim
|
||||||
|
.iter(config_names)
|
||||||
|
:unique()
|
||||||
|
--- @param name string
|
||||||
|
:filter(function(name)
|
||||||
|
return name ~= '*'
|
||||||
|
end)
|
||||||
|
:totable()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Key-value pairs used to filter the returned configs.
|
||||||
|
--- @class vim.lsp.get_configs.Filter
|
||||||
|
--- @inlinedoc
|
||||||
|
---
|
||||||
|
--- If true, only return enabled configs. If false, only return configs that
|
||||||
|
--- aren't enabled.
|
||||||
|
--- @field enabled? boolean
|
||||||
|
---
|
||||||
|
--- Only return configs which attach to the given filetype.
|
||||||
|
--- @field filetype? string
|
||||||
|
|
||||||
|
--- Get LSP configs.
|
||||||
|
---
|
||||||
|
--- Note: Will eagerly evaluate config files in `'runtimepath'` if necessary.
|
||||||
|
--- @param filter? vim.lsp.get_configs.Filter
|
||||||
|
--- @return vim.lsp.Config[]: List of |vim.lsp.Config| objects
|
||||||
|
function lsp.get_configs(filter)
|
||||||
|
validate('filter', filter, 'table', true)
|
||||||
|
|
||||||
|
filter = filter or {}
|
||||||
|
|
||||||
|
local configs = {} --- @type vim.lsp.Config[]
|
||||||
|
|
||||||
|
local config_names --- @type string[]
|
||||||
|
if not filter.enabled then
|
||||||
|
config_names = get_config_names()
|
||||||
|
else
|
||||||
|
-- Shortcut filtering enabled configs by directly getting enabled configs
|
||||||
|
config_names = vim.tbl_keys(lsp._enabled_configs)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, config_name in ipairs(config_names) do
|
||||||
|
local config = lsp.config[config_name]
|
||||||
|
if
|
||||||
|
config
|
||||||
|
and (filter.enabled ~= false or not lsp.is_enabled(config_name))
|
||||||
|
and (
|
||||||
|
filter.filetype == nil
|
||||||
|
or (config.filetypes ~= nil and vim.list_contains(config.filetypes, filter.filetype))
|
||||||
|
)
|
||||||
|
then
|
||||||
|
configs[#configs + 1] = config
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return configs
|
||||||
|
end
|
||||||
|
|
||||||
local lsp_enable_autocmd_id --- @type integer?
|
local lsp_enable_autocmd_id --- @type integer?
|
||||||
|
|
||||||
local function validate_cmd(v)
|
local function validate_cmd(v)
|
||||||
|
|||||||
@@ -7114,6 +7114,52 @@ describe('LSP', function()
|
|||||||
exec_lua([[vim.lsp.enable('foo', false)]])
|
exec_lua([[vim.lsp.enable('foo', false)]])
|
||||||
eq(false, exec_lua([[return vim.lsp.is_enabled('foo')]]))
|
eq(false, exec_lua([[return vim.lsp.is_enabled('foo')]]))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('vim.lsp.get_configs()', function()
|
||||||
|
exec_lua(function()
|
||||||
|
vim.lsp.config('foo', {
|
||||||
|
cmd = { 'foo' },
|
||||||
|
filetypes = { 'foofile' },
|
||||||
|
root_markers = { '.foorc' },
|
||||||
|
})
|
||||||
|
vim.lsp.config('bar', {
|
||||||
|
cmd = { 'bar' },
|
||||||
|
root_markers = { '.barrc' },
|
||||||
|
})
|
||||||
|
vim.lsp.enable('foo')
|
||||||
|
end)
|
||||||
|
|
||||||
|
local function names(configs)
|
||||||
|
local config_names = vim
|
||||||
|
.iter(configs)
|
||||||
|
:map(function(config)
|
||||||
|
return config.name
|
||||||
|
end)
|
||||||
|
:totable()
|
||||||
|
table.sort(config_names)
|
||||||
|
return config_names
|
||||||
|
end
|
||||||
|
|
||||||
|
-- With no filter, return all configs
|
||||||
|
eq({ 'bar', 'foo' }, names(exec_lua([[return vim.lsp.get_configs()]])))
|
||||||
|
|
||||||
|
-- Confirm `enabled` works
|
||||||
|
eq({ 'foo' }, names(exec_lua([[return vim.lsp.get_configs { enabled = true }]])))
|
||||||
|
eq({ 'bar' }, names(exec_lua([[return vim.lsp.get_configs { enabled = false }]])))
|
||||||
|
|
||||||
|
-- Confirm `filetype` works
|
||||||
|
eq({ 'foo' }, names(exec_lua([[return vim.lsp.get_configs { filetype = 'foofile' }]])))
|
||||||
|
|
||||||
|
-- Confirm filters combine
|
||||||
|
eq(
|
||||||
|
{ 'foo' },
|
||||||
|
names(exec_lua([[return vim.lsp.get_configs { filetype = 'foofile', enabled = true }]]))
|
||||||
|
)
|
||||||
|
eq(
|
||||||
|
{},
|
||||||
|
names(exec_lua([[return vim.lsp.get_configs { filetype = 'foofile', enabled = false }]]))
|
||||||
|
)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('vim.lsp.buf.workspace_diagnostics()', function()
|
describe('vim.lsp.buf.workspace_diagnostics()', function()
|
||||||
|
|||||||
Reference in New Issue
Block a user