Skip to content

fix(review-diff): page over collapsed files instead of through them - #3030

Merged
sinelaw merged 1 commit into
masterfrom
claude/review-diff-cursor-collapse-bug-g8mdsh
Aug 19, 2026
Merged

fix(review-diff): page over collapsed files instead of through them#3030
sinelaw merged 1 commit into
masterfrom
claude/review-diff-cursor-collapse-bug-g8mdsh

Conversation

@sinelaw

@sinelaw sinelaw commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Fixes #3029.

Symptom

In Review Diff, paging down towards a collapsed file wedges the view: the same frame is redrawn press after press, the cursor is nowhere on screen, and Ln keeps climbing by a page each time. The stall lasts for as many presses as the collapsed file has hidden rows — on a HEAD~100..HEAD review with a ~3000-row file collapsed, ~80 presses of nothing.

Reproduced by hand in tmux against HEAD~100..HEAD before touching any code, then again after the fix: the same key sequence that used to freeze now steps over all six collapsed files in a single press, in both directions.

Cause

handle_page_motion scrolls the viewport a page of drawn rows — a fold-aware walk that steps over a collapsed body for free — and then lands the cursor at the new viewport top. It resolves the leaf to move correctly (effective_active_split), but delegates the actual scroll to handle_scroll_event, which targets the split manager's active leaf instead.

For a grouped buffer those two differ. The review panel is an inner leaf of the group, not a node of the split tree, so the scroll moved the group host's viewport while the panel's stayed exactly where it was. Seeing no movement, handle_page_motion concluded the buffer was already at its edge and returned None, falling back to the plain logical-line cursor page-down — which counts lines whether or not the renderer draws them. The cursor walks into the collapsed body, the viewport has nowhere to follow it, and the screen stops.

Without folds the two motions look identical (every logical line is a drawn row), which is why this only shows up once something is collapsed.

Change

  • handle_page_motion scrolls the leaf it already resolved, via a new handle_scroll_event_for_split.
  • handle_scroll_event keeps its old signature but now resolves effective_active_split() rather than the tree's active leaf, so Ctrl+Up / Ctrl+Down in a panel hit the same fix (they had the identical mismatch). Its early return for a window with no split layout is preserved — effective_active_pair asserts one.
  • buffer_for_leaf resolves the buffer for a leaf: SplitManager::buffer_for_split only knows tree nodes, so it answers None for an inner panel; the fallback reads the leaf's own SplitViewState::active_buffer, which effective_active_pair already treats as authoritative.

Left alone deliberately: handle_set_viewport_event and handle_recenter_event resolve their leaf the same old way and would have the same blind spot for inner panels. Neither is reachable from a review panel by a keybinding I could find, so there's no reproducer to write a test against and no fix worth making without one.

Tests

crates/fresh-editor/tests/e2e/plugins/review_diff_collapsed_paging.rs drives keys and asserts only on rendered output: it opens a review whose src/file02.rs is forty times longer than its neighbours, collapses it with Enter on the file header, returns to the top of the stream, and requires PageDown to reach src/file03.rs's content — and PageUp to get back above the fold — within 30 presses. The fold-blind motion needs ~60 to cross that file's 1600 hidden rows; the fixed motion needs about four.

Verified failing on the parent commit (PageDown never reached src/file03.rs past the collapsed src/file02.rs — 30 presses were spent inside its hidden body) and passing with the change.

Also run: cargo fmt, cargo clippy --all-targets (no new warnings), cargo check --all-targets --features gui, cargo test -p fresh-editor --lib (3375 passed), and the e2e suites covering paging, scrolling, viewports, review diff / audit mode, splits, composites and folds (697 tests, 0 failures).

🤖 Generated with Claude Code

https://claude.ai/code/session_01EM6V5VanwxUpmnhqtxjy8R


Generated by Claude Code

In Review Diff, PageDown/PageUp near a collapsed file wedged the view:
the frame stopped changing, the cursor left the screen, and `Ln` kept
climbing a page per press until it had crawled past every hidden row of
the collapsed file. On a large collapsed file that is dozens of presses
of nothing.

`handle_page_motion` scrolls the viewport a page of *drawn* rows — a
fold-aware walk that steps over a collapsed body for free — and then
lands the cursor at the new top. It resolved the leaf to move correctly
(`effective_active_split`), but delegated the scroll to
`handle_scroll_event`, which targets the split manager's active leaf
instead. For a grouped buffer those differ: the review panel is an inner
leaf of the group, so the scroll moved the group host's viewport while
the panel's stayed put. Seeing no movement, the page motion concluded
the buffer was already at its edge and fell back to the plain
logical-line cursor page-down, which counts lines whether or not the
renderer draws them.

Scroll the leaf the caller resolved, and let `handle_scroll_event` reach
the same leaf for its own callers (Ctrl+Up / Ctrl+Down in a panel had
the same split mismatch). Inner group leaves aren't nodes of the split
tree, so `buffer_for_split` doesn't know them; `buffer_for_leaf` falls
back to the leaf's own view state, which `effective_active_pair` already
treats as authoritative.

Fixes #3029

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EM6V5VanwxUpmnhqtxjy8R
@sinelaw
sinelaw merged commit 04d3356 into master Aug 19, 2026
9 of 10 checks passed
@sinelaw
sinelaw deleted the claude/review-diff-cursor-collapse-bug-g8mdsh branch August 19, 2026 04:59
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.

Review Diff: PageDown stalls and the cursor vanishes when paging into a collapsed file

2 participants