feat(compiler): add configurable error output modes (#14)

Problem: all parse errors went to vim.diagnostic with no way to silence
them or route them to the quickfix list. Users wanting quickfix-style
error navigation had no option.

Solution: add an errors field to ProviderConfig accepting false,
'diagnostic' (default), or 'quickfix'. false suppresses error handling
entirely. 'quickfix' converts parsed diagnostics to qflist items
(1-indexed), calls setqflist, and opens the window. On success,
'quickfix' mode clears the qflist the same way 'diagnostic' mode clears
vim.diagnostic.
This commit is contained in:
Barrett Ruth 2026-03-03 14:57:44 -05:00 committed by GitHub
parent 7995d6422d
commit 253ca05da3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 133 additions and 3 deletions

View file

@ -132,6 +132,108 @@ describe('compiler', function()
end)
end)
describe('errors mode', function()
it('errors = false suppresses error parser', function()
local bufnr = helpers.create_buffer({ 'hello' }, 'text')
vim.api.nvim_buf_set_name(bufnr, '/tmp/preview_test_errors_false.txt')
vim.bo[bufnr].modified = false
local parser_called = false
local provider = {
cmd = { 'false' },
errors = false,
error_parser = function()
parser_called = true
return {}
end,
}
local ctx = {
bufnr = bufnr,
file = '/tmp/preview_test_errors_false.txt',
root = '/tmp',
ft = 'text',
}
compiler.compile(bufnr, 'falsecmd', provider, ctx)
vim.wait(2000, function()
return compiler._test.active[bufnr] == nil
end, 50)
assert.is_false(parser_called)
helpers.delete_buffer(bufnr)
end)
it('errors = quickfix populates quickfix list', function()
local bufnr = helpers.create_buffer({ 'hello' }, 'text')
vim.api.nvim_buf_set_name(bufnr, '/tmp/preview_test_errors_qf.txt')
vim.bo[bufnr].modified = false
local provider = {
cmd = { 'sh', '-c', 'echo "line 1 error" >&2; exit 1' },
errors = 'quickfix',
error_parser = function()
return {
{ lnum = 0, col = 0, message = 'test error', severity = vim.diagnostic.severity.ERROR },
}
end,
}
local ctx = {
bufnr = bufnr,
file = '/tmp/preview_test_errors_qf.txt',
root = '/tmp',
ft = 'text',
}
vim.fn.setqflist({}, 'r')
compiler.compile(bufnr, 'qfcmd', provider, ctx)
vim.wait(2000, function()
return compiler._test.active[bufnr] == nil
end, 50)
local qflist = vim.fn.getqflist()
assert.are.equal(1, #qflist)
assert.are.equal('test error', qflist[1].text)
assert.are.equal(1, qflist[1].lnum)
vim.fn.setqflist({}, 'r')
helpers.delete_buffer(bufnr)
end)
it('errors = quickfix clears quickfix on success', function()
local bufnr = helpers.create_buffer({ 'hello' }, 'text')
vim.api.nvim_buf_set_name(bufnr, '/tmp/preview_test_errors_qf_clear.txt')
vim.bo[bufnr].modified = false
vim.fn.setqflist({ { text = 'old error', lnum = 1 } }, 'r')
assert.are.equal(1, #vim.fn.getqflist())
local provider = {
cmd = { 'true' },
errors = 'quickfix',
error_parser = function()
return {}
end,
}
local ctx = {
bufnr = bufnr,
file = '/tmp/preview_test_errors_qf_clear.txt',
root = '/tmp',
ft = 'text',
}
compiler.compile(bufnr, 'truecmd', provider, ctx)
vim.wait(2000, function()
return compiler._test.active[bufnr] == nil
end, 50)
assert.are.equal(0, #vim.fn.getqflist())
helpers.delete_buffer(bufnr)
end)
end)
describe('stop', function()
it('does nothing when no process is active', function()
assert.has_no.errors(function()