Since publishing this post, the textlint checker below has been integrated upstream on 24 January 2019, giving Flycheck built-in support for textlint.
The blog post below is preserved as an archive.
Here is a setup guide for configuring textlint with Flycheck's built-in support for textlint.
textlint is an open source pluggable linting tool for natural language text.
This post shows how to integrate textlint with flycheck in the Emacs text editor, e.g.
This configuration uses textlint plugins:
It supports modes:
For other modes see "Configuration" below.
Install npx
:
sudo npm install -g npx
Download the textlint rules and the latex plugin:
npm install textlint write-good textlint-plugin-latex textlint-rule-write-good textlint-rule-no-start-duplicated-conjunction textlint-rule-max-comma textlint-rule-terminology textlint-rule-period-in-list-item textlint-rule-unexpanded-acronym textlint-rule-abbr-within-parentheses textlint-rule-alex textlint-rule-common-misspellings textlint-rule-en-max-word-count textlint-rule-diacritics textlint-rule-stop-words
Now test the file by creating a file file.txt
:
echo "Mistakes were made." > file.txt
Now try textlint
:
npx textlint --rule write-good --rule no-start-duplicated-conjunction --rule max-comma --rule terminology --rule period-in-list-item --rule period-in-list-item --rule unexpanded-acronym --rule abbr-within-parentheses --rule alex --rule common-misspellings --rule en-max-word-count --rule diacritics --rule stop-words file.txt
This should print:
file.txt:1:10: "were made" may be passive voice [Error/write-good]
This GitHub gist inspires the elisp below.
Put it in your ~/.emacs
, ~/.emacs.el
, or ~/.emacs.d/init.el
file:
Edit the location of .textlintrc
for the --config
flag.
(require 'flycheck) (flycheck-define-checker textlint "A linter for textlint." :command ("npx" "textlint" "--config" "/home/rob/.emacs.d/.textlintrc" "--format" "unix" "--rule" "write-good" "--rule" "no-start-duplicated-conjunction" "--rule" "max-comma" "--rule" "terminology" "--rule" "period-in-list-item" "--rule" "abbr-within-parentheses" "--rule" "alex" "--rule" "common-misspellings" "--rule" "en-max-word-count" "--rule" "diacritics" "--rule" "stop-words" "--plugin" (eval (if (derived-mode-p 'tex-mode) "latex" "@textlint/text")) source-inplace) :error-patterns ((warning line-start (file-name) ":" line ":" column ": " (message (one-or-more not-newline) (zero-or-more "\n" (any " ") (one-or-more not-newline))) line-end)) :modes (text-mode latex-mode org-mode markdown-mode) ) (add-to-list 'flycheck-checkers 'textlint)
It supports text-mode, latex-mode, org-mode and markdown-mode.
If flycheck-mode
is not enabled for your buffer: M-x
flcheck-mode
. Display the textlint warnings for file.txt
with: C-c
! l
.
Debugging If flycheck errors buffer shows no warnings, debug
textlint
by running C-c ! C-c
which will run the textlint
command in a new buffer. It should show:
npx textlint --config /home/rob/.emacs.d/.textlintrc --format unix --rule write-good --rule no-start-duplicated-conjunction --rule max-comma --rule terminology --rule period-in-list-item --rule abbr-within-parentheses --rule alex --rule common-misspellings --rule en-max-word-count --rule diacritics --rule stop-words --plugin \@textlint/text mistakes.txt file.txt:1:10: "were made" may be passive voice [Error/write-good] 1 problem
textlint is customisable:
textlint applies no rules by default, rules must be used with the
--rule
flag.
Each rule is configurable, e.g. passive mode checks can be
disabled in the write-good
plugin.
You can modify .textlintrc
to customise the rules. The hyperlinks
above provide details on rule specific customisations.
E.g. to disable some checks in the write-good
rule:
{ "rules": { "write-good": { "passive": false, "thereIs": false } } }
There are two ways to support additional file types:
Develop a plugin, e.g. the latex textlint plugin, which parses
latex content, which removes latex syntax leaving just text
content. This eliminates textlint false positives (on spurious
syntax e.g. \begin{section}
.. \end{section}
), but requires
more engineering than the 2nd approach. I've started an org-mode
plugin, a pull request to complete the implementation is welcome
:)
Add additional file extensions to be treated as plain text files, where spurious syntax may be picked up by textlint rules.
E.g. adding the following to the .textlintrc
file tells
textlint
to treat .org
files (org mode) as text files:
{ "plugins": { "@textlint/text": { "extensions": [".org"] } } }
Acknowledgement
Thanks to Blair Archibald for feedback on a draft of this post and Malcolm Purvis for improving the flycheck integration.