Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

memelint

memelint lints the words that spread through comments, docstrings, and documentation. It tells you which words and sentences do not follow Simplified Technical English (ASD-STE100), with an allowlist for the words of your project.

Each finding gives the file, the position, the severity, the message and the rule:

$ memelint check
foo.py:2:29: error: 'ensure' is not approved; use 'make sure' [STE 1.1]
foo.py:3:7: error: 'don't' is a contraction; write the words in full [STE 4.2]
foo.py:3:13: error: 'delve' is not in the STE dictionary; if it is a technical name, add it to memelint.toml [STE 1.6]
foo.py:4:7: error: sentence has 28 words; the STE limit for descriptive text is 25 [STE 6.3]
foo.py:4:7: error: 'closing' is the -ing form of 'close'; STE allows only the infinitive, imperative, past tense and past participle [STE 3.5]

The exit code is 1 when there is an error.

Installing

ASD-STE100 is copyrighted, thus the binary does not contain its dictionary. The first run downloads the PDF from ASD and makes the vocabulary in ~/.cache/memelint/. The Nix package makes it when it builds.

On your machine

Use the install script, or use Nix.

The install script

The release binaries are for Linux and macOS, on x86_64 and aarch64:

curl -fsSL https://memelint.sh | sh
memelint check

Nix

With Nix, there is no installation. This builds the checker with the vocabulary and with each tree-sitter grammar that nixpkgs has, and runs it:

$(nix-build --no-out-link \
  https://github.com/antimemes/memelint/archive/main.tar.gz)\
/bin/memelint check

With flakes:

nix run github:antimemes/memelint -- check

In GitHub Actions

Put this in .github/workflows/memelint.yml. The findings become annotations on the pull request:

name: memelint

on:
  push:
    branches: [main]
  pull_request:

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: antimemes/memelint@latest

Configuration

memelint reads memelint.toml at the project root. Each key is optional. The first line gives your editor the schema:

#:schema https://raw.githubusercontent.com/antimemes/memelint/main/crates/memelint/memelint.schema.json

profile = "strict"                 # "strict" or "basic"
words = ["gantry", "sprocket"]
word-lists = ["words.txt", "https://example.com/team-words.txt"]
default-word-lists = true
ignore = ["vendor/", "*.generated.go"]

[rules]
"6.3" = "warning"                  # "error", "warning" or "off"

[languages.rust]                   # for the files of one language
words = ["monomorphize"]
word-lists = ["rust-words.txt"]
default-word-lists = true

[languages.rust.rules]
"1.6" = "off"
KeyEffect
profilethe severity of each rule, see Rules
rulesthe severity of one rule
wordsthe technical names and verbs of the project, see Words
word-listsfiles, URLs and bundled lists of words
default-word-listsuse the bundled lists (default: true)
ignorepaths that memelint does not examine, in the syntax of .gitignore
languages.<name>the same keys for the files of one language, see Languages

Words

The ASD-STE100 dictionary has approximately 900 words. The technical names and technical verbs of your domain are not in it, and the standard lets you use them. Tell memelint which they are:

  • words: a list in memelint.toml.
  • word-lists: files with one word on each line and # comments. An entry is a path from the directory of memelint.toml, a URL, or the name of a bundled list.
  • default-word-lists: the bundled lists are on unless this is false. The software list applies to all files, and the list of a language to its files.

The entries add to each other. memelint accepts a listed word with its usual inflections: the plural, -ed and -ing.

memelint fetch downloads the URLs into ~/.cache/memelint/words/, and memelint check reads them from there.

The bundled lists are software, c, cpp, go, java, javascript, markdown, nix, python, rust, toml, tsx and typescript. Their text is in the repository. They are not complete. If you add words, send a pull request.

To use only your lists:

default-word-lists = false
word-lists = ["words.txt"]

Rules

ASD-STE100 Issue 9 has 53 rules. A program can check a part of them. memelint checks these:

RuleFinding
1.1a word that is not approved, with the approved alternatives, for example commence (use start)
1.2an approved word in a part of speech in which it is not approved. For example, test is a noun, thus “do a test” and not “test it”
1.6a word that is not in the dictionary and not in your word list, for example kubelet. Put the words of your project in memelint.toml, and they are approved
3.5the -ing form of an approved verb, for example starting
4.2a contraction, for example don't
6.3a sentence of more than 25 words

Each rule has a severity: error, warning or off. The exit code is 1 when there is an error. The profile sets the severity of each rule:

ProfileEffect
strict (the default)each finding is an error
basic1.6 and 6.3 are warnings

[rules] changes one rule, and [languages.<name>.rules] changes it for the files of one language. The language value applies first, then [rules], then the profile:

profile = "basic"

[rules]
"4.2" = "off"

[languages.markdown.rules]
"1.6" = "off"

A rule that gives no findings cannot be set. memelint stops with an error message when it reads memelint.toml.

Languages

memelint lints each language that has a tree-sitter grammar. The grammar name is the key of [languages.<name>], for example rust, python, cpp or markdown.

Rust, Python, JavaScript, TypeScript, Go, C, Java, Nix, TOML and Markdown are compiled in. For each other language memelint loads <name>.so from a grammar directory, in this sequence:

  1. --grammars <dir>
  2. each directory in MEMELINT_GRAMMARS
  3. ~/.local/share/memelint/grammars

These are the grammar files that Neovim and nixpkgs make. The Nix package sets MEMELINT_GRAMMARS to all the grammars in nixpkgs. When a file has no grammar, memelint does not examine it, and gives a note at the end.

A [languages.<name>] table has the keys words, word-lists, default-word-lists and rules, for the files of that language.

Markdown files are prose. memelint reads their paragraphs, headings and table cells, and not their code blocks.