irongit

Configure synchronization of files and directories through a plugin.

syncmap.nvim/lua/syncmap/simple_cmd.lua
84 lines3.7 KBLua
1local M = {}
2
3---@alias StdIO integer|uv.uv_stream_t|nil
4
5---@alias SpawnCommandCallback fun(code:integer, signal:integer, handle:uv.uv_process_t, pid:integer)
6
7---@class SpawnCommandParams
8---@field args string[] The arguments to run on the exectuable
9---@field cwd? string @[default=vim.fn.getcwd()] Set the current working directory for the sub-process.
10---@field env? table<string,string> @[default=vim.fn.environ()] Set environment variables for the new process.
11---@field stdio? { [1]: integer|uv.uv_stream_t|nil, [2]: integer|uv.uv_stream_t|nil, [3]: integer|uv.uv_stream_t|nil } @[default={nil,nil,nil}] Set the file descriptors that will be made available to the child process. The convention is that the first entries are stdin, stdout, and stderr. (**Note**: On Windows, file descriptors after the third are available to the child process only if the child processes uses the MSVCRT runtime.)
12---@field detatched? boolean @[default=true] If true, spawn the child process in a detached state - this will make it a process group leader, and will effectively enable the child to keep running after the parent exits. Note that the child process will still keep the parent's event loop alive unless the parent process calls `uv.unref()` on the child's process handle.
13---@field hide? boolean @[default=true] If true, hide the subprocess console window that would normally be created. This option is only meaningful on Windows systems. On Unix it is silently ignored.
14---@field uid? integer @[default=vim.uv.getuid()] Set the child process' user id.
15---@field verbatim? boolean @[default=false] If true, do not wrap any arguments in quotes, or perform any other escaping, when converting the argument list into a command line string. This option is only meaningful on Windows systems. On Unix it is silently ignored.
16---@field gid? integer @[default=vim.uv.getgid()] Set the child process' group id.
17---The callback to run after the command has returned
18---@field callback? SpawnCommandCallback
19---@field close? boolean @[default=true] Request the handle to be closed (to simplify callbacks)
20
21---A wrapper for uv.spawn that includes defaults. This makes it easier to spawn commands in the background. Also automatically closes the handle unless close is specified to false.
22---@param path string the exectuable path
23---@param p SpawnCommandParams
24function M.spawn(path, p)
25 local args = p.args
26 local stdio = p.stdio or { nil, nil, nil }
27 local cwd = p.cwd or vim.fn.getcwd()
28 local env = p.env or vim.fn.environ()
29 local detached = p.detatched ~= nil and p.detatched or true
30 local hide = p.hide ~= nil and p.hide or true
31 local uid = p.uid or vim.uv.getuid()
32 local verbatim = p.verbatim ~= nil and p.verbatim or false
33 local gid = p.gid ~= nil and p.gid or vim.uv.getgid()
34 local close = p.close ~= nil and p.close or true
35
36 local handle, pid
37 handle, pid = vim.uv.spawn(path, {
38 args = args,
39 stdio = stdio,
40 cwd = cwd,
41 env = env,
42 detached = detached,
43 hide = hide,
44 ---@diagnostic disable-next-line: assign-type-mismatch
45 uid = uid,
46 verbatim = verbatim,
47 ---@diagnostic disable-next-line: assign-type-mismatch
48 gid = gid,
49 }, function(code, signal)
50 if p.callback then
51 p.callback(code, signal, handle, pid)
52 end
53 if close then
54 handle:close()
55 end
56 end)
57 return handle, pid
58end
59
60---Kills a process and all of its descendents
61---@param pid integer|string
62function M.kill(pid)
63 vim.fn.system({ "kill", "-TERM", "-" .. tostring(pid) })
64end
65
66---Checks if a process is running
67---@param pid string|integer
68function M.exists(pid)
69 local result = false
70 local done = false
71 M.spawn("ps", {
72 args = { "-s", tostring(pid) },
73 callback = function(code, _, _, _)
74 result = code == 0
75 done = true
76 end,
77 })
78 vim.wait(100, function()
79 return done
80 end, 10)
81 return result
82end
83
84return M