• Stars
    star
    679
  • Rank 63,937 (Top 2 %)
  • Language
    Lua
  • License
    GNU General Publi...
  • Created about 3 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An asynchronous linter plugin for Neovim complementary to the built-in Language Server Protocol support.

nvim-lint

An asynchronous linter plugin for Neovim (>= 0.6.0) complementary to the built-in Language Server Protocol support.

Motivation & Goals

With ale we already got an asynchronous linter, why write yet another one?

Because ale reports diagnostics with its own home grown solution and even includes its own language server client.

nvim-lint instead uses the vim.diagnostic module to present diagnostics in the same way the language client built into neovim does. nvim-lint is meant to fill the gaps for languages where either no language server exists, or where standalone linters provide better results than the available language server do.

Installation

  • Requires Neovim >= 0.6.0
  • nvim-lint is a plugin. Install it like any other Neovim plugin.
    • If using vim-plug: Plug 'mfussenegger/nvim-lint'
    • If using packer.nvim: use 'mfussenegger/nvim-lint'

Usage

Configure the linters you want to run per file type. For example:

require('lint').linters_by_ft = {
  markdown = {'vale',}
}

Then setup a autocmd to trigger linting. For example:

au BufWritePost * lua require('lint').try_lint()

or with Lua autocmds (requires 0.7):

vim.api.nvim_create_autocmd({ "BufWritePost" }, {
  callback = function()
    require("lint").try_lint()
  end,
})

Some linters require a file to be saved to disk, others support linting stdin input. For such linters you could also define a more aggressive autocmd, for example on the InsertLeave or TextChanged events.

If you want to customize how the diagnostics are displayed, read :help vim.diagnostic.config.

Available Linters

There is a generic linter called compiler that uses the makeprg and errorformat options of the current buffer.

Other dedicated linters that are built-in are:

Tool Linter name
Set via makeprg compiler
actionlint actionlint
ansible-lint ansible_lint
bandit bandit
bean-check bean_check
buf_lint buf_lint
cfn-lint cfn_lint
cfn_nag cfn_nag
checkpatch.pl checkpatch
checkstyle checkstyle
chktex chktex
clang-tidy clangtidy
clazy clazy
clj-kondo clj-kondo
cmakelint cmakelint
codespell codespell
cppcheck cppcheck
cpplint cpplint
credo credo
cspell cspell
curlylint curlylint
djlint djlint
erb-lint erb_lint
ESLint eslint
eslint_d eslint_d
fennel fennel
Flake8 flake8
flawfinder flawfinder
Golangci-lint golangcilint
glslc glslc
DirectX Shader Compiler dxc
hadolint hadolint
hlint hlint
HTML Tidy tidy
Inko inko
janet janet
jshint jshint
jsonlint jsonlint
ktlint ktlint
lacheck lacheck
Languagetool languagetool
luacheck luacheck
markdownlint markdownlint
mlint mlint
Mypy mypy
Nix nix
npm-groovy-lint npm-groovy-lint
oelint-adv oelint-adv
php php
phpcs phpcs
phpmd phpmd
phpstan phpstan
proselint proselint
psalm psalm
pycodestyle pycodestyle
pydocstyle pydocstyle
Pylint pylint
Revive revive
rflint rflint
robocop robocop
rstcheck rstcheck
rstlint rstlint
Ruby ruby
RuboCop rubocop
Ruff ruff
Selene selene
ShellCheck shellcheck
sqlfluff sqlfluff
StandardRB standardrb
statix check statix
stylelint stylelint
Nagelfar nagelfar
Vale vale
Verilator verilator
vint vint
vulture vulture
yamllint yamllint
tfsec tfsec

Custom Linters

You can register custom linters by adding them to the linters table, but please consider contributing a linter if it is missing.

require('lint').linters.your_linter_name = {
  cmd = 'linter_cmd',
  stdin = true, -- or false if it doesn't support content input via stdin. In that case the filename is automatically added to the arguments.
  append_fname = true, -- Automatically append the file name to `args` if `stdin = false` (default: true)
  args = {}, -- list of arguments. Can contain functions with zero arguments that will be evaluated once the linter is used.
  stream = nil, -- ('stdout' | 'stderr' | 'both') configure the stream to which the linter outputs the linting result.
  ignore_exitcode = false, -- set this to true if the linter exits with a code != 0 and that's considered normal.
  env = nil, -- custom environment table to use with the external process. Note that this replaces the *entire* environment, it is not additive.
  parser = your_parse_function
}

Instead of declaring the linter as a table, you can also declare it as a function which returns the linter table in case you want to dynamically generate some of the properties.

your_parse_function can be a function which takes two arguments:

  • output
  • bufnr

The output is the output generated by the linter command. The function must return a list of diagnostics as specified in :help diagnostic-structure.

You can override the environment that the linting process runs in by setting the env key, e.g.

env = { ["FOO"] = "bar" }

Note that this completely overrides the environment, it does not add new environment variables. The one exception is that the PATH variable will be preserved if it is not explicitly set.

You can generate a parse function from a Lua pattern or from an errorformat using the function in the lint.parser module:

from_errorformat

parser = require('lint.parser').from_errorformat(errorformat)

The function takes a single argument which is the errorformat.

from_pattern

parser = require('lint.parser').from_pattern(pattern, groups, severity_map, defaults, opts)

The function allows to parse the linter's output using a Lua regular expression pattern.

  • pattern: The regular expression pattern applied on each line of the output
  • groups: The groups specified by the pattern

Available groups:

  • lnum
  • end_lnum
  • col
  • end_col
  • message
  • file
  • severity
  • code

The order of the groups must match the order of the captures within the pattern. An example:

local pattern = '[^:]+:(%d+):(%d+):(%w+):(.+)'
local groups = { 'lnum', 'col', 'code', 'message' }
  • severity: A mapping from severity codes to diagnostic codes
default_severity = {
['error'] = vim.diagnostic.severity.ERROR,
['warning'] = vim.diagnostic.severity.WARN,
['information'] = vim.diagnostic.severity.INFO,
['hint'] = vim.diagnostic.severity.HINT,
}
  • defaults: The defaults diagnostic values
defaults = {["source"] = "mylint-name"}
  • opts: Additional options

    • end_col_offset: offset added to end_col. Defaults to -1, assuming that the end-column position is exclusive.

Customize built-in linter parameters

You can import a linter and modify its properties. An example:

local phpcs = require('lint').linters.phpcs
phpcs.args = {
  '-q',
  -- <- Add a new parameter here
  '--report=json',
  '-'
}

Alternatives

Development ☢️

Run tests

Running tests requires busted.

See neorocks or Using Neovim as Lua interpreter with Luarocks for installation instructions.

busted tests/

More Repositories

1

nvim-dap

Debug Adapter Protocol client implementation for Neovim
Lua
3,600
star
2

nvim-jdtls

Extensions for the built-in LSP support in Neovim for eclipse.jdt.ls
Lua
657
star
3

nvim-treehopper

Region selection with hints on the AST nodes of a document powered by treesitter
Lua
369
star
4

nvim-dap-python

An extension for nvim-dap, providing default configurations for python and methods to debug individual test methods or classes.
Lua
297
star
5

dotfiles

Various config files from my home directory
Lua
73
star
6

nvim-lsp-compl

A fast and asynchronous auto-completion plugin for Neovim, focused on LSP.
Lua
67
star
7

nvim-fzy

Fuzzy picker & vim.ui.select implementation via fzy for neovim
Lua
50
star
8

cr8

CLI collection of utilities for working with CrateDB or PostgreSQL. Benchmark queries, insert data.
Python
34
star
9

knx

python knx / eib client library
Python
26
star
10

mkjson

A commandline tool to generate static or random JSON records
Haskell
26
star
11

tornado-template

Tornado template with Jinja2 and Sqlalchemy
Python
22
star
12

nvim-lua-debugger

a Debug Adapter that allows debugging lua plugins written for Neovim
Lua
18
star
13

nvim-ansible

Small neovim plugin to make working with Ansible playbooks or roles more convenient
Lua
14
star
14

nvim-qwahl

Pickers for vim.ui.select
Lua
13
star
15

Huluobo

Web based rss reader written in python using tornado
CSS
13
star
16

crate-mono

Unmaintained Mono/.NET client driver for crate. Use npgsql-cratedb instead.
C#
10
star
17

easymail

A module that makes sending (valid) emails from python a little bit easier.
Python
6
star
18

pypsh

UNMAINTAINED: remotely execute commands in parallel with ssh on hostnames that match a regex.
Python
5
star
19

BaanPrint

Very simple output management framework for Infor ERP LN written in python.
Python
5
star
20

dinspect

Commandline tool to turn JSON into a chart
Python
3
star
21

docker-tornado-crate-demo

Simple demo showing how to run a python web app inside a docker container with a linked crate container
Python
3
star
22

crate-autocomplete

Plugin for Crate that provides SQL auto-complete functionality.
Java
3
star
23

java-benchopedia

Java
3
star
24

spacman

simple wrapper around pacman/pacsearch/aria2c to improve file download speed
Python
1
star
25

paperstore

python script to scan documents and search them later using a fulltext index
Python
1
star
26

crate-udf

Plugin for Crate that provides a mechanism to load user defined functions
Java
1
star
27

riccodo

generates static html sites from markdown files using jinja
Python
1
star
28

crate-peewee

Crate driver for peewee
Python
1
star