Skip to content

Commit 35e88e9

Browse files
committed
refactor: make executable check async
executable is sync version when one of formatter is not executable it will cause nvim block, make executable check async and move to FileType callback we don't need check all when config. just lazied check when need.
1 parent 612b1a7 commit 35e88e9

File tree

1 file changed

+28
-10
lines changed

1 file changed

+28
-10
lines changed

lua/guard/events.lua

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -175,20 +175,38 @@ end
175175
---@param ft string
176176
---@param formatters FmtConfig[]
177177
function M.fmt_on_filetype(ft, formatters)
178-
-- check if all cmds executable before registering formatter
179-
iter(formatters):any(function(config)
180-
if type(config) == 'table' and config.cmd and vim.fn.executable(config.cmd) ~= 1 then
181-
report_error(config.cmd .. ' not executable')
182-
return false
183-
end
184-
return true
185-
end)
186-
187178
au('FileType', {
188179
group = M.group,
189180
pattern = ft,
190181
callback = function(args)
191-
M.try_attach_fmt_to_buf(args.buf)
182+
local ok = true
183+
local co
184+
co = coroutine.create(function()
185+
local it = iter(formatters)
186+
while true do
187+
local config = it:next()
188+
if not config then
189+
break
190+
end
191+
if type(config) == 'table' and config.cmd then
192+
vim.uv.fs_stat(vim.fn.exepath(config.cmd), function(err, stat)
193+
if err or not stat or stat.type ~= 'file' then
194+
ok = false
195+
end
196+
coroutine.resume(co)
197+
end)
198+
coroutine.yield()
199+
if not ok then
200+
vim.schedule(function()
201+
report_error(('%s not executable'):format(config.cmd))
202+
api.nvim_del_autocmd(args.id)
203+
end)
204+
end
205+
end
206+
end
207+
M.try_attach_fmt_to_buf(args.buf)
208+
end)
209+
coroutine.resume(co)
192210
end,
193211
desc = 'guard',
194212
})

0 commit comments

Comments
 (0)