mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
Merge pull request #27420 from MariaSolOs/warning-anxiety
refactor(lsp): fix type annotations and add shared diagnostic helper
This commit is contained in:
commit
8e86193502
@ -1415,8 +1415,9 @@ on_publish_diagnostics({_}, {result}, {ctx}, {config})
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {result} (`lsp.PublishDiagnosticsParams`)
|
||||
• {ctx} (`lsp.HandlerContext`)
|
||||
• {config} (`table`) Configuration table (see
|
||||
• {config} (`vim.diagnostic.Opts?`) Configuration table (see
|
||||
|vim.diagnostic.config()|).
|
||||
|
||||
|
||||
|
@ -64,7 +64,7 @@ local state_by_group = setmetatable({}, {
|
||||
---@param client lsp.Client
|
||||
---@return vim.lsp.CTGroup
|
||||
local function get_group(client)
|
||||
local allow_inc_sync = vim.F.if_nil(client.config.flags.allow_incremental_sync, true)
|
||||
local allow_inc_sync = vim.F.if_nil(client.config.flags.allow_incremental_sync, true) --- @type boolean
|
||||
local change_capability = vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'change')
|
||||
local sync_kind = change_capability or protocol.TextDocumentSyncKind.None
|
||||
if not allow_inc_sync and change_capability == protocol.TextDocumentSyncKind.Incremental then
|
||||
|
@ -24,7 +24,7 @@ function M:supports_registration(method)
|
||||
end
|
||||
|
||||
--- @param registrations lsp.Registration[]
|
||||
--- @private
|
||||
--- @package
|
||||
function M:register(registrations)
|
||||
-- remove duplicates
|
||||
self:unregister(registrations)
|
||||
|
@ -630,8 +630,9 @@ end
|
||||
--- @param code integer Error code
|
||||
--- @param err any Error arguments
|
||||
function Client:write_error(code, err)
|
||||
log.error(self._log_prefix, 'on_error', { code = lsp.client_errors[code], err = err })
|
||||
err_message(self._log_prefix, ': Error ', lsp.client_errors[code], ': ', vim.inspect(err))
|
||||
local client_error = lsp.client_errors[code] --- @type string|integer
|
||||
log.error(self._log_prefix, 'on_error', { code = client_error, err = err })
|
||||
err_message(self._log_prefix, ': Error ', client_error, ': ', vim.inspect(err))
|
||||
end
|
||||
|
||||
--- @param method string
|
||||
|
@ -22,7 +22,7 @@ end
|
||||
---@param severity lsp.DiagnosticSeverity
|
||||
local function severity_lsp_to_vim(severity)
|
||||
if type(severity) == 'string' then
|
||||
severity = protocol.DiagnosticSeverity[severity]
|
||||
severity = protocol.DiagnosticSeverity[severity] --- @type integer
|
||||
end
|
||||
return severity
|
||||
end
|
||||
@ -48,7 +48,7 @@ local function line_byte_from_position(lines, lnum, col, offset_encoding)
|
||||
local line = lines[lnum + 1]
|
||||
local ok, result = pcall(vim.str_byteindex, line, col, offset_encoding == 'utf-16')
|
||||
if ok then
|
||||
return result
|
||||
return result --- @type integer
|
||||
end
|
||||
|
||||
return col
|
||||
@ -228,6 +228,40 @@ local function convert_severity(opt)
|
||||
end
|
||||
end
|
||||
|
||||
--- @param uri string
|
||||
--- @param client_id? integer
|
||||
--- @param diagnostics vim.Diagnostic[]
|
||||
--- @param is_pull boolean
|
||||
--- @param config? vim.diagnostic.Opts
|
||||
local function handle_diagnostics(uri, client_id, diagnostics, is_pull, config)
|
||||
local fname = vim.uri_to_fname(uri)
|
||||
|
||||
if #diagnostics == 0 and vim.fn.bufexists(fname) == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local bufnr = vim.fn.bufadd(fname)
|
||||
if not bufnr then
|
||||
return
|
||||
end
|
||||
|
||||
client_id = get_client_id(client_id)
|
||||
local namespace = M.get_namespace(client_id, is_pull)
|
||||
|
||||
if config then
|
||||
--- @cast config table<string, table>
|
||||
for _, opt in pairs(config) do
|
||||
convert_severity(opt)
|
||||
end
|
||||
-- Persist configuration to ensure buffer reloads use the same
|
||||
-- configuration. To make lsp.with configuration work (See :help
|
||||
-- lsp-handler-configuration)
|
||||
vim.diagnostic.config(config, namespace)
|
||||
end
|
||||
|
||||
vim.diagnostic.set(namespace, bufnr, diagnostic_lsp_to_vim(diagnostics, bufnr, client_id))
|
||||
end
|
||||
|
||||
--- |lsp-handler| for the method "textDocument/publishDiagnostics"
|
||||
---
|
||||
--- See |vim.diagnostic.config()| for configuration options. Handler-specific
|
||||
@ -253,36 +287,11 @@ end
|
||||
--- )
|
||||
--- ```
|
||||
---
|
||||
---@param result lsp.PublishDiagnosticsParams
|
||||
---@param ctx lsp.HandlerContext
|
||||
---@param config table Configuration table (see |vim.diagnostic.config()|).
|
||||
---@param config? vim.diagnostic.Opts Configuration table (see |vim.diagnostic.config()|).
|
||||
function M.on_publish_diagnostics(_, result, ctx, config)
|
||||
local client_id = ctx.client_id
|
||||
local uri = result.uri
|
||||
local fname = vim.uri_to_fname(uri)
|
||||
local diagnostics = result.diagnostics
|
||||
if #diagnostics == 0 and vim.fn.bufexists(fname) == 0 then
|
||||
return
|
||||
end
|
||||
local bufnr = vim.fn.bufadd(fname)
|
||||
|
||||
if not bufnr then
|
||||
return
|
||||
end
|
||||
|
||||
client_id = get_client_id(client_id)
|
||||
local namespace = M.get_namespace(client_id, false)
|
||||
|
||||
if config then
|
||||
for _, opt in pairs(config) do
|
||||
convert_severity(opt)
|
||||
end
|
||||
-- Persist configuration to ensure buffer reloads use the same
|
||||
-- configuration. To make lsp.with configuration work (See :help
|
||||
-- lsp-handler-configuration)
|
||||
vim.diagnostic.config(config, namespace)
|
||||
end
|
||||
|
||||
vim.diagnostic.set(namespace, bufnr, diagnostic_lsp_to_vim(diagnostics, bufnr, client_id))
|
||||
handle_diagnostics(result.uri, ctx.client_id, result.diagnostics, false, config)
|
||||
end
|
||||
|
||||
--- |lsp-handler| for the method "textDocument/diagnostic"
|
||||
@ -314,45 +323,11 @@ end
|
||||
---@param ctx lsp.HandlerContext
|
||||
---@param config table Configuration table (see |vim.diagnostic.config()|).
|
||||
function M.on_diagnostic(_, result, ctx, config)
|
||||
local client_id = ctx.client_id
|
||||
--- @type lsp.DocumentDiagnosticParams
|
||||
local params = ctx.params
|
||||
local uri = params.textDocument.uri
|
||||
local fname = vim.uri_to_fname(uri)
|
||||
|
||||
if result == nil then
|
||||
if result == nil or result.kind == 'unchanged' then
|
||||
return
|
||||
end
|
||||
|
||||
if result.kind == 'unchanged' then
|
||||
return
|
||||
end
|
||||
|
||||
local diagnostics = result.items
|
||||
if #diagnostics == 0 and vim.fn.bufexists(fname) == 0 then
|
||||
return
|
||||
end
|
||||
local bufnr = vim.fn.bufadd(fname)
|
||||
|
||||
if not bufnr then
|
||||
return
|
||||
end
|
||||
|
||||
client_id = get_client_id(client_id)
|
||||
|
||||
local namespace = M.get_namespace(client_id, true)
|
||||
|
||||
if config then
|
||||
for _, opt in pairs(config) do
|
||||
convert_severity(opt)
|
||||
end
|
||||
-- Persist configuration to ensure buffer reloads use the same
|
||||
-- configuration. To make lsp.with configuration work (See :help
|
||||
-- lsp-handler-configuration)
|
||||
vim.diagnostic.config(config, namespace)
|
||||
end
|
||||
|
||||
vim.diagnostic.set(namespace, bufnr, diagnostic_lsp_to_vim(diagnostics, bufnr, client_id))
|
||||
handle_diagnostics(ctx.params.textDocument.uri, ctx.client_id, result.items, true, config)
|
||||
end
|
||||
|
||||
--- Clear push diagnostics and diagnostic cache.
|
||||
@ -362,7 +337,7 @@ end
|
||||
--- implementation so it's simply marked @private rather than @deprecated.
|
||||
---
|
||||
---@param client_id integer
|
||||
---@param buffer_client_map table map of buffers to active clients
|
||||
---@param buffer_client_map table<integer, table<integer, table>> map of buffers to active clients
|
||||
---@private
|
||||
function M.reset(client_id, buffer_client_map)
|
||||
buffer_client_map = vim.deepcopy(buffer_client_map)
|
||||
@ -462,7 +437,8 @@ function M._enable(bufnr)
|
||||
return
|
||||
end
|
||||
if bufstates[bufnr] and bufstates[bufnr].enabled then
|
||||
_refresh(bufnr, { only_visible = true, client_id = opts.data.client_id })
|
||||
local client_id = opts.data.client_id --- @type integer?
|
||||
_refresh(bufnr, { only_visible = true, client_id = client_id })
|
||||
end
|
||||
end,
|
||||
group = augroup,
|
||||
|
@ -7,7 +7,7 @@ function M.check()
|
||||
|
||||
local log = vim.lsp.log
|
||||
local current_log_level = log.get_level()
|
||||
local log_level_string = log.levels[current_log_level]
|
||||
local log_level_string = log.levels[current_log_level] ---@type string
|
||||
report_info(string.format('LSP log level : %s', log_level_string))
|
||||
|
||||
if current_log_level < log.levels.WARN then
|
||||
|
@ -498,7 +498,7 @@ function Client:handle_body(body)
|
||||
if decoded.error then
|
||||
decoded.error = setmetatable(decoded.error, {
|
||||
__tostring = M.format_rpc_error,
|
||||
})
|
||||
}) --- @type table
|
||||
end
|
||||
self:try_call(
|
||||
M.client_errors.SERVER_RESULT_CALLBACK_ERROR,
|
||||
|
@ -58,8 +58,7 @@ local function byte_to_utf(line, byte, offset_encoding)
|
||||
-- convert to 0 based indexing for str_utfindex
|
||||
byte = byte - 1
|
||||
|
||||
local utf_idx --- @type integer
|
||||
local _
|
||||
local utf_idx, _ --- @type integer, integer
|
||||
-- Convert the byte range to utf-{8,16,32} and convert 1-based (lua) indexing to 0-based
|
||||
if offset_encoding == 'utf-16' then
|
||||
_, utf_idx = str_utfindex(line, byte)
|
||||
@ -77,8 +76,7 @@ end
|
||||
---@param offset_encoding string
|
||||
---@return integer
|
||||
local function compute_line_length(line, offset_encoding)
|
||||
local length --- @type integer
|
||||
local _
|
||||
local length, _ --- @type integer, integer
|
||||
if offset_encoding == 'utf-16' then
|
||||
_, length = str_utfindex(line)
|
||||
elseif offset_encoding == 'utf-32' then
|
||||
@ -122,6 +120,11 @@ local function align_end_position(line, byte, offset_encoding)
|
||||
return byte, char
|
||||
end
|
||||
|
||||
---@class vim.lsp.sync.Range
|
||||
---@field line_idx integer
|
||||
---@field byte_idx integer
|
||||
---@field char_idx integer
|
||||
|
||||
--- Finds the first line, byte, and char index of the difference between the previous and current lines buffer normalized to the previous codepoint.
|
||||
---@param prev_lines string[] list of lines from previous buffer
|
||||
---@param curr_lines string[] list of lines from current buffer
|
||||
@ -129,7 +132,7 @@ end
|
||||
---@param lastline integer lastline from on_lines, adjusted to 1-index
|
||||
---@param new_lastline integer new_lastline from on_lines, adjusted to 1-index
|
||||
---@param offset_encoding string utf-8|utf-16|utf-32|nil (fallback to utf-8)
|
||||
---@return table result table include line_idx, byte_idx, and char_idx of first change position
|
||||
---@return vim.lsp.sync.Range result table include line_idx, byte_idx, and char_idx of first change position
|
||||
local function compute_start_range(
|
||||
prev_lines,
|
||||
curr_lines,
|
||||
@ -202,14 +205,14 @@ end
|
||||
--- prev_end_range is the text range sent to the server representing the changed region.
|
||||
--- curr_end_range is the text that should be collected and sent to the server.
|
||||
--
|
||||
---@param prev_lines table list of lines
|
||||
---@param curr_lines table list of lines
|
||||
---@param start_range table
|
||||
---@param prev_lines string[] list of lines
|
||||
---@param curr_lines string[] list of lines
|
||||
---@param start_range vim.lsp.sync.Range
|
||||
---@param firstline integer
|
||||
---@param lastline integer
|
||||
---@param new_lastline integer
|
||||
---@param offset_encoding string
|
||||
---@return integer|table end_line_idx and end_col_idx of range
|
||||
---@return table|nil end_col_idx of range
|
||||
---@return vim.lsp.sync.Range, vim.lsp.sync.Range
|
||||
local function compute_end_range(
|
||||
prev_lines,
|
||||
curr_lines,
|
||||
@ -253,7 +256,7 @@ local function compute_end_range(
|
||||
-- Editing the same line
|
||||
-- If the byte offset is zero, that means there is a difference on the last byte (not newline)
|
||||
if prev_line_idx == curr_line_idx then
|
||||
local max_length
|
||||
local max_length --- @type integer
|
||||
if start_line_idx == prev_line_idx then
|
||||
-- Search until beginning of difference
|
||||
max_length = min(
|
||||
@ -286,7 +289,7 @@ local function compute_end_range(
|
||||
local prev_end_range =
|
||||
{ line_idx = prev_line_idx, byte_idx = prev_byte_idx, char_idx = prev_char_idx }
|
||||
|
||||
local curr_end_range
|
||||
local curr_end_range ---@type vim.lsp.sync.Range
|
||||
-- Deletion event, new_range cannot be before start
|
||||
if curr_line_idx < start_line_idx then
|
||||
curr_end_range = { line_idx = start_line_idx, byte_idx = 1, char_idx = 1 }
|
||||
@ -347,8 +350,8 @@ end
|
||||
-- Line endings count here as 2 chars for \r\n (dos), 1 char for \n (unix), and 1 char for \r (mac)
|
||||
-- These correspond to Windows, Linux/macOS (OSX and newer), and macOS (version 9 and prior)
|
||||
---@param lines string[]
|
||||
---@param start_range table
|
||||
---@param end_range table
|
||||
---@param start_range vim.lsp.sync.Range
|
||||
---@param end_range vim.lsp.sync.Range
|
||||
---@param offset_encoding string
|
||||
---@param line_ending string
|
||||
---@return integer
|
||||
|
Loading…
Reference in New Issue
Block a user