Shape reading mode: fold function bodies in the whole-file view - #26
Draft
davegaeddert wants to merge 4 commits into
Draft
Shape reading mode: fold function bodies in the whole-file view#26davegaeddert wants to merge 4 commits into
davegaeddert wants to merge 4 commits into
Conversation
Groundwork for the shape reading-mode spike (fold function bodies in the whole-file view). Implementation lands in follow-up commits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013mVGpFa5b6ZNMVaXE7bQQq
1-based first interior line of a symbol's body — the first line a fold may hide while the whole signature, including a trailing brace, stays visible. Populated wherever the grammar exposes a body node; None for one-liners, expression-bodied functions, and bodyless declarations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013mVGpFa5b6ZNMVaXE7bQQq
A toolbar toggle folds every function/method body to an elision marker so the file reads as its outline; markers (and gutter chevrons) expand and collapse individual bodies in place. Pierre has no fold API and recycles rows while virtualizing, so shape mode hands it a smaller real document — collapsed bodies removed, one indent-matched marker line each — keeping virtualization correct, and renders real line numbers from a custom self-virtualized gutter with pierre's own numbers disabled. A collapsed fold's marker occupies the same row its first body line takes when expanded, so single toggles never shift content above the click point. Read-only: token, selection, and annotation interactions are inert in shape mode. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013mVGpFa5b6ZNMVaXE7bQQq
ShapeDocument shrinks to the two fields the renderer consumes; the test-only exports and parallel fold maps are gone. Shape derivation moves into hooks/useShapeMode.ts, which also hoists the per-toggle file split and content hash to once per file (the synthesized doc's cache key replaces re-hashing the whole document on every fold click). The gutter now translates one wrapper on scroll instead of rebuilding every visible row, and only shape mode pays the scroll-node state that previously cost every file view a second CodeView render. Toolbar fold controls reuse ToggleButtonGroup; the six shape props are required. Line-addressed features (in-file search, go-to-line, outline tracking) speak real-file coordinates, which the synthesized document does not share — they are now explicitly suppressed while shape mode is on rather than silently mis-mapped, with the mapping path documented for whoever closes the gap properly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013mVGpFa5b6ZNMVaXE7bQQq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spike of the
reading-modesarc's first future (futures:review/reading-modes/shape-view.md): a "Shape" toggle for the whole-file view that folds every function/method body to a faint⋯marker — signatures, docstrings, fields, and imports stay literal — with per-fold expand/collapse and real line numbers preserved.Approach
Deliberately without forking
@pierre/diffs(which has no fold/hidden-range API and recycles rows while virtualizing): shape mode synthesizes a smaller real document — collapsed bodies removed, one indent-matched⋯marker line each — so pierre's virtualization stays correct. Pierre's line numbers are disabled (disableLineNumbers) and a custom self-virtualized gutter (ShapeGutter) renders real line numbers + fold chevrons; on scroll it translates one wrapper instead of rebuilding rows. A collapsed fold's marker occupies the same row its first body line takes when expanded, so single toggles never shift content above the click point. Read-only by design: token/selection/annotation interactions are inert in shape mode, and line-addressed features that speak real-file coordinates (in-file search, go-to-line, outline active-tracking/clicks) are explicitly suppressed while shape is on rather than silently mis-mapped.Backing data:
Symbolgains optionalbodyStartLine(1-based first interior line; the signature including its trailing{line stays visible), populated at all 66 construction sites in the tree-sitter extractor.Nonefor one-liners, expression-bodied functions, and bodyless declarations.Shape state and derivation live in
hooks/useShapeMode.ts(component state by design, likesvgViewMode/markdownViewMode— promoting to a slice is required only if this ever becomes a palette command). A/simplifyfour-angle cleanup pass (2a15ea9) shrank the model to the two fields the renderer consumes, hoisted per-toggle hashing/splitting to once per file, and reusedToggleButtonGroupfor the fold controls.Status
bodyStartLineincore/src/symbols/(+3 extractor tests: Rust incl. multi-line signatures, Python incl. docstring-as-interior, TypeScript incl. arrow consts)shape-model.tspure + 16 unit tests,ShapeGutter.tsx,useShapeMode.ts, toolbar toggle + expand/collapse-all, gated to plain whole-file mode)tscclean, 628 vitest tests passcore/src/symbols/extractor.rs(3.5k lines → 598 rows / 97 folds), re-verified after the cleanup pass: fold markers, multi-line signatures intact, gutter alignment deep mid-file, in-place expand with no scroll shift, expand-all/collapse-all, raw togglestatic.crates.io, socargo check/cargo testcould not run here (Rust code is rustfmt-parse-clean and structurally audited, but the 3 new extractor tests are unrun). Please runscripts/testlocally, thenscripts/dev-web→ open a repo → an unchanged file in whole-file view → the Shape toggle in the toolbar.Known follow-ups (deliberate spike scope)
buildShapeDocument's rows can carry a real↔doc mapping when someone closes this properly (the suppression site documents the path).Symbol::from_nodeconstructor to collapse the 66 mechanical field initializations; passing precomputed line bounds intobody_interior_start; replacing itsstarts_with('{')text test with the tree-sitter-structuralbody.named_child(0)answer.🤖 Generated with Claude Code
https://claude.ai/code/session_013mVGpFa5b6ZNMVaXE7bQQq