Skip to content

Drop the autocorrection underline on a document switch - #198

Merged
luca-chen198 merged 3 commits into
mainfrom
fix/correction-underline-on-switch
Oct 10, 2026
Merged

luca-chen198 merged 3 commits into
mainfrom
fix/correction-underline-on-switch

Conversation

@luca-chen198

Copy link
Copy Markdown
Member

Problem

Type a word that autocorrects (the blue underline appears), then switch to another document: the underline stays over the incoming document for about half a second. Sometimes it then reappears as a line across the new text and stays there (still up after 4 s in the device log).

Root cause

The underline belongs to the text view, not to the document. AppKit draws an NSCorrectionIndicatorUnderlineView into the text view, and the text view's NSTextCheckingController tracks the corrected range. The editor shows every document in one NativeTextView and swaps the text on a switch. Nothing told AppKit the corrected word was gone, so the view stayed and the tracked range moved into the new text.

Fix

The switch branch of updateNSView now calls NativeTextView.removeCorrectionUnderlines(), next to removeAllWideTableOverlays(). It asks the text checking controller to removeCorrectionIndicatorUnderlines. Both the controller (textCheckingController on NSTextView) and the call are private, so each step is guarded by responds(to:). If a future macOS drops either, nothing happens.

Measured before choosing this call:

  • NSSpellChecker.dismissCorrectionIndicator(for:) (public) and toggling isAutomaticSpellingCorrectionEnabled leave the underline up.
  • NSSpellChecker's removeCorrectionIndicatorUnderlinesForView: removes the view but the controller keeps the range.
  • The controller's removeCorrectionIndicatorUnderlines removes both.

Typing is untouched: the call runs only on a document switch.

Tests

  • CorrectionUnderlineTests: puts an underline up the way a correction does (through the controller), swaps the text, and expects neither the view nor the tracked range to remain. It fails with an empty removeCorrectionUnderlines().
  • Full suite: 585 tests in 77 suites pass.
  • Confirmed by hand in Nodes (macOS), pinned to this branch.

🤖 Generated with Claude Code

luca-chen198 and others added 3 commits October 9, 2026 20:45
AppKit's blue underline under an autocorrected word belongs to the text
view: an NSCorrectionIndicatorUnderlineView over it, and a range the text
view's NSTextCheckingController tracks. The editor shows every note in one
view and swaps the text, so the outgoing note's underline stood over the
incoming one for about half a second, and its range moved into the new
text and drew a line across it that was still there after 4 s (device log).

The switch now asks the text checking controller to remove its underlines,
next to the wide-table overlays it already drops. Both the controller and
the call are private, so each step is guarded by responds(to:). The public
NSSpellChecker.dismissCorrectionIndicator(for:) and toggling autocorrection
leave the underline up; removing it through NSSpellChecker leaves the range.

The test puts an underline up the way a correction does, swaps the text and
expects neither the view nor the range to remain. 585 tests pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@luca-chen198
luca-chen198 merged commit f2e3fc5 into main Oct 10, 2026
1 check passed
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.

1 participant