mirror of
https://github.com/neovim/neovim.git
synced 2025-09-27 21:48:35 +00:00
fix(diagnostic): show diagnostics on buffer load #35866
Problem: Diagnostics set on unloaded buffers are not shown when the buffer loads. Solution: Use `once_buf_loaded()` to show the diagnostics on BufRead is the buffer is not yet loaded.
This commit is contained in:

committed by
GitHub

parent
0790e08f52
commit
09266830bd
@@ -1636,45 +1636,43 @@ M.handlers.signs = {
|
|||||||
bufnr = vim._resolve_bufnr(bufnr)
|
bufnr = vim._resolve_bufnr(bufnr)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
if not api.nvim_buf_is_loaded(bufnr) then
|
once_buf_loaded(bufnr, function()
|
||||||
return
|
-- 10 is the default sign priority when none is explicitly specified
|
||||||
end
|
local priority = opts.signs and opts.signs.priority or 10
|
||||||
|
local get_priority = severity_to_extmark_priority(priority, opts)
|
||||||
|
|
||||||
-- 10 is the default sign priority when none is explicitly specified
|
local ns = M.get_namespace(namespace)
|
||||||
local priority = opts.signs and opts.signs.priority or 10
|
if not ns.user_data.sign_ns then
|
||||||
local get_priority = severity_to_extmark_priority(priority, opts)
|
ns.user_data.sign_ns =
|
||||||
|
api.nvim_create_namespace(string.format('nvim.%s.diagnostic.signs', ns.name))
|
||||||
local ns = M.get_namespace(namespace)
|
|
||||||
if not ns.user_data.sign_ns then
|
|
||||||
ns.user_data.sign_ns =
|
|
||||||
api.nvim_create_namespace(string.format('nvim.%s.diagnostic.signs', ns.name))
|
|
||||||
end
|
|
||||||
|
|
||||||
local text = {} ---@type table<vim.diagnostic.Severity|string, string>
|
|
||||||
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] = k:sub(1, 1):upper()
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
local numhl = opts.signs.numhl or {}
|
local text = {} ---@type table<vim.diagnostic.Severity|string, string>
|
||||||
local linehl = opts.signs.linehl or {}
|
for k in pairs(M.severity) do
|
||||||
|
if opts.signs.text and opts.signs.text[k] then
|
||||||
local line_count = api.nvim_buf_line_count(bufnr)
|
text[k] = opts.signs.text[k]
|
||||||
|
elseif type(k) == 'string' and not text[k] then
|
||||||
for _, diagnostic in ipairs(diagnostics) do
|
text[k] = k:sub(1, 1):upper()
|
||||||
if diagnostic.lnum <= line_count then
|
end
|
||||||
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],
|
|
||||||
number_hl_group = numhl[diagnostic.severity],
|
|
||||||
line_hl_group = linehl[diagnostic.severity],
|
|
||||||
priority = get_priority(diagnostic.severity),
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
local numhl = opts.signs.numhl or {}
|
||||||
|
local linehl = opts.signs.linehl or {}
|
||||||
|
|
||||||
|
local line_count = api.nvim_buf_line_count(bufnr)
|
||||||
|
|
||||||
|
for _, diagnostic in ipairs(diagnostics) do
|
||||||
|
if diagnostic.lnum <= line_count 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],
|
||||||
|
number_hl_group = numhl[diagnostic.severity],
|
||||||
|
line_hl_group = linehl[diagnostic.severity],
|
||||||
|
priority = get_priority(diagnostic.severity),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--- @param namespace integer
|
--- @param namespace integer
|
||||||
@@ -1697,45 +1695,43 @@ M.handlers.underline = {
|
|||||||
bufnr = vim._resolve_bufnr(bufnr)
|
bufnr = vim._resolve_bufnr(bufnr)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
if not api.nvim_buf_is_loaded(bufnr) then
|
once_buf_loaded(bufnr, function()
|
||||||
return
|
local ns = M.get_namespace(namespace)
|
||||||
end
|
if not ns.user_data.underline_ns then
|
||||||
|
ns.user_data.underline_ns =
|
||||||
local ns = M.get_namespace(namespace)
|
api.nvim_create_namespace(string.format('nvim.%s.diagnostic.underline', ns.name))
|
||||||
if not ns.user_data.underline_ns then
|
|
||||||
ns.user_data.underline_ns =
|
|
||||||
api.nvim_create_namespace(string.format('nvim.%s.diagnostic.underline', ns.name))
|
|
||||||
end
|
|
||||||
|
|
||||||
local underline_ns = ns.user_data.underline_ns
|
|
||||||
local get_priority = severity_to_extmark_priority(vim.hl.priorities.diagnostics, opts)
|
|
||||||
|
|
||||||
for _, diagnostic in ipairs(diagnostics) do
|
|
||||||
local higroup = underline_highlight_map[diagnostic.severity]
|
|
||||||
|
|
||||||
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
|
end
|
||||||
|
|
||||||
local lines =
|
local underline_ns = ns.user_data.underline_ns
|
||||||
api.nvim_buf_get_lines(diagnostic.bufnr, diagnostic.lnum, diagnostic.lnum + 1, true)
|
local get_priority = severity_to_extmark_priority(vim.hl.priorities.diagnostics, opts)
|
||||||
|
|
||||||
vim.hl.range(
|
for _, diagnostic in ipairs(diagnostics) do
|
||||||
bufnr,
|
local higroup = underline_highlight_map[diagnostic.severity]
|
||||||
underline_ns,
|
|
||||||
higroup,
|
if diagnostic._tags then
|
||||||
{ diagnostic.lnum, math.min(diagnostic.col, #lines[1] - 1) },
|
-- TODO(lewis6991): we should be able to stack these.
|
||||||
{ diagnostic.end_lnum, diagnostic.end_col },
|
if diagnostic._tags.unnecessary then
|
||||||
{ priority = get_priority(diagnostic.severity) }
|
higroup = 'DiagnosticUnnecessary'
|
||||||
)
|
end
|
||||||
end
|
if diagnostic._tags.deprecated then
|
||||||
save_extmarks(underline_ns, bufnr)
|
higroup = 'DiagnosticDeprecated'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local lines =
|
||||||
|
api.nvim_buf_get_lines(diagnostic.bufnr, diagnostic.lnum, diagnostic.lnum + 1, true)
|
||||||
|
|
||||||
|
vim.hl.range(
|
||||||
|
bufnr,
|
||||||
|
underline_ns,
|
||||||
|
higroup,
|
||||||
|
{ diagnostic.lnum, math.min(diagnostic.col, #lines[1] - 1) },
|
||||||
|
{ diagnostic.end_lnum, diagnostic.end_col },
|
||||||
|
{ priority = get_priority(diagnostic.severity) }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
save_extmarks(underline_ns, bufnr)
|
||||||
|
end)
|
||||||
end,
|
end,
|
||||||
hide = function(namespace, bufnr)
|
hide = function(namespace, bufnr)
|
||||||
local ns = M.get_namespace(namespace)
|
local ns = M.get_namespace(namespace)
|
||||||
@@ -1795,51 +1791,54 @@ M.handlers.virtual_text = {
|
|||||||
bufnr = vim._resolve_bufnr(bufnr)
|
bufnr = vim._resolve_bufnr(bufnr)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
if not api.nvim_buf_is_loaded(bufnr) then
|
once_buf_loaded(bufnr, function()
|
||||||
return
|
if opts.virtual_text then
|
||||||
end
|
if opts.virtual_text.format then
|
||||||
|
diagnostics = reformat_diagnostics(opts.virtual_text.format, diagnostics)
|
||||||
if opts.virtual_text then
|
end
|
||||||
if opts.virtual_text.format then
|
if
|
||||||
diagnostics = reformat_diagnostics(opts.virtual_text.format, diagnostics)
|
opts.virtual_text.source
|
||||||
|
and (opts.virtual_text.source ~= 'if_many' or count_sources(bufnr) > 1)
|
||||||
|
then
|
||||||
|
diagnostics = prefix_source(diagnostics)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if
|
|
||||||
opts.virtual_text.source
|
local ns = M.get_namespace(namespace)
|
||||||
and (opts.virtual_text.source ~= 'if_many' or count_sources(bufnr) > 1)
|
if not ns.user_data.virt_text_ns then
|
||||||
then
|
ns.user_data.virt_text_ns =
|
||||||
diagnostics = prefix_source(diagnostics)
|
api.nvim_create_namespace(string.format('nvim.%s.diagnostic.virtual_text', ns.name))
|
||||||
|
end
|
||||||
|
if not ns.user_data.virt_text_augroup then
|
||||||
|
ns.user_data.virt_text_augroup = api.nvim_create_augroup(
|
||||||
|
string.format('nvim.%s.diagnostic.virt_text', ns.name),
|
||||||
|
{ clear = true }
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
local ns = M.get_namespace(namespace)
|
api.nvim_clear_autocmds({ group = ns.user_data.virt_text_augroup, buffer = bufnr })
|
||||||
if not ns.user_data.virt_text_ns then
|
|
||||||
ns.user_data.virt_text_ns =
|
|
||||||
api.nvim_create_namespace(string.format('nvim.%s.diagnostic.virtual_text', ns.name))
|
|
||||||
end
|
|
||||||
if not ns.user_data.virt_text_augroup then
|
|
||||||
ns.user_data.virt_text_augroup = api.nvim_create_augroup(
|
|
||||||
string.format('nvim.%s.diagnostic.virt_text', ns.name),
|
|
||||||
{ clear = true }
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
api.nvim_clear_autocmds({ group = ns.user_data.virt_text_augroup, buffer = bufnr })
|
local line_diagnostics = diagnostic_lines(diagnostics, true)
|
||||||
|
|
||||||
local line_diagnostics = diagnostic_lines(diagnostics, true)
|
if opts.virtual_text.current_line ~= nil then
|
||||||
|
api.nvim_create_autocmd('CursorMoved', {
|
||||||
|
buffer = bufnr,
|
||||||
|
group = ns.user_data.virt_text_augroup,
|
||||||
|
callback = function()
|
||||||
|
render_virtual_text(
|
||||||
|
ns.user_data.virt_text_ns,
|
||||||
|
bufnr,
|
||||||
|
line_diagnostics,
|
||||||
|
opts.virtual_text
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
if opts.virtual_text.current_line ~= nil then
|
render_virtual_text(ns.user_data.virt_text_ns, bufnr, line_diagnostics, opts.virtual_text)
|
||||||
api.nvim_create_autocmd('CursorMoved', {
|
|
||||||
buffer = bufnr,
|
|
||||||
group = ns.user_data.virt_text_augroup,
|
|
||||||
callback = function()
|
|
||||||
render_virtual_text(ns.user_data.virt_text_ns, bufnr, line_diagnostics, opts.virtual_text)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
render_virtual_text(ns.user_data.virt_text_ns, bufnr, line_diagnostics, opts.virtual_text)
|
save_extmarks(ns.user_data.virt_text_ns, bufnr)
|
||||||
|
end)
|
||||||
save_extmarks(ns.user_data.virt_text_ns, bufnr)
|
|
||||||
end,
|
end,
|
||||||
hide = function(namespace, bufnr)
|
hide = function(namespace, bufnr)
|
||||||
local ns = M.get_namespace(namespace)
|
local ns = M.get_namespace(namespace)
|
||||||
@@ -2054,53 +2053,51 @@ M.handlers.virtual_lines = {
|
|||||||
bufnr = vim._resolve_bufnr(bufnr)
|
bufnr = vim._resolve_bufnr(bufnr)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
if not api.nvim_buf_is_loaded(bufnr) then
|
once_buf_loaded(bufnr, function()
|
||||||
return
|
local ns = M.get_namespace(namespace)
|
||||||
end
|
if not ns.user_data.virt_lines_ns then
|
||||||
|
ns.user_data.virt_lines_ns =
|
||||||
|
api.nvim_create_namespace(string.format('nvim.%s.diagnostic.virtual_lines', ns.name))
|
||||||
|
end
|
||||||
|
if not ns.user_data.virt_lines_augroup then
|
||||||
|
ns.user_data.virt_lines_augroup = api.nvim_create_augroup(
|
||||||
|
string.format('nvim.%s.diagnostic.virt_lines', ns.name),
|
||||||
|
{ clear = true }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
local ns = M.get_namespace(namespace)
|
api.nvim_clear_autocmds({ group = ns.user_data.virt_lines_augroup, buffer = bufnr })
|
||||||
if not ns.user_data.virt_lines_ns then
|
|
||||||
ns.user_data.virt_lines_ns =
|
|
||||||
api.nvim_create_namespace(string.format('nvim.%s.diagnostic.virtual_lines', ns.name))
|
|
||||||
end
|
|
||||||
if not ns.user_data.virt_lines_augroup then
|
|
||||||
ns.user_data.virt_lines_augroup = api.nvim_create_augroup(
|
|
||||||
string.format('nvim.%s.diagnostic.virt_lines', ns.name),
|
|
||||||
{ clear = true }
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
api.nvim_clear_autocmds({ group = ns.user_data.virt_lines_augroup, buffer = bufnr })
|
diagnostics =
|
||||||
|
reformat_diagnostics(opts.virtual_lines.format or format_virtual_lines, diagnostics)
|
||||||
|
|
||||||
diagnostics =
|
if opts.virtual_lines.current_line == true then
|
||||||
reformat_diagnostics(opts.virtual_lines.format or format_virtual_lines, diagnostics)
|
-- Create a mapping from line -> diagnostics so that we can quickly get the
|
||||||
|
-- diagnostics we need when the cursor line doesn't change.
|
||||||
|
local line_diagnostics = diagnostic_lines(diagnostics, true)
|
||||||
|
api.nvim_create_autocmd('CursorMoved', {
|
||||||
|
buffer = bufnr,
|
||||||
|
group = ns.user_data.virt_lines_augroup,
|
||||||
|
callback = function()
|
||||||
|
render_virtual_lines(
|
||||||
|
ns.user_data.virt_lines_ns,
|
||||||
|
bufnr,
|
||||||
|
diagnostics_at_cursor(line_diagnostics)
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
-- Also show diagnostics for the current line before the first CursorMoved event.
|
||||||
|
render_virtual_lines(
|
||||||
|
ns.user_data.virt_lines_ns,
|
||||||
|
bufnr,
|
||||||
|
diagnostics_at_cursor(line_diagnostics)
|
||||||
|
)
|
||||||
|
else
|
||||||
|
render_virtual_lines(ns.user_data.virt_lines_ns, bufnr, diagnostics)
|
||||||
|
end
|
||||||
|
|
||||||
if opts.virtual_lines.current_line == true then
|
save_extmarks(ns.user_data.virt_lines_ns, bufnr)
|
||||||
-- Create a mapping from line -> diagnostics so that we can quickly get the
|
end)
|
||||||
-- diagnostics we need when the cursor line doesn't change.
|
|
||||||
local line_diagnostics = diagnostic_lines(diagnostics, true)
|
|
||||||
api.nvim_create_autocmd('CursorMoved', {
|
|
||||||
buffer = bufnr,
|
|
||||||
group = ns.user_data.virt_lines_augroup,
|
|
||||||
callback = function()
|
|
||||||
render_virtual_lines(
|
|
||||||
ns.user_data.virt_lines_ns,
|
|
||||||
bufnr,
|
|
||||||
diagnostics_at_cursor(line_diagnostics)
|
|
||||||
)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
-- Also show diagnostics for the current line before the first CursorMoved event.
|
|
||||||
render_virtual_lines(
|
|
||||||
ns.user_data.virt_lines_ns,
|
|
||||||
bufnr,
|
|
||||||
diagnostics_at_cursor(line_diagnostics)
|
|
||||||
)
|
|
||||||
else
|
|
||||||
render_virtual_lines(ns.user_data.virt_lines_ns, bufnr, diagnostics)
|
|
||||||
end
|
|
||||||
|
|
||||||
save_extmarks(ns.user_data.virt_lines_ns, bufnr)
|
|
||||||
end,
|
end,
|
||||||
hide = function(namespace, bufnr)
|
hide = function(namespace, bufnr)
|
||||||
local ns = M.get_namespace(namespace)
|
local ns = M.get_namespace(namespace)
|
||||||
|
Reference in New Issue
Block a user