1

Regenerate nvim config

This commit is contained in:
2024-06-02 03:29:20 +02:00
parent 75eea0c030
commit ef2e28883d
5576 changed files with 604886 additions and 503 deletions

View File

@ -0,0 +1,28 @@
return {
cmd = 'actionlint',
stdin = true,
args = { '-format', '{{json .}}', '-' },
ignore_exitcode = true,
parser = function(output)
if output == '' then
return {}
end
local decoded = vim.json.decode(output)
if decoded == nil then
return {}
end
local diagnostics = {}
for _, item in ipairs(decoded) do
table.insert(diagnostics, {
lnum = item.line - 1,
end_lnum = item.line - 1,
col = item.column - 1,
end_col = item.end_column,
severity = vim.diagnostic.severity.WARN,
source = 'actionlint: ' .. item.kind,
message = item.message,
})
end
return diagnostics
end,
}

View File

@ -0,0 +1,29 @@
local pattern = "%s*(%d+):(%d+)-(%d+):(%d+)%s+(%w+)%s+(.-)%s+%s+(%g+)%s+%g+"
local groups = { "lnum", "col", "end_lnum", "end_col", "severity", "message", "code" }
local severity_map = {
warning = vim.diagnostic.severity.WARN,
error = vim.diagnostic.severity.ERROR,
}
return {
cmd = "alex",
stdin = true,
stream = "stderr",
ignore_exitcode = true,
args = {
"--stdin",
function()
if vim.bo.ft == "html" then
return "--html"
elseif vim.bo.ft ~= "markdown" then
return "--text"
end
end,
},
parser = require("lint.parser").from_pattern(
pattern,
groups,
severity_map,
{ severity = vim.diagnostic.severity.WARN, source = "alex" }
),
}

View File

@ -0,0 +1,9 @@
return {
cmd = 'ansible-lint',
args = { '-p', '--nocolor' },
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat('%f:%l: %m', {
source = 'ansible-lint',
severity = vim.diagnostic.severity.INFO
})
}

View File

@ -0,0 +1,28 @@
local pattern = [[(%d+):(%d+):(%u+):(%w+) (.*)]]
local groups = { "lnum", "col", "severity", "code", "message" }
local severity_map = {
["HIGH"] = vim.diagnostic.severity.ERROR,
["MEDIUM"] = vim.diagnostic.severity.WARN,
["LOW"] = vim.diagnostic.severity.INFO,
}
local defaults = {
source = "bandit",
}
return {
cmd = "bandit",
stdin = false,
args = {
"-f",
"custom",
"--msg-template",
"{line}:{col}:{severity}:{test_id} {msg}",
},
stream = "stdout",
ignore_exitcode = true,
parser = require("lint.parser").from_pattern(pattern, groups, severity_map, defaults, {
col_offset = 0,
}),
}

View File

@ -0,0 +1,10 @@
return {
cmd = 'bean-check',
stdin = false,
stream = 'stderr',
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat('%f:%l: %m', {
source = 'bean-check',
severity = vim.diagnostic.severity.ERROR,
})
}

View File

@ -0,0 +1,83 @@
-- Sample biome lint output:
--
-- index.js:6:13 lint/suspicious/noDoubleEquals FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
--
-- ✖ Use === instead of ==
--
-- 4 │ count += 1;
-- 5 │ var f = function (opt) {
-- > 6 │ if (opt == true) {
-- │ ^^
-- 7 │ return "true";
-- 8 │ }
--
-- == is only allowed when comparing against null
--
-- 4 │ count += 1;
-- 5 │ var f = function (opt) {
-- > 6 │ if (opt == true) {
-- │ ^^
-- 7 │ return "true";
-- 8 │ }
--
-- Using === may be unsafe if you are relying on type coercion
--
-- Suggested fix: Use ===
--
-- 6 │ ····if·(opt·===·true)·{
-- │
local binary_name = "biome"
return {
cmd = function()
local local_binary = vim.fn.fnamemodify('./node_modules/.bin/' .. binary_name, ':p')
return vim.loop.fs_stat(local_binary) and local_binary or binary_name
end,
args = { "lint" },
stdin = false,
ignore_exitcode = true,
stream = "both",
parser = function(output)
local diagnostics = {}
-- The diagnostic details we need are spread in the first 3 lines of
-- each error report. These variables are declared out of the FOR
-- loop because we need to carry their values to parse multiple lines.
local fetch_message = false
local lnum, col, code, message
-- When a lnum:col:code line is detected fetch_message is set to true.
-- While fetch_message is true we will search for the error message.
-- When a error message is detected, we will create the diagnostic and
-- set fetch_message to false to restart the process and get the next
-- diagnostic.
for _, line in ipairs(vim.fn.split(output, "\n")) do
if fetch_message then
_, _, message = string.find(line, "%s×(.+)")
if message then
message = (message):gsub("^%s+×%s*", "")
table.insert(diagnostics, {
source = "biomejs",
lnum = tonumber(lnum) - 1,
col = tonumber(col),
message = message,
code = code
})
fetch_message = false
end
else
_, _, lnum, col, code = string.find(line, "[^:]+:(%d+):(%d+)%s([%a%/]+)")
if lnum then
fetch_message = true
end
end
end
return diagnostics
end
}

View File

@ -0,0 +1,9 @@
return {
cmd = "blocklint",
args = { "--stdin", "--end-pos" },
stdin = true,
parser = require("lint.parser").from_errorformat("stdin:%l:%c:%k: %m", {
source = "blocklint",
severity = vim.diagnostic.severity.INFO,
}),
}

View File

@ -0,0 +1,31 @@
return {
cmd = 'buf',
args = { 'lint', '--error-format', 'json' },
stdin = false,
ignore_exitcode = true,
parser = function(output)
if output == '' then
return {}
end
local lines = vim.split(output, '\n')
local diagnostics = {}
for _, line in ipairs(lines) do
if line == '' then
break
end
local item = vim.json.decode(line)
if item then
table.insert(diagnostics, {
lnum = (item.start_line or 1) - 1,
col = (item.start_column or 1) - 1,
end_lnum = (item.end_line or 1) - 1,
end_col = (item.end_column or 1) - 1,
severity = vim.diagnostic.severity.WARN,
source = item.type,
message = item.message,
})
end
end
return diagnostics
end,
}

View File

@ -0,0 +1,134 @@
-- See the source for the formats
-- https://github.com/bazelbuild/buildtools/blob/b31f2c13c407575100d4614bcc9a3c60be07cc1c/buildifier/utils/diagnostics.go#L39
local function get_cur_file_type(bufnr)
-- Logic taken from https://github.com/bazelbuild/buildtools/blob/master/build/lex.go#L125
bufnr = bufnr or 0
local fname = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(bufnr), ':t')
fname = string.lower(fname)
if fname == "module.bazel" then
return "module"
elseif vim.endswith(fname, ".bzl") then
return "bzl"
elseif vim.endswith(fname, ".sky") then
return "default"
elseif fname == "build" or vim.startswith(fname, "build.") or vim.endswith(fname, ".build") then
return "build"
elseif fname == "workspace" or vim.startswith(fname, "workspace.") or vim.endswith(fname, ".workspace") then
return "workspace"
else
return "default"
end
end
local function parse_stdout_json(bufnr, line)
local diagnostics = {}
local out = vim.json.decode(line)
if out.success == true then
return diagnostics
end
local f = out.files[1]
if not f.warnings then
return diagnostics
end
if not f.formatted then
table.insert(diagnostics, {
bufnr = bufnr,
lnum = 0,
col = 0,
severity = vim.diagnostic.severity.HINT,
source = 'buildifier',
message = 'Please run buildifier to reformat the file contents.',
code = 'reformat',
})
end
for _, item in ipairs(f.warnings) do
local severity = vim.diagnostic.severity.INFO
if item.actionable == true then
severity = vim.diagnostic.severity.WARN
end
table.insert(diagnostics, {
bufnr = bufnr,
lnum = item.start.line - 1,
col = item.start.column - 1,
end_lnum = item["end"].line - 1,
end_col = item["end"].column - 1,
severity = severity,
source = 'buildifier',
message = item.message .. '\n\n' .. item.url,
code = item.category,
})
end
return diagnostics
end
local function parse_stderr_line(bufnr, line)
-- This part parses the buildifier output that usually comes via stderr which
-- is not in JSON format yet.
local parts = vim.split(line, ":")
local lnum, col, message = 0, 0, ""
if #parts >= 4 then
lnum = tonumber(parts[2]) - 1
col = tonumber(parts[3]) - 1
message = table.concat(parts, ":", 4)
elseif #parts == 3 then
message = parts[3]
elseif #parts == 2 then
message = parts[2]
elseif #parts == 1 then
message = line
end
if message ~= "" then
return {{
bufnr = bufnr,
lnum = lnum,
col = col,
severity = vim.diagnostic.severity.ERROR,
source = 'buildifier',
message = message:gsub("^%s+", ""),
code = 'syntax',
}}
end
return {}
end
return {
cmd = 'buildifier',
args = {
"-lint", "warn",
"-mode", "check",
"-warnings", "all",
"-format", "json",
"-type", get_cur_file_type
},
stdin = true,
append_fname = false,
stream = "both",
parser = function(output, bufnr)
local diagnostics = {}
local lines = vim.split(output, '\n')
for _, line in ipairs(lines) do
if vim.startswith(line, '{') then
for _, d in ipairs(parse_stdout_json(bufnr, line)) do
table.insert(diagnostics, d)
end
else
for _, d in ipairs(parse_stderr_line(bufnr, line)) do
table.insert(diagnostics, d)
end
end
end
return diagnostics
end,
}

View File

@ -0,0 +1,13 @@
local pattern = "([^:]+):(%d+):(%d+):(%d+):(%d+):(%w)(%d+):(.*)"
local groups = { "file", "lnum", "col", "end_lnum", "end_col", "severity", "code", "message" }
local severity_map = {
["W"] = vim.diagnostic.severity.WARN,
["E"] = vim.diagnostic.severity.ERROR,
}
return {
cmd = "cfn-lint",
args = { "--format", "parseable" },
stdin = false,
parser = require("lint.parser").from_pattern(pattern, groups, severity_map, { ["source"] = "cfn-lint" }),
}

View File

@ -0,0 +1,34 @@
local severity_map = {
["WARN"] = vim.diagnostic.severity.WARN,
["FAIL"] = vim.diagnostic.severity.ERROR,
}
return {
cmd = "cfn_nag_scan",
stdin = false,
args = { "--output-format", "json", "--input-path" },
parser = function(output)
if output == nil then
return {}
end
local diagnostics = {}
local decoded = vim.json.decode(output)
local violations = decoded[1].file_results.violations
for _, violation in pairs(violations) do
for _, line in pairs(violation.line_numbers) do
table.insert(diagnostics, {
lnum = line,
end_lnum = line,
col = 1,
code = violation.id,
severity = assert(severity_map[violation.type], "missing mapping for severity " .. violation.type),
message = violation.message,
})
end
end
return diagnostics
end,
}

View File

@ -0,0 +1,16 @@
local pattern = "(%d+):(%w+):(.+)"
local groups = { "lnum", "code", "message" }
return {
cmd = "checkmake",
stdin = false,
append_fname = true,
args = {
"--format='{{.LineNumber}}:{{.Rule}}:{{.Violation}}\n'",
},
ignore_exitcode = true,
parser = require("lint.parser").from_pattern(pattern, groups, nil, {
["source"] = "checkmake",
["severity"] = vim.diagnostic.severity.WARN,
}),
}

View File

@ -0,0 +1,27 @@
-- The scripts/ directory of the Linux kernel tree needs to be in your PATH or
-- the full path to the checkpatch.pl script can be overriden from user config:
-- require("lint").linters.checkpatch.cmd = '…/checkpatch.pl'
-- path/to/file:line: severity: message
local pattern = '([^:]+):(%d+): (%a+): (.+)'
local groups = { 'file', 'lnum', 'severity', 'message' }
local severity_map = {
['ERROR'] = vim.diagnostic.severity.ERROR,
['WARNING'] = vim.diagnostic.severity.WARN,
['CHECK'] = vim.diagnostic.severity.INFO,
}
return {
cmd = 'checkpatch.pl',
stdin = false,
args = {
'--strict',
'--terse',
'--file',
},
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(
pattern, groups, severity_map,
{ ['source'] = 'checkpatch' }
),
}

View File

@ -0,0 +1,23 @@
local format = '[%tRROR] %f:%l:%c: %m, [%tRROR] %f:%l: %m, [%tARN] %f:%l:%c: %m, [%tARN] %f:%l: %m'
local M
local function config()
if M.config_file == nil then
error "Missing checkstyle config. e.g.: `require('lint.linters.checkstyle').config_file = '/path/to/checkstyle_config.xml'`"
end
return M.config_file
end
M = {
cmd = 'checkstyle',
args = {'-c', config},
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat(format, {
source = 'checkstyle',
}),
-- use the bundled Google style by default
config_file = '/google_checks.xml'
}
return M

View File

@ -0,0 +1,42 @@
local pattern = '(%d+):(%d+):(%d+):(.+):(%d+):(.*)'
local severities = {
Error = vim.diagnostic.severity.ERROR,
Warning = vim.diagnostic.severity.WARN,
Message = vim.diagnostic.severity.INFO
}
return {
cmd = 'chktex',
stdin = true,
args = {'-v0', '-I0', '-s', ':', '-f', '%l%b%c%b%d%b%k%b%n%b%m%b%b%b'},
parser = function(output, _)
local result = vim.fn.split(output, ":::")
local diagnostics = {}
for _, line in ipairs(result) do
local lineno, off, d, sev, code, desc = string.match(line, pattern)
lineno = tonumber(lineno or 1) - 1
off = tonumber(off or 1) - 1
d = tonumber(d or 1)
table.insert(diagnostics, {
source = 'chktex',
lnum = lineno,
col = off,
end_lnum = lineno,
end_col = off + d,
message = desc,
severity = assert(severities[sev],
'missing mapping for severity ' .. sev),
code = code,
user_data = {
lsp = {
code = code
},
}
})
end
return diagnostics
end
}

View File

@ -0,0 +1,18 @@
local pattern = [[([^:]*):(%d+):(%d+): (%w+): ([^[]+)]]
local groups = { 'file', 'lnum', 'col', 'severity', 'message' }
local severity_map = {
['error'] = vim.diagnostic.severity.ERROR,
['warning'] = vim.diagnostic.severity.WARN,
['information'] = vim.diagnostic.severity.INFO,
['hint'] = vim.diagnostic.severity.HINT,
['note'] = vim.diagnostic.severity.HINT,
}
return {
cmd = 'clang-tidy',
stdin = false,
args = { '--quiet' },
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, severity_map, { ['source'] = 'clang-tidy' }),
}

View File

@ -0,0 +1,13 @@
-- Clazy will also emit clang's regular compiler warnings.
-- There doesn't seem to be a way to disable this,
-- so only filter out the ones starting with -Wclazy-
local pattern = [=[([^:]*):(%d+):(%d+): (%w+): ([^[]+) %[%-Wclazy%-(.*)%]]=]
local groups = { 'file', 'lnum', 'col', 'severity', 'message', 'code'}
return {
cmd = 'clazy-standalone',
stdin = false,
args = {},
stream = 'stderr',
parser = require('lint.parser').from_pattern(pattern, groups, nil, { ['source'] = 'clazy' }),
}

View File

@ -0,0 +1,36 @@
local severities = {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
}
local function get_file_name()
return vim.api.nvim_buf_get_name(0)
end
return {
cmd = 'clj-kondo',
stdin = true,
stream = 'stdout',
ignore_exitcode = true,
args = {
'--config', '{:output {:format :json}}', '--filename', get_file_name, '--lint', '-',
},
parser = function(output)
local decoded = vim.json.decode(output) or {}
local findings = decoded.findings
local diagnostics = {}
for _, finding in pairs(findings or {}) do
table.insert(diagnostics, {
lnum = finding.row - 1,
col = finding.col - 1,
end_lnum = finding.row - 1,
end_col = finding.col - 1,
severity = assert(severities[finding.level], 'missing mapping for severity ' .. finding.level),
message = finding.message,
})
end
return diagnostics
end,
}

View File

@ -0,0 +1,15 @@
-- path/to/file:line: message [code]
local pattern = '([^:]+):(%d+): (.+) %[(.+)%]'
local groups = { 'file', 'lnum', 'message', 'code' }
local is_windows = vim.loop.os_uname().version:match('Windows')
return {
cmd = is_windows and 'cmakelint.cmd' or 'cmakelint',
stdin = false,
args = {'--quiet'},
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, nil, {
['source'] = 'cmakelint',
['severity'] = vim.diagnostic.severity.WARN,
}),
}

View File

@ -0,0 +1,11 @@
return {
cmd = 'codespell',
stdin = false,
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat(
'%f:%l:%m',
{ severity = vim.diagnostic.severity.INFO,
source = 'codespell'}
)
}

View File

@ -0,0 +1,27 @@
return {
cmd = "commitlint",
stdin = true,
args = {},
ignore_exitcode = true,
parser = function(output)
local diagnostics = {}
local result = vim.fn.split(output, "\n")
for _, line in ipairs(result) do
local label = line:sub(1, 3)
if label == "" then
if not string.find(line, "found") then
table.insert(diagnostics, {
source = "commitlint",
lnum = 0,
col = 0,
severity = vim.diagnostic.severity.ERROR,
message = vim.fn.split(line, " ")[2],
})
end
end
end
return diagnostics
end,
}

View File

@ -0,0 +1,28 @@
local api = vim.api
return function()
local ok, errorformat = pcall(api.nvim_buf_get_option, 0, 'errorformat')
if not ok then
errorformat = vim.o.errorformat
end
local makeprg
ok, makeprg = pcall(api.nvim_buf_get_option, 0, 'makeprg')
if not ok then
makeprg = vim.o.makeprg
end
local bufname = api.nvim_buf_get_name(0)
local args = {
api.nvim_get_option('shellcmdflag'),
makeprg:gsub(' %%', ' ' .. bufname),
}
return {
cmd = vim.opt.shell:get(),
args = args,
stdin = false,
append_fname = false,
stream = 'both',
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat(errorformat)
}
end

View File

@ -0,0 +1,37 @@
-- cppcheck <= 1.84 doesn't support {column} so the start_col group is ambiguous
local pattern = [[([^:]*):(%d*):([^:]*): %[([^%]\]*)%] ([^:]*): (.*)]]
local groups = { "file", "lnum", "col", "code", "severity", "message" }
local severity_map = {
["error"] = vim.diagnostic.severity.ERROR,
["warning"] = vim.diagnostic.severity.WARN,
["performance"] = vim.diagnostic.severity.WARN,
["style"] = vim.diagnostic.severity.INFO,
["information"] = vim.diagnostic.severity.INFO,
}
return {
cmd = "cppcheck",
stdin = false,
args = {
"--enable=warning,style,performance,information",
function()
if vim.bo.filetype == "cpp" then
return "--language=c++"
else
return "--language=c"
end
end,
"--inline-suppr",
"--quiet",
function()
if vim.fn.isdirectory("build") == 1 then
return "--cppcheck-build-dir=build"
else
return nil
end
end,
"--template={file}:{line}:{column}: [{id}] {severity}: {message}",
},
stream = "stderr",
parser = require("lint.parser").from_pattern(pattern, groups, severity_map, { ["source"] = "cppcheck" }),
}

View File

@ -0,0 +1,15 @@
-- path/to/file:line: message [code] [code_id]
local pattern = '([^:]+):(%d+): (.+) (.+)'
local groups = { 'file', 'lnum', 'message', 'code'}
return {
cmd = 'cpplint',
stdin = false,
args = {},
ignore_exitcode = true,
stream = 'stderr',
parser = require('lint.parser').from_pattern(pattern, groups, nil, {
['source'] = 'cpplint',
['severity'] = vim.diagnostic.severity.WARN,
}),
}

View File

@ -0,0 +1,10 @@
local errorfmt = '[%t] %. stdin:%l:%c %m, [%t] %. stdin:%l %m'
return {
cmd = 'mix',
stdin = true,
args = { 'credo', 'list', '--format=oneline', '--read-from-stdin', '--strict'},
stream = 'stdout',
ignore_exitcode = true, -- credo only returns 0 if there are no errors
parser = require('lint.parser').from_errorformat(errorfmt, { ['source'] = 'credo' })
}

View File

@ -0,0 +1,38 @@
local efm = '%f:%l:%c - %m'
return {
cmd = 'cspell',
ignore_exitcode = true,
args = {
'lint',
'--no-color',
'--no-progress',
'--no-summary',
},
stream = 'stdout',
parser = function(output)
local lines = vim.split(output, '\n')
local qflist = vim.fn.getqflist({ efm = efm, lines = lines })
local result = {}
for _, item in pairs(qflist.items) do
if item.valid == 1 then
local message = item.text:match('^%s*(.-)%s*$')
local word = message:match('%(.*%)')
local lnum = math.max(0, item.lnum - 1)
local col = math.max(0, item.col - 1)
local end_lnum = item.end_lnum > 0 and (item.end_lnum - 1) or lnum
local end_col = col + word:len() - 2 or col
local diagnostic = {
lnum = lnum,
col = col,
end_lnum = end_lnum,
end_col = end_col,
message = message,
source = 'cspell',
severity = vim.diagnostic.severity.INFO
}
table.insert(result, diagnostic)
end
end
return result
end
}

View File

@ -0,0 +1,12 @@
local efm = "%E%m:,%C%f:%l:%c"
return {
cmd = "cue",
args = { "vet" },
stdin = false,
ignore_exitcode = true,
stream = "stderr",
parser = require("lint.parser").from_errorformat(efm, {
source = "cue vet",
}),
}

View File

@ -0,0 +1,12 @@
local efm = '%f:%l:%c: %m'
return {
cmd = 'curlylint',
args = {'--format', 'compact'},
stdin = false,
stream = 'stdout',
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat(efm, {
source = 'curlylint',
severity = vim.diagnostic.severity.WARN
})
}

View File

@ -0,0 +1,14 @@
local pattern = "(.+): (%d+): (.+)"
local groups = { "file", "lnum", "message" }
return {
cmd = "dash",
stdin = false,
ignore_exitcode = true,
args = { "-n" },
stream = "stderr",
parser = require("lint.parser").from_pattern(pattern, groups, nil, {
["source"] = "dash",
["severity"] = vim.diagnostic.severity.ERROR,
}),
}

View File

@ -0,0 +1,31 @@
return {
cmd = "deadnix",
stdin = false,
append_fname = true,
args = { "--output-format=json" },
stream = nil,
ignore_exitcode = false,
env = nil,
parser = function(output, _)
local diagnostics = {}
if output == "" then
return diagnostics
end
local decoded = vim.json.decode(output) or {}
for _, diag in ipairs(decoded.results) do
table.insert(diagnostics, {
lnum = diag.line - 1,
end_lnum = diag.line - 1,
col = diag.column - 1,
end_col = diag.endColumn,
message = diag.message,
severity = vim.diagnostic.severity.WARN,
})
end
return diagnostics
end,
}

View File

@ -0,0 +1,47 @@
return {
cmd = "deno",
stdin = false,
args = { 'lint', '--json' },
ignore_exitcode = true,
parser = function(output)
local decoded = vim.json.decode(output)
local diagnostics = {}
local groups = {
{ name = "diagnostics", severity = vim.diagnostic.severity.WARN },
{ name = "errors", severity = vim.diagnostic.severity.ERROR }
}
for _, group in ipairs(groups) do
for _, diag in ipairs(decoded[group.name]) do
-- Parse Error data
if group.name == "errors" then
local message, line, col
_, _, message, line, col = string.find(diag.message, "([%a%p%s]+):(%d+):(%d+)%s*")
-- build range data
diag["range"] = {
start = { line = tonumber(line), col = tonumber(col) },
["end"] = { line = tonumber(line), col = tonumber(col) },
}
-- override message
diag["message"] = message
end
table.insert(diagnostics, {
source = "deno",
lnum = diag.range.start.line - 1,
col = diag.range.start.col - 1,
end_lnum = diag.range["end"].line - 1,
end_col = diag.range["end"].col,
severity = group.severity,
message = diag.message,
code = diag.code
})
end
end
return diagnostics
end
}

View File

@ -0,0 +1,20 @@
local pattern = [[(%d+):(%d+):(%a%d+): (.*)]]
local groups = { 'lnum', 'col', 'code', 'message' }
local defaults = {
['source'] = 'djlint',
['severity'] = vim.diagnostic.severity.INFO
}
return {
cmd = 'djlint',
stdin = true,
args = {
'--linter-output-format',
'{line}:{code}: {message}',
'-',
},
stream = 'both',
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, nil, defaults, {}),
}

View File

@ -0,0 +1,15 @@
return {
cmd = "dotenv-linter",
stdin = false,
args = { "--quiet", "--no-color" },
stream = "stdout",
ignore_exitcode = true,
env = nil,
parser = require("lint.parser").from_pattern(
[=[%w+:(%d+) (%w+): (.*)]=],
{ "lnum", "code", "message" },
nil,
{ ["source"] = "dotenv_linter", ["severity"] = vim.diagnostic.severity.INFO }
),
}

View File

@ -0,0 +1,19 @@
-- example:
-- blur.hlsl:18:6: error: expected ';' after top level declarator
local pattern = "%s*([^:]+):(%d+):(%d+): (.+): (.+)"
local groups = { "file", "lnum", "col", "severity", "message" }
return {
cmd = "dxc",
stdin = false,
args = { "-T", "cs_6_5" },
ignore_exitcode = true,
stream = "stderr",
parser = require("lint.parser").from_pattern(pattern, groups, {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
}, {
["source"] = "dxc",
["severity"] = vim.diagnostic.severity.WARN,
}),
}

View File

@ -0,0 +1,15 @@
local pattern = "%s*(%d+): (.+)"
local groups = { "lnum", "message" }
return {
cmd = "editorconfig-checker",
stdin = false,
ignore_exitcode = true,
args = { "-no-color" },
parser = require("lint.parser").from_pattern(
pattern,
groups,
nil,
{ severity = vim.diagnostic.severity.INFO, source = "editorconfig-checker" }
),
}

View File

@ -0,0 +1,13 @@
local efm = '%f:%l:%c: %m'
return {
cmd = 'bundle',
args = { 'exec', 'erblint', '--format', 'compact' },
stream = 'stdout',
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat(efm, {
source = 'erb-lint',
severity = vim.diagnostic.severity.WARN
})
}

View File

@ -0,0 +1,56 @@
local binary_name = "eslint"
local severities = {
vim.diagnostic.severity.WARN,
vim.diagnostic.severity.ERROR,
}
return {
cmd = function()
local local_binary = vim.fn.fnamemodify('./node_modules/.bin/' .. binary_name, ':p')
return vim.loop.fs_stat(local_binary) and local_binary or binary_name
end,
args = {
'--format',
'json',
'--stdin',
'--stdin-filename',
function() return vim.api.nvim_buf_get_name(0) end,
},
stdin = true,
stream = 'stdout',
ignore_exitcode = true,
parser = function(output, bufnr)
if vim.trim(output) == "" then
return {}
end
local decode_opts = { luanil = { object = true, array = true } }
local ok, data = pcall(vim.json.decode, output, decode_opts)
if not ok then
return {
{
bufnr = bufnr,
lnum = 0,
col = 0,
message = "Could not parse linter output due to: " .. data .. "\noutput: " .. output
}
}
end
-- See https://eslint.org/docs/latest/use/formatters/#json
local diagnostics = {}
for _, result in ipairs(data or {}) do
for _, msg in ipairs(result.messages or {}) do
table.insert(diagnostics, {
lnum = msg.line and (msg.line - 1) or 0,
end_lnum = msg.endLine and (msg.endLine - 1) or nil,
col = msg.column and (msg.column - 1) or 0,
end_col = msg.endColumn and (msg.endColumn - 1) or nil,
message = msg.message,
code = msg.ruleId,
severity = severities[msg.severity],
source = binary_name
})
end
end
return diagnostics
end
}

View File

@ -0,0 +1,24 @@
local binary_name = "eslint_d"
return {
cmd = function()
local local_binary = vim.fn.fnamemodify('./node_modules/.bin/' .. binary_name, ':p')
return vim.loop.fs_stat(local_binary) and local_binary or binary_name
end,
args = {
'--format',
'json',
'--stdin',
'--stdin-filename',
function() return vim.api.nvim_buf_get_name(0) end,
},
stdin = true,
stream = 'stdout',
ignore_exitcode = true,
parser = function(output, bufnr)
local result = require("lint.linters.eslint").parser(output, bufnr)
for _, d in ipairs(result) do
d.source = binary_name
end
return result
end
}

View File

@ -0,0 +1,25 @@
local efm = "%C%[%^^]%#,%E%>Parse error in %f:%l,%E%>Compile error in %f:%l,%-Z%p^%.%#,%C%m,%-G* %.%#"
local M
local function globals()
return table.concat(M.globals, ",")
end
M = {
cmd = "fennel",
args = { "--globals", globals, "--compile" },
stdin = false,
ignore_exitcode = true,
stream = "stderr",
parser = require("lint.parser").from_errorformat(efm, {
source = "fennel",
severity = vim.diagnostic.severity.ERROR,
}),
-- Users can modify this list like this:
-- require("lint.linters.fennel").globals = { "foo", "bar" }
globals = {},
}
return M

View File

@ -0,0 +1,12 @@
local efm = "%E%f (line %l): %m,%C%p^,%C%.%#"
return {
cmd = "fish",
args = { "--no-execute" },
stdin = false,
ignore_exitcode = true,
stream = "stderr",
parser = require("lint.parser").from_errorformat(efm, {
source = "fish",
severity = vim.diagnostic.severity.ERROR,
}),
}

View File

@ -0,0 +1,20 @@
-- path/to/file:line:col: code message
local pattern = '[^:]+:(%d+):(%d+):(%w+):(.+)'
local groups = { 'lnum', 'col', 'code', 'message' }
return {
cmd = 'flake8',
stdin = true,
args = {
'--format=%(path)s:%(row)d:%(col)d:%(code)s:%(text)s',
'--no-show-source',
'--stdin-display-name',
function() return vim.api.nvim_buf_get_name(0) end,
'-',
},
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, nil, {
['source'] = 'flake8',
['severity'] = vim.diagnostic.severity.WARN,
}),
}

View File

@ -0,0 +1,24 @@
-- Look for patterns like the following:
--
-- vuln.c:6:3: [5] (buffer) gets:Does not check for buffer overflows (CWE-120, CWE-20). Use fgets() instead.
local pattern = [[^(.*):(%d+):(%d+): *%[([0-5])%] (.*)$]]
local groups = { 'file', 'lnum', 'col', 'severity', 'message' }
local severity_map = {
['5'] = vim.diagnostic.severity.WARN,
['4'] = vim.diagnostic.severity.WARN,
['3'] = vim.diagnostic.severity.WARN,
['2'] = vim.diagnostic.severity.WARN,
['1'] = vim.diagnostic.severity.WARN,
}
return {
cmd = 'flawfinder',
stdin = false,
args = {'-S', '-Q', '-D', '-C', '--'},
stream = 'stdout',
parser = require('lint.parser').from_pattern(pattern, groups, severity_map, {
['source'] = 'flawfinder'
})
}

View File

@ -0,0 +1,25 @@
local pattern = [[(%S+):(%d+):%s(%a+):%s(.*)]]
local groups = {
'file',
'lnum',
'severity',
'message',
}
local severity_map = {
['Error'] = vim.diagnostic.severity.WARN,
}
return {
cmd = 'gdlint',
stdin = false,
append_fname = true,
args = {},
stream = 'stderr',
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(
pattern,
groups,
severity_map,
{ ['source'] = 'gdlint' }
),
}

View File

@ -0,0 +1,15 @@
local pattern = "^(%d+): (%w+) (.*)$"
local groups = { "lnum", "code", "message" }
return {
cmd = "gitlint",
stdin = true,
args = {
"--staged",
"--msg-filename",
function() return vim.api.nvim_buf_get_name(0) end
},
stream = "stderr",
ignore_exitcode = true,
parser = require("lint.parser").from_pattern(pattern, groups),
}

View File

@ -0,0 +1,18 @@
-- path/to/file:line: severity: 'offending part of source code': message
local pattern = "%s*([^:]+):(%d+): (.+): (.+: .+)"
local groups = { "file", "lnum", "severity", "message" }
return {
cmd = "glslc",
stdin = false,
args = {"-o", "-"}, -- "-" represents output of compilation result to stdout
ignore_exitcode = true,
stream = "stderr",
parser = require("lint.parser").from_pattern(pattern, groups, {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
}, {
["source"] = "glslc",
["severity"] = vim.diagnostic.severity.WARN,
}),
}

View File

@ -0,0 +1,53 @@
local severities = {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
refactor = vim.diagnostic.severity.INFO,
convention = vim.diagnostic.severity.HINT,
}
return {
cmd = 'golangci-lint',
append_fname = false,
args = {
'run',
'--out-format',
'json',
'--show-stats=false',
'--print-issued-lines=false',
'--print-linter-name=false',
function()
return vim.fn.fnamemodify(vim.api.nvim_buf_get_name(0), ":h")
end
},
stream = 'stdout',
ignore_exitcode = true,
parser = function(output, bufnr, cwd)
if output == '' then
return {}
end
local decoded = vim.json.decode(output)
if decoded["Issues"] == nil or type(decoded["Issues"]) == 'userdata' then
return {}
end
local diagnostics = {}
for _, item in ipairs(decoded["Issues"]) do
local curfile = vim.api.nvim_buf_get_name(bufnr)
local lintedfile = cwd .. "/" .. item.Pos.Filename
if curfile == lintedfile then
-- only publish if those are the current file diagnostics
local sv = severities[item.Severity] or severities.warning
table.insert(diagnostics, {
lnum = item.Pos.Line > 0 and item.Pos.Line - 1 or 0,
col = item.Pos.Column > 0 and item.Pos.Column - 1 or 0,
end_lnum = item.Pos.Line > 0 and item.Pos.Line - 1 or 0,
end_col = item.Pos.Column > 0 and item.Pos.Column - 1 or 0,
severity = sv,
source = item.FromLinter,
message = item.Text,
})
end
end
return diagnostics
end
}

View File

@ -0,0 +1,33 @@
local severities = {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
info = vim.diagnostic.severity.INFO,
style = vim.diagnostic.severity.HINT,
}
return {
cmd = 'hadolint',
stdin = true,
stream = 'stdout',
ignore_exitcode = true,
args = {'-f', 'json', '-'},
parser = function(output)
local findings = vim.json.decode(output)
local diagnostics = {}
for _, finding in pairs(findings or {}) do
table.insert(diagnostics, {
lnum = finding.line - 1,
col = finding.column,
end_lnum = finding.line - 1,
end_col = finding.column,
severity = assert(severities[finding.level], 'missing mapping for severity ' .. finding.level),
message = finding.message,
source = 'hadolint',
code = finding.code,
})
end
return diagnostics
end,
}

View File

@ -0,0 +1,26 @@
local severities = {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
suggestion = vim.diagnostic.severity.HINT,
}
return {
cmd = "hlint",
args = { "--json", "--no-exit-code" },
parser = function(output)
local diagnostics = {}
local items = #output > 0 and vim.json.decode(output) or {}
for _, item in ipairs(items) do
table.insert(diagnostics, {
lnum = item.startLine,
col = item.startColumn,
end_lnum = item.endLine,
end_col = item.endColumn,
severity = severities[item.severity:lower()],
source = "hlint",
message = item.hint .. (item.to ~= vim.NIL and (": " .. item.to) or ""),
})
end
return diagnostics
end,
}

View File

@ -0,0 +1,24 @@
local pattern = '.*: line (%d+), col (%d+), (%a+) %- (.+) %((.+)%)'
local groups = { 'lnum', 'col', 'severity', 'message', 'code' }
local severities = {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
}
return {
cmd = "htmlhint",
stdin = true,
args = {
"stdin",
"-f",
"compact",
},
stream = "stdout",
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(
pattern,
groups,
severities,
{ source = "htmlhint" }
)
}

View File

@ -0,0 +1,64 @@
local util = require('lint.util')
local severities = {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
}
-- Inko unit tests require the inclusion of an extra directory, otherwise we
-- won't be able to find some of the files imported into unit tests.
local function include_tests()
local path = vim.fn.expand('%:p')
local separator = vim.fn.has('win32') == 1 and '\\' or '/'
local find = 'tests' .. separator .. 'test' .. separator
if not path:match(find) then
return
end
local tests_dir = util.find_nearest_directory('tests')
return '--include=' .. tests_dir
end
return {
cmd = 'inko',
args = {
'build',
include_tests,
'--format=json',
'--check',
},
stream = 'stderr',
stdin = false,
ignore_exitcode = true,
parser = function(output, _)
local items = {}
if output == '' then
return items
end
local decoded = vim.json.decode(output) or {}
local bufpath = vim.fn.expand('%:p')
for _, diag in ipairs(decoded) do
if diag.file == bufpath then
table.insert(items, {
source = 'inko',
lnum = diag.line - 1,
col = diag.column - 1,
end_lnum = diag.line - 1,
end_col = diag.column,
message = diag.message,
severity = assert(
severities[diag.level],
'missing mapping for severity ' .. diag.level
)
})
end
end
return items
end
}

View File

@ -0,0 +1,17 @@
-- error: path/to/file:line:col: message
local pattern = '[^:]+:[^:]+:(%d+):(%d+):(.+)'
local groups = { 'lnum', 'col', 'message' }
return {
cmd = 'janet',
stdin = true,
args = {
'-k',
},
stream = 'stderr',
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, nil, {
['source'] = 'janet',
['severity'] = vim.diagnostic.severity.ERROR,
}),
}

View File

@ -0,0 +1,10 @@
return {
cmd = "joker",
stdin = false,
stream = "stderr",
args = { "--lint" },
ignore_exitcode = true,
parser = require("lint.parser").from_errorformat("%f:%l:%c: %m", {
source = "joker",
}),
}

View File

@ -0,0 +1,13 @@
return {
cmd = "jq",
stdin = true,
stream = "stderr",
ignore_exitcode = true,
parser = require("lint.parser").from_pattern(
"^(.+): (.+) at line (%d+), column (%d+)$",
{ "code", "message", "lnum", "col" },
nil,
nil,
{ lnum_offset = -1 }
),
}

View File

@ -0,0 +1,11 @@
return {
cmd = 'jshint',
stdin = false,
args = {'--reporter', 'unix', '--extract', 'auto'},
stream = 'stdout',
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat('%f:%l:%c: %m', {
source = 'jshint',
severity = vim.diagnostic.severity.WARN,
})
}

View File

@ -0,0 +1,15 @@
local pattern = "line (%d+), col (%d+), (.*)"
local groups = { "lnum", "col", "message" }
local severities = nil -- none provided
return {
cmd = 'jsonlint',
stream = 'stderr',
args = { '--compact' },
stdin = true,
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, severities, {
source = 'jsonlint',
severity = vim.diagnostic.severity.ERROR,
}),
}

View File

@ -0,0 +1,26 @@
return {
cmd = 'ktlint',
stdin = true,
args = { '--reporter=json', '--stdin' },
stream = 'stderr',
ignore_exitcode = true,
parser = function(output)
local ktlint_output = vim.json.decode(output)
if vim.tbl_isempty(ktlint_output) then
return {}
end
local diagnostics = {}
for _, error in pairs(ktlint_output[1].errors) do
table.insert(diagnostics, {
lnum = error.line - 1,
col = error.column - 1,
end_lnum = error.line - 1,
end_col = error.column - 1,
message = error.message,
severity = vim.diagnostic.severity.WARN,
source = 'ktlint',
})
end
return diagnostics
end
}

View File

@ -0,0 +1,15 @@
-- path/to/file, line <linum>: <message>
local pattern = '[^:]+, line (%d+):(.+)'
local groups = { 'lnum', 'message' }
return {
cmd = 'lacheck',
stdin = false,
args = {},
stream = 'stdout',
ignore_exitcode = false,
parser = require('lint.parser').from_pattern(pattern, groups, nil, {
["source"] = "lacheck",
['severity'] = vim.diagnostic.severity.WARN,
}),
}

View File

@ -0,0 +1,42 @@
-- LanguageTool might give output like "Err: 'yada yada'\n{ ... json here ... }'
local function parse_err_json(str)
local json_start = str:find('{', 1, true)
local err = nil
local json = str
if json_start and json_start > 1 then
err = str:sub(1, json_start - 1):gsub("^%s*(.-)%s*$", "%1") -- trim spaces
json = str:sub(json_start)
end
return err, json
end
return {
cmd = 'languagetool',
args = {'--autoDetect', '--json'},
stream = 'stdout',
parser = function(output, bufnr)
local err, json = parse_err_json(output)
if err then
vim.notify_once(err, vim.log.levels.INFO)
end
local decoded = vim.json.decode(json)
local diagnostics = {}
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, true)
local content = table.concat(lines, '\n')
for _, match in pairs(decoded.matches or {}) do
local byteidx = vim.fn.byteidx(content, match.offset)
local line = vim.fn.byte2line(byteidx)
local col = byteidx - vim.fn.line2byte(line)
table.insert(diagnostics, {
lnum = line - 1,
end_lnum = line - 1,
col = col + 1,
end_col = col + 1,
message = match.message,
})
end
return diagnostics
end,
}

View File

@ -0,0 +1,55 @@
local function get_cur_file_name(bufnr)
bufnr = bufnr or 0
local str, _ = string.gsub(vim.api.nvim_buf_get_name(bufnr), '\\', '/')
return str
end
local severities = {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
information = vim.diagnostic.severity.INFO,
hint = vim.diagnostic.severity.HINT,
}
return {
cmd = 'lint-openapi.cmd',
stdin = true,
args = {
'--json',
get_cur_file_name(0)
},
ignore_exitcode = true,
append_fname = false,
parser = function(output, _)
if vim.trim(output) == '' then
return {}
end
local decoded = vim.fn.json_decode(output)
local diagnostics = {}
local items_err = decoded['errors']
local items_warn = decoded['warnings']
for _, item in pairs(items_err or {}) do
table.insert(diagnostics, {
lnum = item.line - 1,
end_lnum = item.line - 1,
col = 1,
end_col = 1,
message = item.message .. ' | rule: ' .. item.rule,
source = 'lint-openapi',
severity = severities['error'],
})
end
for _, item in pairs(items_warn or {}) do
table.insert(diagnostics, {
lnum = item.line - 1,
end_lnum = item.line - 1,
col = 1,
end_col = 1,
message = item.message .. ' | rule: ' .. item.rule,
source = 'lint-openapi',
severity = severities['warning'],
})
end
return diagnostics
end
}

View File

@ -0,0 +1,20 @@
local pattern = '[^:]+:(%d+):(%d+)-(%d+): %((%a)(%d+)%) (.*)'
local groups = { 'lnum', 'col', 'end_col', 'severity', 'code', 'message' }
local severities = {
W = vim.diagnostic.severity.WARN,
E = vim.diagnostic.severity.ERROR,
}
return {
cmd = 'luacheck',
stdin = true,
args = { '--formatter', 'plain', '--codes', '--ranges', '-' },
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(
pattern,
groups,
severities,
{ ['source'] = 'luacheck' },
{ end_col_offset = 0 }
),
}

View File

@ -0,0 +1,10 @@
local efm = "%f:%l:%c %m,%f:%l %m"
return {
cmd = "markdownlint-cli2",
ignore_exitcode = true,
stream = "stderr",
parser = require("lint.parser").from_errorformat(efm, {
source = "markdownlint",
severity = vim.diagnostic.severity.WARN,
}),
}

View File

@ -0,0 +1,11 @@
local efm = '%f:%l:%c %m,%f:%l %m'
local is_windows = vim.loop.os_uname().version:match('Windows')
return {
cmd = is_windows and 'markdownlint.cmd' or 'markdownlint',
ignore_exitcode = true,
stream = 'stderr',
parser = require('lint.parser').from_errorformat(efm, {
source = 'markdownlint',
severity = vim.diagnostic.severity.WARN,
})
}

View File

@ -0,0 +1,38 @@
local binary_name = "markuplint"
local severity_map = {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
}
return {
cmd = function()
local local_binary = vim.fn.fnamemodify("./node_modules/.bin/" .. binary_name, ":p")
return vim.loop.fs_stat(local_binary) and local_binary or binary_name
end,
args = { "--format", "JSON" },
stdin = false,
stream = "stdout",
ignore_exitcode = true,
parser = function(output)
if vim.trim(output) == "" then
return {}
end
local decode_opts = { luanil = { object = true, array = true } }
local data = vim.json.decode(output, decode_opts)
local diagnostics = {}
for _, result in ipairs(data or {}) do
table.insert(diagnostics, {
lnum = result.line and result.line - 1 or 0,
col = result.col and result.col - 1 or 0,
message = result.message,
code = result.ruleId,
severity = severity_map[result.severity] or vim.diagnostic.severity.ERROR,
source = "markuplint",
})
end
return diagnostics
end,
}

View File

@ -0,0 +1,19 @@
local pattern = "L (%d+) %(C (%d+)[-]?([%d]*)%): (.-): (.-): (.*)"
local groups = { "lnum", "col", "end_col", "code", "severity", "message" }
local severities = {
ML2 = vim.diagnostic.severity.ERROR,
ML3 = vim.diagnostic.severity.ERROR,
ML4 = vim.diagnostic.severity.ERROR,
ML1 = vim.diagnostic.severity.WARN,
ML0 = vim.diagnostic.severity.INFO,
ML5 = vim.diagnostic.severity.HINT,
}
return {
cmd = "mlint",
stdin = false,
stream = "stderr",
args = { "-cyc", "-id", "-severity" },
ignore_exitcode = true,
parser = require("lint.parser").from_pattern(pattern, groups, severities, { ["source"] = "mlint" }),
}

View File

@ -0,0 +1,30 @@
-- path/to/file:line:col: severity: message
local pattern = '([^:]+):(%d+):(%d+):(%d+):(%d+): (%a+): (.*)'
local groups = { 'file', 'lnum', 'col', 'end_lnum', 'end_col', 'severity', 'message' }
local severities = {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
note = vim.diagnostic.severity.HINT,
}
return {
cmd = 'mypy',
stdin = false,
ignore_exitcode = true,
args = {
'--show-column-numbers',
'--show-error-end',
'--hide-error-codes',
'--hide-error-context',
'--no-color-output',
'--no-error-summary',
'--no-pretty',
},
parser = require('lint.parser').from_pattern(
pattern,
groups,
severities,
{ ['source'] = 'mypy' },
{ end_col_offset = 0 }
),
}

View File

@ -0,0 +1,12 @@
local pattern = '%f: %l: %t %m,%-GChecking file %f'
return {
cmd = 'nagelfar',
args = {'-H'},
append_fname = true,
stdin = false,
stream = 'both',
ignore_exitcode = true,
env = nil,
parser = require('lint.parser').from_errorformat(pattern)
}

View File

@ -0,0 +1,18 @@
local pattern = '^(%w+): (.+) at .+:(%d+):(%d+)$'
local groups = { 'severity', 'message', 'lnum', 'col' }
local severity_map = { error = vim.diagnostic.severity.ERROR }
return {
cmd = 'nix-instantiate',
stdin = true,
args = {
'--parse',
'-',
},
stream = 'stderr',
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, severity_map, {
['source'] = 'nix',
['severity'] = vim.diagnostic.severity.WARN,
})
}

View File

@ -0,0 +1,13 @@
local pattern = "^%s+(%d+)%s+[^a-z]+m([a-z]+)[^a-z]+m%s+(.*)%s+(%w+)"
local groups = { "lnum", "severity", "message", "code" }
local severity_map = {
["info"] = vim.diagnostic.severity.INFO,
["warning"] = vim.diagnostic.severity.WARN,
["error"] = vim.diagnostic.severity.ERROR,
}
return {
cmd = "npm-groovy-lint",
stdin = false,
parser = require("lint.parser").from_pattern(pattern, groups, severity_map, { ["source"] = "npm-groovy-lint" }),
}

View File

@ -0,0 +1,23 @@
-- path/to/file:line:severity:code:message
local pattern = '([^:]+):(%d+):(%a+):(.+):(.+)'
local groups = { 'file', 'lnum', 'severity', 'code', 'message' }
local severity_map = {
['error'] = vim.diagnostic.severity.ERROR,
['warning'] = vim.diagnostic.severity.WARN,
['info'] = vim.diagnostic.severity.INFO,
}
return {
cmd = 'oelint-adv',
stdin = false,
args = {
'--quiet',
'--messageformat={path}:{line}:{severity}:{id}:{msg}',
},
ignore_exitcode = true,
stream = 'stderr',
parser = require('lint.parser').from_pattern(
pattern, groups, severity_map,
{ ['source'] = 'oelint-adv' }
),
}

View File

@ -0,0 +1,36 @@
-- https://github.com/open-policy-agent/opa
return {
cmd = "opa",
args = { "check", "--strict", "--format", "json" },
stdin = false,
append_fname = true,
stream = "stderr",
ignore_exitcode = true,
parser = function(output, _)
local diagnostics = {}
if output == "" then
return diagnostics
end
local decoded = vim.json.decode(output)
if decoded ~= nil then
for _, item in ipairs(decoded.errors or {}) do
local lnum = item.location.row - 1
table.insert(diagnostics, {
lnum = lnum,
end_lnum = lnum,
col = item.location.col - 1,
end_col = item.location.col,
severity = vim.diagnostic.severity.ERROR,
source = "opa_check",
message = item.message,
code = item.code,
})
end
end
return diagnostics
end,
}

View File

@ -0,0 +1,11 @@
return {
cmd = "oxlint",
stdin = false,
args = { "--format", "unix" },
stream = "stdout",
ignore_exitcode = true,
parser = require("lint.parser").from_errorformat("%f:%l:%c: %m", {
source = "oxlint",
severity = vim.diagnostic.severity.WARN,
}),
}

View File

@ -0,0 +1,32 @@
local pattern = '(%d+):(%d+):(%w+) (.+)'
local groups = { 'lnum', 'col', 'severity', 'message' }
local severity_map = {
['1'] = vim.diagnostic.severity.HINT,
['2'] = vim.diagnostic.severity.INFO,
['3'] = vim.diagnostic.severity.WARN,
['4'] = vim.diagnostic.severity.WARN,
['5'] = vim.diagnostic.severity.ERROR,
}
local find_conf = function()
local conf = vim.fs.find('.perlcriticrc', {
upward = true,
stop = vim.fs.dirname(vim.loop.os_homedir()),
path = vim.fs.dirname(vim.api.nvim_buf_get_name(0)),
})
return conf[1] or ''
end
return function()
local profile = find_conf()
return {
cmd = 'perlcritic',
stdin = true,
args = { '--nocolor', '--verbose', '%l:%c:%s %m [%p]\n', '--profile', profile },
stream = 'stdout',
ignore_exitcode = true, -- returns 2 if policy violations are found, but 1 if perlcritic itself has errors. :-(
parser = require('lint.parser').from_pattern(pattern, groups, severity_map, {
['source'] = 'perlcritic',
}),
}
end

View File

@ -0,0 +1,27 @@
-- perlimports requires both to read from stdin *and*
-- to have the filename appended.
return function()
local filename = vim.api.nvim_buf_get_name(0)
return {
cmd = 'perlimports',
stdin = true,
args = { '--lint', '--json', '--read-stdin', '--filename', filename },
stream = 'stderr',
parser = function(output)
local result = vim.fn.split(output, '\n')
local diagnostics = {}
for _, message in ipairs(result) do
local decoded = vim.json.decode(message)
table.insert(diagnostics, {
lnum = decoded.location.start.line - 1,
col = decoded.location.start.column - 1,
end_lnum = decoded.location['end'].line - 1,
end_col = decoded.location['end'].column - 1,
severity = vim.diagnostic.severity.INFO,
message = decoded.reason,
})
end
return diagnostics
end,
}
end

View File

@ -0,0 +1,18 @@
-- path/to/file:line:col: code message
local pattern = "[^:]+:(%d+):(%d+):(%w+):(.+)"
local groups = { "lnum", "col", "code", "message" }
return {
cmd = "pflake8",
stdin = true,
args = {
"--format=%(path)s:%(row)d:%(col)d:%(code)s:%(text)s",
"--no-show-source",
"-",
},
ignore_exitcode = true,
parser = require("lint.parser").from_pattern(pattern, groups, nil, {
["source"] = "flake8",
["severity"] = vim.diagnostic.severity.WARN,
}),
}

View File

@ -0,0 +1,21 @@
local efm = table.concat({
'Deprecated:\\ %m\\ %tn\\ Standard\\ input\\ code\\ on\\ line\\ %l', -- nasty hack for %t
'%tarning:\\ %m\\ in\\ Standard\\ input\\ code\\ on\\ line\\ %l',
'Parse\\ %trror:\\ %m\\ in\\ Standard\\ input\\ code\\ on\\ line\\ %l',
'Fatal\\ %trror:\\ %m\\ in\\ Standard\\ input\\ code\\ on\\ line\\ %l',
}, ',')
return {
cmd = 'php',
stdin = true,
args = {
-- '-d error_reporting=-1',
'-d display_errors=stdout',
'-l',
},
stream = 'stdout',
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat(efm, {
source = 'php'
})
}

View File

@ -0,0 +1,49 @@
local severities = {
ERROR = vim.diagnostic.severity.ERROR,
WARNING = vim.diagnostic.severity.WARN,
}
local bin ='phpcs'
return {
cmd = function()
local local_bin = vim.fn.fnamemodify('vendor/bin/' .. bin, ':p')
return vim.loop.fs_stat(local_bin) and local_bin or bin
end,
stdin = true,
args = {
'-q',
'--report=json',
'-', -- need `-` at the end for stdin support
},
ignore_exitcode = true,
parser = function(output, _)
if vim.trim(output) == '' or output == nil then
return {}
end
if not vim.startswith(output,'{') then
vim.notify(output)
return {}
end
local decoded = vim.json.decode(output)
local diagnostics = {}
local messages = decoded['files']['STDIN']['messages']
for _, msg in ipairs(messages or {}) do
table.insert(diagnostics, {
lnum = msg.line - 1,
end_lnum = msg.line - 1,
col = msg.column - 1,
end_col = msg.column - 1,
message = msg.message,
code = msg.source,
source = bin,
severity = assert(severities[msg.type], 'missing mapping for severity ' .. msg.type),
})
end
return diagnostics
end
}

View File

@ -0,0 +1,39 @@
local bin = 'phpinsights'
local insight_to_severity = {
Code = vim.diagnostic.severity.ERROR,
Complexity = vim.diagnostic.severity.WARN,
Architecture = vim.diagnostic.severity.WARN,
Style = vim.diagnostic.severity.HINT,
Security = vim.diagnostic.severity.ERROR,
}
return {
cmd = function ()
local local_bin = vim.fn.fnamemodify('vendor/bin/' .. bin, ':p')
return vim.loop.fs_stat(local_bin) and local_bin or bin
end,
stdin = false,
args = { 'analyse', '--format', 'json' },
parser = function(output)
if output == nil then
return {}
end
local diagnostics = {}
local json = vim.json.decode(output) or {}
for insight, severity in pairs(insight_to_severity) do
for _, message in ipairs(json[insight] or {}) do
table.insert(diagnostics, {
lnum = message.line - 1,
col = 0,
message = message.message,
severity = severity,
source = bin,
})
end
end
return diagnostics
end,
}

View File

@ -0,0 +1,56 @@
local severities = {}
severities[1] = vim.diagnostic.severity.ERROR
severities[2] = vim.diagnostic.severity.WARN
severities[3] = vim.diagnostic.severity.INFO
severities[4] = vim.diagnostic.severity.HINT
severities[5] = vim.diagnostic.severity.HINT
local bin = 'phpmd'
return {
cmd = function ()
local local_bin = vim.fn.fnamemodify('vendor/bin/' .. bin, ':p')
return vim.loop.fs_stat(local_bin) and local_bin or bin
end,
stdin = true,
args = {
'-',
'json',
'cleancode,codesize,controversial,design,naming,unusedcode',
},
stream = 'stdout',
ignore_exitcode = true,
parser = function(output, _)
if vim.trim(output) == '' or output == nil then
return {}
end
if not vim.startswith(output, '{') then
vim.notify(output)
return {}
end
local decoded = vim.json.decode(output)
local diagnostics = {}
local messages = {}
if decoded['files'] and decoded['files'][1] and decoded['files'][1]['violations'] then
messages = decoded['files'][1]['violations']
end
for _, msg in ipairs(messages or {}) do
table.insert(diagnostics, {
lnum = msg.beginLine - 1,
end_lnum = msg.endLine - 1,
col = 0,
end_col = 0,
message = msg.description,
code = msg.rule,
source = bin,
severity = assert(severities[msg.priority], 'missing mapping for severity ' .. msg.priority),
})
end
return diagnostics
end
}

View File

@ -0,0 +1,38 @@
local bin = 'phpstan'
return {
cmd = function ()
local local_bin = vim.fn.fnamemodify('vendor/bin/' .. bin, ':p')
return vim.loop.fs_stat(local_bin) and local_bin or bin
end,
args = {
'analyze',
'--error-format=json',
'--no-progress',
},
ignore_exitcode = true,
parser = function(output, bufnr)
if vim.trim(output) == '' or output == nil then
return {}
end
local file = vim.json.decode(output).files[vim.api.nvim_buf_get_name(bufnr)]
if file == nil then
return {}
end
local diagnostics = {}
for _, message in ipairs(file.messages or {}) do
table.insert(diagnostics, {
lnum = type(message.line) == 'number' and (message.line - 1) or 0,
col = 0,
message = message.message,
source = bin,
})
end
return diagnostics
end,
}

View File

@ -0,0 +1,15 @@
local pattern = [[([^:]*):(%d+):(%d+): ([^[]+)]]
local groups = { 'file', 'lnum', 'col', 'message'}
return {
cmd = "ponyc",
stdin = false,
append_fname = false,
args = { "--pass=verify" },
stream = "stderr",
ignore_exitcode = true,
parser = require("lint.parser").from_pattern(pattern, groups, nil, {
["source"] = "ponyc",
["severity"] = vim.diagnostic.severity.ERROR,
}),
}

View File

@ -0,0 +1,38 @@
local binary_name = "prisma-lint"
return {
cmd = function()
local local_binary = vim.fn.fnamemodify('./node_modules/.bin/' .. binary_name, ':p')
return vim.loop.fs_stat(local_binary) and local_binary or binary_name
end,
stdin = false,
args = {
"--output-format",
"json"
},
append_fname = true,
stream = 'both',
ignore_exitcode = true,
parser = function(output)
local decoded = vim.json.decode(output)
local diagnostics = {}
if decoded == nil then
return diagnostics
end
for _, violation in pairs(decoded["violations"]) do
local location = violation.location
table.insert(diagnostics, {
source = binary_name,
lnum = location.startLine - 1,
end_lnum = location.endLine - 1,
col = location.startColumn - 1,
-- endColumn is inclusive, but end_col is exclusive.
end_col = location.endColumn,
message = violation.message,
code = violation.ruleName,
severity = vim.diagnostic.severity.ERROR,
})
end
return diagnostics
end,
}

View File

@ -0,0 +1,14 @@
-- path/to/file:line:col: code.subcode.subsubcode message
local pattern = '([^:]+):(%d+):(%d+): ([^ ]+) (.*)'
local groups = { 'file', 'lnum', 'col', 'code', 'message' }
return {
cmd = 'proselint',
stdin = false,
args = {},
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, nil, {
['source'] = 'proselint',
['severity'] = vim.diagnostic.severity.INFO,
}),
}

View File

@ -0,0 +1,43 @@
return {
cmd = function ()
for _, fname in ipairs({ './vendor/bin/psalm', './vendor/bin/psalm.phar' }) do
local local_psalm = vim.fn.fnamemodify(fname, ':p')
local stat = vim.loop.fs_stat(local_psalm)
if stat then
return local_psalm
end
end
return 'psalm'
end,
args = {
'--output-format=json',
'--show-info=true',
'--no-progress',
},
parser = function(output, bufnr)
if output == nil then
return {}
end
local filename = vim.api.nvim_buf_get_name(bufnr)
local messages = vim.json.decode(output)
local diagnostics = {}
for _, message in ipairs(messages or {}) do
if message.file_path == filename then
table.insert(diagnostics, {
lnum = message.line_from - 1,
end_lnum = message.line_to - 1,
col = message.column_from - 1,
end_col = message.column_to - 1,
message = message.message,
source = 'psalm',
severity = message.severity,
})
end
end
return diagnostics
end
}

View File

@ -0,0 +1,20 @@
local pattern = '(.+):(%d+):(%d+):(%l+):(.+):(.+)'
local groups = { 'file', 'lnum', 'col', 'severity', 'code', 'message' }
local severities = {
['error'] = vim.diagnostic.severity.ERROR,
['warning'] = vim.diagnostic.severity.WARN,
}
return {
cmd = 'puppet-lint',
stdin = false,
args = {
'--no-autoloader_layout-check',
'--log-format', '%{path}:%{line}:%{column}:%{kind}:%{check}:%{message}'
},
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, severities, {
['source'] = 'puppet-lint',
}),
}

View File

@ -0,0 +1,17 @@
-- path/to/file:line:col:code:message
local pattern = '[^:]+:(%d+):(%d+):(%w+):(.+)'
local groups = { 'lnum', 'col', 'code', 'message' }
return {
cmd = 'pycodestyle',
stdin = true,
args = {
'--format=%(path)s:%(row)d:%(col)d:%(code)s:%(text)s',
'-',
},
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, nil, {
['source'] = 'pycodestyle',
['severity'] = vim.diagnostic.severity.WARN,
}),
}

View File

@ -0,0 +1,9 @@
return {
cmd = 'pydocstyle',
stdin = false,
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat(
'%N%f:%l%.%#,%Z%s%#D%n: %m',
{source = 'pydocstyle'}
),
}

View File

@ -0,0 +1,45 @@
local severities = {
error = vim.diagnostic.severity.ERROR,
fatal = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
refactor = vim.diagnostic.severity.INFO,
info = vim.diagnostic.severity.INFO,
convention = vim.diagnostic.severity.HINT,
}
return {
cmd = 'pylint',
stdin = false,
args = {
'-f', 'json'
},
ignore_exitcode = true,
parser = function(output, bufnr)
if output == "" then return {} end
local diagnostics = {}
local buffer_path = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(bufnr), ":~:.")
for _, item in ipairs(vim.json.decode(output) or {}) do
if not item.path or vim.fn.fnamemodify(item.path, ":~:.") == buffer_path then
local column = item.column > 0 and item.column or 0
local end_column = item.endColumn ~= vim.NIL and item.endColumn or column
table.insert(diagnostics, {
source = 'pylint',
lnum = item.line - 1,
col = column,
end_lnum = item.line - 1,
end_col = end_column,
severity = assert(severities[item.type], 'missing mapping for severity ' .. item.type),
message = item.message .. " (" .. item.symbol .. ")",
code = item['message-id'],
user_data = {
lsp = {
code = item['message-id'],
},
},
})
end
end
return diagnostics
end,
}

View File

@ -0,0 +1,26 @@
-- example output:
-- hello_world.ts:48:5: warning: use of undeclared variable: DEV_MODE [E0057]
local pattern = "[^:]+:(%d+):(%d+): (%w+): (.+)"
local groups = { "lnum", "col", "severity", "message" }
local severities = {
["error"] = vim.diagnostic.severity.ERROR,
["warning"] = vim.diagnostic.severity.WARN,
}
local defaults = { ["source"] = "quick-lint-js" }
return {
cmd = "quick-lint-js",
args = {
"--stdin",
-- --stdin-path is required to determine the language
"--stdin-path",
function()
return vim.api.nvim_buf_get_name(0)
end,
},
ignore_exitcode = true,
stream = "stderr",
parser = require("lint.parser").from_pattern(pattern, groups, severities, defaults),
}

View File

@ -0,0 +1,43 @@
-- https://github.com/StyraInc/regal
local severities = {
error = vim.diagnostic.severity.ERROR,
warning = vim.diagnostic.severity.WARN,
}
return {
cmd = "regal",
args = { "lint", "--format", "json" },
stdin = false,
append_fname = true,
stream = "stdout",
ignore_exitcode = true,
parser = function(output, _)
local diagnostics = {}
if output == "" then
return diagnostics
end
local decoded = vim.json.decode(output)
if decoded ~= nil then
for _, item in ipairs(decoded.violations or {}) do
local end_col = item.location.text ~= nil and item.location.text:len() + 1 or item.location.col
local lnum = math.max(item.location.row - 1, 0)
table.insert(diagnostics, {
lnum = lnum,
end_lnum = lnum,
col = math.max(item.location.col - 1, 0),
end_col = end_col,
severity = severities[item.level] or severities.error,
source = "[regal] " .. item.category,
message = item.description,
code = item.title,
})
end
end
return diagnostics
end,
}

View File

@ -0,0 +1,12 @@
-- path/to/file:line:col: code message
local pattern = '[^:]+:(%d+):(%d+): (.*)'
local groups = { 'lnum', 'col', 'message' }
return {
cmd = 'revive',
stdin = false,
args = {},
parser = require('lint.parser').from_pattern(pattern, groups, nil, {
['source'] = 'revive',
}),
}

View File

@ -0,0 +1,10 @@
return {
cmd = 'rflint',
stdin = false,
args = {'--format', '{filename}:{severity}:{linenumber}:{char}:{message}'},
stream = 'stdout',
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat('%f:%t:%l:%c:%m', {
source = 'rflint'
})
}

View File

@ -0,0 +1,10 @@
return {
cmd = 'robocop',
stdin = false,
args = {'--format', '{source}:{line}:{col}:{severity}:{rule_id}:{desc}'},
stream = 'stdout',
ignore_exitcode = true,
parser = require('lint.parser').from_errorformat('%f:%l:%c:%t:%n:%m', {
source = 'robocop'
})
}

View File

@ -0,0 +1,42 @@
-- This is a linter for https://rpm.org/
local parsers = {
-- errors
require('lint.parser').from_pattern(
[[(%w+): line (%d+): (.*)]],
{ 'severity', 'lnum', 'message' },
nil,
{
severity = vim.diagnostic.severity.ERROR,
source = 'rpmspec'
}
),
-- warnings
require('lint.parser').from_pattern(
[[(%w+): (.*) on line (%d+):]],
{ 'severity', 'message', 'lnum' },
nil,
{
severity = vim.diagnostic.severity.WARN,
source = 'rpmspec'
}
),
}
-- Usage: rpmspec -P <file>
return {
cmd = 'rpmspec',
stdin = false,
append_fname = true,
args = { '-P' },
stream = 'stderr',
ignore_exitcode = true,
parser = function(output, bufnr)
local diagnostics = {}
for _, parser in ipairs(parsers) do
local result = parser(output, bufnr)
vim.list_extend(diagnostics, result)
end
return diagnostics
end,
}

View File

@ -0,0 +1,20 @@
-- path/to/file:line: (severity/severity_id) message
local pattern = '([^:]+):(%d+): %((.+)/%d%) (.+)'
local groups = { 'file', 'lnum', 'severity', 'message' }
local severities = {
INFO = vim.diagnostic.severity.INFO,
WARNING = vim.diagnostic.severity.WARN,
ERROR = vim.diagnostic.severity.ERROR,
SEVERE = vim.diagnostic.severity.ERROR,
}
return {
cmd = 'rstcheck',
stdin = false,
stream = 'stderr',
args = {},
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, severities, {
['source'] = 'rstcheck',
}),
}

View File

@ -0,0 +1,19 @@
-- severity path/to/file:line message
local pattern = '(.*) (.*):(%d+) (.*)'
local groups = { 'severity', 'file', 'lnum', 'message' }
local severities = {
INFO = vim.diagnostic.severity.INFO,
WARNING = vim.diagnostic.severity.WARN,
ERROR = vim.diagnostic.severity.ERROR,
SEVERE = vim.diagnostic.severity.SEVERE,
}
return {
cmd = 'restructuredtext-lint',
stdin = false,
args = {},
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, severities, {
['source'] = 'rstlint',
}),
}

View File

@ -0,0 +1,47 @@
local severity_map = {
['fatal'] = vim.diagnostic.severity.ERROR,
['error'] = vim.diagnostic.severity.ERROR,
['warning'] = vim.diagnostic.severity.WARN,
['convention'] = vim.diagnostic.severity.HINT,
['refactor'] = vim.diagnostic.severity.INFO,
['info'] = vim.diagnostic.severity.INFO,
}
return {
cmd = 'rubocop',
stdin = true,
args = {
'--format',
'json',
'--force-exclusion',
'--server',
'--stdin',
function() return vim.api.nvim_buf_get_name(0) end,
},
ignore_exitcode = true,
parser = function(output)
local diagnostics = {}
local decoded = vim.json.decode(output)
if not decoded.files[1] then
return diagnostics
end
local offences = decoded.files[1].offenses
for _, off in pairs(offences) do
table.insert(diagnostics, {
source = 'rubocop',
lnum = off.location.start_line - 1,
col = off.location.start_column - 1,
end_lnum = off.location.last_line - 1,
end_col = off.location.last_column,
severity = severity_map[off.severity],
message = off.message,
code = off.cop_name
})
end
return diagnostics
end,
}

View File

@ -0,0 +1,39 @@
local pattern1 = '([^:]+):(%d+): warning: (.+)'
local groups1 = { 'file', 'lnum', 'message' }
local pattern2 = '([^:]+):(%d+): syntax error, (.+)'
local groups2 = { 'file', 'lnum', 'message' }
local parsers = {
require('lint.parser').from_pattern(
pattern1,
groups1,
nil,
{ ['severity'] = vim.diagnostic.severity.WARN, ['source'] = 'ruby' }
),
require('lint.parser').from_pattern(
pattern2,
groups2,
nil,
{ ['severity'] = vim.diagnostic.severity.ERROR, ['source'] = 'ruby' }
),
}
return {
cmd = 'ruby',
stdin = false,
args = { '-w', '-c' },
ignore_exitcode = true,
stream = 'stderr',
parser = function(output, bufnr)
local diagnostics = {}
for _, parser in ipairs(parsers) do
local result = parser(output, bufnr)
for _, diagnostic in ipairs(result) do
table.insert(diagnostics, diagnostic)
end
end
return diagnostics
end,
}

View File

@ -0,0 +1,48 @@
local function get_file_name()
return vim.api.nvim_buf_get_name(0)
end
local error = vim.diagnostic.severity.ERROR
local severities = {
["F821"] = error, -- undefined name `name`
["E902"] = error, -- `IOError`
["E999"] = error, -- `SyntaxError`
}
return {
cmd = "ruff",
stdin = true,
args = {
"--force-exclude",
"--quiet",
"--stdin-filename",
get_file_name,
"--no-fix",
"--output-format",
"json",
"-",
},
ignore_exitcode = true,
stream = "stdout",
parser = function(output)
local diagnostics = {}
local ok, results = pcall(vim.json.decode, output)
if not ok then
return diagnostics
end
for _, result in ipairs(results or {}) do
local diagnostic = {
message = result.message,
col = result.location.column - 1,
end_col = result.end_location.column - 1,
lnum = result.location.row - 1,
end_lnum = result.end_location.row - 1,
code = result.code,
severity = severities[result.code] or vim.diagnostic.severity.WARN,
source = "ruff",
}
table.insert(diagnostics, diagnostic)
end
return diagnostics
end,
}

View File

@ -0,0 +1,28 @@
local severities = {
HIGH = vim.diagnostic.severity.ERROR,
LOW = vim.diagnostic.severity.WARN,
INFO = vim.diagnostic.severity.INFO,
}
return {
cmd = "salt-lint",
stdin = true,
args = { "--json" },
stream = "stdout",
ignore_exitcode = true,
parser = function(output)
local decoded = vim.json.decode(output)
local diagnostics = {}
for _, item in ipairs(decoded or {}) do
table.insert(diagnostics, {
lnum = item.linenumber - 1,
col = 1,
severity = severities[item.severity] or vim.diagnostic.severity.WARN,
message = item.message,
source = "salt-lint",
code = item.id,
})
end
return diagnostics
end,
}

View File

@ -0,0 +1,52 @@
local severities = {
Error = vim.diagnostic.severity.ERROR,
Warning = vim.diagnostic.severity.WARN,
}
return {
cmd = "selene",
stdin = true,
args = { "--display-style", "json", "-" },
stream = "stdout",
ignore_exitcode = true,
parser = function(output)
local lines = vim.fn.split(output, "\n")
local diagnostics = {}
for _, line in ipairs(lines) do
local ok, decoded = pcall(vim.json.decode, line)
if not ok then
return diagnostics
end
local labels = decoded.secondary_labels
table.insert(labels, decoded.primary_label)
for _, label in ipairs(labels) do
local message = decoded.message
if label.message ~= "" then
message = message .. ". " .. label.message
end
table.insert(diagnostics, {
user_data = {
lsp = {
code = decoded.code,
codeDescription = decoded.code,
}
},
code = decoded.code,
source = "selene",
severity = assert(
severities[decoded.severity],
"missing mapping for severity " .. decoded.severity
),
lnum = label.span.start_line,
col = label.span.start_column,
end_lnum = label.span.end_line,
end_col = label.span.end_column,
message = message,
})
end
end
return diagnostics
end,
}

Some files were not shown because too many files have changed in this diff Show More