From a17065e15160a009d892b2f94db1782d614892f8 Mon Sep 17 00:00:00 2001 From: Smirnov Oleksandr Date: Wed, 26 Jul 2023 17:01:19 +0300 Subject: [PATCH] feat(utils): first impl of own commands runner --- lua/gopher/_utils/runner.lua | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 lua/gopher/_utils/runner.lua diff --git a/lua/gopher/_utils/runner.lua b/lua/gopher/_utils/runner.lua new file mode 100644 index 0000000..99c26bd --- /dev/null +++ b/lua/gopher/_utils/runner.lua @@ -0,0 +1,54 @@ +local runner = {} + +local uv = vim.loop + +---@class ProcessOpts +---@field args? string[] +---@field cwd? string +---@field on_exit? fun(ok:boolean, output:string) + +---@param opts? ProcessOpts +---@param cmd string +function runner.spawn(cmd, opts) + opts = opts or {} + + local stdout = assert(uv.new_pipe()) + local stderr = assert(uv.new_pipe()) + + local output = "" + ---@type uv_process_t? + local handle = nil + + handle = uv.spawn(cmd, { + stdio = { nil, stdout, stderr }, + args = opts.args, + cwd = opts.cwd, + }, function(status) + if handle then + handle:close() + end + stderr:close() + stdout:close() + + if opts.on_exit then + output = output:gsub("[^\r\n]+\r", "") + vim.schedule(function() + opts.on_exit(status == 0, output) + end) + end + end) + + local function on_output(err, data) + assert(not err, err) + if data then + output = output .. data:gsub("\r\n", "\n") + end + end + + uv.read_start(stdout, on_output) + uv.read_start(stderr, on_output) + + return handle +end + +return runner