aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/_editor.lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim/_editor.lua')
-rw-r--r--runtime/lua/vim/_editor.lua119
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