channel-callback buffered
E5210 on_stdout on_stderr on_stdin on_data
A callback function on_{stream} will be invoked with data read from the
channel. By default, the callback will be invoked immediately when data is
available, to facilitate interactive communication. The same callback will
then be invoked with empty data, to indicate that the stream reached EOF.
Alternatively the {stream}_buffered option can be set to invoke the callback
only when the underlying stream reaches EOF, and will then be passed in
complete output. This is helpful when only the complete output is useful, and
not partial data. Futhermore if {stream}_buffered is set but not a callback,
the data is saved in the options dict, with the stream name as key. For this
to work a new options dict must be used for each opened channel. If a script
uses a global s:job_opts dict, it can be copied with copy() before supplying
it to jobstart(). If a dict is reused, so that the dict key already is
occupied, error E5210 will be raised.
- The arguments passed to the callback function are:
0: The channel id
1: the raw data read from the channel, formatted as a readfile()-style
list. If EOF occured, a single empty string [''] will be passed in.
Note that the items in this list do not directly correspond to actual
lines in the output. See channel-lines
2: Stream name as a string, like "stdout" . This is to allow multiple
on_{event} handlers to be implemented by the same function. The available
events depend on how the channel was opened and in what mode/protocol.
channel-lines
Note:
stream event handlers may receive partial (incomplete) lines. For a given
invocation of on_stdout etc, 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']`.
If you only are interested in complete output when the process exits,
use buffered mode. Otherwise, an easy way to deal with this:
initialize a list as [''] , then append to it as follows:
let s:chunks = ['']
func! s:on_event(job_id, data, event) dict
let s:chunks[-1] .= a:data[0]
call extend(s:chunks, a:data[1:])
endf
Additionally, if the callbacks are Dictionary functions, self can be used to
refer to the options dictionary containing the callbacks. Partials can also be
used as callbacks.
Data can be sent to the channel using the chansend() function. Here is a
simple example, echoing some data through a cat-process:
function! s:OnEvent(id, data, event) dict
let str = join(a:data, "\n")
echomsg str
endfunction
let id = jobstart(['cat'], {'on_stdout': function('s:OnEvent') } )
call chansend(id, "hello!")
Here is a example of setting a buffer to the result of grep, but only after
all data has been processed:
function! s:OnEvent(id, data, event) dict
call nvim_buf_set_lines(2, 0, -1, v:true, a:data)
endfunction
let id = jobstart(['grep', '^[0-9]'], { 'on_stdout': function('s:OnEvent'),
\ 'stdout_buffered':v:true } )
call chansend(id, "stuff\n10 PRINT \"NVIM\"\nxx")
" no output is received, buffer is empty
call chansend(id, "xx\n20 GOTO 10\nzz\n")
call chanclose(id, 'stdin')
" now buffer has result
For additional examples with jobs, see job-control.