mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00: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:
		| @@ -5104,8 +5104,8 @@ rpcrequest({channel}, {method}[, {args}...])		 {Nvim} *rpcrequest()* | ||||
| 			: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 | ||||
|   | ||||
| @@ -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,7 +43,7 @@ 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' | ||||
| @@ -59,21 +59,21 @@ event. The best way to understand is with a complete example: | ||||
|  | ||||
|     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 | ||||
| < | ||||
| 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: | ||||
|   | ||||
| @@ -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 | ||||
| @@ -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()|. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Justin M. Keyes
					Justin M. Keyes