fix(picker/fzf): bugfix pass — hide/resume opt-out + reload action field index#303
Merged
barrettruth merged 2 commits intomainfrom Apr 17, 2026
Merged
fix(picker/fzf): bugfix pass — hide/resume opt-out + reload action field index#303barrettruth merged 2 commits intomainfrom
barrettruth merged 2 commits intomainfrom
Conversation
Forge already manages its own picker navigation and back flow through the back action and picker sessions. fzf-lua's default hide/resume state would keep older pickers alive in its own stack, so aborting the current picker with <c-c> could surface a stale session from an earlier flow instead of fully exiting. Pass no_hide = true and no_resume = true to fzf_exec so the hide-stack is never populated and <c-c> terminates the active forge picker flow cleanly. Adds a regression test asserting both flags are on captured.opts for any forge picker.
Pickers that use entry_source mark every action as reload=true.
fzf-lua converts those into fzf-level execute-silent(...)+reload(...)
binds via shell.stringify_data2(fn, opts, field_index or "{+}"). With
the default "{+}" placeholder, fzf expands the full tab-delimited
line when the bind fires.
selected_index expects the index column to be the last tab-delimited
field. That held before #300 (line layout track_id<TAB>text<TAB>index).
#300 appended a per-row header column whenever a dynamic label was
present, shifting the layout to track_id<TAB>text<TAB>index<TAB>header,
so the trailing-digits regex started matching the numeric track_id (or
nothing at all) and every reload action in the CI picker dispatched
with entry = nil, silently no-oping.
Pin field_index on each reload-mode action to the index column:
"{3}" for tracked pickers, "{2}" for untracked. fzf now passes just
the index string to action_fn, matching what --accept-nth already
does for non-reload actions, and works identically whether or not
the hidden header column is present.
Adds regression tests asserting the field_index value on tracked
and untracked pickers, plus a dispatch round-trip.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Two picker bugs after #300:
<c-c>on a forge picker could revive an older fzf-lua session instead of cleanly exiting. fzf-lua's default hide/resume behavior keeps a stack of previously-run pickers and restores the previous one on abort, which conflicts with forge's own back-flow navigation.entry_source), every action is registered withreload = true. fzf-lua converts those into fzf-levelexecute-silent(...)+reload(...)binds viashell.stringify_data2(fn, opts, v.field_index or "{+}"). We never setfield_index, so fzf expanded the full tab-delimited line.selected_indexexpected the last\t(%d+)$to be the index column — true before feat(pickers): unify <c-s> state toggle across pr, issue, ci with per-row labels #300, but feat(pickers): unify <c-s> state toggle across pr, issue, ci with per-row labels #300 appended a per-row header column after the index whenever a dynamic label was present, so the regex either matched the numerictrack_idat the head or nothing at all. Every reload action (including<cr>,<c-w>,<c-x>in the CI picker) dispatched withentry = niland silently no-oped.Solution
Two independent commits on this branch:
fix(picker/fzf): opt out of fzf-lua hide/resume so <c-c> fully exits— passno_hide = trueandno_resume = truetofzf_exec. Forge manages its own picker navigation (back action + picker session) so fzf-lua's hide-stack is unnecessary and actively harmful here.fix(picker/fzf): pass only the index field to reload actions— setfield_index = tracked and '{3}' or '{2}'on each reload-mode action. fzf now passes just the index column toaction_fn, matching what--accept-nthalready does for non-reload actions, and works identically whether or not the hidden header column is present.Regression tests added for both:
no_hide/no_resumeon any forge picker, andfield_indexplus a dispatch round-trip on tracked/untracked pickers. 502 busted tests, full local CI clean (stylua / selene / prettier / nix fmt / lua-language-server / vimdoc-language-server / busted).Supersedes #302.