feat(explorer): added quick nav with [, ] with d/w/e for diagnostics

This commit is contained in:
Folke Lemaitre 2025-02-07 08:59:35 +01:00
parent c55dabb0d8
commit d1d55850ec
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040
4 changed files with 65 additions and 25 deletions

View file

@ -1,6 +1,10 @@
local Git = require("snacks.explorer.git")
local Tree = require("snacks.explorer.tree")
---@class snacks.explorer.diagnostic.Action: snacks.picker.Action
---@field severity? number
---@field up? boolean
local uv = vim.uv or vim.loop
local M = {}
@ -260,4 +264,24 @@ function M.actions.confirm(picker, item, action)
end
end
function M.actions.explorer_diagnostic(picker, item, action)
---@cast action snacks.explorer.diagnostic.Action
local node = Tree:next(picker:cwd(), function(node)
if not node.severity then
return false
end
return action.severity == nil or node.severity == action.severity
end, { up = action.up, path = item and item.file })
if node then
M.update(picker, { target = node.path })
end
end
M.actions.explorer_diagnostic_next = { action = "explorer_diagnostic" }
M.actions.explorer_diagnostic_prev = { action = "explorer_diagnostic", up = true }
M.actions.explorer_warn_next = { action = "explorer_diagnostic", severity = vim.diagnostic.severity.WARN }
M.actions.explorer_warn_prev = { action = "explorer_diagnostic", severity = vim.diagnostic.severity.WARN, up = true }
M.actions.explorer_error_next = { action = "explorer_diagnostic", severity = vim.diagnostic.severity.ERROR }
M.actions.explorer_error_prev = { action = "explorer_diagnostic", severity = vim.diagnostic.severity.ERROR, up = true }
return M

View file

@ -149,31 +149,9 @@ end
---@param up? boolean
function M.next(cwd, path, up)
local Tree = require("snacks.explorer.tree")
path = path or cwd
local root = Tree:node(cwd) or nil
if not root then
return
end
local first ---@type snacks.picker.explorer.Node?
local last ---@type snacks.picker.explorer.Node?
local prev ---@type snacks.picker.explorer.Node?
local next ---@type snacks.picker.explorer.Node?
local found = false
Tree:walk(root, function(node)
local want = not node.dir and node.status and not node.ignored
if node.path == path then
found = true
end
if want then
first, last = first or node, node
next = next or (found and node.path ~= path and node) or nil
prev = not found and node or prev
end
end, { all = true })
if up then
return prev or last
end
return next or first
return Tree:next(cwd, function(node)
return node.status ~= nil
end, { up = up, path = path })
end
return M

View file

@ -271,4 +271,36 @@ function Tree:close_all(cwd)
end, { all = true })
end
---@param cwd string
---@param filter fun(node: snacks.picker.explorer.Node):boolean?
---@param opts? {up?: boolean, path?: string}
function Tree:next(cwd, filter, opts)
opts = opts or {}
local path = opts.path or cwd
local root = self:node(cwd) or nil
if not root then
return
end
local first ---@type snacks.picker.explorer.Node?
local last ---@type snacks.picker.explorer.Node?
local prev ---@type snacks.picker.explorer.Node?
local next ---@type snacks.picker.explorer.Node?
local found = false
self:walk(root, function(node)
local want = not node.dir and filter(node) and not node.ignored
if node.path == path then
found = true
end
if want then
first, last = first or node, node
next = next or (found and node.path ~= path and node) or nil
prev = not found and node or prev
end
end, { all = true })
if opts.up then
return prev or last
end
return next or first
end
return Tree.new()

View file

@ -93,6 +93,12 @@ M.explorer = {
["Z"] = "explorer_close_all",
["]g"] = "explorer_git_next",
["[g"] = "explorer_git_prev",
["]d"] = "explorer_diagnostic_next",
["[d"] = "explorer_diagnostic_prev",
["]w"] = "explorer_warn_next",
["[w"] = "explorer_warn_prev",
["]e"] = "explorer_error_next",
["[e"] = "explorer_error_prev",
},
},
},