Skip to content

Commit

Permalink
feat: notify when formatter errors, and add notify_on_error config op…
Browse files Browse the repository at this point in the history
…tion (#9)
  • Loading branch information
stevearc committed Aug 30, 2023
1 parent 288068b commit 93743e1
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 14 deletions.
7 changes: 6 additions & 1 deletion lua/conform/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ M.formatters_by_ft = {}
---@type table<string, conform.FormatterConfig|fun(bufnr: integer): nil|conform.FormatterConfig>
M.formatters = {}

M.notify_on_error = true

M.setup = function(opts)
opts = opts or {}

Expand All @@ -59,6 +61,9 @@ M.setup = function(opts)
if opts.log_level then
require("conform.log").level = opts.log_level
end
if opts.notify_on_error ~= nil then
M.notify_on_error = opts.notify_on_error
end

for ft, formatters in pairs(M.formatters_by_ft) do
---@diagnostic disable-next-line: undefined-field
Expand Down Expand Up @@ -272,7 +277,7 @@ M.format = function(opts)
end

if opts.async then
require("conform.runner").format_async(opts.bufnr, formatters, opts.range)
require("conform.runner").format_async(opts.bufnr, formatters, opts.quiet, opts.range)
else
require("conform.runner").format_sync(
opts.bufnr,
Expand Down
54 changes: 41 additions & 13 deletions lua/conform/runner.lua
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,17 @@ local function apply_format(bufnr, original_lines, new_lines, range, only_apply_
end
end

local last_run_errored = {}

---@param bufnr integer
---@param formatter conform.FormatterInfo
---@param config conform.FormatterConfig
---@param ctx conform.Context
---@param quiet boolean
---@param input_lines string[]
---@param callback fun(err?: string, output?: string[])
---@return integer job_id
local function run_formatter(bufnr, formatter, config, ctx, input_lines, callback)
local function run_formatter(bufnr, formatter, config, ctx, quiet, input_lines, callback)
local cmd = M.build_cmd(ctx, config)
local cwd = nil
if config.cwd then
Expand All @@ -108,18 +111,34 @@ local function run_formatter(bufnr, formatter, config, ctx, input_lines, callbac
if type(env) == "function" then
env = env(ctx)
end
callback = util.wrap_callback(callback, function(err)
if err then
if
not last_run_errored[formatter.name]
and not quiet
and require("conform").notify_on_error
then
vim.notify(
string.format("Formatter '%s' failed. See :ConformInfo for details", formatter.name),
vim.log.levels.ERROR
)
end
last_run_errored[formatter.name] = true
else
last_run_errored[formatter.name] = false
end
end)

log.info("Run %s on %s", formatter.name, vim.api.nvim_buf_get_name(bufnr))
if not config.stdin then
log.debug("Creating temp file %s", ctx.filename)
local fd = assert(uv.fs_open(ctx.filename, "w", 448)) -- 0700
uv.fs_write(fd, table.concat(input_lines, "\n"))
uv.fs_close(fd)
local final_cb = callback
callback = function(...)
callback = util.wrap_callback(callback, function()
log.debug("Cleaning up temp file %s", ctx.filename)
uv.fs_unlink(ctx.filename)
final_cb(...)
end
end)
end
log.debug("Run command: %s", cmd)
if cwd then
Expand Down Expand Up @@ -229,9 +248,10 @@ end

---@param bufnr integer
---@param formatters conform.FormatterInfo[]
---@param quiet boolean
---@param range? conform.Range
---@param callback? fun(err?: string)
M.format_async = function(bufnr, formatters, range, callback)
M.format_async = function(bufnr, formatters, quiet, range, callback)
if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf()
end
Expand Down Expand Up @@ -271,7 +291,7 @@ M.format_async = function(bufnr, formatters, range, callback)
local config = assert(require("conform").get_formatter_config(formatter.name, bufnr))
local ctx = M.build_context(bufnr, config, range)
local jid
jid = run_formatter(bufnr, formatter, config, ctx, input_lines, function(err, output)
jid = run_formatter(bufnr, formatter, config, ctx, quiet, input_lines, function(err, output)
if err then
-- Only log the error if the job wasn't canceled
if vim.api.nvim_buf_is_valid(bufnr) and jid == vim.b[bufnr].conform_jid then
Expand Down Expand Up @@ -326,13 +346,21 @@ M.format_sync = function(bufnr, formatters, timeout_ms, quiet, range)
local result = nil
local config = assert(require("conform").get_formatter_config(formatter.name, bufnr))
local ctx = M.build_context(bufnr, config, range)
local jid = run_formatter(bufnr, formatter, config, ctx, input_lines, function(err, output)
if err then
log.error(err)
local jid = run_formatter(
bufnr,
formatter,
config,
ctx,
quiet,
input_lines,
function(err, output)
if err then
log.error(err)
end
done = true
result = output
end
done = true
result = output
end)
)
all_support_range_formatting = all_support_range_formatting and config.range_args ~= nil

local wait_result, wait_reason = vim.wait(remaining, function()
Expand Down
10 changes: 10 additions & 0 deletions lua/conform/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,14 @@ M.tbl_slice = function(tbl, start_idx, end_idx)
return ret
end

---@param cb fun(...)
---@param wrapper fun(...)
---@return fun(...)
M.wrap_callback = function(cb, wrapper)
return function(...)
wrapper(...)
cb(...)
end
end

return M
2 changes: 2 additions & 0 deletions tests/options_doc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ require("conform").setup({
},
-- Set the log level. Use `:ConformInfo` to see the location of the log file.
log_level = vim.log.levels.ERROR,
-- Conform will notify you when a formatter errors
notify_on_error = true,
-- Define custom formatters here
formatters = {
my_formatter = {
Expand Down

0 comments on commit 93743e1

Please sign in to comment.