-
-
Notifications
You must be signed in to change notification settings - Fork 628
fix(#2519): Diagnostics Not Updated When Tree Not Visible #2597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
7bc3616
2baf3da
f30a8f6
7413041
e3c90fd
b8079fb
e6f343a
a15c8a9
b05f7e3
d7bd359
c37c895
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
local utils = require "nvim-tree.utils" | ||
local view = require "nvim-tree.view" | ||
local core = require "nvim-tree.core" | ||
local log = require "nvim-tree.log" | ||
|
||
local M = {} | ||
|
@@ -12,6 +11,16 @@ local severity_levels = { | |
Hint = 4, | ||
} | ||
|
||
--- A dictionary tree containing buffer-severity mappings. | ||
---@type table | ||
local buffer_severity_dict = {} | ||
|
||
---@param path string | ||
---@return string | ||
local function uniformize_path(path) | ||
return utils.canonical_path(path:gsub("\\", "/")) | ||
end | ||
|
||
---@return table | ||
local function from_nvim_lsp() | ||
local buffer_severity = {} | ||
|
@@ -25,11 +34,10 @@ local function from_nvim_lsp() | |
for _, diagnostic in ipairs(vim.diagnostic.get(nil, { severity = M.severity })) do | ||
local buf = diagnostic.bufnr | ||
if vim.api.nvim_buf_is_valid(buf) then | ||
local bufname = vim.api.nvim_buf_get_name(buf) | ||
local lowest_severity = buffer_severity[bufname] | ||
if not lowest_severity or diagnostic.severity < lowest_severity then | ||
buffer_severity[bufname] = diagnostic.severity | ||
end | ||
local bufname = uniformize_path(vim.api.nvim_buf_get_name(buf)) | ||
local severity = diagnostic.severity | ||
local highest_severity = buffer_severity[bufname] or severity | ||
buffer_severity[bufname] = math.min(highest_severity, severity) | ||
end | ||
end | ||
end | ||
|
@@ -55,19 +63,13 @@ local function from_coc() | |
return {} | ||
end | ||
|
||
local diagnostics = {} | ||
local buffer_severity = {} | ||
for _, diagnostic in ipairs(diagnostic_list) do | ||
local bufname = diagnostic.file | ||
local bufname = uniformize_path(diagnostic.file) | ||
local coc_severity = severity_levels[diagnostic.severity] | ||
|
||
local serverity = diagnostics[bufname] or vim.diagnostic.severity.HINT | ||
diagnostics[bufname] = math.min(coc_severity, serverity) | ||
end | ||
|
||
local buffer_severity = {} | ||
for bufname, severity in pairs(diagnostics) do | ||
if is_severity_in_range(severity, M.severity) then | ||
buffer_severity[bufname] = severity | ||
local highest_severity = buffer_severity[bufname] or coc_severity | ||
if is_severity_in_range(highest_severity, M.severity) then | ||
buffer_severity[bufname] = math.min(highest_severity, coc_severity) | ||
end | ||
end | ||
|
||
|
@@ -79,47 +81,52 @@ local function is_using_coc() | |
end | ||
|
||
function M.update() | ||
if not M.enable or not core.get_explorer() or not view.is_buf_valid(view.get_bufnr()) then | ||
if not M.enable then | ||
return | ||
end | ||
utils.debounce("diagnostics", M.debounce_delay, function() | ||
local profile = log.profile_start "diagnostics update" | ||
log.line("diagnostics", "update") | ||
|
||
local buffer_severity | ||
if is_using_coc() then | ||
buffer_severity = from_coc() | ||
buffer_severity_dict = from_coc() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. / nit no dict please - we're not writing python here ;) |
||
else | ||
buffer_severity = from_nvim_lsp() | ||
buffer_severity_dict = from_nvim_lsp() | ||
end | ||
|
||
local nodes_by_line = utils.get_nodes_by_line(core.get_explorer().nodes, core.get_nodes_starting_line()) | ||
for _, node in pairs(nodes_by_line) do | ||
node.diag_status = nil | ||
log.node("diagnostics", buffer_severity_dict, "update") | ||
log.profile_end(profile) | ||
if view.is_buf_valid(view.get_bufnr()) then | ||
require("nvim-tree.renderer").draw() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. / nit please require once at the start of the file |
||
end | ||
end) | ||
end | ||
|
||
---@param node Node | ||
function M.update_node_severity_level(node) | ||
if not M.enable then | ||
return | ||
end | ||
|
||
for bufname, severity in pairs(buffer_severity) do | ||
local bufpath = utils.canonical_path(bufname) | ||
log.line("diagnostics", " bufpath '%s' severity %d", bufpath, severity) | ||
if 0 < severity and severity < 5 then | ||
for line, node in pairs(nodes_by_line) do | ||
local nodepath = utils.canonical_path(node.absolute_path) | ||
log.line("diagnostics", " %d checking nodepath '%s'", line, nodepath) | ||
|
||
local node_contains_buf = vim.startswith(bufpath:gsub("\\", "/"), nodepath:gsub("\\", "/") .. "/") | ||
if M.show_on_dirs and node_contains_buf and (not node.open or M.show_on_open_dirs) then | ||
log.line("diagnostics", " matched fold node '%s'", node.absolute_path) | ||
node.diag_status = severity | ||
elseif nodepath == bufpath then | ||
log.line("diagnostics", " matched file node '%s'", node.absolute_path) | ||
node.diag_status = severity | ||
local is_folder = node.nodes ~= nil | ||
local nodepath = uniformize_path(node.absolute_path) | ||
|
||
if is_folder then | ||
local max_severity = nil | ||
if M.show_on_dirs and (not node.open or M.show_on_open_dirs) then | ||
for bufname, severity in pairs(buffer_severity_dict) do | ||
local node_contains_buf = vim.startswith(bufname, nodepath .. "/") | ||
if node_contains_buf then | ||
if severity == M.severity.max then | ||
max_severity = severity | ||
break | ||
else | ||
max_severity = math.min(max_severity or severity, severity) | ||
end | ||
end | ||
end | ||
end | ||
log.profile_end(profile) | ||
require("nvim-tree.renderer").draw() | ||
end) | ||
node.diag_status = max_severity | ||
else | ||
node.diag_status = buffer_severity_dict[nodepath] | ||
end | ||
end | ||
|
||
function M.setup(opts) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -413,6 +413,8 @@ end | |
function Builder:_build_line(node, idx, num_children, unloaded_bufnr) | ||
local copy_paste = require "nvim-tree.actions.fs.copy-paste" | ||
|
||
require("nvim-tree.diagnostics").update_node_severity_level(node) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one is very concerning from a performance perspective; we go out of our way to avoid such calls on drawing each line. Could we improve via one of:
|
||
|
||
-- various components | ||
local indent_markers = pad.get_indent_markers(self.depth, idx, num_children, node, self.markers) | ||
local arrows = pad.get_arrows(node) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice name!