Commit Graph

53 Commits

Author SHA1 Message Date
Levi Neuwirth 071e79ffee M11.4: segment diffing for StyleSpans/Decorations
Replace the M11.2/M11.3 coarse whole-payload suppression with a
CellDelta-style diff lifted from positional cells to byte-anchored
ranges.

- protocol.rs: StyleSpans/Decorations refined to
  { buffer_id, generation, full: bool, segments: Vec<...Segment> }.
  New StyleSegment{range,spans} / DecorationSegment{range,decorations}.
  full=true → frontend discards prior state for the buffer; full=false
  → replace styling only within each segment's range, bytes in no
  segment keep prior state. Decorations gains generation for parity.
  Each segment carries ALL current items intersecting its range
  (clipped), so an unchanged span overlapping a dirty range is
  reconstructed. ResourceOffer stays an honest stub (no producer).
- semantic_render.rs: LastFrame baseline per buffer (viewport region
  + full item set). full on first frame / viewport-region change;
  else symmetric-difference the ordered sets, coalesce changed ranges
  into maximal disjoint dirty intervals, emit one segment per
  interval with current items clipped to it; suppress when no dirty
  interval. Independent baselines for styling vs decorations.

Byte offsets cascade on edits (an insert shifts later spans), so an
incremental post-edit frame dirties [edit, viewport_end) — bounded;
no-edit frames (cursor/scroll/selection-only) still cost nothing.

10 semantic_render tests (full-on-first/viewport-change, incremental
dirty intervals, independent suppression, unchanged-overlapping
reconstruction) + updated protocol round-trip. Lib (1397 crdt / 1242
non-crdt) + integration green both flavors; clippy -D warnings clean
both.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:04:49 -04:00
Levi Neuwirth efa8f6f8ed M11.3: Decorations projection (selection + diagnostics)
SemanticRenderState now also projects InstanceMessage::Decorations
from the instance-side state pmacs actually has.

- Selection: per-window byte-native state via active_window_for(fid)
  (SemanticRenderState now carries the session FrontendId), gated to
  the declared buffer and clipped to the viewport →
  DecorationKind::Selection.
- Diagnostics: the shared DiagnosticStore keyed by file URI. Made
  lsp::path_to_file_uri pub(crate) (byte-identical to the Lua
  file_uri_for) so the projection reproduces the exact store key from
  core.file_path. LSP (line,col) -> byte via a line-start scan
  against the buffer source; severity -> DiagnosticError/Warning/
  Info/Hint. Clipped to the viewport.
- StyleSpans and Decorations suppress unchanged frames independently
  (separate last_* maps): a selection move doesn't force a styling
  re-send and vice versa.
- Deliberately NOT emitted: SearchMatch/SearchMatchActive (no
  instance search-hit store), CurrentLine (frontend derives from
  CursorByte; emitting it would breach the contract boundary).
- InlineAdornments/BlockAdornments/FoldState remain unproduced by
  design — no inlay/blame/lens/fold/diff source exists in pmacs yet.
  Honest stubs (the M11.1 "declared, not yet wired" discipline), not
  empty messages every frame.

Dispatcher updated for SemanticRenderState::new(frontend_id). Lib
(1394 crdt / 1239 non-crdt) + integration green on both feature
flavors; clippy -D warnings clean on both.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:47:18 -04:00
Levi Neuwirth 4ba6fd7bb8 M11.2: semantic projection seam (SemanticRenderState)
The first real producer of the semantic-frontend arc. The instance
projects syntax styling to semantic_render sessions without
rasterizing to a cell grid.

- src/semantic_render.rs: SemanticRenderState, sibling of
  instance_render::RenderState. Reads the same EditorState, emits
  InstanceMessage::StyleSpans (tree-sitter spans via the active
  Theme), scoped + clipped to the FrontendEvent::Viewport byte range.
  Emits nothing until a viewport is declared; suppresses
  byte-identical frames (per-span delta encoding deferred to M11.4).
- CrdtState::version_scalar(): oplog version vector summed to a
  monotonic non-decreasing u64 — the StyleSpans.generation anchor.
- daemon dispatcher: semantic_states map parallel to render_states;
  projection selected per session. Semantic sessions get StyleSpans +
  CursorByte + BufferSnapshot + CrdtOp + presence, never CellDelta /
  grid Cursor. FrontendEvent::Viewport consumed (routed by
  authenticated source). SessionEstablished body extracted to
  handle_session_established (clippy 100-line ceiling). Grid-less
  sessions no longer panic the _ => apply_event arm.
- InstanceCapabilities default semantic_render flipped to
  cfg!(feature = "crdt") — the "M11.2 enables semantic" moment,
  analogous to the M10.8 Day-4 flip. M11.1 negotiation test comment
  updated for the flip (frontend-side default still false keeps M10.7
  outcomes unperturbed).

Lib (1392 crdt / 1237 non-crdt) + integration suites green on both
feature flavors; clippy -D warnings clean on both.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:14:08 -04:00