fix: stream stderr for long-running providers, clear errors on success
Problem: Long-running providers (e.g. `typst watch`) never exit on compile error, so the exit callback never fired and diagnostics/quickfix were never populated. The `typst watch` `reload` command also lacked `--diagnostic-format short`, producing unparseable verbose output. Solution: Add a `stderr` streaming callback to the long-running `vim.system` call that accumulates chunks and re-parses on each new chunk, populating diagnostics or quickfix in real time. When the fs_event fires (successful compile), clear `stderr_acc` and the reported errors. Add `--diagnostic-format short` to the typst `reload` command to match the one-shot `args` format.
This commit is contained in:
parent
239f8a4769
commit
2edeef478d
2 changed files with 44 additions and 1 deletions
|
|
@ -143,12 +143,45 @@ function M.compile(bufnr, name, provider, ctx, opts)
|
|||
table.concat(reload_cmd, ' ')
|
||||
)
|
||||
|
||||
local stderr_acc = {}
|
||||
local obj
|
||||
obj = vim.system(
|
||||
reload_cmd,
|
||||
{
|
||||
cwd = cwd,
|
||||
env = provider.env,
|
||||
stderr = vim.schedule_wrap(function(err, data)
|
||||
if not data or not vim.api.nvim_buf_is_valid(bufnr) then
|
||||
return
|
||||
end
|
||||
stderr_acc[#stderr_acc + 1] = data
|
||||
local errors_mode = provider.errors
|
||||
if errors_mode == nil then
|
||||
errors_mode = 'diagnostic'
|
||||
end
|
||||
if provider.error_parser and errors_mode then
|
||||
local output = table.concat(stderr_acc)
|
||||
if errors_mode == 'diagnostic' then
|
||||
diagnostic.set(bufnr, name, provider.error_parser, output, ctx)
|
||||
elseif errors_mode == 'quickfix' then
|
||||
local ok, diags = pcall(provider.error_parser, output, ctx)
|
||||
if ok and diags and #diags > 0 then
|
||||
local items = {}
|
||||
for _, d in ipairs(diags) do
|
||||
table.insert(items, {
|
||||
bufnr = bufnr,
|
||||
lnum = d.lnum + 1,
|
||||
col = d.col + 1,
|
||||
text = d.message,
|
||||
type = d.severity == vim.diagnostic.severity.WARN and 'W' or 'E',
|
||||
})
|
||||
end
|
||||
vim.fn.setqflist(items, 'r')
|
||||
vim.cmd('copen')
|
||||
end
|
||||
end
|
||||
end
|
||||
end),
|
||||
},
|
||||
vim.schedule_wrap(function(result)
|
||||
if active[bufnr] and active[bufnr].obj == obj then
|
||||
|
|
@ -228,6 +261,16 @@ function M.compile(bufnr, name, provider, ctx, opts)
|
|||
return
|
||||
end
|
||||
stop_open_watcher(bufnr)
|
||||
stderr_acc = {}
|
||||
local errors_mode = provider.errors
|
||||
if errors_mode == nil then
|
||||
errors_mode = 'diagnostic'
|
||||
end
|
||||
if errors_mode == 'diagnostic' then
|
||||
diagnostic.clear(bufnr)
|
||||
elseif errors_mode == 'quickfix' then
|
||||
vim.fn.setqflist({}, 'r')
|
||||
end
|
||||
do_open(bufnr, output_file, provider.open)
|
||||
opened[bufnr] = true
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ M.typst = {
|
|||
end,
|
||||
open = true,
|
||||
reload = function(ctx)
|
||||
return { 'typst', 'watch', ctx.file }
|
||||
return { 'typst', 'watch', '--diagnostic-format', 'short', ctx.file }
|
||||
end,
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue