Home Explore Blog CI



neovim

2nd chunk of `runtime/doc/channel.txt`
e400d2b8fe5ee226b954501c4b4e576890d8fa89f22542f70000000100000e84
 `data_buffered` option keys to invoke the callback only after all output
    was gathered and the stream was closed.
						*E5210*
    If a buffering mode is used without a callback, the data is saved in the
    stream {name} key of the options dict. It is an error if the key exists.

							      *channel-lines*
    Stream event handlers receive data as it becomes available from the OS,
    thus the first and last items in the {data} list may be partial lines.
    Empty string completes the previous partial line. Examples (not including
    the final `['']` emitted at EOF):
      - `foobar` may arrive as `['fo'], ['obar']`
      - `foo\nbar` may arrive as
	- `['foo','bar']`
	- or `['foo',''], ['bar']`
	- or `['foo'], ['','bar']`
	- or `['fo'], ['o','bar']`

    There are two ways to deal with this:
    - 1. To wait for the entire output, use |channel-buffered| mode.
    - 2. To read line-by-line, use the following code: >vim
	let s:lines = ['']
	func! s:on_event(job_id, data, event) dict
	  let eof = (a:data == [''])
	  " Complete the previous line.
	  let s:lines[-1] .= a:data[0]
	  " Append (last item may be a partial line, until EOF).
	  call extend(s:lines, a:data[1:])
	endf
<

If the callback functions are |Dictionary-function|s, |self| refers to the
options dictionary containing the callbacks. |Partial|s 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:
>vim
    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 an example of setting a buffer to the result of grep, but only after
all data has been processed:
>vim
    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|.

							      *channel-pty*
Special case: PTY channels opened with `jobstart(..., {'pty': v:true})` do not
preprocess ANSI escape sequences, these will be sent raw to the callback.
However, change of PTY size can be signaled to the slave using |jobresize()|.
See also |terminal-emulator|.

Terminal characteristics (termios) for |:terminal| and PTY channels are copied
from the host TTY, or if Nvim is |--headless| it uses default values: >vim
    :echo system('nvim --headless +"te stty -a" +"sleep 1" +"1,/^$/print" +q')

==============================================================================
3. Communicating with msgpack RPC			      *channel-rpc*

When channels are opened with the `rpc` option set to true, the channel can be
used for remote method calls in both directions, see |msgpack-rpc|. Note that
rpc channels are implicitly trusted and the process at the other end can
invoke any |API| function!

==============================================================================
4. Standard IO channel					    *channel-stdio*

Nvim uses stdin/stdout to interact with the user over the terminal interface
(TUI). If Nvim is |--headless| the TUI is not started and stdin/stdout can be
used as a channel. See also |--embed|.

Call |stdioopen()| during |startup| to open the stdio channel as |channel-id| 1.
Nvim's stderr is always available as |v:stderr|, a write-only

Title: Nvim Channels: Handling Raw Bytes, Examples, and RPC
Summary
This section continues the discussion of Nvim channels, focusing on handling raw bytes received from streams, including partial lines and EOF. It provides code examples for processing data line-by-line and setting a buffer with grep results. It also covers special considerations for PTY channels and introduces RPC communication via channels using msgpack, highlighting the implicit trust and API access granted to the remote process. Finally, it briefly mentions the use of stdin/stdout as a channel in headless mode.