Skip to content

Snacks explorer: visible jump when follow_file expands and scrolls after first render #2945

Description

@li-zck

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:

  1. find() walks the current (collapsed) tree -> first paint at root.
  2. 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

  1. Open a file several folders deep in a project.
  2. Open the explorer with follow_file = true set.
  3. Observe: tree paints at root/collapsed first, then visibly jumps to expand+scroll to the open file.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions