Nvim :help
pages, generated
from source
using the tree-sitter-vimdoc parser.
nvim
is started with --headless
, and a startup
script or --cmd command opens the stdio channel using stdioopen().
jobstart(..., {'pty': v:true})
or termopen().
on_stdout
, on_stderr
, on_stdin
, or
on_data
option keys. Callbacks should be fast: avoid potentially
slow/expensive work.
{chan-id}
Channel handle. channel-id
{data}
Raw data (readfile()-style list of strings) read from
the channel. EOF is a single-item list: ['']
. First and
last items may be partial lines! channel-lines
{name}
Stream name (string) like "stdout", so the same function
can handle multiple streams. Event names depend on how the
channel was opened and in what mode/protocol.
['']
indicates EOF (stream closed). Alternatively
set the stdout_buffered
, stderr_buffered
, stdin_buffered
, or
data_buffered
option keys to invoke the callback only after all output
was gathered and the stream was closed.
E5210{name}
key of the options dict. It is an error if the key exists.
{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']
['foo',''], ['bar']
['foo'], ['','bar']
['fo'], ['o','bar']
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
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!")
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
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.
:echo system('nvim --headless +"te stty -a" +"sleep 1" +"1,/^$/print" +q')
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!
func! OnEvent(id, data, event)
if a:data == [""]
quit
end
call chansend(a:id, map(a:data, {i,v -> toupper(v)}))
endfunc
call stdioopen({'on_stdin': 'OnEvent'})
uppercase.vim
and run:nvim --headless --cmd "source uppercase.vim"
:startinsert
if you want to enter Insert mode, so that the user
can start typing a line.
CTRL-W
key can be used to start a window command, such as CTRL-W
w to
switch to the next window. This also works in Insert mode (use Shift-CTRL-W
to delete a word). When leaving the window Insert mode will be stopped. When
coming back to the prompt window Insert mode will be restored.
" Function handling a line of text that has been typed.
func TextEntered(text)
" Send the text to a shell with Enter appended.
call chansend(g:shell_job, [a:text, ''])
endfunc
" Function handling output from the shell: Add it above the prompt.
func GotOutput(channel, msg, name)
call append(line("$") - 1, a:msg)
endfunc
" Function handling the shell exits: close the window.
func JobExit(job, status, event)
quit!
endfunc
" Start a shell in the background.
let shell_job = jobstart(["/bin/sh"], #{
\ on_stdout: function('GotOutput'),
\ on_stderr: function('GotOutput'),
\ on_exit: function('JobExit'),
\ })
new
set buftype=prompt
let buf = bufnr('')
call prompt_setcallback(buf, function("TextEntered"))
call prompt_setprompt(buf, "shell command: ")
" start accepting shell commands
startinsert