mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #1710 from Pyrohh/improve-docs-job-control
Misc. improvements to job control & msgpack rpc docs [ci skip]
This commit is contained in:
commit
c53852a244
@ -5100,12 +5100,12 @@ rpcnotify({channel}, {event}[, {args}...]) {Nvim} *rpcnotify()*
|
||||
rpcrequest({channel}, {method}[, {args}...]) {Nvim} *rpcrequest()*
|
||||
Sends a request to {channel} to invoke {method} via
|
||||
|msgpack-rpc| and blocks until a response is received.
|
||||
Example: >
|
||||
Example: >
|
||||
:let result = rpcrequest(rpc_chan, "func", 1, 2, 3)
|
||||
|
||||
rpcstart({prog}[, {argv}]) {Nvim} *rpcstart()*
|
||||
Spawns {prog} as a job(optionally passing the {argv} list),
|
||||
and opens a |msgpack-rpc| channel with the spawned process
|
||||
Spawns {prog} as a job (optionally passing the list {argv}),
|
||||
and opens a |msgpack-rpc| channel with the spawned process's
|
||||
stdin/stdout. It returns:
|
||||
- The channel id on success, which is used by |rpcrequest()|,
|
||||
|rpcnotify()| and |rpcstop()|
|
||||
@ -5114,10 +5114,9 @@ rpcstart({prog}[, {argv}]) {Nvim} *rpcstart()*
|
||||
:let rpc_chan = rpcstart('prog', ['arg1', 'arg2'])
|
||||
|
||||
rpcstop({channel}) {Nvim} *rpcstop()*
|
||||
Closes a |msgpack-rpc| channel, possibly created via
|
||||
|rpcstart()| (Though it will also close channels created by
|
||||
connections to |$NVIM_LISTEN_ADDRESS|). It accepts the rpc
|
||||
channel id as only argument.
|
||||
Closes a |msgpack-rpc| {channel}, possibly created via
|
||||
|rpcstart()|. Also closes channels created by connections to
|
||||
|$NVIM_LISTEN_ADDRESS|.
|
||||
|
||||
screenattr(row, col) *screenattr()*
|
||||
Like screenchar(), but return the attribute. This is a rather
|
||||
|
@ -13,7 +13,7 @@ Nvim's facilities for job control *job-control*
|
||||
1. Introduction *job-control-intro*
|
||||
|
||||
Job control is a simple way to perform multitasking in vimscript. Wikipedia
|
||||
contains a more generic/detailed description:
|
||||
contains a more generic/detailed description:
|
||||
|
||||
"Job control in computing refers to the control of multiple tasks or Jobs on a
|
||||
computer system, ensuring that they each have access to adequate resources to
|
||||
@ -27,8 +27,8 @@ control multiple processes without blocking the current Nvim instance.
|
||||
|
||||
Nvim's job control was designed to be simple and familiar to vimscript
|
||||
programmers, instead of being very powerful but complex. Unlike Vim's
|
||||
facilities for calling with external commands, job control does not depend
|
||||
on installed shells, calling OS functions for process management directly.
|
||||
facilities for calling with external commands, job control does not depend on
|
||||
available shells, instead relying on OS functionality for process management.
|
||||
|
||||
Internally, Nvim job control is powered by libuv, which has a nice
|
||||
cross-platform API for managing processes. See https://github.com/libuv/libuv
|
||||
@ -43,8 +43,8 @@ event. The best way to understand is with a complete example:
|
||||
>
|
||||
set nocp
|
||||
let job1 = jobstart('shell1', 'bash')
|
||||
let job2 = jobstart('shell2', 'bash', ['-c', 'for ((i = 0; i < 10; i++)); do echo -n hello $i!; sleep 2; done'])
|
||||
|
||||
let job2 = jobstart('shell2', 'bash', ['-c', 'for ((i = 0; i < 10; i++)); do echo hello $i!; sleep 1; done'])
|
||||
|
||||
function JobHandler()
|
||||
if v:job_data[1] == 'stdout'
|
||||
let str = 'shell '. v:job_data[0].' stdout: '.join(v:job_data[2])
|
||||
@ -53,27 +53,27 @@ event. The best way to understand is with a complete example:
|
||||
else
|
||||
let str = 'shell '.v:job_data[0].' exited'
|
||||
endif
|
||||
|
||||
|
||||
call append(line('$'), str)
|
||||
endfunction
|
||||
|
||||
|
||||
au JobActivity shell* call JobHandler()
|
||||
<
|
||||
To test the above, copy it to the ~/jobcontrol.vim file and start with a clean
|
||||
To test the above, copy it to the file ~/jobcontrol.vim and start with a clean
|
||||
nvim instance:
|
||||
>
|
||||
nvim -u NONE -S ~/jobcontrol.vim
|
||||
>
|
||||
nvim -u NONE -S ~/jobcontrol.vim
|
||||
<
|
||||
Here's what is happening:
|
||||
|
||||
- Two bash instances are spawned by |jobstart()| and their stdin/stdout/stderr
|
||||
are connected to nvim.
|
||||
- The first shell is idle, waiting to read commands from it's stdin
|
||||
- The second shell is passed the -c option to execute a command and exit. In
|
||||
our case, the command is a for loop that will print numbers and exit after
|
||||
a while.
|
||||
- The JobHandler function is called by the JobActivity autocommand(notice how
|
||||
the shell* pattern matches the `shell1` and `shell2` names passed to
|
||||
- Two bash instances are spawned by |jobstart()| with their stdin/stdout/stderr
|
||||
connected to nvim.
|
||||
- The first shell is idle, waiting to read commands from its stdin.
|
||||
- The second shell is started with the -c argument, causing it to execute a
|
||||
command then exit. In this case, the command is a for loop that will print 0
|
||||
through 9 then exit.
|
||||
- The |JobHandler()| function is called by the `JobActivity` autocommand (notice
|
||||
how the shell* pattern matches the names `shell1` and `shell2` passed to
|
||||
|jobstart()|), and it takes care of displaying stdout/stderr received from
|
||||
the shells.
|
||||
- The v:job_data is an array set by the JobActivity event. It has the
|
||||
@ -86,16 +86,16 @@ Here's what is happening:
|
||||
To send data to the job's stdin, one can use the |jobsend()| function, like
|
||||
this:
|
||||
>
|
||||
:call jobsend(job1, 'ls\n')
|
||||
:call jobsend(job1, 'invalid-command\n')
|
||||
:call jobsend(job1, 'exit\n')
|
||||
:call jobsend(job1, "ls\n")
|
||||
:call jobsend(job1, "invalid-command\n")
|
||||
:call jobsend(job1, "exit\n")
|
||||
<
|
||||
A job may be killed at any time with the |jobstop()| function:
|
||||
>
|
||||
:call jobstop(job1)
|
||||
<
|
||||
When |jobstop()| is called, it will send `SIGTERM` to the job. If a job
|
||||
doesn't exit after a while, `SIGKILL` will be sent.
|
||||
|
||||
When |jobstop()| is called, `SIGTERM` will be sent to the job. If a job does
|
||||
not exit after 2 seconds, `SIGKILL` will be sent.
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@ -4,10 +4,10 @@
|
||||
NVIM REFERENCE MANUAL by Thiago de Arruda
|
||||
|
||||
|
||||
The Msgpack-RPC Interface to Nvim *msgpack-rpc*
|
||||
The Msgpack-RPC Interface to Nvim *msgpack-rpc*
|
||||
|
||||
1. Introduction |msgpack-rpc-intro|
|
||||
2. API |msgpack-rpc-api|
|
||||
2. API |msgpack-rpc-api|
|
||||
3. Connecting |msgpack-rpc-connecting|
|
||||
4. Clients |msgpack-rpc-clients|
|
||||
5. Types |msgpack-rpc-types|
|
||||
@ -40,9 +40,9 @@ Nvim's msgpack-rpc interface can be seen as a more powerful version of Vim's
|
||||
|
||||
The Nvim C API is automatically exposed to the msgpack-rpc interface by the
|
||||
build system, which parses headers at src/nvim/api from the project root. A
|
||||
dispatch function is generated, which matches msgpack-rpc method names
|
||||
with non-static API functions, converting/validating arguments and return
|
||||
values back to msgpack.
|
||||
dispatch function is generated, which matches msgpack-rpc method names with
|
||||
non-static API functions, converting/validating arguments and return values
|
||||
back to msgpack.
|
||||
|
||||
Client libraries will normally provide wrappers that hide msgpack-rpc details
|
||||
from programmers, which can be automatically generated by reading bundled API
|
||||
@ -60,7 +60,7 @@ There are two ways to obtain API metadata:
|
||||
separate compilation step.
|
||||
|
||||
Here's a simple way to get human-readable description of the API (requires
|
||||
python and the pyyaml/msgpack-python pip packages):
|
||||
python and the `pyyaml`/`msgpack-python` pip packages):
|
||||
>
|
||||
nvim --api-info | python -c 'import msgpack, sys, yaml; print yaml.dump(msgpack.unpackb(sys.stdin.read()))' > api.yaml
|
||||
|
||||
@ -69,21 +69,19 @@ python and the pyyaml/msgpack-python pip packages):
|
||||
|
||||
There are four ways to open msgpack-rpc streams to nvim:
|
||||
|
||||
1. Through nvim's stdin/stdout when started with the `--embed` option. This is
|
||||
1. Through Nvim's stdin/stdout when started with the `--embed` option. This is
|
||||
how other programs can embed nvim.
|
||||
|
||||
2. Through stdin/stdout of a program spawned by the |rpcstart()| function.
|
||||
2. Through the stdin/stdout of a program spawned by the |rpcstart()| function.
|
||||
|
||||
3. Through the socket automatically created with each instance. To find out
|
||||
the socket location (which is random by default) from a running nvim
|
||||
instance, one can inspect the *$NVIM_LISTEN_ADDRESS* environment variable
|
||||
like this:
|
||||
instance, one can inspect the |$NVIM_LISTEN_ADDRESS| environment variable:
|
||||
>
|
||||
:echo $NVIM_LISTEN_ADDRESS
|
||||
<
|
||||
4. Through a TCP/IP socket. To make nvim listen on a TCP/IP socket, you need
|
||||
to set the $NVIM_LISTEN_ADDRESS environment variable before starting, like
|
||||
this:
|
||||
4. Through a TCP/IP socket. To make nvim listen on a TCP/IP socket, set the
|
||||
|$NVIM_LISTEN_ADDRESS| environment variable in a shell before starting:
|
||||
>
|
||||
NVIM_LISTEN_ADDRESS=127.0.0.1:6666 nvim
|
||||
<
|
||||
@ -120,34 +118,34 @@ functions can be called interactively:
|
||||
==============================================================================
|
||||
4. Implementing new clients *msgpack-rpc-clients*
|
||||
|
||||
Nvim is still alpha and there's no in-depth documentation explaining how to
|
||||
properly implement a client library. The python client (neovim pip package)
|
||||
will be always up-to-date with the latest API changes, so its source code is
|
||||
the best documentation currently available. There are some guidelines however:
|
||||
Nvim is still in alpha, so there's no in-depth documentation explaining how to
|
||||
properly implement a client library yet. The python client (the pip package
|
||||
"neovim") will always be up-to-date with the latest API changes, so its source
|
||||
code is the best documentation currently available. There are some guidelines
|
||||
however:
|
||||
|
||||
- Separate the transport layer from the rest of the library (see
|
||||
|msgpack-rpc-connecting| for details of how a client can connect to nvim).
|
||||
- Use a msgpack library that implements the spec version 5, Nvim uses the
|
||||
BIN/EXT types.
|
||||
- Separate the transport layer from the rest of the library. See
|
||||
|msgpack-rpc-connecting| for details on how clients can connect to nvim.
|
||||
- Use a MessagePack library that implements at least version 5 of the
|
||||
MessagePack spec, which supports the `bin` and `ext` types used by nvim.
|
||||
- Read API metadata in order to create client-side wrappers for all
|
||||
msgpack-rpc methods.
|
||||
- Use a single-threaded event loop library/pattern.
|
||||
- Use a fiber/coroutine library for the language you are implementing a client
|
||||
for. These greatly simplify concurrency and allow the library to expose a
|
||||
blocking API on top of a non-blocking event loop without the complexity
|
||||
that comes with preemptive multitasking.
|
||||
- Use a fiber/coroutine library for the language being used for implementing a
|
||||
client. These greatly simplify concurrency and allow the library to expose a
|
||||
blocking API on top of a non-blocking event loop without the complexity that
|
||||
comes with preemptive multitasking.
|
||||
- Don't assume anything about the order that responses to msgpack-rpc requests
|
||||
will arrive.
|
||||
- Clients should expect to receive msgpack-rpc requests, which need to be
|
||||
handled immediately because Nvim is blocked while waiting for the client
|
||||
response.
|
||||
- Clients should expect to receive msgpack-rpc notifications, but these don't
|
||||
need to be handled immediately because they won't block Nvim (though you
|
||||
probably want to handle them immediately anyway).
|
||||
|
||||
need to be handled immediately because they won't block Nvim (although they
|
||||
should probably be handled immediately anyway).
|
||||
|
||||
Most of the complexity could be handled by a msgpack-rpc library that supports
|
||||
server->client requests and notifications, but it's not clear if this is part
|
||||
server to client requests and notifications, but it's not clear if this is part
|
||||
of the msgpack-rpc spec. At least the ruby msgpack-rpc library does not seem
|
||||
to support it:
|
||||
https://github.com/msgpack-rpc/msgpack-rpc-ruby/blob/master/lib/msgpack/rpc/transport/tcp.rb#L150-L158
|
||||
@ -217,7 +215,7 @@ that makes this task easier:
|
||||
- Methods that operate instances of Nvim's types are prefixed with the type
|
||||
name in lower case, e.g. `buffer_get_line` represents the `get_line` method
|
||||
of a Buffer instance.
|
||||
- Global methods are prefixed with `vim`, e.g.`vim_list_buffers`.
|
||||
- Global methods are prefixed with `vim`, e.g. `vim_list_buffers`.
|
||||
|
||||
So, for an object-oriented language, a client library would have the classes
|
||||
that represent Nvim's types, and the methods of each class could be defined
|
||||
@ -227,13 +225,13 @@ class with methods mapped to functions prefixed with `vim_`
|
||||
==============================================================================
|
||||
7. Vimscript functions *msgpack-rpc-vim-functions*
|
||||
|
||||
Four functions related to msgpack-rpc are available to vimscript:
|
||||
Four functions related to msgpack-rpc are available in vimscript:
|
||||
|
||||
1. |rpcstart()|: Similarly to |jobstart()|, this will spawn a co-process with
|
||||
its standard handles connected to Nvim. The difference is that it's not
|
||||
possible to process raw data to/from the process stdin/stdout/stderr (since
|
||||
the job's stdin/stdout combo are used as a msgpack channel that is
|
||||
processed directly by Nvim C code).
|
||||
possible to process raw data to/from the process's stdin/stdout/stderr.
|
||||
This is because the job's stdin and stdout are used as a single msgpack
|
||||
channel that is processed directly by Nvim.
|
||||
|
||||
2. |rpcstop()|: Same as |jobstop()|, but operates on handles returned by
|
||||
|rpcstart()|.
|
||||
|
Loading…
Reference in New Issue
Block a user