Skip to content

feat: enable macOS autocorrect on the editor#150

Open
erictli wants to merge 2 commits into
mainfrom
feat/autocorrect-support
Open

feat: enable macOS autocorrect on the editor#150
erictli wants to merge 2 commits into
mainfrom
feat/autocorrect-support

Conversation

@erictli
Copy link
Copy Markdown
Owner

@erictli erictli commented May 5, 2026

Summary

Adds Apple Notes-style spellcheck and autocorrect to the editor. Two layers were needed:

  1. HTML opt-in (Editor.tsx:1131-1138): adds spellcheck="true", autocorrect="on", autocapitalize="sentences" to the ProseMirror contenteditable.
  2. WebKit per-app defaults (lib.rs:3635-3675): WKWebView reads NSUserDefaults like WebContinuousSpellCheckingEnabled and WebAutomaticSpellingCorrectionEnabled to decide whether to render the red underline and auto-replace. These keys default to off for new bundle IDs — that's why the HTML attributes alone weren't enough. We registerDefaults for the relevant WebKit keys at the very top of run() (setting them inside .setup() is too late, per tauri#7705).

Defaults registered:

  • WebContinuousSpellCheckingEnabled — red wavy underline + check
  • WebGrammarCheckingEnabled — grammar
  • WebAutomaticSpellingCorrectionEnabled — auto-replace misspellings
  • WebAutomaticQuoteSubstitutionEnabled — smart quotes
  • WebAutomaticDashSubstitutionEnabled — em / en dash
  • WebAutomaticTextReplacementEnabled — Text Replacement
  • WebAutomaticLinkDetectionEnabled — auto-detect URLs

Source-mode textarea is intentionally left with spellCheck={false} since it edits raw markdown.

Closes #142

Why registerDefaults instead of setBool_forKey

registerDefaults only fills in values when the key isn't already set — so a user who right-clicks in the editor and unchecks "Correct Spelling Automatically" will have their preference persisted across launches. Forcing the value with setBool_forKey would override that choice on every startup.

Notes

  • Adds a macOS-only dep on objc2 / objc2-foundation (already transitive from Tauri/wry, just promoted to direct deps).
  • Existing installs already have the bundle ID com.scratch.app; if you've previously toggled WebKit context-menu items off, those choices win over the new defaults.

Test plan

  • On macOS, type This is a sampl sentance wihh some typos so you can see if auto corret is working currectly. in a note — confirm misspellings get the red underline and that auto-replace fires (matches the Apple Notes GIF in macOS auto correct support like Apple Notes #142).
  • Confirm sentence-initial auto-capitalization (e.g. typing hello. then world capitalizes to World).
  • Confirm smart quotes / em-dash substitution work when typing.
  • Right-click on a misspelled word — confirm context menu shows correction suggestions.
  • Right-click → uncheck "Correct Spelling Automatically", restart app — confirm choice is persisted (defaults don't override it).
  • Switch to source/markdown mode and confirm the textarea still has no spellcheck underlines (intentional).
  • Confirm CI passes (cargo check + cargo clippy + frontend build).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Improvements
    • Editor now enables spell check, autocorrect, and auto-capitalization for a smoother writing experience.
    • On macOS, system text defaults (spelling/grammar/autocorrect and text substitutions) are registered so WebKit-based views honor those settings on first use.

Adds autocorrect="on", autocapitalize="sentences", and spellcheck="true"
to the ProseMirror contenteditable so WKWebView applies the user's
system-level spelling correction and auto-capitalization, matching the
behavior of Apple Notes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

📝 Walkthrough

Walkthrough

Added native input attributes to the editor root element and registered macOS WebKit text-substitution / autocorrect defaults at app startup so the system-level WebView preferences are set before creating the webview.

Changes

Editor Native Input Attributes

Layer / File(s) Summary
DOM Attributes
src/components/editor/Editor.tsx
Adds spellcheck="true", autocorrect="on", and autocapitalize="sentences" to editorProps.attributes on the Tiptap/ProseMirror root element.

macOS WebView Defaults Registration

Layer / File(s) Summary
Build configuration
src-tauri/Cargo.toml
Adds a macOS-only dependency block with objc2 and objc2-foundation (features: NSUserDefaults, NSString, NSDictionary, NSValue).
Defaults construction
src-tauri/src/lib.rs
New register_webview_defaults() (gated #[cfg(target_os = "macos")]) builds an NSDictionary mapping WebKit preference keys to boolean true values via Objective-C interop.
Startup wiring
src-tauri/src/lib.rs
pub fn run() calls register_webview_defaults() on macOS before constructing the Tauri webview so the defaults are applied on first webview creation.
sequenceDiagram
  participant App as Tauri App
  participant Defaults as NSUserDefaults
  participant WebView as WebKit WebView

  App->>Defaults: register_webview_defaults() (build NSDictionary)
  Defaults-->>App: defaults registered
  App->>WebView: create webview (Tauri builder)
  WebView->>Defaults: read registered defaults for text/autocorrect
  WebView-->>App: webview initialized with macOS text prefs
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped in code with tiny paws,
Taught the editor friendly laws,
Mac defaults set before the view,
Typos now fix as morning dew,
A happy hare, and text that awes.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately describes the main change: enabling autocorrect on the editor specifically for macOS, which is the primary objective of this PR.
Linked Issues check ✅ Passed The PR fully addresses issue #142 by implementing macOS autocorrect support through HTML attributes in the editor and registering WebKit defaults, enabling spelling corrections and auto-capitalization as requested.
Out of Scope Changes check ✅ Passed All changes are directly related to enabling macOS autocorrect: HTML attributes for the editor, Cargo.toml dependencies for macOS-specific functionality, and Rust code to register WebKit defaults at startup.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/autocorrect-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

WKWebView reads per-app NSUserDefaults to decide whether to render the
spelling underline and apply auto-correct / smart-substitution inside
contenteditable. These keys default to off for new bundle IDs, so the
HTML spellcheck/autocorrect attributes alone produced no visible
behavior. Register the WebKit defaults from Rust before the Tauri
builder runs (setting them inside .setup() is too late). Uses
registerDefaults so user toggles via the WebKit context menu still win.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src-tauri/src/lib.rs`:
- Around line 3649-3657: The registered defaults array named keys includes
substitution settings beyond spellcheck/autocorrect scope; trim it to only the
spelling/correction-related entries by removing
"WebAutomaticQuoteSubstitutionEnabled", "WebAutomaticDashSubstitutionEnabled",
"WebAutomaticTextReplacementEnabled", and "WebAutomaticLinkDetectionEnabled" so
keys contains only "WebContinuousSpellCheckingEnabled",
"WebGrammarCheckingEnabled", and "WebAutomaticSpellingCorrectionEnabled" (update
the keys array in lib.rs accordingly).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dd08f2b7-50af-4f93-a67e-0c1ea56bcc4b

📥 Commits

Reviewing files that changed from the base of the PR and between 4771ded and 447b7e3.

⛔ Files ignored due to path filters (1)
  • src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • src-tauri/Cargo.toml
  • src-tauri/src/lib.rs

Comment thread src-tauri/src/lib.rs
Comment on lines +3649 to +3657
let keys = [
"WebContinuousSpellCheckingEnabled",
"WebGrammarCheckingEnabled",
"WebAutomaticSpellingCorrectionEnabled",
"WebAutomaticQuoteSubstitutionEnabled",
"WebAutomaticDashSubstitutionEnabled",
"WebAutomaticTextReplacementEnabled",
"WebAutomaticLinkDetectionEnabled",
];
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Trim the registered defaults to the behaviors this PR is actually shipping.

Lines 3653-3656 also enable smart quotes, dash substitution, text replacement, and link detection. That is a broader behavior change than the spellcheck/autocorrect/autocapitalize scope in this PR, and in a markdown editor it can silently rewrite literal text or code-like content. I’d keep this list to the spelling/correction keys unless product explicitly wants the extra substitutions too.

Suggested diff
     let keys = [
         "WebContinuousSpellCheckingEnabled",
         "WebGrammarCheckingEnabled",
         "WebAutomaticSpellingCorrectionEnabled",
-        "WebAutomaticQuoteSubstitutionEnabled",
-        "WebAutomaticDashSubstitutionEnabled",
-        "WebAutomaticTextReplacementEnabled",
-        "WebAutomaticLinkDetectionEnabled",
     ];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let keys = [
"WebContinuousSpellCheckingEnabled",
"WebGrammarCheckingEnabled",
"WebAutomaticSpellingCorrectionEnabled",
"WebAutomaticQuoteSubstitutionEnabled",
"WebAutomaticDashSubstitutionEnabled",
"WebAutomaticTextReplacementEnabled",
"WebAutomaticLinkDetectionEnabled",
];
let keys = [
"WebContinuousSpellCheckingEnabled",
"WebGrammarCheckingEnabled",
"WebAutomaticSpellingCorrectionEnabled",
];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src-tauri/src/lib.rs` around lines 3649 - 3657, The registered defaults array
named keys includes substitution settings beyond spellcheck/autocorrect scope;
trim it to only the spelling/correction-related entries by removing
"WebAutomaticQuoteSubstitutionEnabled", "WebAutomaticDashSubstitutionEnabled",
"WebAutomaticTextReplacementEnabled", and "WebAutomaticLinkDetectionEnabled" so
keys contains only "WebContinuousSpellCheckingEnabled",
"WebGrammarCheckingEnabled", and "WebAutomaticSpellingCorrectionEnabled" (update
the keys array in lib.rs accordingly).

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.

macOS auto correct support like Apple Notes

1 participant