6.5 KiB
| id | ticket | title | created | tags | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| LSN-0034 | studio-editor-scope-guides-and-brace-anchoring | Active-Scope Gutter and Frontend-Owned Structural Anchors | 2026-04-06 |
|
Context
The Studio editor already exposed structural guides in the gutter, but the old behavior mixed two different concerns:
- active-scope context in the editor UI,
- and exact structural start/end anchoring.
That combination caused two failures at once:
- the default gutter became visually noisy because it rendered a stacked ancestry map,
- and the guide geometry still depended on approximate local heuristics rather than on language-owned structural metadata.
This discussion split those concerns into a simpler first-wave editor behavior plus a stable long-term semantic contract.
Key Decisions
Limit the Default Gutter to activeScope and activeContainer
What: The default editor gutter now renders at most two active structural indicators:
activeScope, defined as the smallest structural range containing the caret;activeContainer, defined as the immediate structural ancestor ofactiveScope.
Why: The stacked ancestry gutter produced too much visual noise for routine editing. The editor needs the nearest structure context, not the whole ancestry map.
Trade-offs: The first wave intentionally drops persistent visibility of higher ancestors. That loses some ambient hierarchy, but it produces a much clearer default editing signal.
Keep Exact Anchoring Frontend-Owned Through a Dedicated Semantic Surface
What:
Exact guide start and end positions now belong to a dedicated structural-anchor semantic surface rather than to documentSymbols or Studio-local text scanning.
Why: Outline/navigation structure and guide geometry are different contracts. Exact anchoring must survive languages with braces, keywords, indentation, or mixed delimiter schemes, so the final source of truth has to be frontend-owned and language-agnostic.
Trade-offs: The transport and DTO surface become richer, and Studio must consume one more semantic payload. That cost is worth it because it prevents brace-specific heuristics from becoming the canonical editor contract.
Keep Presentation Ownership Out of the Core Contract
What:
The contract distinguishes semantic roles such as activeContainer and activeScope, but concrete styling remains frontend-owned.
Why: The host should know which guide is which, but it should not freeze colors, strokes, or theme details into the semantic decision.
Trade-offs: Presentation choices remain distributed across frontend or theme layers. That is preferable to coupling semantic meaning to one hardcoded Studio style.
Final Implementation
The final implementation landed across editor behavior, semantic transport, and specs:
EditorDocumentScopeGuideModelnow resolvesactiveScopeas the smallest containing range andactiveContaineras the immediate parent, with structural-anchor-aware construction when that metadata is available.EditorWorkspacerecomputes active guide state from caret movement and prefers transported structural anchors over approximate local ranges when the analyze result includes them.EditorDocumentScopeGuideGraphicFactoryrenders the constrained two-slot gutter model instead of the old stacked active ancestry presentation.LspStructuralAnchorDTOandprometeu-lspnow expose a dedicated structural-anchor transport surface separate fromdocumentSymbols.SemanticIndexderives exact structural anchors for Studio consumption.- Studio and semantic-read specs now define the two-indicator gutter model, the dedicated structural-anchor surface, and the frontend-owned exact-anchor contract.
- Tests now cover smallest-containing-range selection, immediate-parent selection, structural-anchor transport, and anchor-aware rendering.
Patterns and Algorithms
Pattern: Split Local Active State from Exact Structural Geometry
The useful decomposition is:
- derive active editor context locally from the current structural range set;
- derive exact guide geometry from frontend-owned structural anchors.
The editor can therefore ship a useful first wave without inventing the long-term anchor contract.
Pattern: Use the Smallest Containing Range as the Active Scope
When multiple structural ranges contain the caret, the active scope must be the nearest one, not the largest semantic owner. That keeps the editor aligned with the user's current editing neighborhood.
Example: Anchor Upgrade Path
The resulting flow is:
- semantic read returns structural ranges and, when available, exact structural anchors;
- Studio computes
activeScopeandactiveContainerfrom containment; - gutter rendering uses exact anchor positions when present;
- no fallback contract is allowed to redefine exact anchoring through source scanning.
Pitfalls
- Do not overload
documentSymbolswith guide-only anchor data. - Do not restore the full stacked ancestry gutter as the default active-scope experience.
- Do not treat brace scanning as a production contract for exact anchors.
- Do not promote high-level owners such as function or type when a nearer structural ancestor exists.
- Do not hardcode theme or stroke policy into the semantic guide model.
References
DEC-0014Code Editor active container, active scope, and frontend-owned structural anchorsPLN-0030Wave 1 editor implementation for active container and active scope gutter indicatorsPLN-0031Structural anchor semantic surface specification for Studio semantic readPLN-0032Frontend structural-anchor payload propagation and anchor-aware test coveragedocs/specs/studio/5. Code Editor Workspace Specification.mddocs/specs/studio/7. Integrated LSP Semantic Read Phase Specification.mdprometeu-lsp/prometeu-lsp-api/src/main/java/p/studio/lsp/dtos/LspStructuralAnchorDTO.javaprometeu-lsp/prometeu-lsp-v1/src/main/java/p/studio/lsp/models/SemanticIndex.javaprometeu-studio/src/main/java/p/studio/workspaces/editor/EditorDocumentScopeGuideModel.javaprometeu-studio/src/main/java/p/studio/workspaces/editor/EditorDocumentScopeGuideGraphicFactory.javaprometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java
Takeaways
- Active structure and exact anchor geometry should be modeled as separate concerns.
- The default gutter becomes much clearer when it shows only the nearest scope context.
- Exact structural anchors belong to a frontend-owned semantic surface, not to Studio heuristics.