mirror of
https://github.com/neovim/neovim.git
synced 2025-12-11 17:12:40 +00:00
refactor(diagnostic): set sign by using extmark (#26193)
after sign implementation refactor by using extmark, we can use `nvim_buf_set_extmark` to set diagnostic sign instead use `sign_define`
This commit is contained in:
@@ -435,6 +435,16 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
|
|||||||
for signs. When {severity_sort} is used, the priority
|
for signs. When {severity_sort} is used, the priority
|
||||||
of a sign is adjusted based on its severity.
|
of a sign is adjusted based on its severity.
|
||||||
Otherwise, all signs use the same priority.
|
Otherwise, all signs use the same priority.
|
||||||
|
• text: (table) A table mapping |diagnostic-severity|
|
||||||
|
to the sign text to display in the sign column. The
|
||||||
|
default is to use "E", "W", "I", and "H" for errors,
|
||||||
|
warnings, information, and hints, respectively.
|
||||||
|
Example: >lua
|
||||||
|
|
||||||
|
vim.diagnostic.config({
|
||||||
|
sign = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } }
|
||||||
|
})
|
||||||
|
<
|
||||||
|
|
||||||
• float: Options for floating windows. See
|
• float: Options for floating windows. See
|
||||||
|vim.diagnostic.open_float()|.
|
|vim.diagnostic.open_float()|.
|
||||||
|
|||||||
@@ -341,6 +341,9 @@ The following changes to existing APIs or features add new behavior.
|
|||||||
|
|
||||||
• Vimscript function |exists()| supports checking |v:lua| functions.
|
• Vimscript function |exists()| supports checking |v:lua| functions.
|
||||||
|
|
||||||
|
• Diagnostic sign text is no longer configured with |sign_define()|.
|
||||||
|
Use |vim.diagnostic.config()| instead.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
REMOVED FEATURES *news-removed*
|
REMOVED FEATURES *news-removed*
|
||||||
|
|
||||||
|
|||||||
@@ -221,30 +221,6 @@ local underline_highlight_map = make_highlight_map('Underline')
|
|||||||
local floating_highlight_map = make_highlight_map('Floating')
|
local floating_highlight_map = make_highlight_map('Floating')
|
||||||
local sign_highlight_map = make_highlight_map('Sign')
|
local sign_highlight_map = make_highlight_map('Sign')
|
||||||
|
|
||||||
---@private
|
|
||||||
local define_default_signs = (function()
|
|
||||||
local signs_defined = false
|
|
||||||
return function()
|
|
||||||
if signs_defined then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
for severity, sign_hl_name in pairs(sign_highlight_map) do
|
|
||||||
if vim.tbl_isempty(vim.fn.sign_getdefined(sign_hl_name)) then
|
|
||||||
local severity_name = M.severity[severity]
|
|
||||||
vim.fn.sign_define(sign_hl_name, {
|
|
||||||
text = (severity_name or 'U'):sub(1, 1),
|
|
||||||
texthl = sign_hl_name,
|
|
||||||
linehl = '',
|
|
||||||
numhl = '',
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
signs_defined = true
|
|
||||||
end
|
|
||||||
end)()
|
|
||||||
|
|
||||||
local function get_bufnr(bufnr)
|
local function get_bufnr(bufnr)
|
||||||
if not bufnr or bufnr == 0 then
|
if not bufnr or bufnr == 0 then
|
||||||
return api.nvim_get_current_buf()
|
return api.nvim_get_current_buf()
|
||||||
@@ -618,6 +594,14 @@ end
|
|||||||
--- * priority: (number, default 10) Base priority to use for signs. When
|
--- * priority: (number, default 10) Base priority to use for signs. When
|
||||||
--- {severity_sort} is used, the priority of a sign is adjusted based on
|
--- {severity_sort} is used, the priority of a sign is adjusted based on
|
||||||
--- its severity. Otherwise, all signs use the same priority.
|
--- its severity. Otherwise, all signs use the same priority.
|
||||||
|
--- * text: (table) A table mapping |diagnostic-severity| to the sign text
|
||||||
|
--- to display in the sign column. The default is to use "E", "W", "I", and "H"
|
||||||
|
--- for errors, warnings, information, and hints, respectively. Example:
|
||||||
|
--- <pre>lua
|
||||||
|
--- vim.diagnostic.config({
|
||||||
|
--- sign = { text = { [vim.diagnostic.severity.ERROR] = 'E', ... } }
|
||||||
|
--- })
|
||||||
|
--- </pre>
|
||||||
--- - float: Options for floating windows. See |vim.diagnostic.open_float()|.
|
--- - float: Options for floating windows. See |vim.diagnostic.open_float()|.
|
||||||
--- - update_in_insert: (default false) Update diagnostics in Insert mode (if false,
|
--- - update_in_insert: (default false) Update diagnostics in Insert mode (if false,
|
||||||
--- diagnostics are updated on InsertLeave)
|
--- diagnostics are updated on InsertLeave)
|
||||||
@@ -868,8 +852,6 @@ M.handlers.signs = {
|
|||||||
diagnostics = filter_by_severity(opts.signs.severity, diagnostics)
|
diagnostics = filter_by_severity(opts.signs.severity, diagnostics)
|
||||||
end
|
end
|
||||||
|
|
||||||
define_default_signs()
|
|
||||||
|
|
||||||
-- 10 is the default sign priority when none is explicitly specified
|
-- 10 is the default sign priority when none is explicitly specified
|
||||||
local priority = opts.signs and opts.signs.priority or 10
|
local priority = opts.signs and opts.signs.priority or 10
|
||||||
local get_priority
|
local get_priority
|
||||||
@@ -890,22 +872,33 @@ M.handlers.signs = {
|
|||||||
end
|
end
|
||||||
|
|
||||||
local ns = M.get_namespace(namespace)
|
local ns = M.get_namespace(namespace)
|
||||||
if not ns.user_data.sign_group then
|
if not ns.user_data.sign_ns then
|
||||||
ns.user_data.sign_group = string.format('vim.diagnostic.%s', ns.name)
|
ns.user_data.sign_ns = api.nvim_create_namespace('')
|
||||||
|
end
|
||||||
|
|
||||||
|
local text = {}
|
||||||
|
for k in pairs(M.severity) do
|
||||||
|
if opts.signs.text and opts.signs.text[k] then
|
||||||
|
text[k] = opts.signs.text[k]
|
||||||
|
elseif type(k) == 'string' and not text[k] then
|
||||||
|
text[k] = string.sub(k, 1, 1):upper()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local sign_group = ns.user_data.sign_group
|
|
||||||
for _, diagnostic in ipairs(diagnostics) do
|
for _, diagnostic in ipairs(diagnostics) do
|
||||||
vim.fn.sign_place(0, sign_group, sign_highlight_map[diagnostic.severity], bufnr, {
|
if api.nvim_buf_is_loaded(diagnostic.bufnr) then
|
||||||
|
api.nvim_buf_set_extmark(bufnr, ns.user_data.sign_ns, diagnostic.lnum, 0, {
|
||||||
|
sign_text = text[diagnostic.severity] or text[M.severity[diagnostic.severity]] or 'U',
|
||||||
|
sign_hl_group = sign_highlight_map[diagnostic.severity],
|
||||||
priority = get_priority(diagnostic.severity),
|
priority = get_priority(diagnostic.severity),
|
||||||
lnum = diagnostic.lnum + 1,
|
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
hide = function(namespace, bufnr)
|
hide = function(namespace, bufnr)
|
||||||
local ns = M.get_namespace(namespace)
|
local ns = M.get_namespace(namespace)
|
||||||
if ns.user_data.sign_group and api.nvim_buf_is_valid(bufnr) then
|
if ns.user_data.sign_group and api.nvim_buf_is_valid(bufnr) then
|
||||||
vim.fn.sign_unplace(ns.user_data.sign_group, { buffer = bufnr })
|
api.nvim_buf_clear_namespace(bufnr, ns.user_data.sign_ns, 0, -1)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1080,9 +1080,19 @@ end)
|
|||||||
table.insert(virt_texts, (string.gsub(virt_text[i][2], "DiagnosticVirtualText", "")))
|
table.insert(virt_texts, (string.gsub(virt_text[i][2], "DiagnosticVirtualText", "")))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local ns = vim.diagnostic.get_namespace(diagnostic_ns)
|
||||||
|
local sign_ns = ns.user_data.sign_ns
|
||||||
local signs = {}
|
local signs = {}
|
||||||
for _, v in ipairs(vim.fn.sign_getplaced(diagnostic_bufnr, {group = "*"})[1].signs) do
|
local all_signs = vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, sign_ns, 0, -1, {type = 'sign', details = true})
|
||||||
table.insert(signs, (string.gsub(v.name, "DiagnosticSign", "")))
|
table.sort(all_signs, function(a, b)
|
||||||
|
return a[1] > b[1]
|
||||||
|
end)
|
||||||
|
|
||||||
|
for _, v in ipairs(all_signs) do
|
||||||
|
local s = v[4].sign_hl_group:gsub('DiagnosticSign', "")
|
||||||
|
if not vim.tbl_contains(signs, s) then
|
||||||
|
signs[#signs + 1] = s
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return {virt_texts, signs}
|
return {virt_texts, signs}
|
||||||
@@ -1498,7 +1508,15 @@ end)
|
|||||||
|
|
||||||
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
|
vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
|
||||||
|
|
||||||
return vim.fn.sign_getplaced(diagnostic_bufnr, {group = '*'})[1].signs
|
local ns = vim.diagnostic.get_namespace(diagnostic_ns)
|
||||||
|
local sign_ns = ns.user_data.sign_ns
|
||||||
|
|
||||||
|
local signs = vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, sign_ns, 0, -1, {type ='sign', details = true})
|
||||||
|
local result = {}
|
||||||
|
for _, s in ipairs(signs) do
|
||||||
|
result[#result + 1] = { lnum = s[2] + 1, name = s[4].sign_hl_group }
|
||||||
|
end
|
||||||
|
return result
|
||||||
]]
|
]]
|
||||||
|
|
||||||
eq({2, 'DiagnosticSignError'}, {result[1].lnum, result[1].name})
|
eq({2, 'DiagnosticSignError'}, {result[1].lnum, result[1].name})
|
||||||
|
|||||||
Reference in New Issue
Block a user