Skip to content

fix(editor): restore highlighting after format and refactor editor sync state (#1612)#1616

Merged
datlechin merged 3 commits into
mainfrom
refactor/editor-text-sync
Jun 7, 2026
Merged

fix(editor): restore highlighting after format and refactor editor sync state (#1612)#1616
datlechin merged 3 commits into
mainfrom
refactor/editor-text-sync

Conversation

@datlechin
Copy link
Copy Markdown
Member

@datlechin datlechin commented Jun 7, 2026

Fixes #1612. Also carries the behavior-neutral refactor of the editor sync and completion state that #1608/#1612 exposed. Replaces #1615.

Part 1: fix for #1612 (highlighting lost after Format)

Two layers:

  1. syncBindingText called the TextView-level textView.setText(...), bypassing TextViewController.setText(_:), the documented controller-level path that rebuilds the highlighter for the replacement storage. The old highlighter kept tree-sitter state for the dead document.
  2. Rebuilding alone is not enough: a fresh Highlighter only queries when triggered (an edit, a frame/bounds notification, or invalidate()). Initial load works because the first layout pass fires frameDidChangeNotification; after a mid-session storage swap no trigger is guaranteed. setUpHighlighter() now ends with highlighter.invalidate(), making "after setup, the editor is highlighted" an invariant instead of a timing accident.

Tests: test_syncRebuildsHighlighterForReplacementStorage, test_syncQueriesHighlightsForReplacementStorage (mock provider proves the rebuilt highlighter is re-set-up AND re-queried; fails with the route-through change alone).

Part 2: refactor of text binding sync (package)

The coordinator juggled four pieces of implicit state (isUpdatingFromRepresentable, isUpdateFromTextView, lastSyncedText, textBindingTask); both recent bugs were interactions between them. Now:

  • RepresentableSyncPhase: explicit origin state machine (idle / editorChangePending / applyingRepresentableValue). The mutual exclusion the booleans only implied is enforced by construction.
  • TextBindingSync: single owner of writeback (sync + large-doc debounce) and push-down, carrying the documented invariants (editor wins while its edit is in flight; push-down routes through TextViewController.setText).
  • Coordinator and updateNSViewController shrink to thin delegation.

All 11 binding-sync behavior tests pass unchanged in meaning (retargeted in the same commit), plus 5 new state-machine transition tests.

Part 3: refactor of completion sessions (package + app)

  • SQLCompletionAdapter replaces three ad-hoc fields (currentCompletionContext that was never cleared, suppressNextCompletion, a hand-rolled debounce generation counter) with one CompletionSession carrying an explicit phase (intermediate keyword seed -> final full result), the immediate-sync-then-async-refine shape NSTextSuggestionsDelegate documents.
  • Debounce dedup now uses cooperative task cancellation; cancelled requests stop at the sleep instead of computing results nobody reads.
  • Apply-time trigger suppression moves into SuggestionViewModel (isApplyingCompletion around the delegate apply call), fixing it for every delegate instead of each adapter keeping its own flag.
  • completionWindowDidClose() was declared on the delegate protocol but never invoked; willClose() now calls it, and the adapter uses it to end the session, so context no longer leaks across popups.

New tests: trigger-during-apply ignored, willClose notifies the delegate once. All 6 app autocomplete suites pass (366 cases).

Manual checks worth doing

Type (popup filters per keystroke), accept with Tab/Return (no flicker after accept), Format (highlighting survives), Clear, JSON viewer session.

@datlechin datlechin changed the base branch from fix/1612-highlight-after-format to main June 7, 2026 21:28
@datlechin datlechin merged commit 87cdec8 into main Jun 7, 2026
4 checks passed
@datlechin datlechin changed the title refactor(editor): explicit state machines for text binding sync and completion sessions fix(editor): restore highlighting after format and refactor editor sync state (#1612) Jun 7, 2026
@datlechin datlechin deleted the refactor/editor-text-sync branch June 7, 2026 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Code highlighting is lost after the code is formatted

1 participant