Skip to content

fix: Menu Viewport Scrolling#28

Merged
sahil-noon merged 4 commits into
mainfrom
260705-3wr8-menu-viewport-scrolling
Jul 5, 2026
Merged

fix: Menu Viewport Scrolling#28
sahil-noon merged 4 commits into
mainfrom
260705-3wr8-menu-viewport-scrolling

Conversation

@sahil-noon

Copy link
Copy Markdown
Collaborator

Meta

Change ID Type Confidence Plan Review
3wr8 fix 3.8/5.0 12/12 tasks, 21/21 acceptance ✓ ✓ 3 cycles
Impact +/− Net
raw +1220 / −42 +1178
true +780 / −33 +747
└ impl +322 / −29 +293
└ tests +458 / −4 +454

excludes fab/, docs/ · generated by fab-kit v2.13.4

Pipeline: intake ✓ → apply ✓ → review ✓ → hydrate ✓ → ship → review-pr

Summary

The interactive arrow-key menu renderer had no concept of terminal height: menus taller than the terminal scrolled into scrollback on first paint, and the cursor-up in-place redraw couldn't reach rows that had scrolled off, so repaints re-emitted the whole menu on every keystroke and earlier rows became permanently unreachable with arrow keys. This adds an fzf/gum-style scrolling viewport to the shared renderer so rowsRendered never exceeds terminal height, restoring full arrow-key reachability across all menus.

Changes

  • Terminal-height-aware window
  • Window offset in menuState
  • Row slicing in renderRows + overflow indicators
  • PageUp/PageDown — out of scope for this change
  • Explicitly rejected alternatives (user-confirmed this session)
  • What does NOT change
  • Tests (Constitution Principle IV)

sahil87 added 2 commits July 5, 2026 17:55
Menus taller than the terminal broke arrow-key navigation and leaked
scrollback on every repaint. The shared renderer now windows rows to
terminal height (term.GetSize, 24-row fallback), tracks a scroll
offset in menuState, and shows up/down overflow indicators — fixing
all 11 call sites through the single ShowMenu/MenuSession primitive.
@sahil-noon sahil-noon marked this pull request as ready for review July 5, 2026 12:27
@sahil-noon sahil-noon requested a review from Copilot July 5, 2026 12:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes interactive menus that are taller than the terminal by introducing a terminal-height-aware scrolling viewport inside the shared menu renderer, ensuring arrow-key navigation remains usable without repainting into scrollback.

Changes:

  • Added a pure menuLayout viewport calculator and menuState.top window offset, with overflow indicators and a “drop chrome on cramped heights” rule to maintain a safe repaint footprint.
  • Threaded an injectable heightFn (production uses term.GetSize with a 24-row fallback) through the interactive render path so windowing is PTY-free testable.
  • Expanded unit tests to cover layout invariants, byte-equality between paint/redraw, shrink hardening, and the GetSize fallback; updated CLI memory docs to reflect the new viewport contract.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/internal/worktree/menu.go Implements viewport windowing (layout + rendering) and injects terminal height into the interactive menu core.
src/internal/worktree/menu_test.go Adds comprehensive PTY-free tests for windowing invariants, rendering, shrink hardening, and height fallback.
fab/changes/260705-3wr8-menu-viewport-scrolling/plan.md Captures requirements, non-goals, and acceptance criteria for the viewport change.
fab/changes/260705-3wr8-menu-viewport-scrolling/intake.md Records the diagnosed bug, chosen approach, and explicit rejections/out-of-scope items.
fab/changes/260705-3wr8-menu-viewport-scrolling/.status.yaml Tracks fab pipeline status/metrics for this change.
fab/changes/260705-3wr8-menu-viewport-scrolling/.history.jsonl Records fab stage transition history for auditability.
docs/memory/wt-cli/menu-navigation-contract.md Updates the documented menu navigation and redraw/viewport invariants (including PageUp/PageDown staying ignored).
docs/memory/wt-cli/index.md Updates the memory index entry to reflect the viewport-enhanced contract description.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/internal/worktree/menu.go Outdated
Comment on lines +892 to +896
// rowsRendered tracks how many lines the menu currently occupies on
// screen so the next redraw knows how far up to move the cursor.
// The menu region is: 1 prompt line + len(options) option rows +
// 1 Cancel row = len(options) + 2 lines.
rowsRendered := paintMenu(w, prompt, options, state)
// screen so the next redraw knows how far up to move the cursor. It is the
// *windowed* row count (1 prompt + indicators + visible options + 1 Cancel)
// and never exceeds the terminal height — this is what keeps the cursor-up
// in-place redraw sound for lists taller than the terminal.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed — aligned the rowsRendered doc comment with menuLayout's invariant: the footprint stays within height-1 (one reserved row), overshooting only at degenerate heights 1–3 via the ≥1-option escape hatch. (dbe1100)

Comment thread src/internal/worktree/menu.go Outdated
Comment on lines +933 to +937
// paintMenu writes the (windowed) menu region for the first time and returns
// the number of lines written (so redraw / finalize know how far to move up).
// height drives the scrolling viewport; the returned count is the windowed
// total (prompt + indicators + visible options + Cancel) and never exceeds
// height, keeping the cursor-up in-place redraw sound for over-tall lists.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed — corrected paintMenu's doc comment to state the returned count stays within menuLayout's budget of height-1 (one reserved row), except at degenerate heights 1–3 where the ≥1-option escape hatch overshoots. (dbe1100)

@sahil-noon sahil-noon merged commit d3ef005 into main Jul 5, 2026
2 checks passed
@sahil-noon sahil-noon deleted the 260705-3wr8-menu-viewport-scrolling branch July 5, 2026 15:00
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.

3 participants