aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r--runtime/lua/vim/lsp.lua88
-rw-r--r--runtime/lua/vim/lsp/log.lua5
2 files changed, 62 insertions, 31 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 91f2895f04..6c23c24220 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -374,26 +374,31 @@ lsp.config = setmetatable({ _configs = {} }, {
validate('name', name, 'string')
local rconfig = lsp._enabled_configs[name] or {}
- self._configs[name] = self._configs[name] or {}
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
+ 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)
+ --- @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))
end
end
+ if not rtp_config and not self._configs[name] then
+ log.warn(string.format('%s does not have a configuration', name))
+ return
+ end
+
rconfig.resolved_config = vim.tbl_deep_extend(
'force',
lsp.config._configs['*'] or {},
- rtp_config,
- lsp.config._configs[name] or {}
+ rtp_config or {},
+ self._configs[name] or {}
)
rconfig.resolved_config.name = name
end
@@ -424,39 +429,60 @@ lsp.config = setmetatable({ _configs = {} }, {
local lsp_enable_autocmd_id --- @type integer?
---- @param bufnr integer
-local function lsp_enable_callback(bufnr)
- -- Only ever attach to buffers that represent an actual file.
- if vim.bo[bufnr].buftype ~= '' then
- return
+local function validate_cmd(v)
+ if type(v) == 'table' then
+ if vim.fn.executable(v[1]) == 0 then
+ return false, v[1] .. ' is not executable'
+ end
+ return true
end
+ return type(v) == 'function'
+end
- --- @param config vim.lsp.Config
- local function can_start(config)
- if config.filetypes and not vim.tbl_contains(config.filetypes, vim.bo[bufnr].filetype) then
- return false
- elseif type(config.cmd) == 'table' and vim.fn.executable(config.cmd[1]) == 0 then
- return false
- end
+--- @param config vim.lsp.Config
+local function validate_config(config)
+ validate('cmd', config.cmd, validate_cmd, 'expected function or table with executable command')
+ validate('reuse_client', config.reuse_client, 'function', true)
+ validate('filetypes', config.filetypes, 'table', true)
+end
- return true
+--- @param bufnr integer
+--- @param name string
+--- @param config vim.lsp.Config
+local function can_start(bufnr, name, config)
+ local config_ok, err = pcall(validate_config, config)
+ if not config_ok then
+ log.error(('cannot start %s due to config error: %s'):format(name, err))
+ return false
end
- --- @param config vim.lsp.Config
- local function start(config)
- return vim.lsp.start(config, {
- bufnr = bufnr,
- reuse_client = config.reuse_client,
- _root_markers = config.root_markers,
- })
+ if config.filetypes and not vim.tbl_contains(config.filetypes, vim.bo[bufnr].filetype) then
+ return false
+ end
+
+ return true
+end
+
+--- @param bufnr integer
+--- @param config vim.lsp.Config
+local function start_config(bufnr, config)
+ return vim.lsp.start(config, {
+ bufnr = bufnr,
+ reuse_client = config.reuse_client,
+ _root_markers = config.root_markers,
+ })
+end
+
+--- @param bufnr integer
+local function lsp_enable_callback(bufnr)
+ -- Only ever attach to buffers that represent an actual file.
+ if vim.bo[bufnr].buftype ~= '' then
+ return
end
for name in vim.spairs(lsp._enabled_configs) do
local config = lsp.config[name]
- validate('cmd', config.cmd, { 'function', 'table' })
- validate('cmd', config.reuse_client, 'function', true)
-
- if can_start(config) then
+ if config and can_start(bufnr, name, config) then
-- Deepcopy config so changes done in the client
-- do not propagate back to the enabled configs.
config = vim.deepcopy(config)
@@ -466,11 +492,11 @@ local function lsp_enable_callback(bufnr)
config.root_dir(bufnr, function(root_dir)
config.root_dir = root_dir
vim.schedule(function()
- start(config)
+ start_config(bufnr, config)
end)
end)
else
- start(config)
+ start_config(bufnr, config)
end
end
end
diff --git a/runtime/lua/vim/lsp/log.lua b/runtime/lua/vim/lsp/log.lua
index ec78dd3dc5..0f93369a0c 100644
--- a/runtime/lua/vim/lsp/log.lua
+++ b/runtime/lua/vim/lsp/log.lua
@@ -45,6 +45,11 @@ function log.get_filename()
return logfilename
end
+--- @param s string
+function log._set_filename(s)
+ logfilename = s
+end
+
--- @type file*?, string?
local logfile, openerr