Skip to content

feat: resume last picker (#405)#438

Merged
dmtrKovalenko merged 4 commits into
dmtrKovalenko:mainfrom
thuan1412:feat/resume-last-picker
Jun 14, 2026
Merged

feat: resume last picker (#405)#438
dmtrKovalenko merged 4 commits into
dmtrKovalenko:mainfrom
thuan1412:feat/resume-last-picker

Conversation

@thuan1412

@thuan1412 thuan1412 commented May 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the ability to resume the last closed picker, similar to Telescope's resume(). The full picker state (query, results, cursor, mode, pagination, etc.) is saved before closing and restored on resume.

Changes

  • lua/fff/picker_ui.lua: Core resume logic

    • save_state_and_close() — saves full picker state before closing, routed to mode-specific slot (file vs grep)
    • restore_from_state() — shared helper to restore picker from a saved snapshot
    • M.resume() — resumes the most recently closed picker (any mode)
    • M.resume_find_files(opts) — resumes last file picker, falls back to find_files
    • M.resume_live_grep(opts) — resumes last grep picker, falls back to live_grep
  • lua/fff/main.lua: Public API

    • find_files({ resume = true }) — resume last file picker or open new
    • live_grep({ resume = true }) — resume last grep picker or open new
    • resume() — resume last closed picker (generic)
  • plugin/fff.lua: User command

    • :FFFResume — resume last closed picker

Usage

" Resume last closed picker
:FFFResume

" Or pass resume flag to find_files/live_grep
:lua require('fff').find_files({ resume = true })
:lua require('fff').live_grep({ resume = true })

Demo

Screen.Recording.2026-05-03.at.08.18.29.mov

Closes #405

@thuan1412 thuan1412 force-pushed the feat/resume-last-picker branch from 73c3655 to 9d6b287 Compare May 2, 2026 14:07
@dmtrKovalenko

Copy link
Copy Markdown
Owner

cool thank you let me know when its ready

@thuan1412 thuan1412 marked this pull request as ready for review May 3, 2026 01:29
@thuan1412

Copy link
Copy Markdown
Contributor Author

Hi @dmtrKovalenko , the PR is ready for review. I'm happy to update/rewrite if we have better approach!

Comment thread lua/fff/picker_ui.lua Outdated
Comment thread lua/fff/picker_ui.lua Outdated
Comment thread lua/fff/picker_ui.lua Outdated
@thuan1412

Copy link
Copy Markdown
Contributor Author

Thanks for the review @dmtrKovalenko , i've addressed the comments.

@thuan1412 thuan1412 requested a review from dmtrKovalenko May 9, 2026 01:37
@dmtrKovalenko

Copy link
Copy Markdown
Owner

oh well looking into these changes I think this is again wrong I made a wrong suggestion origianlly I am sorry

what we actually want to persist is query, right? I mean we never know how results would change in between there is no reason to store the items if the files were deleted, or the order of file items would change as well?

I can try to update the PR myself I am sorry for kicking you back and forth

@thuan1412

Copy link
Copy Markdown
Contributor Author

No problem @dmtrKovalenko, i can update the PR. Do you mean this suggestion #438 (comment)?

@thuan1412

Copy link
Copy Markdown
Contributor Author

@dmtrKovalenko I have spent a bit of time reviewing which fields on the state to be stored and can't make a conclusion, since there's a lot, and testing each when toggle the field takes time. So need your suggestion on choosing which field on M.state to be stored for the resume.

Regarding the current implementation, I've tested with cases where the results changed between 2 searches, and it works fine.

@thuan1412

Copy link
Copy Markdown
Contributor Author

Also, just push a new commit to handle empty query case, we shouldn't save the state when query is empty

@thuan1412 thuan1412 force-pushed the feat/resume-last-picker branch from 4be3f1c to d3c0284 Compare June 2, 2026 15:16
@thuan1412

Copy link
Copy Markdown
Contributor Author

Hi @dmtrKovalenko , please help take a look at this PR again when u have time. Thank you!

@dmtrKovalenko

Copy link
Copy Markdown
Owner

@gustav-fff please rebase this PR and fix any CI issues (in a separate commit if they are not flaky) tag me here when you done

@gustav-fff

Copy link
Copy Markdown
Collaborator

[triage-bot] DIRECTED: cannot rebase cleanly — needs re-implementation, not a rebase.

PR head is thuan1412/fff:feat/resume-last-picker (cross-repo fork) so I cannot push directly. Beyond that, the rebase onto current main does NOT auto-merge:

CONFLICT (modify/delete): lua/fff/picker_ui.lua deleted in HEAD and modified in 9d6b287 (feat: resume last picker (#405)).
CONFLICT (content): Merge conflict in lua/fff/main.lua

lua/fff/picker_ui.lua was split into focused submodules in #564 (refactor(nvim): split monolithic picker_ui.lua). The resume feature here lives entirely in the old monolithic file and must be re-homed across the new modules (combo_renderer.lua, file_renderer.lua, list_renderer.lua, etc.). Not a mechanical rebase.

CI status: only red check is Stress Test (Watcher + Git) (windows-latest) — flaky, fails on main too (runs 27481875741, 27392116278, 27325172168 all hit the same fuzz_git_watcher_stress::stress_random panic on a freshly merged main commit). Not caused by this branch.

Also: your 2026-05-12 review point (persist only query, not the full snapshot) is still unaddressed — that's the bigger blocker and changes which file the resume code even belongs in.

Suggested next step: reduce scope to "save query (+ mode) only" and re-target against the post-#564 module layout. Happy to take a swing at that as a fresh branch if you want — tag me with the go-ahead.

Honk-Honk 🪿

Add ability to resume the last closed picker with full state (query,
results, cursor, mode) by adapting for the refactored module structure.

In the coordinator (picker_ui.lua):
- save_state_and_close() deep-copies picker state before closing
- restore_from_state() recreates UI from saved snapshot
- M.close() overrides the wired close to save state then call close_windows
- M.resume(), M.resume_find_files(), M.resume_live_grep() public API
- Per-mode saved state (find_files vs live_grep)

In layout_manager.lua:
- Extracted close_windows() as the low-level cleanup
- close() now delegates to close_windows()

In main.lua:
- find_files and live_grep support opts.resume
- M.resume() public API for :FFFResume command

plugin/fff.lua:
- :FFFResume user command
@thuan1412 thuan1412 force-pushed the feat/resume-last-picker branch from 2a2f715 to d36ef1b Compare June 14, 2026 05:32
@thuan1412

Copy link
Copy Markdown
Contributor Author

@dmtrKovalenko i've rebased main, please help take a look when u have time!

@dmtrKovalenko dmtrKovalenko left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that it works, I'll merge it to unblock just will ask @gustav-fff to create a new PR on top of main with the suggestions I have applied

I'll take it from there

local snapshot = vim.deepcopy(M.state)

local fuzzy = require('fff.core').ensure_initialized()
local ok, base_path = pcall(fuzzy.get_base_path)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be using state from config here but it's okay


-- Resume state: saved snapshots of closed pickers for the resume feature.
--- @type table|nil Saved state from last file picker (find_files) session
local last_file_picker_state = nil

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put this to a one object

---@return boolean|nil true if a picker was resumed, false otherwise
function M.resume()
if M.state.active then
vim.notify('FFF: close the current picker before resuming', vim.log.levels.INFO)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do this? Can we enforce recreation it if the user simply wants to get previous results?

@dmtrKovalenko dmtrKovalenko merged commit 1fba10c into dmtrKovalenko:main Jun 14, 2026
46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: resume last picker

3 participants