Job_control
Nvim :help
pages, generated
from source
using the tree-sitter-vimdoc parser.
Usage
function! s:OnEvent(job_id, data, event) dict if a:event == 'stdout' let str = self.shell.' stdout: '.join(a:data) elseif a:event == 'stderr' let str = self.shell.' stderr: '.join(a:data) else let str = self.shell.' exited' endifTo test the above script, copy it to a file ~/foo.vim and run it:call append(line(’$’), str) endfunction let s:callbacks = { \ ‘on_stdout’: function(‘s:OnEvent’), \ ‘on_stderr’: function(‘s:OnEvent’), \ ‘on_exit’: function(‘s:OnEvent’) \ } let job1 = jobstart([‘bash’], extend({‘shell’: ‘shell 1’}, s:callbacks)) let job2 = jobstart([‘bash’, ‘-c’, ‘for i in {1..10}; do echo hello $i!; sleep 1; done’], extend({‘shell’: ‘shell 2’}, s:callbacks))
nvim -u ~/foo.vim
OnEvent()
callback is passed to jobstart() to handle various job
events. It displays stdout/stderr data received from the shells.
on_exit
Arguments passed to on_exit callback:
0: job-id
1: Exit-code of the process, or 128+SIGNUM if by signal (e.g. 143 on SIGTERM).
2: Event type: "exit"function! Receive(job_id, data, event) echom printf('%s: %s',a:event,string(a:data)) endfunction call jobstart(['ruby', '-e', \ '$stdout.sync = true; 5.times do sleep 1 and puts "Hello Ruby!" end'], \ {'on_stdout': 'Receive'})
a:data
is not guaranteed to end
with a newline.
abcdefg
may arrive as ['abc']
, ['defg']
.
abc\nefg
may arrive as ['abc', '']
, ['efg']
or ['abc']
,
['','efg']
, or even ['ab']
, ['c','efg']
.
Easy way to deal with this: initialize a list as ['']
, then append
to it as follows:let s:chunks = [''] func! s:on_stdout(job_id, data, event) dict let s:chunks[-1] .= a:data[0] call extend(s:chunks, a:data[1:]) endf
let Shell = {}function Shell.on_stdout(_job_id, data, event) call append(line(’$’), \ printf(’[%s] %s: %s’, a:event, self.name, join(a:data[:-2]))) endfunction
let Shell.on_stderr = function(Shell.on_stdout)
function Shell.on_exit(job_id, _data, event) let msg = printf(‘job %d (“%s”) finished’, a:job_id, self.name) call append(line(’$’), printf(’[%s] BOOM!’, a:event)) call append(line(’$’), printf(’[%s] %s!’, a:event, msg)) endfunction
function Shell.new(name, cmd) let object = extend(copy(g:Shell), {‘name’: a:name}) let object.cmd = [‘sh’, ‘-c’, a:cmd] let object.id = jobstart(object.cmd, object) $ return object endfunction
let instance = Shell.new(‘bomb’, \ ‘for i in $(seq 9 -1 1); do echo $i 1>&$((i % 2 + 1)); sleep 1; done’)
:call chansend(job1, "ls\n") :call chansend(job1, "invalid-command\n") :call chansend(job1, "exit\n")
:call jobstop(job1)
:call jobstop(job1)