Skip to content

fix(fuzzylist): clamp pickers to the pane with a scrolling viewport#41

Open
todie wants to merge 1 commit into
cloudmanic:mainfrom
todie:fix/picker-viewport
Open

fix(fuzzylist): clamp pickers to the pane with a scrolling viewport#41
todie wants to merge 1 commit into
cloudmanic:mainfrom
todie:fix/picker-viewport

Conversation

@todie

@todie todie commented Jul 10, 2026

Copy link
Copy Markdown

Problem

Both pickers render every list row unconditionally. With more entries than the pane has rows (I hit this with ~66 project files), the alt-screen view overflows: rows past the pane height are truncated, the detail bar and footer disappear, and arrowing down walks the cursor out of view. Independently, rows longer than the pane soft-wrap, which breaks the line accounting rowIndexAt relies on for mouse clicks.

Fix

Give fuzzyList a viewport:

  • setViewport(rows, width) caps how many body lines view() emits; a scroll offset (lineOffset) follows the cursor in both directions via ensureVisible(), so the highlighted row is always on screen.
  • Every emitted line is truncated ANSI-aware (x/ansi.Truncate, already an indirect dep) to the pane width so nothing soft-wraps.
  • rowIndexAt maps clicks through the scroll offset, so click-to-open keeps working while scrolled and clicks on the query block or below the window stay no-ops.
  • The projects browser and both quick-actions stages feed their pane size through on WindowSizeMsg (and when the select-stage option list is created), each reserving its own fixed chrome lines.

With no viewport set the component behaves exactly as before (unbounded), so existing tests pass unchanged; two new tests cover window-follows-cursor (both directions + click mapping through the offset) and width truncation.

Verified

Drove projects-ui with 66 project files in a 25x90 pty and checked the emulated screen: the list windows to the pane with the detail box and footer pinned and visible, scrolling 30 rows down keeps the cursor and its detail preview on screen, and filtering re-clamps the window. Same check on quick-actions-ui at 12x70.

Both pickers render every row unconditionally, so a list taller than the
pane (e.g. 60+ project files) overflows the alt-screen: rows past the
pane height are cut off, the detail bar and footer scroll away, and the
cursor can walk out of view. Long rows also soft-wrap, breaking the
list's line accounting for mouse clicks.

Give fuzzyList a viewport: setViewport(rows, width) caps how many body
lines view() emits, a scroll offset follows the cursor in both
directions (ensureVisible), and every emitted line is ANSI-aware
truncated to the pane width so nothing soft-wraps. rowIndexAt maps
clicks through the scroll offset, so click-to-open keeps working while
scrolled. The projects browser and both quick-actions stages feed their
pane size through on WindowSizeMsg (and when the select-stage option
list is created), each reserving its own fixed chrome lines.

With no viewport set, behavior is unchanged (unbounded, as before).
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.

1 participant