Commit Graph

4 Commits

Author SHA1 Message Date
Levi Neuwirth 9718958c4c Fix stale TUI styling after edits 2026-05-26 11:15:23 -04:00
Levi Neuwirth 822aa946f4 Step 1: SemanticTokenStore/InlayHintStore::for_uri (+ repair main)
Adds the URI-only store views the semantic-frontend producer arc
needs. The stores key by (server, uri); the producer only knows the
document, so `for_uri` scans by uri and picks the lowest *numeric*
server id deterministically (HashMap order is otherwise
nondeterministic; lowest id == oldest/primary attachment). Blending
multiple servers' styling on one buffer is a deferred open question.

Inlay-hint `for_uri` returns no server: Step 0 established inlay
positions are already pmacs byte offsets by the time they hit the
store (the absorb path's inbound_converted rewrites the
Position-shaped InlayHint.position), so the producer needs no
per-server encoding for them. Semantic tokens differ — start/length
stay UTF-16, hence the (server, response) tuple so the matching
LspManager::semantic_style_context can resolve encoding + legend.

Also repairs main: PR #28 (file-watch) inadvertently swept in the
uncommitted lsp.rs side of this work — SemanticStyleContext and
semantic_style_context, which call store.for_uri — without these
defining accessors, leaving main referencing an undefined method
(no method `for_uri`). This commit supplies the missing definitions,
so main compiles again.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 15:04:19 -04:00
Levi Neuwirth ea37a8f7ce T M4.5: semantic tokens /range + /full/delta
Backlog item 2 — perf refinement over the v1 full-only request.

- src/semantic_tokens.rs: SemanticTokensResponse retains the raw
  int stream; factored decode(); new apply_delta(prev_raw, v)
  splices a SemanticTokensDelta (edits:[{start,deleteCount,data}])
  over the previous raw — descending-start application so unordered
  server edits stay valid, bounds clamped, spec-allowed
  full-instead-of-delta detected and parsed. +4 unit tests.
- src/lsp.rs: request_semantic_tokens_range (reuses the
  SemanticTokens route/store) and request_semantic_tokens_delta
  (new ResponseRoute::SemanticTokensDelta; absorb splices against
  the store's retained raw). Capability upgraded to
  requests:{ full:{ delta:true }, range:true }.
- src/lua_bindings.rs: _request_semantic_tokens_range_raw,
  _request_semantic_tokens_delta_raw,
  pmacs.semantic_tokens.result_id(sid,uri).
- builtin/runtime/lsp.lua: range/delta wrappers;
  pmacs.lsp.semantic_tokens() auto-prefers delta when a prior
  result id exists (else full), no longer clears the store (delta
  needs the retained raw), tags the modeline "(delta)". The range
  wrapper is exposed without a default command (no viewport source
  in the bundle yet).
- pmacs_fake_lsp.rs: /range and /full/delta arms (delta is an
  edit script over the /full data).
- tests/m4_acceptance.rs: m4_20 (range decode), m4_21 (full seeds
  rid-1; delta against it splices to the updated 3rd token + rid-2).

Gates: lib 1289/0, m4 76/0, m8_1 10/0, m8_9 26/0, m8_10 19/0,
m9_1 18/0, m5_8 5/0, m11_5 (--features crdt) 2/0; fmt + clippy
clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 13:50:05 -04:00
Levi Neuwirth cf2947f7f9 T M4.5: semantic tokens (textDocument/semanticTokens/full)
LSP data layer only — independent of the M11 semantic-render
protocol (semantic_render.rs / semantic_client.rs, tree-sitter →
frontend wire families). No InstanceMessage family added; wiring
LSP tokens into styling is a separate rendering milestone. Same
shape as every sibling LSP feature: typed store + async request
+ Lua surface + command + modeline summary.

- src/semantic_tokens.rs: decode the 5-int relative encoding
  (deltaLine, deltaStartChar, length, tokenType, tokenModifiers)
  into absolute SemanticToken{line,start,length,token_type,
  token_modifiers}, with the same-line-vs-new-line deltaStartChar
  rule and defensive truncation of a malformed trailing group.
  SemanticTokensLegend::from_capabilities parses
  semanticTokensProvider.legend and resolves type index / modifier
  bitset to names. Store keyed (server, uri). 6 unit tests.
- src/lsp.rs: store + accessor, ResponseRoute::SemanticTokens +
  absorb, request_semantic_tokens (/full; v1 no range/delta),
  textDocument.semanticTokens client capability (full-only,
  formats=[relative], standard LSP legend).
- src/lua_bindings.rs: _request_semantic_tokens_raw,
  pmacs.semantic_tokens.{tokens, legend, clear} (legend reads the
  per-server initialize capabilities).
- pmacs_fake_lsp.rs: semanticTokensProvider.legend in initialize;
  textDocument/semanticTokens/full arm with relative-encoded data.
- builtin/runtime/lsp.lua: pmacs.lsp.semantic_tokens() requests
  full, stores, modeline summary (first token's type resolved via
  legend); lsp.semantic-tokens command + C-c y.
- tests/m4_acceptance.rs: m4_17 drives the request via the Lua
  surface, asserts decoded absolute tokens (incl. deltaLine!=0 ⇒
  absolute startChar) and legend index→name resolution.

Gates: lib 1285/0, m4 72/0, m8_1 10/0, m8_9 26/0, m8_10 19/0,
m9_1 18/0, m5_8 5/0, m11_5 (--features crdt) 2/0 (confirms no
collision with the M11 render protocol); fmt + clippy clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 13:15:19 -04:00