Why Should You Lint Markdown?

Isn't the syntax easy enough? There's nothing that can go wrong. Right?

The goal of some markdown linters is to offer a consistent style, and to avoid obvious mistakes (e.g., duplicated headings).

Some plugins also provide help in improving your writing style.

Linting in Vim

ALE is a popular lint engine for Vim and NeoVim. ALE also offers interfaces for markdown linters.

You can see a list of all supported plugins on GitHub.

Here are some examples for Markdown:

These tools offer different functionalities.

For example, remark-lint and markdownlint fall into the first category. These plugins check the file's syntax (single trailing newline, code fence style, etc.). The linters make sure that your markdown files are up to standards and that the formatting is consistent.

Tools like proselint or write-good are examples of the second category. They offer suggestions for writing. They try to improve your style by pointing out ambiguous wording or the use of passive voice.

Install The Linters

Take a look at the respective documentations and decide which linters you'd like to use. You have to install every tool per hand.

Let's take a look at markdownlint, which is a tool written in Ruby:

gem install mdl

write-good is a JavaScript tool. You can install it with npm:

npm install write-good

Install And Configure ALE

Now let's configure Vim to integrate with the linters.

Install ALE with your Vim package manager (or find alternative instructions on GitHub).

For example:

call minpac#add('dense-analysis/ale')

Example setup in your init.vim (or .vimrc):

let g:ale_sign_error                  = '✘'
let g:ale_sign_warning                = '⚠'
highlight ALEErrorSign ctermbg        =NONE ctermfg=red
highlight ALEWarningSign ctermbg      =NONE ctermfg=yellow
let g:ale_linters_explicit            = 1
let g:ale_lint_on_text_changed        = 'never'
let g:ale_lint_on_enter               = 0
let g:ale_lint_on_save                = 1
let g:ale_fix_on_save                 = 1

let g:ale_linters = {
\   'markdown':      ['mdl', 'writegood'],

let g:ale_fixers = {
\   '*':          ['remove_trailing_lines', 'trim_whitespace'],

Improve ALE's performance by setting the linters you need and don't lint every time you type in something.
Fix a file when you save or call :ALEFix manually.
See :h ale for more information.