Skip to content

Commit

Permalink
improv(ignoreComment): more helpful info if config/code/source missing
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisgrieser committed Jun 12, 2024
1 parent 9c5450e commit bdb43f1
Showing 1 changed file with 40 additions and 33 deletions.
73 changes: 40 additions & 33 deletions lua/rulebook/diagnostic-actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,33 @@ local M = {}
local notify = require("rulebook.utils").notify
--------------------------------------------------------------------------------

---checks whether rule has id and source, as prescribed in nvim diagnostic structure
---@param diag vim.Diagnostic
---@return boolean whether rule is valid
---@return boolean
---@nodiscard
local function validDiagObj(diag)
local function sourceUsesCodes(diag)
local config = require("rulebook.config").config
local sourcesWithNoCodes = vim.iter(config.ignoreComments)
:filter(function(_, conf) return conf.doesNotUseCodes end)
:map(function(linter, _) return linter end)
:totable()
if vim.tbl_contains(sourcesWithNoCodes, diag.source) then return true end
return not vim.tbl_contains(sourcesWithNoCodes, diag.source)
end

---checks whether rule has id and source, as prescribed in nvim diagnostic structure
---@param diag vim.Diagnostic
---@return boolean
---@nodiscard
local function validDiagObj(diag)
if not sourceUsesCodes(diag) then return true end

local issuePlea =
"\nIf you are using efm or nvim-lint, please check your linter config. Otherwise open an issue at the diagnostic source or the diagnostic provider."
if not diag.code then
notify("Diagnostic is missing a code (rule id)." .. issuePlea, "warn")
return false
elseif not diag.source then
if not diag.source then
notify("Diagnostic is missing a source." .. issuePlea, "warn")
return false
elseif not diag.code and sourceUsesCodes(diag) then
notify("Diagnostic is missing a code (rule id)." .. issuePlea, "warn")
return false
end
return true
end
Expand Down Expand Up @@ -56,13 +63,17 @@ end

---@param diag vim.Diagnostic
function M.ignoreRule(diag)
local configForSource = require("rulebook.config").config.ignoreComments[diag.source]
if not configForSource then
notify(("No ignore comment configured for %q."):format(diag.source), "warn")
return
end
if not validDiagObj(diag) then return end
local config = require("rulebook.config").config

local indent = vim.api.nvim_get_current_line():match("^%s*")
local ignoreComment = config.ignoreComments[diag.source].comment
local ignoreComment = configForSource.comment
if type(ignoreComment) == "function" then ignoreComment = ignoreComment(diag) end
local ignoreLocation = config.ignoreComments[diag.source].location
local ignoreLocation = configForSource.location

-- insert the comment
if ignoreLocation == "prevLine" then
Expand Down Expand Up @@ -98,7 +109,6 @@ end
---@param operation "lookupRule"|"ignoreRule"|"yankDiagnosticCode"
function M.selectRule(operation)
local config = require("rulebook.config").config
local operationIsIgnore = operation == "ignoreRule"
local lnum = vim.api.nvim_win_get_cursor(0)[1] - 1
local startLine = lnum
local lastLine = vim.api.nvim_buf_line_count(0)
Expand All @@ -107,24 +117,12 @@ function M.selectRule(operation)
-- loop through lines until we find a line with diagnostics
while true do
diagsAtLine = vim.diagnostic.get(0, { lnum = lnum })
if operationIsIgnore then
-- INFO for rule search, there is no need to filter the diagnostics, since there
-- is a fallback mechanic
diagsAtLine = vim.tbl_filter(
function(d) return config.ignoreComments[d.source] ~= nil end,
diagsAtLine
)
end

-- no diagnostic -> search the next lines
if #diagsAtLine > 0 then break end
if #diagsAtLine > 0 then break end -- no diagnostic -> search the next lines
lnum = lnum + 1

-- GUARD
if lnum > lastLine or lnum > startLine + config.forwSearchLines then
local msg = ("No supported diagnostics found in the next %s lines."):format(
config.forwSearchLines
)
local msg = ("No diagnostics found in the next %s lines."):format(config.forwSearchLines)
notify(msg, "warn")
return
end
Expand All @@ -133,7 +131,7 @@ function M.selectRule(operation)
-- remove duplicate rules
local uniqueRule = {}
for _, diag in ipairs(diagsAtLine) do
uniqueRule[diag.source .. (diag.code or diag.message)] = diag
uniqueRule[(diag.source or "") .. (diag.code or diag.message)] = diag
end
diagsAtLine = vim.tbl_values(uniqueRule)

Expand All @@ -145,25 +143,34 @@ function M.selectRule(operation)

-- select from multiple diagnostics
local title
if operationIsIgnore then title = "Ignore Rule:" end
if operation == "ignoreRule" then title = "Ignore Rule:" end
if operation == "lookupRule" then title = "Lookup Rule:" end
if operation == "yankDiagnosticCode" then title = "Yank Diagnostic Code:" end

vim.ui.select(diagsAtLine, {
prompt = title,
kind = "rule_selection",
format_item = function(diag)
local source = diag.source and diag.source .. ": " or ""
local desc = diag.code or diag.message
local display = source .. desc
if not (diag.code and diag.source) then display = "" .. display end
local msg = vim.trim((diag.message or ""):sub(1, 50))
if not diag.source then return ("[ No source] %s %s"):format(diag.code or "", msg) end

local display = diag.source .. ": " .. (diag.code or msg)
if operation == "ignoreRule" then
local configForSource = require("rulebook.config").config.ignoreComments[diag.source]
if not configForSource then display = "[ No config] " .. display end
if sourceUsesCodes(diag) and not diag.code then
display = "[ No code] " .. display
end
elseif not diag.code then
display = "[ No code] " .. display
end
return display
end,
}, function(diag)
if not diag then return end -- user aborted

-- move cursor to location where we add the comment
if operationIsIgnore and startLine ~= lnum then
if operation == "ignoreRule" and startLine ~= lnum then
vim.api.nvim_win_set_cursor(0, { lnum + 1, 0 })
vim.cmd("normal! ^")
end
Expand Down

0 comments on commit bdb43f1

Please sign in to comment.