cargo-spellcheck

crates.io CI commits-since rust 1.51.0+ badge

Check your spelling with hunspell and/or nlprule.

Use Cases

Run cargo spellcheck --fix or cargo spellcheck fix to fix all your documentation comments in order to avoid nasty typos all over your source tree. Meant as a helper simplifying review as well as improving CI checks after a learning phase for custom/topic specific lingo.

Check For Spelling and/or Grammar Mistakes

zsh cargo spellcheck check

error: spellcheck
   --> src/main.rs:44
    |
 44 | Fun facets shalld cause some erroris.
    |            ^^^^^^
    | - shall or shall d
    |

Apply Suggestions Interactively

zsh cargo spellcheck fix

error: spellcheck(Hunspell)
    --> /media/supersonic1t/projects/cargo-spellcheck/src/literalset.rs:291
     |
 291 |  Returns literl within the Err variant if not adjacent
     |          ^^^^^^

(13/14) Apply this suggestion [y,n,q,a,d,j,e,?]?

   lite
   litter
   litterer
   liter l
   liters
   literal
   liter
 ยป a custom replacement literal

Continuous Integration / CI

cargo spellcheck can be configured with -m <code> to return a non-zero return code if mistakes are found instead of 0.

git pre-commit hook

```sh

!/usr/bin/sh

Redirect output to stderr.

exec 1>&2

exec cargo spellcheck -m 99 $(git diff-index --cached --name-only --diff-filter=AM HEAD) ```

Implemented Features + Roadmap

hunspell (dictionary based lookups) and nlprules (static grammar rules, derived from languagetool) are currently the two supported checkers.

Configuration

Source

There are various ways to specify the configuration. The prioritization is as follows:

Explicit specification:

  1. Command line flags --cfg=....
  2. Cargo.toml metadata

    toml [package.metadata.spellcheck] config = "somewhere/cfg.toml"

which will fail if specified and not existent on the filesystem.

If neither of those ways of specification is present, continue with the implicit.

  1. Cargo.toml metadata in the current working directory CWD.
  2. Check the first arguments location if present, else the current working directory for .config/spellcheck.toml.
  3. Fallback to per user configuration files:
  4. Use the default, builtin configuration (see config sub-command).

Since this is rather complex, add -vv to your invocation to see the info level logs printed, which will contain the config path.

Format

```toml

Project settings where a Cargo.toml exists and is passed

${CARGOMANIFESTDIR}/.config/spellcheck.toml

Also take into account developer comments

dev_comments = false

Skip the README.md file as defined in the cargo manifest

skip_readme = false

[Hunspell]

lang and name of .dic file

lang = "en_US"

OS specific additives

Linux: [ /usr/share/myspell ]

Windows: []

macOS [ /home/alice/Libraries/hunspell, /Libraries/hunspell ]

Additional search paths, which take presedence over the default

os specific search dirs, searched in order, defaults last

search_dirs = []

Adds additional dictionaries, can be specified as

absolute paths or relative in the search dirs (in this order).

Relative paths are resolved relative to the configuration file

which is used.

Refer to man 5 hunspell

or https://www.systutorials.com/docs/linux/man/4-hunspell/#lbAE

on how to define a custom dictionary file.

extra_dictionaries = []

If set to true, the OS specific default search paths

are skipped and only explicitly specified ones are used.

skiposlookups = false

Use the builtin dictionaries if none were found in

in the configured lookup paths.

Usually combined with skip_os_lookups=true

to enforce the builtin usage for consistent

results across distributions and CI runs.

Setting this will still use the dictionaries

specified in extra_dictionaries = [..]

for topic specific lingo.

use_builtin = true

[Hunspell.quirks]

Transforms words that are provided by the tokenizer

into word fragments based on the capture groups which are to

be checked.

If no capture groups are present, the matched word is whitelisted.

transform_regex = ["^'([^\s])'$", "^[0-9]+x$"]

Accepts alphabeta variants if the checker provides a replacement suggestion

of alpha-beta.

allow_concatenation = true

And the counterpart, which accepts words with dashes, when the suggestion has

recommendations without the dashes. This is less common.

allow_dashed = false

[NlpRules]

Allows the user to override the default included

exports of LanguageTool, with other custom

languages

overriderules = "/path/to/rulesbinencoded.bin"

overridetokenizer = "/path/to/tokenizerbinencoded.bin"

[Reflow]

Reflows doc comments to adhere to adhere to a given maximum line width limit.

maxlinelength = 80 ```

To increase verbosity add -v (multiple) to increase verbosity.

Installation

cargo install --locked cargo-spellcheck

The --locked flag is the preferred way of installing to get the tested set of dependencies.

Checkers

Available checker support

Hunspell

Requires a C++ compiler to compile the hunspell CXX source files which are part of hunspell-sys

Fedora 30+

sh dnf install -y clang

Ubuntu 19.10+

sh apt install -y clang

Mac OS X

sh brew install llvm

The environment variable LLVM_CONFIG_PATH needs to point to llvm-config, to do so:

sh export LLVM_CONFIG_PATH=/usr/local/opt/llvm/bin/llvm-config

NlpRules

When compiled with the default featureset which includes nlprules, the resulting binary can only be distributed under the LGPLv2.1 since the rules and tokenizer definitions are extracted from LanguageTool (which is itself licensed under LGPLv2.1) as described by the library that is used for pulling and integrating - details are to be found under crate nlprule's README.md.

๐ŸŽˆ Contribute!

Contributions are very welcome!

Generally the preferred way of doing so, is to comment in an issue that you would like to tackle the implementation/fix.

This is usually followed by an initial PR where the implementation is then discussed and iteratively refined. No need to get it all correct the first time!