diff --git a/lua/guard/events.lua b/lua/guard/events.lua index 64f7eec..2884a43 100644 --- a/lua/guard/events.lua +++ b/lua/guard/events.lua @@ -175,22 +175,48 @@ end ---@param ft string ---@param formatters FmtConfig[] function M.fmt_on_filetype(ft, formatters) - -- check if all cmds executable before registering formatter - iter(formatters):any(function(config) - if type(config) == 'table' and config.cmd and vim.fn.executable(config.cmd) ~= 1 then - report_error(config.cmd .. ' not executable') - return false - end - return true - end) + -- safely check do we need? + if #formatters == 0 then + return + end au('FileType', { group = M.group, pattern = ft, callback = function(args) - M.try_attach_fmt_to_buf(args.buf) + coroutine.resume(coroutine.create(function() + local co = assert(coroutine.running()) + local it = iter(formatters) + local ok = true + while true do + local config = it:next() + if not config then + break + end + if type(config) == 'table' and config.cmd then + vim.uv.fs_stat(vim.fn.exepath(config.cmd), function(err, stat) + if err or not stat or stat.type ~= 'file' then + ok = false + end + coroutine.resume(co) + end) + coroutine.yield() + if not ok then + vim.schedule(function() + report_error(('%s not executable'):format(config.cmd)) + api.nvim_del_autocmd(args.id) + end) + return + end + end + end + + vim.schedule(function() + M.try_attach_fmt_to_buf(args.buf) + end) + end)) end, - desc = 'guard', + desc = '[Guard] register BufWritePre for auto format when save', }) end diff --git a/lua/guard/format.lua b/lua/guard/format.lua index 6d4dc69..78dd5a6 100644 --- a/lua/guard/format.lua +++ b/lua/guard/format.lua @@ -51,6 +51,18 @@ local function fail(msg) vim.notify('[Guard]: ' .. msg, vim.log.levels.WARN) end +--- Error handler +---@param errno table +local function err_handler(errno) + if errno.reason:match('exited with errors$') then + fail(('%s exited with code %d\n%s'):format(errno.cmd, errno.code, errno.stderr)) + elseif errno.reason == 'buf changed' then + fail('buffer changed during formatting') + else + fail(errno.reason) + end +end + local function do_fmt(buf) buf = buf or api.nvim_get_current_buf() local ft_conf = filetype[vim.bo[buf].filetype] @@ -169,18 +181,11 @@ local function do_fmt(buf) vim.schedule(function() -- handle errors if errno then - if errno.reason:match('exited with errors$') then - fail(('%s exited with code %d\n%s'):format(errno.cmd, errno.code, errno.stderr)) - elseif errno.reason == 'buf changed' then - fail('buffer changed during formatting') - else - fail(errno.reason) - end - return + return err_handler(errno) end -- check buffer one last time if api.nvim_buf_get_changedtick(buf) ~= changedtick then - fail('buffer changed during formatting') + return fail('buffer changed during formatting') end if not api.nvim_buf_is_valid(buf) then fail('buffer no longer valid')