Description
When opening Snacks.explorer() with follow_file = true, the tree visibly renders once at its default/collapsed state (root level) and then, a moment later, jumps - expanding the parent folders of the currently open file and scrolling the cursorline to it. This is a noticeable two-step flash rather than opening already-focused on the current file.
Root cause (as far as I can trace it)
In lua/snacks/picker/source/explorer.lua, the follow_file support wires up on_find and hands it to the matcher task's done event:
return function(cb)
if on_find then
assert(ctx.picker.matcher.task:running())
ctx.picker.matcher.task:on("done", vim.schedule_wrap(on_find))
end
local items = {}
local top = Tree:find(ctx.filter.cwd)
...
Tree:find(ctx.filter.cwd) walks the current in-memory tree expand state, which on a fresh explorer open starts fully collapsed. The actual expand-and-scroll-to-file logic lives in on_find (lua/snacks/explorer/actions.lua, M.update), which calls Tree:open(target) and re-runs picker:find(...) - but this only fires after the matcher task's done event, i.e. after the first (collapsed) render has already been produced and painted.
So there are structurally two passes:
find() walks the current (collapsed) tree -> first paint at root.
- Matcher task completes ->
on_find fires -> Tree:open(target) expands + re-finds -> second paint, now scrolled to the file.
Since the first paint happens synchronously before the matcher task can possibly be "done," there's no way to reach an already-expanded first frame via existing config (I tried git_status = false to rule out git-status fetching as the gate - it's not; the jump persists regardless).
Expected behavior
When follow_file = true, the explorer would ideally compute the expanded-path state for the target file (a synchronous filesystem walk of just the ancestor directories, not the full tree) before the first find()/paint, so the initial render already shows the correct folders expanded and cursor on the current file - no visible jump.
Environment
- snacks.nvim: 882c996
- Neovim: v0.12.5
- OS: macOS
Reproduction
- Open a file several folders deep in a project.
- Open the explorer with
follow_file = true set.
- Observe: tree paints at root/collapsed first, then visibly jumps to expand+scroll to the open file.
Description
When opening
Snacks.explorer()withfollow_file = true, the tree visibly renders once at its default/collapsed state (root level) and then, a moment later, jumps - expanding the parent folders of the currently open file and scrolling the cursorline to it. This is a noticeable two-step flash rather than opening already-focused on the current file.Root cause (as far as I can trace it)
In
lua/snacks/picker/source/explorer.lua, thefollow_filesupport wires upon_findand hands it to the matcher task'sdoneevent:Tree:find(ctx.filter.cwd)walks the current in-memory tree expand state, which on a fresh explorer open starts fully collapsed. The actual expand-and-scroll-to-file logic lives inon_find(lua/snacks/explorer/actions.lua,M.update), which callsTree:open(target)and re-runspicker:find(...)- but this only fires after the matcher task'sdoneevent, i.e. after the first (collapsed) render has already been produced and painted.So there are structurally two passes:
find()walks the current (collapsed) tree -> first paint at root.on_findfires ->Tree:open(target)expands + re-finds -> second paint, now scrolled to the file.Since the first paint happens synchronously before the matcher task can possibly be "done," there's no way to reach an already-expanded first frame via existing config (I tried
git_status = falseto rule out git-status fetching as the gate - it's not; the jump persists regardless).Expected behavior
When
follow_file = true, the explorer would ideally compute the expanded-path state for the target file (a synchronous filesystem walk of just the ancestor directories, not the full tree) before the firstfind()/paint, so the initial render already shows the correct folders expanded and cursor on the current file - no visible jump.Environment
Reproduction
follow_file = trueset.