mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-04-13 14:09:09 +08:00
feat(api): add lua job api
close https://github.com/neovim/neovim/issues/20856
This commit is contained in:
parent
d908e25959
commit
879129388a
3
bundle/gtags.vim/autoload/ctags.vim
vendored
3
bundle/gtags.vim/autoload/ctags.vim
vendored
@ -103,8 +103,7 @@ endfunction
|
||||
|
||||
function! s:on_update_exit(id, data, event) abort
|
||||
" @bug on exit function is not called when failed
|
||||
" C:\Users\wsdjeg\.SpaceVim>C:\Users\wsdjeg\.SpaceVim\bundle\phpcomplete.vim\bin\ctags.exe -R -o C:/Users/wsdjeg/.cache/SpaceVim/tags/C__Users_wsd
|
||||
" jeg__SpaceVim_/tags C:\Users\wsdjeg\.SpaceVim
|
||||
" C:\Users\wsdjeg\.SpaceVim>C:\Users\wsdjeg\.SpaceVim\bundle\phpcomplete.vim\bin\ctags.exe -R -o C:/Users/wsdjeg/.cache/SpaceVim/tags/C__Users_wsdjeg__SpaceVim_/tags C:\Users\wsdjeg\.SpaceVim
|
||||
"
|
||||
" C:\Users\wsdjeg\.SpaceVim>echo %ERRORLEVEL%
|
||||
" -1073741819
|
||||
|
159
lua/spacevim/api/job.lua
Normal file
159
lua/spacevim/api/job.lua
Normal file
@ -0,0 +1,159 @@
|
||||
--=============================================================================
|
||||
-- job.lua ---
|
||||
-- Copyright (c) 2016-2022 Wang Shidong & Contributors
|
||||
-- Author: Wang Shidong < wsdjeg@outlook.com >
|
||||
-- URL: https://spacevim.org
|
||||
-- License: GPLv3
|
||||
--=============================================================================
|
||||
|
||||
local M = {}
|
||||
|
||||
local uv = vim.loop
|
||||
|
||||
local _jobs = {}
|
||||
local _jobid = 0
|
||||
|
||||
local function new_job_obj(id, handle, opt, state)
|
||||
local jobobj = {
|
||||
id = id,
|
||||
handle = handle,
|
||||
opt = opt,
|
||||
state = state,
|
||||
}
|
||||
return jobobj
|
||||
end
|
||||
|
||||
function M.start(cmd, opts)
|
||||
local stdin = uv.new_pipe()
|
||||
local stdout = uv.new_pipe()
|
||||
local stderr = uv.new_pipe()
|
||||
local command = ''
|
||||
local argv = {}
|
||||
if type(cmd) == 'string' then
|
||||
command = 'cmd.exe'
|
||||
argv = { '/c', cmd }
|
||||
elseif type(cmd) == 'table' then
|
||||
command = cmd[1]
|
||||
argv = vim.list_slice(cmd, 2)
|
||||
end
|
||||
|
||||
local opt = {
|
||||
stdio = { stdin, stdout, stderr },
|
||||
args = argv,
|
||||
}
|
||||
_jobid = _jobid + 1
|
||||
local current_id = _jobid
|
||||
local exit_cb
|
||||
if opts.on_exit then
|
||||
exit_cb = function(code, singin)
|
||||
opts.on_exit(current_id, code, singin)
|
||||
end
|
||||
end
|
||||
|
||||
local handle, pid = uv.spawn(command, opt, exit_cb)
|
||||
|
||||
_jobs['jobid_' .. _jobid] = new_job_obj(_jobid, handle, opts, {
|
||||
stdout = stdout,
|
||||
stderr = stderr,
|
||||
stdin = stdin,
|
||||
pid = pid,
|
||||
})
|
||||
if opts.on_stdout then
|
||||
uv.read_start(stdout, function(err, data)
|
||||
if data then
|
||||
opts.on_stdout(current_id, data, 'stdout')
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if opts.on_stderr then
|
||||
uv.read_start(stderr, function(err, data)
|
||||
if data then
|
||||
opts.on_stderr(current_id, data, 'stderr')
|
||||
end
|
||||
end)
|
||||
end
|
||||
return current_id
|
||||
end
|
||||
|
||||
function M.send(id, data) -- {{{
|
||||
local jobobj = _jobs['jobid_' .. id]
|
||||
|
||||
if not jobobj then
|
||||
error('can not find job:' .. id)
|
||||
end
|
||||
|
||||
local stdin = jobobj.state.stdin
|
||||
|
||||
if not stdin then
|
||||
error('no stdin stream for jobid:' .. id)
|
||||
end
|
||||
|
||||
if type(data) == 'table' then
|
||||
for _, v in ipairs(data) do
|
||||
stdin:write(v)
|
||||
stdin:write('\n')
|
||||
end
|
||||
elseif type(data) == 'string' then
|
||||
stdin:write(data)
|
||||
elseif data == nil then
|
||||
stdin:write('', function()
|
||||
stdin:shutdown(function()
|
||||
if stdin then
|
||||
stdin:close()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function M.chanclose(id, t)
|
||||
local jobobj = _jobs['jobid_' .. id]
|
||||
|
||||
if not jobobj then
|
||||
error('can not find job:' .. id)
|
||||
end
|
||||
if t == 'stdin' then
|
||||
local stdin = jobobj.state.stdin
|
||||
if not stdin then
|
||||
stdin:shutdown(function()
|
||||
if stdin then
|
||||
stdin:close()
|
||||
end
|
||||
end)
|
||||
end
|
||||
elseif t == 'stdout' then
|
||||
elseif t == 'stderr' then
|
||||
else
|
||||
error('the type only can be:stdout, stdin or stderr')
|
||||
end
|
||||
end
|
||||
|
||||
function M.stop(id)
|
||||
local jobobj = _jobs['jobid_' .. id]
|
||||
|
||||
if not jobobj then
|
||||
error('can not find job:' .. id)
|
||||
end
|
||||
|
||||
-- close stdio
|
||||
local stdin = jobobj.state.stdin
|
||||
if stdin and stdin:is_active() then
|
||||
stdin:close()
|
||||
end
|
||||
-- close stdio
|
||||
local stdout = jobobj.state.stout
|
||||
if stdout and stdout:is_active() then
|
||||
stdout:close()
|
||||
end
|
||||
-- close stdio
|
||||
local stderr = jobobj.state.stderr
|
||||
if stderr and stderr:is_active() then
|
||||
stderr:close()
|
||||
end
|
||||
|
||||
local handle = jobobj.handle
|
||||
handle:kill(6)
|
||||
end
|
||||
|
||||
return M
|
23
test/lua/test_job.lua
Normal file
23
test/lua/test_job.lua
Normal file
@ -0,0 +1,23 @@
|
||||
local job = require('spacevim.api.job')
|
||||
|
||||
local jobid = job.start({ 'rg', 'wsdjeg', '.' }, {
|
||||
on_stdout = function(id, data, event)
|
||||
vim.print(id)
|
||||
vim.print(data)
|
||||
vim.print(event)
|
||||
end,
|
||||
on_stderr = function(id, data, event)
|
||||
vim.print(id)
|
||||
vim.print(data)
|
||||
vim.print(event)
|
||||
end,
|
||||
on_exit = function(id, code, signal)
|
||||
vim.print(id)
|
||||
vim.print('exit code', code)
|
||||
vim.print('exit signal', signal)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
-- job.send(jobid, 'hello world')
|
||||
-- job.stop(jobid)
|
Loading…
x
Reference in New Issue
Block a user