130 lines
6.5 KiB
Markdown
130 lines
6.5 KiB
Markdown
---
|
|
id: LSN-0034
|
|
ticket: studio-editor-scope-guides-and-brace-anchoring
|
|
title: Active-Scope Gutter and Frontend-Owned Structural Anchors
|
|
created: 2026-04-06
|
|
tags: [studio, editor, scope-guides, structural-anchors, semantic-read, frontend-contract]
|
|
---
|
|
|
|
## 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 of `activeScope`.
|
|
|
|
**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:
|
|
|
|
- `EditorDocumentScopeGuideModel` now resolves `activeScope` as the smallest containing range and `activeContainer` as the immediate parent, with structural-anchor-aware construction when that metadata is available.
|
|
- `EditorWorkspace` recomputes active guide state from caret movement and prefers transported structural anchors over approximate local ranges when the analyze result includes them.
|
|
- `EditorDocumentScopeGuideGraphicFactory` renders the constrained two-slot gutter model instead of the old stacked active ancestry presentation.
|
|
- `LspStructuralAnchorDTO` and `prometeu-lsp` now expose a dedicated structural-anchor transport surface separate from `documentSymbols`.
|
|
- `SemanticIndex` derives 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:
|
|
|
|
1. semantic read returns structural ranges and, when available, exact structural anchors;
|
|
2. Studio computes `activeScope` and `activeContainer` from containment;
|
|
3. gutter rendering uses exact anchor positions when present;
|
|
4. no fallback contract is allowed to redefine exact anchoring through source scanning.
|
|
|
|
## Pitfalls
|
|
|
|
- Do not overload `documentSymbols` with 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-0014` Code Editor active container, active scope, and frontend-owned structural anchors
|
|
- `PLN-0030` Wave 1 editor implementation for active container and active scope gutter indicators
|
|
- `PLN-0031` Structural anchor semantic surface specification for Studio semantic read
|
|
- `PLN-0032` Frontend structural-anchor payload propagation and anchor-aware test coverage
|
|
- `docs/specs/studio/5. Code Editor Workspace Specification.md`
|
|
- `docs/specs/studio/7. Integrated LSP Semantic Read Phase Specification.md`
|
|
- `prometeu-lsp/prometeu-lsp-api/src/main/java/p/studio/lsp/dtos/LspStructuralAnchorDTO.java`
|
|
- `prometeu-lsp/prometeu-lsp-v1/src/main/java/p/studio/lsp/models/SemanticIndex.java`
|
|
- `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorDocumentScopeGuideModel.java`
|
|
- `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorDocumentScopeGuideGraphicFactory.java`
|
|
- `prometeu-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.
|