typos¶
A source-code spell checker that Scrutin drives as a plugin. Unlike a dictionary-based checker (which treats every unfamiliar token as a misspelling), typos works from a curated list of known-wrong-to-right corrections, so it produces essentially zero false positives on identifiers, package names, and other code tokens. That makes it a much better fit than skyspell for scanning R / Python / Rust source files.
Like the linters (jarl, ruff), diagnostics map to warn events and
clean files produce a synthetic pass, so typo findings appear
alongside test results in the TUI and web dashboard. typos is opt-in:
enable it with an explicit [[suite]] tool = "typos" entry in
.scrutin/config.toml, or pass files on the command line with
-t typos in file mode.
Installing typos¶
typos is not shipped with Scrutin. Follow the upstream install instructions at github.com/crate-ci/typos.
typos vs. skyspell¶
Both are spell checkers. They have opposite philosophies:
| skyspell | typos | |
|---|---|---|
| Model | system dictionary (enchant) | curated misspelling list |
| False positives on code | many (flags identifiers) | ~none by construction |
| Catches new misspellings | yes (anything not in the dictionary) | only ones typos has seen |
| Good for | prose: README, docs, Markdown | source code + prose |
| Output | JSON with ranked suggestions | NDJSON with a single correction |
Use skyspell for prose that needs a real dictionary check. Use typos
for source trees where you want to catch recieve / teh /
occurence without a flood of noise. They coexist: declare both as
[[suite]] entries and Scrutin runs them in the same invocation
(suites run one at a time; files within each suite run in parallel).
Directory structure¶
myproject/
├── .scrutin/
│ └── config.toml # [[suite]] tool = "typos"
├── _typos.toml # optional: typos' own config (custom words, excludes)
├── README.md
└── R/
└── utils.R
Minimal example¶
.scrutin/config.toml
_typos.toml (optional)
_typos.toml (or typos.toml / .typos.toml) is read by typos itself (not by Scrutin) for custom words, locale, and excludes:
[default.extend-words]
# Words that look like typos but aren't (project-specific):
arange = "arange"
[files]
extend-exclude = ["vendor/", "fixtures/"]
R/utils.R
Running Scrutin flags recieve and defintely but ignores foo,
function, x, and every other R identifier.
Running¶
typos runs as its own suite alongside any other suites you've declared;
suites run one at a time, but within the typos suite every matched
file is checked in parallel. It uses command mode (calling
typos --format json <file> directly), so no subprocess protocol is
needed.
File mode works the same way without any config file at all:
Fix flow¶
In Detail view, each typo shows its suggested correction inline as a numbered chip. Hotkeys:
| Key | Action |
|---|---|
1 |
Accept the suggested correction: Scrutin rewrites the file on disk and triggers a rerun so the warning disappears. |
j/k / ↑↓ |
Move between typos. |
In the web dashboard, two additional chip buttons are exposed per file:
- Typos: fix (this file) runs
typos --write-changes <file>. - Typos: fix all (suite) runs
typos --write-changeson every file in the suite, after include / exclude filters.
Affected files are re-checked automatically after any fix action.
Configuration¶
The minimal suite entry is just tool = "typos". typos' own configuration
(_typos.toml, typos.toml, or .typos.toml at the suite root)
controls custom words, exclusions, and locale; Scrutin doesn't
interpret it. See the
typos config reference
for the full schema.
To override Scrutin's default suite targets in .scrutin/config.toml:
[[suite]]
tool = "typos"
# Default `run` covers common source + prose extensions (md, R, py, rs,
# js, ts, go, ...). Override to scope:
# run = ["README.md", "R/**/*.R", "src/**/*.py"]
typos runs with cwd = suite.root so it picks up the local
_typos.toml. Each file is checked independently, with no dependency
tracking.