aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2024-11-01 16:31:51 +0000
committerLewis Russell <me@lewisr.dev>2024-12-10 17:16:01 +0000
commit3f1d09bc94d02266d6fa588a2ccd1be1ca084cf7 (patch)
treef296c9607155bffe75ebaa23e20b19c36ecb87f1 /runtime/lua/vim/lsp
parentca760e645ba4d1fdb0b6fff3ac98231c3d683306 (diff)
downloadrneovim-3f1d09bc94d02266d6fa588a2ccd1be1ca084cf7.tar.gz
rneovim-3f1d09bc94d02266d6fa588a2ccd1be1ca084cf7.tar.bz2
rneovim-3f1d09bc94d02266d6fa588a2ccd1be1ca084cf7.zip
feat(lsp): add vim.lsp.config and vim.lsp.enable
Design goals/requirements: - Default configuration of a server can be distributed across multiple sources. - And via RTP discovery. - Default configuration can be specified for all servers. - Configuration _can_ be project specific. Solution: - Two new API's: - `vim.lsp.config(name, cfg)`: - Used to define default configurations for servers of name. - Can be used like a table or called as a function. - Use `vim.lsp.confg('*', cfg)` to specify default config for all servers. - `vim.lsp.enable(name)` - Used to enable servers of name. Uses configuration defined via `vim.lsp.config()`.
Diffstat (limited to 'runtime/lua/vim/lsp')
-rw-r--r--runtime/lua/vim/lsp/client.lua21
-rw-r--r--runtime/lua/vim/lsp/health.lua74
2 files changed, 63 insertions, 32 deletions
diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua
index 5eefe4600e..72043c18dd 100644
--- a/runtime/lua/vim/lsp/client.lua
+++ b/runtime/lua/vim/lsp/client.lua
@@ -359,16 +359,6 @@ local function get_name(id, config)
return tostring(id)
end
---- @generic T
---- @param x elem_or_list<T>?
---- @return T[]
-local function ensure_list(x)
- if type(x) == 'table' then
- return x
- end
- return { x }
-end
-
--- @nodoc
--- @param config vim.lsp.ClientConfig
--- @return vim.lsp.Client?
@@ -395,13 +385,13 @@ function Client.create(config)
settings = config.settings or {},
flags = config.flags or {},
get_language_id = config.get_language_id or default_get_language_id,
- capabilities = config.capabilities or lsp.protocol.make_client_capabilities(),
+ capabilities = config.capabilities,
workspace_folders = lsp._get_workspace_folders(config.workspace_folders or config.root_dir),
root_dir = config.root_dir,
_before_init_cb = config.before_init,
- _on_init_cbs = ensure_list(config.on_init),
- _on_exit_cbs = ensure_list(config.on_exit),
- _on_attach_cbs = ensure_list(config.on_attach),
+ _on_init_cbs = vim._ensure_list(config.on_init),
+ _on_exit_cbs = vim._ensure_list(config.on_exit),
+ _on_attach_cbs = vim._ensure_list(config.on_attach),
_on_error_cb = config.on_error,
_trace = get_trace(config.trace),
@@ -417,6 +407,9 @@ function Client.create(config)
messages = { name = name, messages = {}, progress = {}, status = {} },
}
+ self.capabilities =
+ vim.tbl_deep_extend('force', lsp.protocol.make_client_capabilities(), self.capabilities or {})
+
--- @class lsp.DynamicCapabilities
--- @nodoc
self.dynamic_capabilities = {
diff --git a/runtime/lua/vim/lsp/health.lua b/runtime/lua/vim/lsp/health.lua
index 0d314108fe..d2cf888d89 100644
--- a/runtime/lua/vim/lsp/health.lua
+++ b/runtime/lua/vim/lsp/health.lua
@@ -28,42 +28,45 @@ local function check_log()
report_fn(string.format('Log size: %d KB', log_size / 1000))
end
+--- @param f function
+--- @return string
+local function func_tostring(f)
+ local info = debug.getinfo(f, 'S')
+ return ('<function %s:%s>'):format(info.source, info.linedefined)
+end
+
local function check_active_clients()
vim.health.start('vim.lsp: Active Clients')
local clients = vim.lsp.get_clients()
if next(clients) then
for _, client in pairs(clients) do
local cmd ---@type string
- if type(client.config.cmd) == 'table' then
- cmd = table.concat(client.config.cmd --[[@as table]], ' ')
- elseif type(client.config.cmd) == 'function' then
- cmd = tostring(client.config.cmd)
+ local ccmd = client.config.cmd
+ if type(ccmd) == 'table' then
+ cmd = vim.inspect(ccmd)
+ elseif type(ccmd) == 'function' then
+ cmd = func_tostring(ccmd)
end
local dirs_info ---@type string
if client.workspace_folders and #client.workspace_folders > 1 then
- dirs_info = string.format(
- ' Workspace folders:\n %s',
- vim
- .iter(client.workspace_folders)
- ---@param folder lsp.WorkspaceFolder
- :map(function(folder)
- return folder.name
- end)
- :join('\n ')
- )
+ local wfolders = {} --- @type string[]
+ for _, dir in ipairs(client.workspace_folders) do
+ wfolders[#wfolders + 1] = dir.name
+ end
+ dirs_info = ('- Workspace folders:\n %s'):format(table.concat(wfolders, '\n '))
else
dirs_info = string.format(
- ' Root directory: %s',
+ '- Root directory: %s',
client.root_dir and vim.fn.fnamemodify(client.root_dir, ':~')
) or nil
end
report_info(table.concat({
string.format('%s (id: %d)', client.name, client.id),
dirs_info,
- string.format(' Command: %s', cmd),
- string.format(' Settings: %s', vim.inspect(client.settings, { newline = '\n ' })),
+ string.format('- Command: %s', cmd),
+ string.format('- Settings: %s', vim.inspect(client.settings, { newline = '\n ' })),
string.format(
- ' Attached buffers: %s',
+ '- Attached buffers: %s',
vim.iter(pairs(client.attached_buffers)):map(tostring):join(', ')
),
}, '\n'))
@@ -174,10 +177,45 @@ local function check_position_encodings()
end
end
+local function check_enabled_configs()
+ vim.health.start('vim.lsp: Enabled Configurations')
+
+ for name in vim.spairs(vim.lsp._enabled_configs) do
+ local config = vim.lsp._resolve_config(name)
+ local text = {} --- @type string[]
+ text[#text + 1] = ('%s:'):format(name)
+ for k, v in
+ vim.spairs(config --[[@as table<string,any>]])
+ do
+ local v_str --- @type string?
+ if k == 'name' then
+ v_str = nil
+ elseif k == 'filetypes' or k == 'root_markers' then
+ v_str = table.concat(v, ', ')
+ elseif type(v) == 'function' then
+ v_str = func_tostring(v)
+ else
+ v_str = vim.inspect(v, { newline = '\n ' })
+ end
+
+ if k == 'cmd' and type(v) == 'table' and vim.fn.executable(v[1]) == 0 then
+ report_warn(("'%s' is not executable. Configuration will not be used."):format(v[1]))
+ end
+
+ if v_str then
+ text[#text + 1] = ('- %s: %s'):format(k, v_str)
+ end
+ end
+ text[#text + 1] = ''
+ report_info(table.concat(text, '\n'))
+ end
+end
+
--- Performs a healthcheck for LSP
function M.check()
check_log()
check_active_clients()
+ check_enabled_configs()
check_watcher()
check_position_encodings()
end