Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

License

NotificationsYou must be signed in to change notification settings

mfussenegger/nvim-lint

Repository files navigation

An asynchronous linter plugin for Neovim (>= 0.9.5) complementary to thebuilt-in Language Server Protocol support.

Motivation & Goals

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

Becauseale also includes its own language server client.

nvim-lint instead has a more narrow scope: It spawns linters, parses theiroutput, and reports the results via thevim.diagnostic module.

nvim-lint complements the built-in language server client for languages wherethere are no language servers, or where standalone linters provide betterresults.

Installation

  • Requires Neovim >= 0.9.5
  • nvim-lint is a regular plugin and can be installed via the:h packagesmechanism or via a plugin manager.

For example:

git clone \    https://github.com/mfussenegger/nvim-lint.git~/.config/nvim/pack/plugins/start/nvim-lint

Usage

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

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

To get thefiletype of a buffer you can run:= vim.bo.filetype.Thefiletype can also be a compoundfiletype. For example, if you have a bufferwith afiletype likeyaml.ghaction, you can use eitherghaction,yaml orthe fullyaml.ghaction as key in thelinters_by_ft table and the linterwill be picked up in that buffer. This is useful for linters likeactionlint in combination withvim.filetype patterns like[".*/.github/workflows/.*%.yml"] = "yaml.ghaction",

Then setup aautocmd to trigger linting. For example:

auBufWritePost*luarequire('lint').try_lint()

or with Lua auto commands:

vim.api.nvim_create_autocmd({"BufWritePost"}, {callback=function()-- try_lint without arguments runs the linters defined in `linters_by_ft`-- for the current filetyperequire("lint").try_lint()-- You can call `try_lint` with a linter name or a list of names to always-- run specific linters, independent of the `linters_by_ft` configurationrequire("lint").try_lint("cspell")end,})

Some linters require a file to be saved to disk, others support lintingstdininput. For such linters you could also define a more aggressiveautocmd, forexample on theInsertLeave orTextChanged events.

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

Available Linters

There is a generic linter calledcompiler that uses themakeprg anderrorformat options of the current buffer.

Other dedicated linters that are built-in are:

ToolLinter name
Set viamakeprgcompiler
actionlintactionlint
alexalex
amebaameba
ansible-lintansible_lint
banditbandit
bashbash
bean-checkbean_check
biomejsbiomejs
blocklintblocklint
buf_lintbuf_lint
buildifierbuildifier
cfn-lintcfn_lint
cfn_nagcfn_nag
checkmakecheckmake
checkpatch.plcheckpatch
checkstylecheckstyle
chktexchktex
clang-tidyclangtidy
clazyclazy
clippyclippy
clj-kondoclj-kondo
cmakelintcmakelint
cmake-lintcmake_lint
codespellcodespell
commitlintcommitlint
cppcheckcppcheck
cpplintcpplint
credocredo
cspellcspell
cuecue
curlylintcurlylint
dashdash
dclintdclint
deadnixdeadnix
denodeno
detect-secretsdetect-secrets
dmypydmypy
DirectX Shader Compilerdxc
djlintdjlint
dotenv-linterdotenv_linter
editorconfig-checkereditorconfig-checker
erb-linterb_lint
ESLinteslint
eslint_deslint_d
eugeneeugene
fennelfennel
fieldalignmentfieldalignment
fishfish
Flake8flake8
flawfinderflawfinder
fortitudefortitude
fsharplintfsharplint
gawkgawk
gdlint (gdtoolkit)gdlint
GHDLghdl
gitlintgitlint
glslcglslc
Golangci-lintgolangcilint
hadolinthadolint
hledgerhledger
hlinthlint
htmlhinthtmlhint
HTML Tidytidy
Inkoinko
janetjanet
jokerjoker
jshintjshint
json5json5
jsonlintjsonlint
json.tooljson_tool
kshksh
ktlintktlint
lachecklacheck
Languagetoollanguagetool
lslintlslint
luacluac
luacheckluacheck
markdownlintmarkdownlint
markdownlint-cli2markdownlint-cli2
markuplintmarkuplint
mlintmlint
Mypymypy
Nagelfarnagelfar
Nixnix
npm-groovy-lintnpm-groovy-lint
oelint-advoelint-adv
opa_checkopa_check
tofutofu
oxlintoxlint
perlcriticperlcritic
perlimportsperlimports
phpcsphpcs
phpinsightsphpinsights
phpmdphpmd
phpphp
phpstanphpstan
pmdpmd
ponycpony
prisma-lintprisma-lint
proselintproselint
protolintprotolint
psalmpsalm
puppet-lintpuppet-lint
pycodestylepycodestyle
pydocstylepydocstyle
Pylintpylint
pyproject-flake8pflake8
quick-lint-jsquick-lint-js
redoclyredolcy
regalregal
Reviverevive
rflintrflint
robocoprobocop
rpmlintrpmlint
RPMrpmspec
rstcheckrstcheck
rstlintrstlint
RuboCoprubocop
Rubyruby
Ruffruff
salt-lintsaltlint
Seleneselene
ShellCheckshellcheck
slangslang
Snakemakesnakemake
snyksnyk_iac
Solhintsolhint
Spectralspectral
sphinx-lintsphinx-lint
sqlfluffsqlfluff
sqruffsqruff
standardjsstandardjs
StandardRBstandardrb
statix checkstatix
stylelintstylelint
svlintsvlint
SwiftLintswiftlint
systemd-analyzesystemd-analyze
systemdlintsystemdlint
tflinttflint
tfsectfsec
tlinttlint
trivytrivy
ts-standardts-standard
twig-cs-fixertwig-cs-fixer
typostypos
Valavala_lint
Valevale
Verilatorverilator
vintvint
VSGvsg
vulturevulture
wokewoke
write-goodwrite_good
yamllintyamllint
yqyq
zizmorzizmor
zlintzlint
zshzsh

Custom Linters

You can register custom linters by adding them to thelinters table, butplease 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 afunction which returns the linter table in case you want to dynamicallygenerate some of the properties.

your_parse_function can be a function which takes three arguments:

  • output
  • bufnr
  • linter_cwd

Theoutput 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 settingtheenv key, e.g.

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

Note that this completely overrides the environment, it does not add newenvironment variables. The one exception is that thePATH variable will bepreserved if it is not explicitly set.

You can generate a parse function from a Lua pattern, from anerrorformator forSARIF using the functions in thelint.parser module:

for_sarif

parser=require("lint.parser").for_sarif()

The function takes an optional argument:

  • skeleton: Default values for the diagnostics

from_errorformat

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

The function takes two arguments:errorformat andskeleton (optional).

from_pattern

Creates a parser function from a pattern.

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

pattern

The function allows to parse the linter's output using a pattern which can be either:

  • A Lua pattern. See:help lua-pattern.
  • A LPEG pattern object. See:help vim.lpeg.
  • A function (fun(line: string):string[]). It takes one parameter - a linefrom the linter output and must return a string array with the matches. Thearray should be empty if there was no match.

groups

The groups specify the result format of 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:

localpattern='[^:]+:(%d+):(%d+):(%w+):(.+)'localgroups= {'lnum','col','code','message'}

The captures in the pattern correspond to the group at the same position.

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

  • lnum_offset: Added tolnum. Defaults to 0
  • end_lnum_offset: Added toend_lnum. Defaults to 0
  • end_col_offset: offset added toend_col. Defaults to-1, assumingthat the end-column position is exclusive.

Customize built-in linters

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

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

Some linters are defined as function for lazy evaluation of some properties.In this case, you need to wrap them like this:

localoriginal=require("lint").linters.terraform_validaterequire("lint").linters.terraform_validate=function()locallinter=original()linter.cmd="my_custom"returnlinterend

You can also post-process the diagnostics produced by a linter by wrapping it.For example, to change the severity of all diagnostics created bycspell:

locallint=require("lint")lint.linters.cspell=require("lint.util").wrap(lint.linters.cspell,function(diagnostic)diagnostic.severity=vim.diagnostic.severity.HINTreturndiagnosticend)

Display configuration

See:help vim.diagnostic.config.

If you want to have different settings per linter, you can get thenamespacefor a linter viarequire("lint").get_namespace("linter_name"). An example:

localns=require("lint").get_namespace("my_linter_name")vim.diagnostic.config({virtual_text=true },ns)

Get the current running linters for your buffer

You can see which linters are running withrequire("lint").get_running().To include the running linters in the status line you could format them like this:

locallint_progress=function()locallinters=require("lint").get_running()if#linters==0thenreturn"󰦕"endreturn"󱉶"..table.concat(linters,",")end

Alternatives

Development ☢️

Run tests

Running tests requiresbusted.

Seeneorocks orUsing Neovim as Lua interpreter withLuarocks for installation instructions.

busted tests/

Docs

API docs is generated usingvimcats:

vimcats -t -f lua/lint.lua lua/lint/parser.lua > doc/lint.txt

About

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

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Languages


[8]ページ先頭

©2009-2025 Movatter.jp