Git Product home page Git Product logo

nvim-lint's Introduction

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 <buffer> lua require('lint').try_lint()

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
ansible-lint ansible_lint
checkstyle checkstyle
chktex chktex
clang-tidy clangtidy
clazy clazy
clj-kondo clj-kondo
cmakelint cmakelint
codespell codespell
cppcheck cppcheck
cpplint cpplint
cspell cspell
ESLint eslint
fennel fennel
Flake8 flake8
flawfinder flawfinder
Golangci-lint golangcilint
hadolint hadolint
hlint hlint
HTML Tidy tidy
Inko inko
jshint jshint
Languagetool languagetool
luacheck luacheck
markdownlint markdownlint
mlint mlint
Mypy mypy
nix nix
proselint proselint
pycodestyle pycodestyle
pydocstyle pydocstyle
Pylint pylint
Revive revive
rflint rflint
robocop robocop
rstcheck rstcheck
rstlint rstlint
Ruby ruby
Selene selene
ShellCheck shellcheck
StandardRB standardrb
statix check statix
stylelint stylelint
Vale vale
vint vint
vulture vulture
yamllint yamllint

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.
  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)

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"}

Alternatives

Development ☢️

Run tests

Running tests requires plenary.nvim to be checked out in the parent directory of this repository. You can then run:

nvim --headless --noplugin -u tests/minimal.vim -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/minimal.vim'}"

Or if you want to run a single test file:

nvim --headless --noplugin -u tests/minimal.vim -c "PlenaryBustedDirectory tests/vale_spec.lua {minimal_init = 'tests/minimal.vim'}"

nvim-lint's People

Contributors

mfussenegger avatar gpanders avatar mflova avatar cyntheticfox avatar dhruvmanila avatar tastyep avatar lithammer avatar xenrox avatar yutsuten avatar mekpavit avatar lispyclouds avatar yorickpeterse avatar nanotee avatar midnightexigent avatar longerhv avatar jurij-robba avatar heygarrett avatar mirryi avatar tsjordan-eng avatar tom-anders avatar patrick96 avatar cpkio avatar will avatar wbthomason avatar vatosarmat avatar julian avatar languitar avatar jeroen-rooijmans avatar jhchabran avatar lancewl avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.