refactor(app): unify the file-collapse predicate - #524
Conversation
Whether a file's diff body is hidden was decided independently in five places: the annotation builder, both diff renderers, and two scroll-height helpers. They have to agree or the cursor lands on rows that were never drawn, which is the failure mode behind several past scroll fixes. Extract `App::is_file_collapsed` and route all five through it. No behavior change. The predicate deliberately says nothing about single-file view, because the call sites genuinely disagree: `file_render_height` ignores it while the renderers honor it. Folding the check in would have silently changed `file_render_height` for its two direct callers, so each site keeps its own gate and the asymmetry is preserved rather than accidentally "fixed". No added per-frame cost. Three sites had cached a reviewed bool and used it to decide two different things -- whether to collapse, and whether to draw the "Marked reviewed" banner -- which a predicate call would have turned into a second map lookup per file per frame. Those two decisions are mutually exclusive on `is_single_file_view`, so they are now one if/else instead of two guarded conditions. Each branch performs exactly one file-state lookup, matching the previous count: multi-file: file_header_prefix_text + is_file_collapsed (2, unchanged) single-file: is_file_reviewed (1, unchanged) hunk_positions: one lookup per file (1, unchanged) Uses of `is_file_reviewed` that drive reviewed-specific decoration -- the tree checkbox, the `✓` header mark, and the banner -- are left alone; only the collapse gates moved. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The red X here is not this change. The 25 Two pieces of evidence that it is environmental:
I do not have rerun rights, so I closed/reopened to trigger a fresh run rather than force-pushing a no-op commit. If it lands red again on the same step, that is the rate limit rather than anything here. Not part of this PR, but if the flake is bothersome: that step reaches the releases API unauthenticated, and passing |
|
Re-run is green on all seven checks, including |
Whether a file's diff body is hidden was decided independently in five places: the annotation builder, both diff renderers, and two scroll-height helpers. They have to agree or the cursor lands on rows that were never drawn, which is the failure mode behind several past scroll fixes.
This extracts
App::is_file_collapsedand routes all five through it. No behavior change — it's a consolidation, and the tests that existed before still pass unchanged.Why the predicate says nothing about single-file view
The call sites genuinely disagree:
file_render_heightignoresis_single_file_viewwhile the renderers honor it. Folding the check into the predicate would have silently changedfile_render_heightfor its two callers, so each site keeps its own gate and the asymmetry is preserved rather than accidentally "fixed". There's a test locking that in (is_file_collapsed_ignores_single_file_view) so a future change can't quietly fold it in.No added per-frame cost
This is called once per file per frame, so I checked the lookup count rather than assuming.
Three sites had cached a reviewed bool and used it to decide two different things — whether to collapse, and whether to draw the "Marked reviewed" banner — which a naive predicate call would have turned into a second map lookup per file per frame. Those two decisions are mutually exclusive on
is_single_file_view, so they're now oneif/elseinstead of two guarded conditions. Each branch performs exactly one file-state lookup, matching the previous count:file_header_prefix_text+ collapse gate (2)is_file_reviewed(1)hunk_positionsUses of
is_file_reviewedthat drive reviewed-specific decoration — the tree checkbox, the✓header mark, the banner — are left alone. Only the collapse gates moved.Testing
cargo fmt --check,cargo clippy --all-targets -- -D warnings, andcargo test(1199 passing) are clean on top of 5675284. Dogfooded per CONTRIBUTING by reviewing this diff in tuicr itself.Note
This is the first of two: #525 builds on it to collapse files marked generated in
.gitattributes, which is what motivated the refactor. This one stands on its own merits either way — five copies of one predicate is a latent bug regardless of whether the follow-up is wanted.🤖 Generated with Claude Code