fix(presets): correct error parsers for real compiler output (#11)
Problem: all three built-in error parsers were broken against real compiler output. Typst set source to the relative file path, overriding the provider name. LaTeX errors go to stdout but the parser only received stderr. Pandoc's pattern matched "Error at" but not the real "Error parsing YAML metadata at" format, and single-line parsing missed multiline messages. Solution: pass combined stdout+stderr to error_parser so LaTeX stdout errors are visible. Remove source = file from the Typst parser so diagnostic.lua defaults it to the provider name. Rewrite the Pandoc parser with line-based lookahead: match (line N, column N) regardless of prefix text, skip YAML parse exception lines when looking ahead for the human-readable message. Rename stderr param to output throughout diagnostic.lua, presets.lua, and init.lua annotations.
This commit is contained in:
parent
87fc00059c
commit
0f353446b6
5 changed files with 101 additions and 79 deletions
|
|
@ -106,7 +106,8 @@ function M.compile(bufnr, name, provider, ctx)
|
|||
else
|
||||
log.dbg('compilation failed for buffer %d (exit code %d)', bufnr, result.code)
|
||||
if provider.error_parser then
|
||||
diagnostic.set(bufnr, name, provider.error_parser, result.stderr or '', ctx)
|
||||
local output = (result.stdout or '') .. (result.stderr or '')
|
||||
diagnostic.set(bufnr, name, provider.error_parser, output, ctx)
|
||||
end
|
||||
vim.api.nvim_exec_autocmds('User', {
|
||||
pattern = 'PreviewCompileFailed',
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ end
|
|||
|
||||
---@param bufnr integer
|
||||
---@param name string
|
||||
---@param error_parser fun(stderr: string, ctx: preview.Context): preview.Diagnostic[]
|
||||
---@param stderr string
|
||||
---@param error_parser fun(output: string, ctx: preview.Context): preview.Diagnostic[]
|
||||
---@param output string
|
||||
---@param ctx preview.Context
|
||||
function M.set(bufnr, name, error_parser, stderr, ctx)
|
||||
local ok, diagnostics = pcall(error_parser, stderr, ctx)
|
||||
function M.set(bufnr, name, error_parser, output, ctx)
|
||||
local ok, diagnostics = pcall(error_parser, output, ctx)
|
||||
if not ok then
|
||||
log.dbg('error_parser for "%s" failed: %s', name, diagnostics)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
---@field cwd? string|fun(ctx: preview.Context): string
|
||||
---@field env? table<string, string>
|
||||
---@field output? string|fun(ctx: preview.Context): string
|
||||
---@field error_parser? fun(stderr: string, ctx: preview.Context): preview.Diagnostic[]
|
||||
---@field error_parser? fun(output: string, ctx: preview.Context): preview.Diagnostic[]
|
||||
---@field clean? string[]|fun(ctx: preview.Context): string[]
|
||||
---@field open? boolean|string[]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
local M = {}
|
||||
|
||||
---@param stderr string
|
||||
---@param output string
|
||||
---@return preview.Diagnostic[]
|
||||
local function parse_typst(stderr)
|
||||
local function parse_typst(output)
|
||||
local diagnostics = {}
|
||||
for line in stderr:gmatch('[^\r\n]+') do
|
||||
local file, lnum, col, severity, msg = line:match('^(.+):(%d+):(%d+): (%w+): (.+)$')
|
||||
for line in output:gmatch('[^\r\n]+') do
|
||||
local _, lnum, col, severity, msg = line:match('^(.+):(%d+):(%d+): (%w+): (.+)$')
|
||||
if lnum then
|
||||
local sev = vim.diagnostic.severity.ERROR
|
||||
if severity == 'warning' then
|
||||
|
|
@ -16,18 +16,17 @@ local function parse_typst(stderr)
|
|||
col = tonumber(col) - 1,
|
||||
message = msg,
|
||||
severity = sev,
|
||||
source = file,
|
||||
})
|
||||
end
|
||||
end
|
||||
return diagnostics
|
||||
end
|
||||
|
||||
---@param stderr string
|
||||
---@param output string
|
||||
---@return preview.Diagnostic[]
|
||||
local function parse_latexmk(stderr)
|
||||
local function parse_latexmk(output)
|
||||
local diagnostics = {}
|
||||
for line in stderr:gmatch('[^\r\n]+') do
|
||||
for line in output:gmatch('[^\r\n]+') do
|
||||
local _, lnum, msg = line:match('^%.?/?(.+%.tex):(%d+): (.+)$')
|
||||
if lnum then
|
||||
table.insert(diagnostics, {
|
||||
|
|
@ -51,41 +50,45 @@ local function parse_latexmk(stderr)
|
|||
return diagnostics
|
||||
end
|
||||
|
||||
---@param stderr string
|
||||
---@param output string
|
||||
---@return preview.Diagnostic[]
|
||||
local function parse_pandoc(stderr)
|
||||
local function parse_pandoc(output)
|
||||
local diagnostics = {}
|
||||
for line in stderr:gmatch('[^\r\n]+') do
|
||||
local lnum, col, msg = line:match('Error at .+ %(line (%d+), column (%d+)%): (.+)$')
|
||||
local lines = vim.split(output, '\n')
|
||||
local i = 1
|
||||
while i <= #lines do
|
||||
local line = lines[i]
|
||||
local lnum, col, msg = line:match('%(line (%d+), column (%d+)%):%s*(.*)$')
|
||||
if lnum then
|
||||
table.insert(diagnostics, {
|
||||
lnum = tonumber(lnum) - 1,
|
||||
col = tonumber(col) - 1,
|
||||
message = msg,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
})
|
||||
else
|
||||
local ylnum, ycol, ymsg =
|
||||
line:match('YAML parse exception at line (%d+), column (%d+)[,:]%s*(.+)$')
|
||||
if ylnum then
|
||||
table.insert(diagnostics, {
|
||||
lnum = tonumber(ylnum) - 1,
|
||||
col = tonumber(ycol) - 1,
|
||||
message = ymsg,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
})
|
||||
else
|
||||
local errmsg = line:match('^pandoc: (.+)$')
|
||||
if errmsg and not errmsg:match('^Error at') then
|
||||
table.insert(diagnostics, {
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
message = errmsg,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
})
|
||||
if msg == '' then
|
||||
for j = i + 1, math.min(i + 2, #lines) do
|
||||
local next_line = lines[j]:match('^%s*(.+)$')
|
||||
if next_line and not next_line:match('^YAML parse exception') then
|
||||
msg = next_line
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if msg ~= '' then
|
||||
table.insert(diagnostics, {
|
||||
lnum = tonumber(lnum) - 1,
|
||||
col = tonumber(col) - 1,
|
||||
message = msg,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
})
|
||||
end
|
||||
else
|
||||
local errmsg = line:match('^pandoc: (.+)$')
|
||||
if errmsg then
|
||||
table.insert(diagnostics, {
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
message = errmsg,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
})
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
return diagnostics
|
||||
end
|
||||
|
|
@ -100,8 +103,8 @@ M.typst = {
|
|||
output = function(ctx)
|
||||
return (ctx.file:gsub('%.typ$', '.pdf'))
|
||||
end,
|
||||
error_parser = function(stderr)
|
||||
return parse_typst(stderr)
|
||||
error_parser = function(output)
|
||||
return parse_typst(output)
|
||||
end,
|
||||
open = true,
|
||||
}
|
||||
|
|
@ -121,8 +124,8 @@ M.latex = {
|
|||
output = function(ctx)
|
||||
return (ctx.file:gsub('%.tex$', '.pdf'))
|
||||
end,
|
||||
error_parser = function(stderr)
|
||||
return parse_latexmk(stderr)
|
||||
error_parser = function(output)
|
||||
return parse_latexmk(output)
|
||||
end,
|
||||
clean = function(ctx)
|
||||
return { 'latexmk', '-c', ctx.file }
|
||||
|
|
@ -141,8 +144,8 @@ M.markdown = {
|
|||
output = function(ctx)
|
||||
return (ctx.file:gsub('%.md$', '.html'))
|
||||
end,
|
||||
error_parser = function(stderr)
|
||||
return parse_pandoc(stderr)
|
||||
error_parser = function(output)
|
||||
return parse_pandoc(output)
|
||||
end,
|
||||
clean = function(ctx)
|
||||
return { 'rm', '-f', (ctx.file:gsub('%.md$', '.html')) }
|
||||
|
|
@ -171,8 +174,8 @@ M.github = {
|
|||
output = function(ctx)
|
||||
return (ctx.file:gsub('%.md$', '.html'))
|
||||
end,
|
||||
error_parser = function(stderr)
|
||||
return parse_pandoc(stderr)
|
||||
error_parser = function(output)
|
||||
return parse_pandoc(output)
|
||||
end,
|
||||
clean = function(ctx)
|
||||
return { 'rm', '-f', (ctx.file:gsub('%.md$', '.html')) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue