Add offline live spell checking (Hunspell via spellbook)
Spelling is now checked live as you type, fully offline, using the pure-Rust `spellbook` crate to read Hunspell .aff/.dic dictionaries (no C libhunspell — the binary stays self-contained; ldd unchanged). - Canadian (en-CA, default) and British (en-GB) English dictionaries are compiled in; more languages are auto-discovered from system Hunspell folders and ~/.config/md-manuscript/dictionaries/. A "Spelling" row in the top bar toggles live checking and picks the dictionary. - Misspellings are underlined in red; right-clicking a word opens a menu of suggested corrections. A results-panel and one-click fixes work too. - Checks run on a background thread, debounced ~400ms after the last edit. Prose is extracted with pulldown-cmark so code spans, code blocks and link targets are skipped; ALL-CAPS initialisms are ignored. - LanguageTool still layers on top: when its results are fresh they own the underlines (spelling + grammar); once you edit, the offline checker resumes. The editor underlines, issues panel and fix-apply logic are now shared between the two sources. Bundled dictionaries are SCOWL-derived under a permissive license (kept in dictionaries/<lang>/license). Adds spell-check unit tests (tokenizer, code-block skipping, offset mapping, en-CA/en-GB spelling); 40 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N9kRuP7JvXoUGdNNeg5ZSs
This commit is contained in:
@@ -110,9 +110,38 @@ The status bar shows a live **word count** for the current file, plus the net
|
||||
words added (or removed) to it since the current session started. The count
|
||||
updates as you type, including unsaved edits.
|
||||
|
||||
## Spelling (offline)
|
||||
|
||||
Spelling is checked **live as you type**, entirely offline — no server, no
|
||||
network. Misspelled words get a red underline; **right-click** one for a menu of
|
||||
suggested corrections (click a suggestion to apply it). It uses Hunspell
|
||||
dictionaries read by the pure-Rust [`spellbook`](https://crates.io/crates/spellbook)
|
||||
crate, so the binary stays self-contained.
|
||||
|
||||
* **Two dictionaries are built in** — Canadian English (`en-CA`, the default)
|
||||
and British English (`en-GB`). Pick one from the **Dictionary** dropdown on
|
||||
the *Spelling* row of the top bar; the choice is remembered.
|
||||
* **More languages** are discovered automatically from the usual Hunspell
|
||||
folders (`/usr/share/hunspell`, `/usr/share/myspell`, …) and from a per-user
|
||||
folder, `~/.config/md-manuscript/dictionaries/`. Drop a matching
|
||||
`xx_YY.aff` + `xx_YY.dic` pair in there (e.g. from your distro's
|
||||
`hunspell-de-de` package) and it appears in the dropdown.
|
||||
* **Untick “Check as I type”** on the Spelling row to turn the underlines off.
|
||||
* Code spans, fenced/indented code blocks and link targets are skipped, and
|
||||
ALL-CAPS initialisms (ODT, HTTP) are left alone, to cut false positives.
|
||||
|
||||
When you run a **LanguageTool** check (below), its richer spelling-and-grammar
|
||||
results take over the underlines until you next edit the text — at which point
|
||||
the live offline checker resumes. In other words, LanguageTool is used when it's
|
||||
available and current; the offline checker is the always-on default.
|
||||
|
||||
The bundled dictionaries live under `dictionaries/` and are derived from
|
||||
[SCOWL](http://wordlist.sourceforge.net/) under a permissive license (kept
|
||||
alongside them in each `license` file).
|
||||
|
||||
## Grammar & spelling (LanguageTool)
|
||||
|
||||
The editor can check the current file against a
|
||||
The editor can *additionally* check the current file against a
|
||||
[LanguageTool](https://languagetool.org/) server — typically a **local
|
||||
instance**, so your manuscript never leaves your machine.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user