local M = {} local jobid = -1 local job = require('spacevim.api.job') local util = require('format.util') local stdout = {} local stderr = {} local current_task local function on_stdout(id, data) for _, v in ipairs(data) do table.insert(stdout, v) end end local function on_stderr(id, data) for _, v in ipairs(data) do table.insert(stderr, v) end end local function on_exit(id, code, single) util.info( 'formatter: ' .. (current_task.formatter.name or current_task.formatter.exe) .. ' exit code:' .. code .. ' single:' .. single ) if code == 0 and single == 0 then local formatted_context if current_task.formatter.use_stderr then formatted_context = stderr else formatted_context = stdout end if table.concat(stdout, '\n') == table.concat(current_task.stdin, '\n') then util.msg('no necessary changes') else util.msg((current_task.formatter.name or current_task.formatter.exe) .. ' formatted buffer') vim.api.nvim_buf_set_lines( current_task.bufnr, current_task.start_line, current_task.end_line, false, formatted_context ) end else util.msg('formatter ' .. current_task.formatter.exe .. ' failed to run') end jobid = -1 end function M.run(task) if jobid > 0 then util.msg('previous formatting command has not ended') return end util.info('running formatter: ' .. task.formatter.exe) local cmd = { task.formatter.exe } for _, v in ipairs(task.formatter.args) do table.insert(cmd, v) end stdout = {} stderr = {} current_task = task jobid = job.start(cmd, { on_stdout = on_stdout, on_stderr = on_stderr, on_exit = on_exit, }) if jobid == -1 then return util.msg('formatter is not executable: ' .. task.formatter.exe) end if task.formatter.stdin then job.send(jobid, task.stdin) job.send(jobid, nil) end end return M