Skip to content

feat(pick): preview the highlighted message while the picker is open - #54

Merged
backnotprop merged 1 commit into
plannotator:mainfrom
Triyambak-CA:feat/picker-live-preview
Sep 1, 2026
Merged

feat(pick): preview the highlighted message while the picker is open#54
backnotprop merged 1 commit into
plannotator:mainfrom
Triyambak-CA:feat/picker-live-preview

Conversation

@Triyambak-CA

Copy link
Copy Markdown
Contributor

The itch

Running several agents against one repo, herdr last regularly gives me a dozen-plus candidates. The picker lists them one line each, but the document behind it is always the newest, so choosing means: Enter, read, p, Enter on the next one, read, and so on. The list tells me a timestamp and a truncated first line, which often is not enough to tell two replies apart.

Moving the cursor now swaps the document underneath and stays in the picker, so the list becomes browsable.

What changed

  • show_candidate(index) swaps the open document without leaving Mode::Pick; j/k/arrows call it.
  • open_candidate is now show_candidate plus the mode change and status line, so Enter behaves exactly as before.
  • Esc returns to whatever was open when the picker appeared. In the common case that is still the newest, so escaping_the_picker_keeps_the_newest_message passes unchanged; when p reopens the picker mid-review it now puts you back where you were instead of leaving a preview showing.
  • Footer reads ↑↓ preview · enter open · esc cancel · q quit.

The one non-obvious bit

Previewing swaps Open, and Open owns the Store. A reply review's store is transient, so a naive swap would silently discard annotations the moment someone touched an arrow key. The document being left is therefore kept in a small map keyed by candidate index and restored on the way back.

That hole exists today on Enter too: annotate the newest, p, Enter on another, and the annotations are gone. This closes it as a side effect rather than widening it.

Memory is bounded by the candidate count, and only visited candidates are ever built.

Tests

Two, one per invariant, in app/tests.rs alongside the existing picker tests:

  • moving_the_picker_cursor_previews_that_message - the document follows the cursor and the picker stays open
  • previewing_away_and_back_keeps_annotations - annotate, p, j, k, and the annotation is still there

cargo fmt --all --check, cargo clippy --workspace --all-targets and cargo test --workspace are all clean on 1.97.1. 34 tests pass.

Note on performance

AGENTS.md says never reparse a whole document on an edit. This reparses on a selection change, not an edit, and only the first time each candidate is visited; after that it comes from the map. Agent replies are small. Happy to add a cap on cached documents if you would rather bound it explicitly.

Context for why I was in here: #53. This does not fix that issue, it is a separate annoyance I hit while testing it.

The picker listed candidates but always showed the newest behind them, so
choosing meant opening a message, reading it, backing out and trying the next
one. Moving the cursor now swaps the document underneath and stays in the
picker, which is what the list is for.

The document being left is kept rather than dropped. A reply review's store is
transient, so previewing away from an annotated message and back would
otherwise lose the annotations; Enter had the same hole.

Esc returns to whatever was open when the picker appeared, so escaping still
leaves the newest message open in the common case, and returns you where you
were when `p` reopened the picker mid-review. Footer updated to match.
@backnotprop
backnotprop force-pushed the feat/picker-live-preview branch from cca1005 to 7bad5b1 Compare September 1, 2026 18:07
@backnotprop
backnotprop added this pull request to the merge queue Sep 1, 2026
Merged via the queue into plannotator:main with commit 983d107 Sep 1, 2026
2 checks passed
@backnotprop

Copy link
Copy Markdown
Contributor

Merged, with the annotation-cache design appreciated in particular — closing an existing data-loss hole as a side effect of the feature is the good kind of side effect. I rebased over #55 (two trivial keep-both hunks in the App struct) using the maintainer-edit permission; the squash is otherwise your commit. Both picker features ship in the next release. Thanks for the #53 investigation too — the follow-up it earned lives in #57.

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.

2 participants