mirror of
https://github.com/folke/snacks.nvim
synced 2025-07-07 21:25:11 +00:00
perf(explorer): only update tree when diagnostics actually changed
This commit is contained in:
parent
06400568aa
commit
1142f46a27
3 changed files with 57 additions and 4 deletions
|
@ -6,6 +6,8 @@ function M.update(cwd)
|
|||
local Tree = require("snacks.explorer.tree")
|
||||
local node = Tree:find(cwd)
|
||||
|
||||
local snapshot = Tree:snapshot(node, { "severity" })
|
||||
|
||||
Tree:walk(node, function(n)
|
||||
n.severity = nil
|
||||
end, { all = true })
|
||||
|
@ -31,6 +33,8 @@ function M.update(cwd)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Tree:changed(node, snapshot)
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
---@field exclude? string[] globs to exclude
|
||||
---@field include? string[] globs to exclude
|
||||
|
||||
---@alias snacks.picker.explorer.Snapshot {fields: string[], state:table<snacks.picker.explorer.Node, any[]>}
|
||||
|
||||
local uv = vim.uv or vim.loop
|
||||
|
||||
local function norm(path)
|
||||
|
@ -331,4 +333,42 @@ function Tree:next(cwd, filter, opts)
|
|||
return next or first
|
||||
end
|
||||
|
||||
---@param node snacks.picker.explorer.Node
|
||||
---@param snapshot snacks.picker.explorer.Snapshot
|
||||
function Tree:changed(node, snapshot)
|
||||
local old = snapshot.state
|
||||
local current = self:snapshot(node, snapshot.fields).state
|
||||
if vim.tbl_count(current) ~= vim.tbl_count(old) then
|
||||
return true
|
||||
end
|
||||
for n, data in pairs(current) do
|
||||
local prev = old[n]
|
||||
if not prev then
|
||||
return true
|
||||
end
|
||||
if not vim.deep_equal(prev, data) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
---@param node snacks.picker.explorer.Node
|
||||
---@param fields string[]
|
||||
function Tree:snapshot(node, fields)
|
||||
---@type snacks.picker.explorer.Snapshot
|
||||
local ret = {
|
||||
state = {},
|
||||
fields = fields,
|
||||
}
|
||||
Tree:walk(node, function(n)
|
||||
local data = {} ---@type any[]
|
||||
for f, field in ipairs(fields) do
|
||||
data[f] = n[field]
|
||||
end
|
||||
ret.state[n] = data
|
||||
end, { all = true })
|
||||
return ret
|
||||
end
|
||||
|
||||
return Tree.new()
|
||||
|
|
|
@ -72,12 +72,21 @@ function State.new(picker)
|
|||
end)
|
||||
|
||||
if opts.diagnostics then
|
||||
picker.list.win:on("DiagnosticChanged", function(_, ev)
|
||||
local dirty = false
|
||||
local diag_update = Snacks.util.debounce(function()
|
||||
dirty = false
|
||||
local p = ref()
|
||||
if p then
|
||||
require("snacks.explorer.diagnostics").update(p:cwd())
|
||||
p.list:set_target()
|
||||
p:find()
|
||||
if require("snacks.explorer.diagnostics").update(p:cwd()) then
|
||||
p.list:set_target()
|
||||
p:find()
|
||||
end
|
||||
end
|
||||
end, { ms = 200 })
|
||||
picker.list.win:on({ "InsertLeave", "DiagnosticChanged" }, function(_, ev)
|
||||
dirty = dirty or ev.event == "DiagnosticChanged"
|
||||
if vim.fn.mode() == "n" and dirty then
|
||||
diag_update()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue