mirror of
https://github.com/neovim/neovim.git
synced 2026-03-30 20:32:08 +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: ~
|
||||
(`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()*
|
||||
Checks if the given LSP config is enabled (globally, not per-buffer).
|
||||
|
||||
|
||||
@@ -330,6 +330,7 @@ LSP
|
||||
• Support for `workspace/codeLens/refresh`:
|
||||
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#codeLens_refresh
|
||||
• |gx| opens `textDocument/documentLink` items found at cursor.
|
||||
• |vim.lsp.get_configs()| can get all LSP configs matching certain conditions.
|
||||
|
||||
LUA
|
||||
|
||||
|
||||
@@ -19,45 +19,22 @@ local function get_client_names()
|
||||
:totable()
|
||||
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()
|
||||
|
||||
--- @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
|
||||
--- @param filter vim.lsp.get_configs.Filter
|
||||
--- @return fun():string[]
|
||||
local function filtered_config_names(filter)
|
||||
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
|
||||
|
||||
local complete_args = {
|
||||
enable = filtered_config_names(function(name)
|
||||
return not lsp.is_enabled(name)
|
||||
end),
|
||||
disable = filtered_config_names(function(name)
|
||||
return lsp.is_enabled(name)
|
||||
end),
|
||||
enable = filtered_config_names { enabled = false },
|
||||
disable = filtered_config_names { enabled = true },
|
||||
restart = 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.
|
||||
if #config_names == 0 then
|
||||
local filetype = vim.bo.filetype
|
||||
for _, name in ipairs(get_config_names()) do
|
||||
local success, result = pcall(function()
|
||||
return lsp.config[name]
|
||||
end)
|
||||
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]])
|
||||
for _, config in ipairs(lsp.get_configs()) do
|
||||
local filetypes = config.filetypes
|
||||
if filetypes == nil or vim.list_contains(filetypes, filetype) then
|
||||
table.insert(config_names, config.name)
|
||||
end
|
||||
end
|
||||
if #config_names == 0 then
|
||||
|
||||
@@ -387,6 +387,76 @@ lsp.config = setmetatable({ _configs = {} }, {
|
||||
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 function validate_cmd(v)
|
||||
|
||||
@@ -7114,6 +7114,52 @@ describe('LSP', function()
|
||||
exec_lua([[vim.lsp.enable('foo', false)]])
|
||||
eq(false, exec_lua([[return vim.lsp.is_enabled('foo')]]))
|
||||
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)
|
||||
|
||||
describe('vim.lsp.buf.workspace_diagnostics()', function()
|
||||
|
||||
Reference in New Issue
Block a user