-
-
Notifications
You must be signed in to change notification settings - Fork 27
Description
Problem X you are solving:
Some linters output diagnostics for multiple files in a single run. For example, terraform validate always validates the entire terraform configuration and returns diagnostics for all .tf files. I need to filter diagnostics to show only those relevant to the current buffer.
Problems encountered under the status quo:
Right now, parse only gets (result, bufnr) as parameters. The issue is that parse runs inside async.run, which means it's in a fast event context where you can't call neovim api.
parse = function(result, bufnr)
-- E5560: must not be called in a fast event context
local fname = vim.api.nvim_buf_get_name(bufnr)
-- This also doesn't work :(
local fname = vim.fn.bufname(bufnr)
endSuggested feature Y:
You're already capturing fname and cwd before the async context (line 82 in guard/lint.lua). Could you pass them to parse too?
-- Current (line ~107,122)
if #data > 0 then
results = lint.parse(data, buf)
end
-- Proposed
if #data > 0 then
results = lint.parse(data, buf, fname, cwd)
endHow to solve X now:
The only workaround I found is to capture the filename before vim.system and inject it through the linter output:
fn = function(acc)
local co = assert(coroutine.running())
vim.system({ 'terraform', 'validate', '-json' }, {...}, function(result)
-- I also tried wrapping the code in a `vim.schedule`
local rpath = vim.fn.expand('%:.')
local decoded = vim.json.decode(result.stdout)
decoded.current_file = rpath
coroutine.resume(co, vim.json.encode(decoded))
end)
...
endI tried using vim.schedule in the callback to exit the fast context, but that breaks the coroutine flow and parse never gets called.
How can X be solved after feature Y is implmented:
parse = function(result, bufnr, fname, cwd)
local current_file = fname:gsub('^%. /', '')
local decoded = vim.json.decode(result)
local diagnostics = {}
for _, diag in ipairs(decoded.diagnostics or {}) do
local diag_file = diag.range.filename:gsub('^%. /', '')
if diag_file == current_file then
table.insert(diagnostics, diag)
end
end
return diagnostics
end