Configuration Schema¶
Complete reference for .languagecheck.yaml.
Editor Completion¶
The extension ships a JSON Schema for the config file, generated from the same types the
core parses it with. In VS Code, .languagecheck.json gets completion and validation out
of the box. .languagecheck.yaml needs the
Red Hat YAML
extension, which the extension offers to install the first time you open the file.
Other editors running yaml-language-server can load the schema with a modeline:
# yaml-language-server: $schema=https://raw.githubusercontent.com/KaiErikNiermann/LangCheck/main/extension/schemas/languagecheck.schema.json
language-check config schema prints the schema for the installed version.
Top-Level Fields¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
See below |
Checker engine configuration |
|
|
|
|
Per-rule severity overrides |
|
|
|
Glob patterns to skip |
|
|
Custom find/replace rules |
|
|
See below |
Performance tuning |
|
|
See below |
Bundled and custom wordlists |
|
|
See below |
Affixed forms of known words |
|
|
See below |
Per-language settings |
Engines¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Enable Harper engine |
|
|
|
Enable LanguageTool |
|
|
|
Enable Vale |
|
|
|
Enable proselint |
|
|
|
Enable Hunspell |
|
|
|
BCP-47 tag to check against |
|
|
External checker binaries |
|
|
|
WASM checker plugins |
Every engine accepts either a bool shorthand (languagetool: true) or a nested
table. Engine-specific settings — including the LanguageTool server URL — live
inside that table:
engines:
spell_language: fr
languagetool:
enabled: true
url: "http://10.0.10.3:8003" # default: http://localhost:8010
level: "picky"
LanguageToolConfig¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Enable the engine |
|
|
|
Server base URL (no |
|
|
|
|
|
|
unset |
BCP-47 tag for false friends |
|
|
|
Rule IDs to switch off |
|
|
|
Extra rule IDs to switch on |
|
|
|
Category IDs to switch off |
|
|
|
Extra category IDs to switch on |
|
|
|
In-flight |
|
|
|
Prose per request; |
Deprecated since version 0.5.1: The flat engines.languagetool_url and engines.vale_config keys are aliases
for engines.languagetool.url and engines.vale.config. They are still read,
but they log a warning and will be removed in a future release.
External Providers¶
Field |
Type |
Required |
Description |
|---|---|---|---|
|
|
Yes |
Display name |
|
|
Yes |
Path to executable |
|
|
No |
Command-line arguments |
|
|
No |
File extensions to check (empty=all) |
WASM Plugins¶
Field |
Type |
Required |
Description |
|---|---|---|---|
|
|
Yes |
Display name |
|
|
Yes |
Path to |
|
|
No |
File extensions to check (empty=all) |
Rule Config¶
Field |
Type |
Description |
|---|---|---|
|
|
|
Auto-Fix¶
Field |
Type |
Required |
Description |
|---|---|---|---|
|
|
Yes |
Text pattern to find |
|
|
Yes |
Replacement text |
|
|
No |
Only apply when context string exists |
|
|
No |
Human-readable rule description |
Performance¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Only use Harper (skip LT/externals) |
|
|
|
Delay after the last keystroke, in milliseconds; |
|
|
|
Max file size in bytes (0=unlimited) |
|
|
|
Engine answers kept, keyed by the prose that produced them; |
|
|
|
Longest prose range handed on; longer ones split at sentence bounds. |
Languages¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Additional file extensions per language ID |
|
See below |
LaTeX-specific settings |
HunspellConfig¶
Spelling for the languages the other engines do not read. See Hunspell Setup.
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Enable the engine |
|
|
|
BCP-47 tags to check; empty means any language with a pack |
|
|
|
Per-language override: a directory, a stem, or either file |
|
|
|
Extra directories, searched before the platform’s own |
|
|
|
Fetch a missing pack without asking |
engines:
hunspell:
enabled: true
languages: ["he", "la"]
dictionary_paths:
la: /opt/dictionaries/latin
Dictionaries are not bundled — Hspell is AGPL-3.0 and the Latin pack is GPL, so
neither can ship inside an MIT binary. Install one with
language-check packs install <lang>, through your package manager, or by
naming an existing pair under dictionary_paths.
languages.latex¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Extra environment names to skip during prose extraction |
Environments listed here are skipped in addition to the built-in set (algorithm, equation, tikzpicture, tabular, etc.). Use this for custom or niche environments whose content should not be grammar-checked.
languages:
latex:
skip_environments:
- prooftree
- mycustomenv
Dictionaries¶
Words listed in a dictionary are never reported as spelling mistakes. Five domain wordlists ship with the checker and all of them load by default.
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Load the bundled domain wordlists |
|
|
|
Names of individual bundled wordlists to skip |
|
|
|
Extra wordlist files, one word per line, |
dictionaries:
disabled: [companies]
paths:
- .languagecheck/project-terms.txt
Bundled wordlists¶
These are the names accepted by disabled:
Name |
Contents |
|---|---|
|
Development tools, acronyms, and compound technical terms |
|
TypeScript and JavaScript keywords, builtins, and API names |
|
Well-known company and brand names |
|
Computing jargon, hardware terms, and domain vocabulary |
|
Mathematics, category theory, type theory, and mathematical physics |
Set bundled: false to switch all five off at once; disabled turns off only the
ones you name and is ignored when bundled is false. An unrecognized name is
warned about in the server log and otherwise ignored, so a typo here never takes
the other wordlists down with it.
See rust-core/dictionaries/THIRD_PARTY_NOTICES.md for each list’s source and
licensing.
Hyphenated words¶
A hyphenated compound is accepted when every one of its parts is known
individually, so Chern-Simons resolves from chern and simons. This matters
because engines disagree about what they report: Harper flags the parts of a
compound separately, while LanguageTool flags the whole span. Requiring all
parts to be known keeps genuine typos visible — Chern-Simmmons and
well-knownn are still reported.
The same rule applies to words you add yourself and to any file listed in
paths, not just the bundled wordlists.
Your own words¶
Add to dictionary in the editor writes to .languagecheck/dictionary.txt in the
workspace. That file is yours; the bundled wordlists are never written back to it.
Morphology¶
One dictionary entry covers the words built on it. Adding algebra also accepts
algebras, subalgebra, sub-algebra and algebraicity, so the dictionary
stops growing one line per inflection. On by default.
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Accept a flagged word that decomposes into a known root |
|
|
|
Also accept the regular inflections of dictionary words |
morphology:
enabled: true
inflections: true
Two switches because the two halves work differently, and can fail differently.
Prefixes and derivational suffixes are recognized¶
A word that is flagged as a misspelling is re-read as a productive prefix
(sub-, semi-, non-, quasi-, counter-, … — the full list is in
rust-core/dictionaries/affixes/prefixes.txt) and/or a derivational suffix
(-ness, -ity, -able, -ly, …) over a root. The root has to be a real
word — one of yours, one from a bundled list, or one Harper knows — so
subalgebra is accepted and subxyzzy is not. The closed and hyphenated
spellings take the same path, because Harper and LanguageTool disagree about
which one they report.
This is done by taking the word apart rather than by listing the results,
because prefixes stack freely: the set of words algebra licenses is
unbounded, so there is nothing to list.
Inflections are generated¶
Plurals, and the past and progressive of -ate/-ize/-ise/-ify verbs, are
generated from each dictionary word when the workspace loads and then matched
like any other entry.
Generated, not stripped, because the spelling rules only run one way. occur
plus -ed is occurred; a checker that instead removed -ed from occured
would find occur and accept a misspelling. The same shape accepts childs and
mouses, which is why plurals are never recognized by taking a word apart.
What keeps typos visible¶
A decomposition on its own is weak evidence: untill reads as un- + till,
and till really is a word. So the engine’s own correction has the final say —
if it can offer something one edit away from what you typed, the squiggle stays.
A word with no plausible correction is what a genuine coinage looks like.
Names¶
Opt-in suppression of spelling diagnostics on human names. Off by default.
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Drop spelling diagnostics on tokens detected as human names |
|
|
|
|
names:
enabled: true
aggressiveness: balanced
The detector is engine-agnostic — it works the same whether Harper or LanguageTool produced the diagnostic, because it reads only the flagged token, the surrounding text, and the engine’s own suggestion list.
A word is treated as a name only when at least two independent signals agree:
Signal |
Meaning |
|---|---|
|
The word is a known given name or surname |
|
No suggestion is within edit distance 3 — not a plausible typo |
|
The engine offered no correction at all |
|
The same spelling occurs more than once in the document |
|
A title, salutation, possessive or citation pattern surrounds it |
|
Capitalized away from the start of a sentence |
Requiring two signals is what keeps real misspellings visible. Hoare is suppressed
because it is a known surname and capitalized mid-sentence; thier is not, because
it is lowercase and sits one edit from their. Raising aggressiveness lowers that
bar and will eventually cost you real typos.
Capitalization is ignored as a signal for German (de-*), where every noun is
capitalized and the shape carries no information.
Use the Names tab in the Inspector to see exactly which words were suppressed and which signals fired for each.