local log = require('pending.log') ---@class pending.SystemResult ---@field code integer ---@field stdout string ---@field stderr string ---@class pending.sync.util local M = {} local _sync_in_flight = false ---@param fn fun(): nil function M.async(fn) coroutine.resume(coroutine.create(fn)) end ---@param args string[] ---@param opts? table ---@return pending.SystemResult function M.system(args, opts) local co = coroutine.running() if not co then return vim.system(args, opts or {}):wait() --[[@as pending.SystemResult]] end vim.system(args, opts or {}, function(result) vim.schedule(function() coroutine.resume(co, result) end) end) return coroutine.yield() --[[@as { code: integer, stdout: string, stderr: string }]] end ---@param name string ---@param fn fun(): nil function M.with_guard(name, fn) if _sync_in_flight then log.warn(name .. ': Sync already in progress — please wait.') return end _sync_in_flight = true local ok, err = pcall(fn) _sync_in_flight = false if not ok then log.error(name .. ': ' .. tostring(err)) end end ---@return boolean function M.sync_in_flight() return _sync_in_flight end ---@param s pending.Store function M.finish(s) s:save() require('pending')._recompute_counts() local buffer = require('pending.buffer') if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then buffer.render(buffer.bufnr()) end end ---@param parts [integer, string][] ---@return string function M.fmt_counts(parts) local items = {} for _, p in ipairs(parts) do if p[1] > 0 then table.insert(items, p[1] .. ' ' .. p[2]) end end if #items == 0 then return 'nothing to do' end return table.concat(items, ' | ') end return M