pmacs/builtin
Levi Neuwirth 5c2a27aaf9 fix(lsp): negotiate delta before requesting; input-origin signature trigger
Addresses the four post-merge findings against PR #102 (merged as
2d157d8). Stacked on the kill-ring branch (PR #103): the trigger
redesign rides its command-boundary substrate.

- BLOCKING delta without the capability: pull_semantic_tokens_quiet (and
  the pre-existing manual pmacs.lsp.semantic_tokens(), same bug) used
  any stored resultId to request /full/delta while only checking that a
  provider exists. A resultId does not imply delta support --- servers
  may return one from /full regardless --- and a conforming full-only
  server rejects the delta request; the pull path swallows the error, so
  styling stayed silently stale after the first edit. Both sites now
  require semanticTokensProvider.full.delta == true. The fake's default
  mode truthfully advertises { "full": { "delta": true } } (it
  implements delta); a new `fullonly` mode advertises "full": true,
  REJECTS /full/delta, and bumps its resultId per /full response so the
  test can observe WHICH pull refreshed the store. Verified the test
  bites: with the capability check reverted, the post-edit rid stays
  rid-1 (stale) and the test fails.

- HIGH false-positive trigger + cross-frontend misclassification: the
  cursor-delta heuristic ("same buffer, cursor +1") fired on any
  one-byte edit --- including a one-byte paste of "(" once PR #103 made
  paste fire buffer.after-edit --- and its singleton last_typed was
  shared across frontends. Replaced with the input-origin signal from
  the #103 substrate: inside after-edit,
  pmacs.editor.this_command() == "buffer.self-insert" names an edit
  produced by typing, per frontend, with nothing inferred from cursor
  deltas. New ed.this_command() binding; handle_remote_crdt_op now
  classifies a single-codepoint optimistic insert as buffer.self-insert
  (rotation, not just break --- kill-chain semantics identical since
  self-insert is not a kill, and GPU typing now carries the same origin
  signal as TUI typing). Paste/pointer/undo/unbound leave this_command
  as something else and can never trigger.

- MEDIUM first-trigger-ignored: the origin signal needs no prior-edit
  snapshot, so the very first "(" typed in a buffer triggers. The test
  that had encoded the warm-up keystroke as "correct" now types a single
  "(" as the first character.

- MEDIUM non-ASCII trigger characters: char_before read one byte and
  rejected multi-byte strings; LSP trigger characters are strings. Now
  codepoint-aware (read up to 4 bytes back, take the suffix from the
  last non-continuation byte). The sighelp fake declares a two-byte
  trigger ("«") and a test types it.

Tests (m4_acceptance 94 -> 97 after +4/-1 rework):
arc1c_full_only_server_repulls_via_full_not_delta (bites --- verified),
arc1d_signature_help_auto_triggers_on_trigger_char (now first-char),
arc1d_signature_help_triggers_on_non_ascii_trigger_char,
arc1d_signature_help_ignores_non_typed_edits (movement-stamped
programmatic "(" insert + manual after-edit must not trigger --- the
case cursor-delta inference cannot distinguish). Daemon unit test
updated for the insert classification (break-then-classify: `this` =
buffer.self-insert, `last` = None, chain still dead).

Note: completion.lua still uses the Q#C9 cursor-delta heuristic and
inherits its weaknesses; migrating it to this_command is a named
follow-up, out of scope here.

Gates: fmt + workspace clippy clean; lib 1500; crdt 1672; m4 97;
killring 28; completion 9; GPU 58; git diff --check clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 20:40:59 -04:00
..
api Fix CI and Documentation issues 2026-05-04 10:19:19 -04:00
commands feat(edit): kill ring + yank-pop on a per-frontend command-boundary substrate 2026-07-09 20:10:39 -04:00
hooks feat(edit): kill ring + yank-pop on a per-frontend command-boundary substrate 2026-07-09 20:10:39 -04:00
keymaps feat(edit): query-replace (M-% / C-M-%) — Arc 2 2026-07-08 16:05:23 -04:00
menus pmacs context menu: core clipboard + menu methods + Lua surface (Q#CM1/Q#CM3/Q#CM6) 2026-06-27 22:03:58 -04:00
packages/repl M7 tail: package system, audit lint, lockfile, resolver 2026-05-07 16:50:37 -04:00
runtime fix(lsp): negotiate delta before requesting; input-origin signature trigger 2026-07-09 20:40:59 -04:00