2016-02-07 14:27:38 +01:00
|
|
|
*channel.txt* For Vim version 7.4. Last change: 2016 Feb 06
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
|
|
|
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
|
|
|
|
|
|
|
|
|
|
|
Inter-process communication *channel*
|
|
|
|
|
|
|
|
DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT
|
|
|
|
|
|
|
|
Vim uses channels to communicate with other processes.
|
|
|
|
A channel uses a socket. *socket-interface*
|
|
|
|
|
2016-02-04 20:57:07 +01:00
|
|
|
Vim current supports up to 10 simultaneous channels.
|
2016-01-28 22:37:01 +01:00
|
|
|
The Netbeans interface also uses a channel. |netbeans|
|
|
|
|
|
|
|
|
1. Demo |channel-demo|
|
|
|
|
2. Opening a channel |channel-open|
|
|
|
|
3. Using a JSON channel |channel-use|
|
|
|
|
4. Vim commands |channel-commands|
|
|
|
|
5. Using a raw channel |channel-use|
|
|
|
|
6. Job control |job-control|
|
|
|
|
|
|
|
|
{Vi does not have any of these features}
|
|
|
|
{only available when compiled with the |+channel| feature}
|
|
|
|
|
|
|
|
==============================================================================
|
|
|
|
1. Demo *channel-demo*
|
|
|
|
|
|
|
|
This requires Python. The demo program can be found in
|
|
|
|
$VIMRUNTIME/tools/demoserver.py
|
|
|
|
Run it in one terminal. We will call this T1.
|
|
|
|
|
|
|
|
Run Vim in another terminal. Connect to the demo server with: >
|
2016-02-05 22:36:41 +01:00
|
|
|
let handle = ch_open('localhost:8765')
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
In T1 you should see:
|
|
|
|
=== socket opened === ~
|
|
|
|
|
|
|
|
You can now send a message to the server: >
|
2016-02-04 20:57:07 +01:00
|
|
|
echo ch_sendexpr(handle, 'hello!')
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
The message is received in T1 and a response is sent back to Vim.
|
|
|
|
You can see the raw messages in T1. What Vim sends is:
|
|
|
|
[1,"hello!"] ~
|
|
|
|
And the response is:
|
|
|
|
[1,"got it"] ~
|
|
|
|
The number will increase every time you send a message.
|
|
|
|
|
|
|
|
The server can send a command to Vim. Type this on T1 (literally, including
|
2016-01-31 20:24:32 +01:00
|
|
|
the quotes):
|
|
|
|
["ex","echo 'hi there'"] ~
|
|
|
|
And you should see the message in Vim. You can move the cursor a word forward:
|
|
|
|
["normal","w"] ~
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
To handle asynchronous communication a callback needs to be used: >
|
|
|
|
func MyHandler(handle, msg)
|
|
|
|
echo "from the handler: " . a:msg
|
|
|
|
endfunc
|
2016-02-04 20:57:07 +01:00
|
|
|
call ch_sendexpr(handle, 'hello!', "MyHandler")
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
Instead of giving a callback with every send call, it can also be specified
|
|
|
|
when opening the channel: >
|
2016-02-04 20:57:07 +01:00
|
|
|
call ch_close(handle)
|
2016-02-05 22:36:41 +01:00
|
|
|
let handle = ch_open('localhost:8765', {'callback': "MyHandler"})
|
2016-02-04 20:57:07 +01:00
|
|
|
call ch_sendexpr(handle, 'hello!', 0)
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
==============================================================================
|
|
|
|
2. Opening a channel *channel-open*
|
|
|
|
|
2016-02-04 20:57:07 +01:00
|
|
|
To open a channel: >
|
2016-02-05 22:36:41 +01:00
|
|
|
let handle = ch_open({address} [, {argdict}])
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
{address} has the form "hostname:port". E.g., "localhost:8765".
|
|
|
|
|
2016-02-05 22:36:41 +01:00
|
|
|
{argdict} is a dictionary with optional entries:
|
|
|
|
|
|
|
|
"mode" can be: *channel-mode*
|
|
|
|
"json" - Use JSON, see below; most convenient way. Default.
|
2016-01-28 22:37:01 +01:00
|
|
|
"raw" - Use raw messages
|
|
|
|
|
|
|
|
*channel-callback*
|
2016-02-05 22:36:41 +01:00
|
|
|
"callback" is a function that is called when a message is received that is not
|
2016-01-28 22:37:01 +01:00
|
|
|
handled otherwise. It gets two arguments: the channel handle and the received
|
|
|
|
message. Example: >
|
|
|
|
func Handle(handle, msg)
|
|
|
|
echo 'Received: ' . a:msg
|
|
|
|
endfunc
|
2016-02-04 20:57:07 +01:00
|
|
|
let handle = ch_open("localhost:8765", 'json', "Handle")
|
2016-01-28 22:37:01 +01:00
|
|
|
|
2016-02-05 22:36:41 +01:00
|
|
|
"waittime" is the time to wait for the connection to be made in milliseconds.
|
|
|
|
The default is zero, don't wait, which is useful if the server is supposed to
|
|
|
|
be running already. A negative number waits forever.
|
|
|
|
|
|
|
|
"timeout" is the time to wait for a request when blocking, using
|
2016-02-07 14:27:38 +01:00
|
|
|
ch_sendexpr(). Again in milliseconds. The default is 2000 (2 seconds).
|
2016-02-05 22:36:41 +01:00
|
|
|
|
|
|
|
When "mode" is "json" the "msg" argument is the body of the received message,
|
2016-01-28 22:37:01 +01:00
|
|
|
converted to Vim types.
|
2016-02-05 22:36:41 +01:00
|
|
|
When "mode" is "raw" the "msg" argument is the whole message as a string.
|
2016-01-28 22:37:01 +01:00
|
|
|
|
2016-02-05 22:36:41 +01:00
|
|
|
When "mode" is "json" the "callback" is optional. When omitted it is only
|
2016-01-28 22:37:01 +01:00
|
|
|
possible to receive a message after sending one.
|
|
|
|
|
|
|
|
The handler can be added or changed later: >
|
2016-02-04 20:57:07 +01:00
|
|
|
call ch_setcallback(handle, {callback})
|
2016-02-07 14:27:38 +01:00
|
|
|
When "callback" is empty (zero or an empty string) the handler is removed.
|
2016-02-05 22:36:41 +01:00
|
|
|
NOT IMPLEMENTED YET
|
|
|
|
|
|
|
|
The timeout can be changed later: >
|
|
|
|
call ch_settimeout(handle, {msec})
|
|
|
|
NOT IMPLEMENTED YET
|
2016-02-07 14:27:38 +01:00
|
|
|
*E906*
|
2016-01-28 22:37:01 +01:00
|
|
|
Once done with the channel, disconnect it like this: >
|
2016-02-04 20:57:07 +01:00
|
|
|
call ch_close(handle)
|
2016-01-28 22:37:01 +01:00
|
|
|
|
2016-01-31 20:24:32 +01:00
|
|
|
Currently up to 10 channels can be in use at the same time. *E897*
|
|
|
|
|
|
|
|
When the channel can't be opened you will get an error message.
|
|
|
|
*E898* *E899* *E900* *E901* *E902*
|
|
|
|
|
|
|
|
If there is an error reading or writing a channel it will be closed.
|
|
|
|
*E896* *E630* *E631*
|
|
|
|
|
2016-01-28 22:37:01 +01:00
|
|
|
==============================================================================
|
|
|
|
3. Using a JSON channel *channel-use*
|
|
|
|
|
|
|
|
If {mode} is "json" then a message can be sent synchronously like this: >
|
2016-02-04 20:57:07 +01:00
|
|
|
let response = ch_sendexpr(handle, {expr})
|
2016-01-28 22:37:01 +01:00
|
|
|
This awaits a response from the other side.
|
|
|
|
|
|
|
|
To send a message, without handling a response: >
|
2016-02-04 20:57:07 +01:00
|
|
|
call ch_sendexpr(handle, {expr}, 0)
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
To send a message and letting the response handled by a specific function,
|
|
|
|
asynchronously: >
|
2016-02-04 20:57:07 +01:00
|
|
|
call ch_sendexpr(handle, {expr}, {callback})
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
The {expr} is converted to JSON and wrapped in an array. An example of the
|
|
|
|
message that the receiver will get when {expr} is the string "hello":
|
|
|
|
[12,"hello"] ~
|
|
|
|
|
|
|
|
The format of the JSON sent is:
|
|
|
|
[{number},{expr}]
|
|
|
|
|
|
|
|
In which {number} is different every time. It must be used in the response
|
|
|
|
(if any):
|
|
|
|
|
|
|
|
[{number},{response}]
|
|
|
|
|
|
|
|
This way Vim knows which sent message matches with which received message and
|
|
|
|
can call the right handler. Also when the messages arrive out of order.
|
|
|
|
|
|
|
|
The sender must always send valid JSON to Vim. Vim can check for the end of
|
|
|
|
the message by parsing the JSON. It will only accept the message if the end
|
|
|
|
was received.
|
|
|
|
|
|
|
|
When the process wants to send a message to Vim without first receiving a
|
|
|
|
message, it must use the number zero:
|
|
|
|
[0,{response}]
|
|
|
|
|
|
|
|
Then channel handler will then get {response} converted to Vim types. If the
|
|
|
|
channel does not have a handler the message is dropped.
|
|
|
|
|
2016-02-04 20:57:07 +01:00
|
|
|
On read error or ch_close() the string "DETACH" is sent, if still possible.
|
2016-01-28 22:37:01 +01:00
|
|
|
The channel will then be inactive.
|
|
|
|
|
|
|
|
==============================================================================
|
|
|
|
4. Vim commands *channel-commands*
|
|
|
|
|
2016-01-31 20:24:32 +01:00
|
|
|
PARTLY IMPLEMENTED: only "ex" and "normal" work
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
With a "json" channel the process can send commands to Vim that will be
|
|
|
|
handled by Vim internally, it does not require a handler for the channel.
|
|
|
|
|
2016-01-31 20:24:32 +01:00
|
|
|
Possible commands are: *E903* *E904* *E905*
|
|
|
|
["redraw" {forced}]
|
2016-01-28 22:37:01 +01:00
|
|
|
["ex", {Ex command}]
|
|
|
|
["normal", {Normal mode command}]
|
2016-01-31 20:24:32 +01:00
|
|
|
["eval", {expression}, {number}]
|
2016-01-28 22:37:01 +01:00
|
|
|
["expr", {expression}]
|
|
|
|
|
|
|
|
With all of these: Be careful what these commands do! You can easily
|
|
|
|
interfere with what the user is doing. To avoid trouble use |mode()| to check
|
|
|
|
that the editor is in the expected state. E.g., to send keys that must be
|
2016-01-31 20:24:32 +01:00
|
|
|
inserted as text, not executed as a command:
|
|
|
|
["ex","if mode() == 'i' | call feedkeys('ClassName') | endif"] ~
|
|
|
|
|
|
|
|
Errors in these commands are normally not reported to avoid them messing up
|
|
|
|
the display. If you do want to see them, set the 'verbose' option to 3 or
|
|
|
|
higher.
|
|
|
|
|
|
|
|
|
|
|
|
Command "redraw" ~
|
|
|
|
|
|
|
|
The other commands do not update the screen, so that you can send a sequence
|
|
|
|
of commands without the cursor moving around. You must end with the "redraw"
|
|
|
|
command to show any changed text and show the cursor where it belongs.
|
|
|
|
|
|
|
|
The argument is normally an empty string:
|
|
|
|
["redraw", ""] ~
|
|
|
|
To first clear the screen pass "force":
|
|
|
|
["redraw", "force"] ~
|
|
|
|
|
|
|
|
|
|
|
|
Command "ex" ~
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
The "ex" command is executed as any Ex command. There is no response for
|
2016-01-31 20:24:32 +01:00
|
|
|
completion or error. You could use functions in an |autoload| script:
|
|
|
|
["ex","call myscript#MyFunc(arg)"]
|
2016-01-28 22:37:01 +01:00
|
|
|
|
2016-01-31 20:24:32 +01:00
|
|
|
You can also use "call |feedkeys()|" to insert any key sequence.
|
2016-01-28 22:37:01 +01:00
|
|
|
|
2016-01-31 20:24:32 +01:00
|
|
|
|
|
|
|
Command "normal" ~
|
|
|
|
|
2016-02-04 20:57:07 +01:00
|
|
|
The "normal" command is executed like with ":normal!", commands are not
|
2016-01-31 20:24:32 +01:00
|
|
|
mapped. Example to open the folds under the cursor:
|
|
|
|
["normal" "zO"]
|
|
|
|
|
|
|
|
|
|
|
|
Command "eval" ~
|
|
|
|
|
|
|
|
The "eval" command an be used to get the result of an expression. For
|
|
|
|
example, to get the number of lines in the current buffer:
|
|
|
|
["eval","line('$')"] ~
|
|
|
|
|
|
|
|
it will send back the result of the expression:
|
2016-01-28 22:37:01 +01:00
|
|
|
[{number}, {result}]
|
2016-01-31 20:24:32 +01:00
|
|
|
Here {number} is the same as what was in the request. Use a negative number
|
|
|
|
to avoid confusion with message that Vim sends.
|
|
|
|
|
|
|
|
{result} is the result of the evaluation and is JSON encoded. If the
|
|
|
|
evaluation fails it is the string "ERROR".
|
|
|
|
|
|
|
|
|
|
|
|
Command "expr" ~
|
2016-01-28 22:37:01 +01:00
|
|
|
|
2016-01-31 20:24:32 +01:00
|
|
|
The "expr" command is similar to "eval", but does not send back any response.
|
2016-01-28 22:37:01 +01:00
|
|
|
Example:
|
2016-01-31 20:24:32 +01:00
|
|
|
["expr","setline('$', ['one', 'two', 'three'])"] ~
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
==============================================================================
|
|
|
|
5. Using a raw channel *channel-raw*
|
|
|
|
|
|
|
|
If {mode} is "raw" then a message can be send like this: >
|
2016-02-04 20:57:07 +01:00
|
|
|
let response = ch_sendraw(handle, {string})
|
2016-01-28 22:37:01 +01:00
|
|
|
The {string} is sent as-is. The response will be what can be read from the
|
|
|
|
channel right away. Since Vim doesn't know how to recognize the end of the
|
|
|
|
message you need to take care of it yourself.
|
|
|
|
|
|
|
|
To send a message, without expecting a response: >
|
2016-02-04 20:57:07 +01:00
|
|
|
call ch_sendraw(handle, {string}, 0)
|
2016-01-28 22:37:01 +01:00
|
|
|
The process can send back a response, the channel handler will be called with
|
|
|
|
it.
|
|
|
|
|
|
|
|
To send a message and letting the response handled by a specific function,
|
|
|
|
asynchronously: >
|
2016-02-04 20:57:07 +01:00
|
|
|
call ch_sendraw(handle, {string}, {callback})
|
2016-01-28 22:37:01 +01:00
|
|
|
|
|
|
|
This {string} can also be JSON, use |jsonencode()| to create it and
|
|
|
|
|jsondecode()| to handle a received JSON message.
|
|
|
|
|
|
|
|
==============================================================================
|
|
|
|
6. Job control *job-control*
|
|
|
|
|
|
|
|
NOT IMPLEMENTED YET
|
|
|
|
|
|
|
|
To start another process: >
|
|
|
|
call startjob({command})
|
|
|
|
|
|
|
|
This does not wait for {command} to exit.
|
|
|
|
|
|
|
|
TODO:
|
|
|
|
|
|
|
|
let handle = startjob({command}, 's') # uses stdin/stdout
|
|
|
|
let handle = startjob({command}, '', {address}) # uses socket
|
|
|
|
let handle = startjob({command}, 'd', {address}) # start if connect fails
|
|
|
|
|
|
|
|
|
|
|
|
vim:tw=78:ts=8:ft=help:norl:
|