mirror of
https://github.com/neovim/neovim.git
synced 2025-10-26 12:27:24 +00:00
feat(diagnostic): add support for tags
The LSP spec supports two tags that can be added to diagnostics: unnecessary and deprecated. Extend vim.diagnostic to be able to handle these.
This commit is contained in:
@@ -483,6 +483,7 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace)
|
||||
local diagnostics =
|
||||
get_diagnostics(bufnr, vim.tbl_extend('keep', opts, { namespace = namespace }), true)
|
||||
local line_diagnostics = diagnostic_lines(diagnostics)
|
||||
|
||||
for i = 0, line_count do
|
||||
local offset = i * (search_forward and 1 or -1)
|
||||
local lnum = position[1] + offset
|
||||
@@ -752,6 +753,7 @@ end
|
||||
---@field message string
|
||||
---@field source nil|string
|
||||
---@field code nil|string
|
||||
---@field _tags { deprecated: boolean, unnecessary: boolean}
|
||||
---@field user_data nil|any arbitrary data plugins can add
|
||||
|
||||
--- Get current diagnostics.
|
||||
@@ -948,6 +950,16 @@ M.handlers.underline = {
|
||||
higroup = underline_highlight_map.Error
|
||||
end
|
||||
|
||||
if diagnostic._tags then
|
||||
-- TODO(lewis6991): we should be able to stack these.
|
||||
if diagnostic._tags.unnecessary then
|
||||
higroup = 'DiagnosticUnnecessary'
|
||||
end
|
||||
if diagnostic._tags.deprecated then
|
||||
higroup = 'DiagnosticDeprecated'
|
||||
end
|
||||
end
|
||||
|
||||
vim.highlight.range(
|
||||
bufnr,
|
||||
underline_ns,
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
---@brief lsp-diagnostic
|
||||
---
|
||||
---@class Diagnostic
|
||||
---@field range Range
|
||||
---@field message string
|
||||
---@field severity DiagnosticSeverity|nil
|
||||
---@field code integer | string
|
||||
---@field source string
|
||||
---@field tags DiagnosticTag[]
|
||||
---@field relatedInformation DiagnosticRelatedInformation[]
|
||||
|
||||
local protocol = require('vim.lsp.protocol')
|
||||
|
||||
local M = {}
|
||||
|
||||
@@ -22,14 +15,16 @@ local function get_client_id(client_id)
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param severity lsp.DiagnosticSeverity
|
||||
local function severity_lsp_to_vim(severity)
|
||||
if type(severity) == 'string' then
|
||||
severity = vim.lsp.protocol.DiagnosticSeverity[severity]
|
||||
severity = protocol.DiagnosticSeverity[severity]
|
||||
end
|
||||
return severity
|
||||
end
|
||||
|
||||
---@private
|
||||
---@return lsp.DiagnosticSeverity
|
||||
local function severity_vim_to_lsp(severity)
|
||||
if type(severity) == 'string' then
|
||||
severity = vim.diagnostic.severity[severity]
|
||||
@@ -38,6 +33,7 @@ local function severity_vim_to_lsp(severity)
|
||||
end
|
||||
|
||||
---@private
|
||||
---@return integer
|
||||
local function line_byte_from_position(lines, lnum, col, offset_encoding)
|
||||
if not lines or offset_encoding == 'utf-8' then
|
||||
return col
|
||||
@@ -77,12 +73,41 @@ local function get_buf_lines(bufnr)
|
||||
return lines
|
||||
end
|
||||
|
||||
--- @private
|
||||
--- @param diagnostic lsp.Diagnostic
|
||||
--- @param client_id integer
|
||||
--- @return table?
|
||||
local function tags_lsp_to_vim(diagnostic, client_id)
|
||||
local tags ---@type table?
|
||||
for _, tag in ipairs(diagnostic.tags or {}) do
|
||||
if tag == protocol.DiagnosticTag.Unnecessary then
|
||||
tags = tags or {}
|
||||
tags.unnecessary = true
|
||||
elseif tag == protocol.DiagnosticTag.Deprecated then
|
||||
tags = tags or {}
|
||||
tags.deprecated = true
|
||||
else
|
||||
vim.notify_once(
|
||||
string.format('Unknown DiagnosticTag %d from LSP client %d', tag, client_id),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
end
|
||||
end
|
||||
return tags
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param diagnostics lsp.Diagnostic[]
|
||||
---@param bufnr integer
|
||||
---@param client_id integer
|
||||
---@return Diagnostic[]
|
||||
local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
|
||||
local buf_lines = get_buf_lines(bufnr)
|
||||
local client = vim.lsp.get_client_by_id(client_id)
|
||||
local offset_encoding = client and client.offset_encoding or 'utf-16'
|
||||
---@diagnostic disable-next-line:no-unknown
|
||||
return vim.tbl_map(function(diagnostic)
|
||||
---@cast diagnostic lsp.Diagnostic
|
||||
local start = diagnostic.range.start
|
||||
local _end = diagnostic.range['end']
|
||||
return {
|
||||
@@ -94,12 +119,12 @@ local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
|
||||
message = diagnostic.message,
|
||||
source = diagnostic.source,
|
||||
code = diagnostic.code,
|
||||
tags = tags_lsp_to_vim(diagnostic, client_id),
|
||||
user_data = {
|
||||
lsp = {
|
||||
-- usage of user_data.lsp.code is deprecated in favor of the top-level code field
|
||||
code = diagnostic.code,
|
||||
codeDescription = diagnostic.codeDescription,
|
||||
tags = diagnostic.tags,
|
||||
relatedInformation = diagnostic.relatedInformation,
|
||||
data = diagnostic.data,
|
||||
},
|
||||
@@ -108,9 +133,13 @@ local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
|
||||
end, diagnostics)
|
||||
end
|
||||
|
||||
---@private
|
||||
--- @private
|
||||
--- @param diagnostics Diagnostic[]
|
||||
--- @return lsp.Diagnostic[]
|
||||
local function diagnostic_vim_to_lsp(diagnostics)
|
||||
---@diagnostic disable-next-line:no-unknown
|
||||
return vim.tbl_map(function(diagnostic)
|
||||
---@cast diagnostic Diagnostic
|
||||
return vim.tbl_extend('keep', {
|
||||
-- "keep" the below fields over any duplicate fields in diagnostic.user_data.lsp
|
||||
range = {
|
||||
@@ -131,6 +160,7 @@ local function diagnostic_vim_to_lsp(diagnostics)
|
||||
end, diagnostics)
|
||||
end
|
||||
|
||||
---@type table<integer,integer>
|
||||
local _client_namespaces = {}
|
||||
|
||||
--- Get the diagnostic namespace associated with an LSP client |vim.diagnostic|.
|
||||
|
||||
@@ -21,6 +21,7 @@ end
|
||||
--]=]
|
||||
|
||||
local constants = {
|
||||
--- @enum lsp.DiagnosticSeverity
|
||||
DiagnosticSeverity = {
|
||||
-- Reports an error.
|
||||
Error = 1,
|
||||
@@ -32,6 +33,7 @@ local constants = {
|
||||
Hint = 4,
|
||||
},
|
||||
|
||||
--- @enum lsp.DiagnosticTag
|
||||
DiagnosticTag = {
|
||||
-- Unused or unnecessary code
|
||||
Unnecessary = 1,
|
||||
|
||||
@@ -18,3 +18,20 @@
|
||||
---@class lsp.FileEvent
|
||||
---@field uri string
|
||||
---@field type lsp.FileChangeType
|
||||
|
||||
---@class lsp.Position
|
||||
---@field line integer
|
||||
---@field character integer
|
||||
|
||||
---@class lsp.Range
|
||||
---@field start lsp.Position
|
||||
---@field end lsp.Position
|
||||
|
||||
---@class lsp.Diagnostic
|
||||
---@field range lsp.Range
|
||||
---@field message string
|
||||
---@field severity? lsp.DiagnosticSeverity
|
||||
---@field code integer | string
|
||||
---@field source string
|
||||
---@field tags? lsp.DiagnosticTag[]
|
||||
---@field relatedInformation DiagnosticRelatedInformation[]
|
||||
|
||||
Reference in New Issue
Block a user