Skip to content

Latest commit

 

History

30 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spellkit

Cross-platform native spell checking for Rust.

On crates.io Downloads CI Docs

Why Spellkit?

Use the spell-checking facilities already on the user's system.

Platform Backend
macOS NSSpellChecker
Windows ISpellChecker (Windows Spell Checker)
Linux / other Unix Hunspell with system dictionaries

Applications should not reimplement macOS, Windows, and Hunspell separately. Spellkit is one small API over those backends.

This project is based on euclio/spellbound (last upstream commit 2020).

What Spellkit is not

Spellkit does not bundle dictionaries or implement its own spelling algorithm. It wraps the platform backend and uses system / installed dictionaries. Behavior can differ across operating systems where the APIs differ.

That is the distinction from crates that ship an engine and word lists (for example Spellbook).

Quick start

cargo add spellkit
use spellkit::Checker;

fn main() -> Result<(), spellkit::Error> {
    let checker = Checker::new()?;

    for err in checker.check("I havv a spelling error.") {
        println!("{} @ {}..{}", err.text(), err.start(), err.end());
        for suggestion in checker.suggest(err.text()) {
            println!("  → {suggestion}");
        }
    }
    Ok(())
}

Checker::locale() is the language this instance is using. Checker::available_locales() lists what the OS can check.

use spellkit::Checker;

fn main() -> Result<(), spellkit::Error> {
    println!("available: {:?}", Checker::available_locales());
    let checker = Checker::new()?;
    println!("using: {}", checker.locale());
    Ok(())
}

Features

  • Cross-platform: macOS, Windows, Linux
  • System dictionaries (no files shipped in the crate)
  • Suggestions (up to 10)
  • Locale via with_locale (en_US and en-US both work)
  • Temporary ignored words (ignore is per checker, not global)
  • UTF-8 byte ranges (start / end / range)
  • Small API

Platform support

Linux macOS Windows
Backend Hunspell NSSpellChecker ISpellChecker
Checker::new() LC_ALL / LC_MESSAGES / LANG if a dict exists, else en_US / en_GB system language user locale, else en-US
Unknown with_locale Error::DictionaryNotFound (paths searched) Error::UnsupportedLocale Error::UnsupportedLocale
Empty locale Error::InvalidLocale Error::InvalidLocale Error::InvalidLocale
Suggestions yes yes yes
ignore yes (this handle only) yes (this document tag only) yes (this checker only)
available_locales *.dic stems on disk (DICPATH then system dirs) availableLanguages SupportedLanguages
Send / Sync no no no

Linux also honors DICPATH (colon-separated directories) before /usr/share/hunspell and the other built-in paths.

Word breaks are not identical: Linux tokenizes alphanumeric / ' runs; macOS and Windows use the OS checker.

How it works

Checker is a thin wrapper. On each OS it calls the native API, then converts misspelling ranges to UTF-8 byte offsets into the original &str.

Spellkit vs other approaches

Why not Spellbook? Use Spellbook when you want a portable engine and bundled (or app-shipped) dictionaries. Use Spellkit when you want the OS dictionaries, native suggestions, and minimal integration.

Why not Hunspell directly? You would own dictionary discovery, FFI, and a second implementation for macOS and Windows. Spellkit is that integration.

Why not ispell? You would own an external process, its lifetime, and the command protocol. Spellkit stays in-process.

Errors

  • empty locale → Error::InvalidLocale
  • Linux missing .aff/.dicError::DictionaryNotFound (includes search paths)
  • macOS / Windows language not installed → Error::UnsupportedLocale
  • backend failed to start (null Hunspell handle, COM factory, empty macOS language) → Error::InitializationFailed

Linux packages

  • Arch: pacman -S hunspell hunspell-en_us
  • Debian/Ubuntu: apt install libhunspell-dev hunspell-en-us
  • Extra languages used in CI: hunspell-de-de, hunspell-fr

Without a dictionary, Checker::new() returns Error::DictionaryNotFound.

Examples

cargo run --example check -- "I havv a spelling error."
cargo run --example suggestions -- "I beleeve I can fly"
cargo run --example locale
cargo run --example highlight

Threading

Checker is not Send or Sync. Do not share it across threads. macOS also serializes access to the shared NSSpellChecker.

Documentation

Contributing

Issues and PRs: github.com/rtmongold/spellkit

License

MIT OR Apache-2.0

Credits

Originally by Andy Russell. Maintained as spellkit by Robert Mongold.

About

Cross-platform native spell checking for Rust (NSSpellChecker, Windows Spell Checker, Hunspell).

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages