diff options
Diffstat (limited to 'runtime/lua/vim/_editor.lua')
-rw-r--r-- | runtime/lua/vim/_editor.lua | 119 |
1 files changed, 91 insertions, 28 deletions
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 7b946a55e4..ab20c36b17 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -3,7 +3,7 @@ -- Lua code lives in one of three places: -- 1. runtime/lua/vim/ (the runtime): For "nice to have" features, e.g. the -- `inspect` and `lpeg` modules. --- 2. runtime/lua/vim/shared.lua: pure lua functions which always +-- 2. runtime/lua/vim/shared.lua: pure Lua functions which always -- are available. Used in the test runner, as well as worker threads -- and processes launched from Nvim. -- 3. runtime/lua/vim/_editor.lua: Code which directly interacts with @@ -42,10 +42,6 @@ for k, v in pairs({ vim._submodules[k] = v end --- Remove at Nvim 1.0 ----@deprecated -vim.loop = vim.uv - -- There are things which have special rules in vim._init_packages -- for legacy reasons (uri) or for performance (_inspector). -- most new things should go into a submodule namespace ( vim.foobar.do_thing() ) @@ -69,13 +65,73 @@ vim.log = { }, } --- Internal-only until comments in #8107 are addressed. --- Returns: --- {errcode}, {output} -function vim._system(cmd) - local out = vim.fn.system(cmd) - local err = vim.v.shell_error - return err, out +-- TODO(lewis6991): document that the signature is system({cmd}, [{opts},] {on_exit}) +--- Run a system command +--- +--- Examples: +--- <pre>lua +--- +--- local on_exit = function(obj) +--- print(obj.code) +--- print(obj.signal) +--- print(obj.stdout) +--- print(obj.stderr) +--- end +--- +--- -- Run asynchronously +--- vim.system({'echo', 'hello'}, { text = true }, on_exit) +--- +--- -- Run synchronously +--- local obj = vim.system({'echo', 'hello'}, { text = true }):wait() +--- -- { code = 0, signal = 0, stdout = 'hello', stderr = '' } +--- +--- </pre> +--- +--- See |uv.spawn()| for more details. +--- +--- @param cmd (string[]) Command to execute +--- @param opts (SystemOpts|nil) Options: +--- - cwd: (string) Set the current working directory for the sub-process. +--- - env: table<string,string> Set environment variables for the new process. Inherits the +--- current environment with `NVIM` set to |v:servername|. +--- - clear_env: (boolean) `env` defines the job environment exactly, instead of merging current +--- environment. +--- - stdin: (string|string[]|boolean) If `true`, then a pipe to stdin is opened and can be written +--- to via the `write()` method to SystemObj. If string or string[] then will be written to stdin +--- and closed. Defaults to `false`. +--- - stdout: (boolean|function) +--- Handle output from stdout. When passed as a function must have the signature `fun(err: string, data: string)`. +--- Defaults to `true` +--- - stderr: (boolean|function) +--- Handle output from stdout. When passed as a function must have the signature `fun(err: string, data: string)`. +--- Defaults to `true`. +--- - text: (boolean) Handle stdout and stderr as text. Replaces `\r\n` with `\n`. +--- - timeout: (integer) +--- - detach: (boolean) 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. +--- +--- @param on_exit (function|nil) Called when subprocess exits. When provided, the command runs +--- asynchronously. Receives SystemCompleted object, see return of SystemObj:wait(). +--- +--- @return SystemObj Object with the fields: +--- - pid (integer) Process ID +--- - wait (fun(timeout: integer|nil): SystemCompleted) +--- - SystemCompleted is an object with the fields: +--- - code: (integer) +--- - signal: (integer) +--- - stdout: (string), nil if stdout argument is passed +--- - stderr: (string), nil if stderr argument is passed +--- - kill (fun(signal: integer)) +--- - write (fun(data: string|nil)) Requires `stdin=true`. Pass `nil` to close the stream. +--- - is_closing (fun(): boolean) +function vim.system(cmd, opts, on_exit) + if type(opts) == 'function' then + on_exit = opts + opts = nil + end + return require('vim._system').run(cmd, opts, on_exit) end -- Gets process info from the `ps` command. @@ -85,13 +141,14 @@ function vim._os_proc_info(pid) error('invalid pid') end local cmd = { 'ps', '-p', pid, '-o', 'comm=' } - local err, name = vim._system(cmd) - if 1 == err and vim.trim(name) == '' then + local r = vim.system(cmd):wait() + local name = assert(r.stdout) + if r.code == 1 and vim.trim(name) == '' then return {} -- Process not found. - elseif 0 ~= err then + elseif r.code ~= 0 then error('command failed: ' .. vim.fn.string(cmd)) end - local _, ppid = vim._system({ 'ps', '-p', pid, '-o', 'ppid=' }) + local ppid = assert(vim.system({ 'ps', '-p', pid, '-o', 'ppid=' }):wait().stdout) -- Remove trailing whitespace. name = vim.trim(name):gsub('^.*/', '') ppid = tonumber(ppid) or -1 @@ -109,14 +166,14 @@ function vim._os_proc_children(ppid) error('invalid ppid') end local cmd = { 'pgrep', '-P', ppid } - local err, rv = vim._system(cmd) - if 1 == err and vim.trim(rv) == '' then + local r = vim.system(cmd):wait() + if r.code == 1 and vim.trim(r.stdout) == '' then return {} -- Process not found. - elseif 0 ~= err then + elseif r.code ~= 0 then error('command failed: ' .. vim.fn.string(cmd)) end local children = {} - for s in rv:gmatch('%S+') do + for s in r.stdout:gmatch('%S+') do local i = tonumber(s) if i ~= nil then table.insert(children, i) @@ -127,6 +184,7 @@ end --- Gets a human-readable representation of the given object. --- +---@see |vim.print()| ---@see https://github.com/kikito/inspect.lua ---@see https://github.com/mpeterv/vinspect local function inspect(object, options) -- luacheck: no unused @@ -477,9 +535,9 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive) return region end ---- Defers calling `fn` until `timeout` ms passes. +--- Defers calling {fn} until {timeout} ms passes. --- ---- Use to do a one-shot timer that calls `fn` +--- Use to do a one-shot timer that calls {fn} --- Note: The {fn} is |vim.schedule_wrap()|ped automatically, so API functions are --- safe to call. ---@param fn function Callback to call once `timeout` expires @@ -782,10 +840,10 @@ do -- some bugs, so fake the two-step dance for now. local matches - --- Omnifunc for completing lua values from the runtime lua interpreter, + --- Omnifunc for completing Lua values from the runtime Lua interpreter, --- similar to the builtin completion for the `:lua` command. --- - --- Activate using `set omnifunc=v:lua.vim.lua_omnifunc` in a lua buffer. + --- Activate using `set omnifunc=v:lua.vim.lua_omnifunc` in a Lua buffer. function vim.lua_omnifunc(find_start, _) if find_start == 1 then local line = vim.api.nvim_get_current_line() @@ -813,6 +871,7 @@ end --- </pre> --- --- @see |vim.inspect()| +--- @see |:=| --- @return any # given arguments. function vim.print(...) if vim.in_fast_event() then @@ -875,7 +934,7 @@ function vim._cs_remote(rcid, server_addr, connect_error, args) or subcmd == 'tab-wait' or subcmd == 'tab-wait-silent' then - return { errmsg = 'E5600: Wait commands not yet implemented in nvim' } + return { errmsg = 'E5600: Wait commands not yet implemented in Nvim' } elseif subcmd == 'tab-silent' then f_tab = true f_silent = true @@ -883,14 +942,14 @@ function vim._cs_remote(rcid, server_addr, connect_error, args) if rcid == 0 then return { errmsg = connection_failure_errmsg('Send failed.') } end - vim.fn.rpcrequest(rcid, 'nvim_input', args[2]) + vim.rpcrequest(rcid, 'nvim_input', args[2]) return { should_exit = true, tabbed = false } elseif subcmd == 'expr' then if rcid == 0 then return { errmsg = connection_failure_errmsg('Send expression failed.') } end - print(vim.fn.rpcrequest(rcid, 'nvim_eval', args[2])) - return { should_exit = true, tabbed = false } + local res = tostring(vim.rpcrequest(rcid, 'nvim_eval', args[2])) + return { result = res, should_exit = true, tabbed = false } elseif subcmd ~= '' then return { errmsg = 'Unknown option argument: ' .. args[1] } end @@ -1006,4 +1065,8 @@ end require('vim._meta') +-- Remove at Nvim 1.0 +---@deprecated +vim.loop = vim.uv + return vim |