Smartphone-style autocorrect for a physical keyboard on Windows — French-first.
Type the way you would on a phone. Press Space and TypeSense silently fixes the last word: restores accents, apostrophes, and common typos — in every application, with no popup, no menu, no red underline, no key combos.
ca → ça
cest → c'est
ete → été
jai → j'ai
alle → allé (after "je suis")
lhomme → l'homme
à cote → à côté (context-aware)
All four crates are implemented and the workspace is green:
| Crate | What | Validation |
|---|---|---|
typesense-engine |
French correction engine | 39 tests, ~µs latency (Linux/Windows) |
typesense-core |
buffer, config, learning, Mode-2 seam | 35 tests (Linux/Windows) |
typesense-platform |
Windows hook + injection | type-checked for x86_64-pc-windows-msvc |
typesense-app |
tray daemon + egui settings | daemon cross-checked; settings builds/runs on Linux |
Packaging (WiX MSI, GitHub Actions CI, optional self-updater) is in place. The
Windows GUI/hook behavior needs on-device testing — development and CI validate
the pure logic on Linux and cross-check the Windows crates. See
docs/ARCHITECTURE.md.
- Automatic — corrections commit on Space; nothing to click.
- Fast — Mode 1 (dictionary + context) runs in microseconds, far under the 20 ms budget. Typing feels native.
- Everywhere — a global keyboard hook, not per-app plugins.
- Contextual — a bigram model disambiguates (
à côtévsla côte). - Bilingual-aware — common English words are protected, so writing English in
a French-first tool doesn't turn
theintothéoruseintousé. Toggle it off per taste (Settings → Correction). - Two modes — an offline dictionary (Mode 1, the default and the whole shipped experience) and an experimental local LLM (Mode 2) that runs off the hot path for ambiguous cases. Mode 2 is opt-in and requires a special build (see AI mode).
- Learns — custom replacements, learned words, and "undo = never correct this again."
- Private & offline — no network required; the local model runs on-device.
- Rust — a single lean native binary, no Electron, no runtime, no GC pauses.
crates/
typesense-engine French correction engine (platform-independent, tested)
typesense-core shadow buffer, config, learning store, orchestration
typesense-platform Windows keyboard hook + text injection (Windows-only)
typesense-app system-tray daemon + egui settings UI (Windows-only)
data/
lexicon-seed.tsv curated seed lexicon (Lexique 3.83 loadable at runtime)
bigrams-seed.tsv seed contextual bigrams
docs/
ARCHITECTURE.md design & trade-offs
Requires a recent stable Rust toolchain.
# Test the platform-independent engine + core on any OS (Linux/macOS/Windows):
cargo test -p typesense-engine -p typesense-core
# Type-check the Windows-only crates from any OS:
cargo check -p typesense-platform --target x86_64-pc-windows-msvc
# Build the full app (on Windows):
cargo build --release # → target/release/typesense.exe + typesense-settings.exe
# Optional features:
cargo build --release --features llm # local llama.cpp Mode-2 backend (needs a C++ toolchain)
cargo build --release --features updater # self-update from GitHub Releases
# Build the MSI installer (on Windows):
cargo install cargo-wix
cargo wix # → target/wix/TypeSense-<version>-x86_64.msiOn first run TypeSense writes %APPDATA%\TypeSense\config.toml. You can also
manage everything from the tray → Settings window: enable/disable, language,
ignored apps, custom dictionary, learned words, AI on/off, and latency stats.
The [correction] section includes protect_english = true (the English guard
described above) alongside the diacritics / elision / typos toggles.
Mode 2 is an experimental local-LLM refinement layer, not part of the
default binaries. It exists to disambiguate cases where the dictionary is
genuinely unsure and context is decisive (e.g. il a ete → été vs
l'ete arrive → l'été). It is not the right tool for "don't correct my
English" — that is handled deterministically by the English guard above, with
zero latency.
Design and honest caveats:
- Off the hot path. A local model takes 100 ms–seconds, so it can never run on the synchronous Space press. Instead, when Mode 1 applies a correction it is unsure about, a background worker consults the model and may apply a second, silent re-correction — only if nothing has changed meanwhile (a buffer-generation guard). This orchestration is fully unit-tested.
- Requires a special build. The default
cargo build --releaseships Mode 2 inert (a no-op provider, no C++ dependency). To actually run a model you must build with--features llmand point[ai].model_pathat a local GGUF file. - Not yet verified on-device. The
llama-cpp-2decode loop (typesense-core/src/llm.rs) targets a moving API and has not been run against a live model on Windows; treat it as the integration point to finish, not a turnkey feature. - GPU. The backend loads on CPU by default (
n_gpu_layersunset). Using a GPU (e.g. an RTX A1000) additionally requires a CUDA-enabled llama.cpp build.
For most users, Mode 1 + the English guard is the complete, fast, private experience; Mode 2 is for tinkerers and future work.
Dual-licensed under either of MIT or Apache 2.0 at your option.
The seed lexicon and bigrams are hand-curated for this project. The full-coverage lexicon supported at runtime is Lexique 3.83 (Creative Commons, New et al., http://www.lexique.org), which you supply/download separately.