Regenerate nvim config
This commit is contained in:
@ -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,
|
||||
}
|
||||
@ -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" }
|
||||
),
|
||||
}
|
||||
@ -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
|
||||
})
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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" }),
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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' }
|
||||
),
|
||||
}
|
||||
@ -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
|
||||
@ -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
|
||||
}
|
||||
@ -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' }),
|
||||
}
|
||||
@ -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' }),
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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'}
|
||||
)
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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
|
||||
@ -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" }),
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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' })
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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",
|
||||
}),
|
||||
}
|
||||
@ -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
|
||||
})
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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, {}),
|
||||
}
|
||||
@ -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 }
|
||||
),
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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" }
|
||||
),
|
||||
}
|
||||
@ -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
|
||||
})
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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'
|
||||
})
|
||||
}
|
||||
@ -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' }
|
||||
),
|
||||
}
|
||||
@ -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),
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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" }
|
||||
)
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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",
|
||||
}),
|
||||
}
|
||||
@ -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 }
|
||||
),
|
||||
}
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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 }
|
||||
),
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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" }),
|
||||
}
|
||||
@ -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 }
|
||||
),
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
@ -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" }),
|
||||
}
|
||||
@ -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' }
|
||||
),
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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'
|
||||
})
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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',
|
||||
}),
|
||||
}
|
||||
@ -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,
|
||||
}),
|
||||
}
|
||||
@ -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'}
|
||||
),
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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),
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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',
|
||||
}),
|
||||
}
|
||||
@ -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'
|
||||
})
|
||||
}
|
||||
@ -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'
|
||||
})
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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',
|
||||
}),
|
||||
}
|
||||
@ -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',
|
||||
}),
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
@ -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
Reference in New Issue
Block a user