Nvim 的 :help
页面,由 源代码 使用 tree-sitter-vimdoc 解析器生成。
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'
endif
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))
要测试上述脚本,请将其复制到 ~/foo.vim 文件中并运行它nvim -u ~/foo.vim
OnEvent()
回调传递给 jobstart() 以处理各种作业事件。它显示从 shell 收到的标准输出/错误数据。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
不保证以换行符结尾。abcdefg
可能会以 ['abc']
、['defg']
的形式到达。abc\nefg
可能会以 ['abc', '']
、['efg']
或 ['abc']
、['','efg']
,甚至 ['ab']
、['c','efg']
的形式到达。处理此问题的一种简单方法是将列表初始化为 ['']
,然后按如下方式追加到列表中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)