blob: bc9e6414497bbe6ffbbabc079f7f31faeac23245 [file] [log] [blame]
Bram Moolenaar595e64e2016-02-07 19:19:53 +01001*channel.txt* For Vim version 7.4. Last change: 2016 Feb 07
Bram Moolenaar3b5f9292016-01-28 22:37:01 +01002
3
4 VIM REFERENCE MANUAL by Bram Moolenaar
5
6
7 Inter-process communication *channel*
8
9DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT
10
11Vim uses channels to communicate with other processes.
12A channel uses a socket. *socket-interface*
13
Bram Moolenaar681baaf2016-02-04 20:57:07 +010014Vim current supports up to 10 simultaneous channels.
Bram Moolenaar3b5f9292016-01-28 22:37:01 +010015The Netbeans interface also uses a channel. |netbeans|
16
171. Demo |channel-demo|
182. Opening a channel |channel-open|
Bram Moolenaar595e64e2016-02-07 19:19:53 +0100193. Using a JSON or JS channel |channel-use|
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100204. Vim commands |channel-commands|
215. Using a raw channel |channel-use|
226. Job control |job-control|
23
24{Vi does not have any of these features}
25{only available when compiled with the |+channel| feature}
26
27==============================================================================
281. Demo *channel-demo*
29
30This requires Python. The demo program can be found in
31$VIMRUNTIME/tools/demoserver.py
32Run it in one terminal. We will call this T1.
33
34Run Vim in another terminal. Connect to the demo server with: >
Bram Moolenaar4d919d72016-02-05 22:36:41 +010035 let handle = ch_open('localhost:8765')
Bram Moolenaar3b5f9292016-01-28 22:37:01 +010036
37In T1 you should see:
38 === socket opened === ~
39
40You can now send a message to the server: >
Bram Moolenaar681baaf2016-02-04 20:57:07 +010041 echo ch_sendexpr(handle, 'hello!')
Bram Moolenaar3b5f9292016-01-28 22:37:01 +010042
43The message is received in T1 and a response is sent back to Vim.
44You can see the raw messages in T1. What Vim sends is:
45 [1,"hello!"] ~
46And the response is:
47 [1,"got it"] ~
48The number will increase every time you send a message.
49
50The server can send a command to Vim. Type this on T1 (literally, including
Bram Moolenaarfb1f6262016-01-31 20:24:32 +010051the quotes):
52 ["ex","echo 'hi there'"] ~
53And you should see the message in Vim. You can move the cursor a word forward:
54 ["normal","w"] ~
Bram Moolenaar3b5f9292016-01-28 22:37:01 +010055
56To handle asynchronous communication a callback needs to be used: >
57 func MyHandler(handle, msg)
58 echo "from the handler: " . a:msg
59 endfunc
Bram Moolenaar681baaf2016-02-04 20:57:07 +010060 call ch_sendexpr(handle, 'hello!', "MyHandler")
Bram Moolenaar3b5f9292016-01-28 22:37:01 +010061
62Instead of giving a callback with every send call, it can also be specified
63when opening the channel: >
Bram Moolenaar681baaf2016-02-04 20:57:07 +010064 call ch_close(handle)
Bram Moolenaar4d919d72016-02-05 22:36:41 +010065 let handle = ch_open('localhost:8765', {'callback': "MyHandler"})
Bram Moolenaar681baaf2016-02-04 20:57:07 +010066 call ch_sendexpr(handle, 'hello!', 0)
Bram Moolenaar3b5f9292016-01-28 22:37:01 +010067
68==============================================================================
692. Opening a channel *channel-open*
70
Bram Moolenaar681baaf2016-02-04 20:57:07 +010071To open a channel: >
Bram Moolenaar4d919d72016-02-05 22:36:41 +010072 let handle = ch_open({address} [, {argdict}])
Bram Moolenaar3b5f9292016-01-28 22:37:01 +010073
74{address} has the form "hostname:port". E.g., "localhost:8765".
75
Bram Moolenaar4d919d72016-02-05 22:36:41 +010076{argdict} is a dictionary with optional entries:
77
78"mode" can be: *channel-mode*
79 "json" - Use JSON, see below; most convenient way. Default.
Bram Moolenaar595e64e2016-02-07 19:19:53 +010080 "js" - Use JavaScript encoding, more efficient than JSON.
Bram Moolenaar3b5f9292016-01-28 22:37:01 +010081 "raw" - Use raw messages
82
83 *channel-callback*
Bram Moolenaar4d919d72016-02-05 22:36:41 +010084"callback" is a function that is called when a message is received that is not
Bram Moolenaar3b5f9292016-01-28 22:37:01 +010085handled otherwise. It gets two arguments: the channel handle and the received
86message. Example: >
87 func Handle(handle, msg)
88 echo 'Received: ' . a:msg
89 endfunc
Bram Moolenaar595e64e2016-02-07 19:19:53 +010090 let handle = ch_open("localhost:8765", {"callback": "Handle"})
Bram Moolenaar3b5f9292016-01-28 22:37:01 +010091
Bram Moolenaar4d919d72016-02-05 22:36:41 +010092"waittime" is the time to wait for the connection to be made in milliseconds.
93The default is zero, don't wait, which is useful if the server is supposed to
94be running already. A negative number waits forever.
Bram Moolenaar3b5f9292016-01-28 22:37:01 +010095
Bram Moolenaar4d919d72016-02-05 22:36:41 +010096"timeout" is the time to wait for a request when blocking, using
Bram Moolenaar835dc632016-02-07 14:27:38 +010097ch_sendexpr(). Again in milliseconds. The default is 2000 (2 seconds).
Bram Moolenaar4d919d72016-02-05 22:36:41 +010098
Bram Moolenaar595e64e2016-02-07 19:19:53 +010099When "mode" is "json" or "js" the "msg" argument is the body of the received
100message, converted to Vim types.
Bram Moolenaar4d919d72016-02-05 22:36:41 +0100101When "mode" is "raw" the "msg" argument is the whole message as a string.
102
Bram Moolenaar595e64e2016-02-07 19:19:53 +0100103When "mode" is "json" or "js" the "callback" is optional. When omitted it is
104only possible to receive a message after sending one.
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100105
106The handler can be added or changed later: >
Bram Moolenaar681baaf2016-02-04 20:57:07 +0100107 call ch_setcallback(handle, {callback})
Bram Moolenaar835dc632016-02-07 14:27:38 +0100108When "callback" is empty (zero or an empty string) the handler is removed.
Bram Moolenaar4d919d72016-02-05 22:36:41 +0100109NOT IMPLEMENTED YET
110
111The timeout can be changed later: >
112 call ch_settimeout(handle, {msec})
113NOT IMPLEMENTED YET
Bram Moolenaar835dc632016-02-07 14:27:38 +0100114 *E906*
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100115Once done with the channel, disconnect it like this: >
Bram Moolenaar681baaf2016-02-04 20:57:07 +0100116 call ch_close(handle)
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100117
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100118Currently up to 10 channels can be in use at the same time. *E897*
119
120When the channel can't be opened you will get an error message.
121*E898* *E899* *E900* *E901* *E902*
122
123If there is an error reading or writing a channel it will be closed.
124*E896* *E630* *E631*
125
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100126==============================================================================
Bram Moolenaar595e64e2016-02-07 19:19:53 +01001273. Using a JSON or JS channel *channel-use*
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100128
129If {mode} is "json" then a message can be sent synchronously like this: >
Bram Moolenaar681baaf2016-02-04 20:57:07 +0100130 let response = ch_sendexpr(handle, {expr})
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100131This awaits a response from the other side.
132
Bram Moolenaar595e64e2016-02-07 19:19:53 +0100133When {mode} is "js" this works the same, except that the messages use
134JavaScript encoding. See |jsencode()| for the difference.
135
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100136To send a message, without handling a response: >
Bram Moolenaar681baaf2016-02-04 20:57:07 +0100137 call ch_sendexpr(handle, {expr}, 0)
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100138
139To send a message and letting the response handled by a specific function,
140asynchronously: >
Bram Moolenaar681baaf2016-02-04 20:57:07 +0100141 call ch_sendexpr(handle, {expr}, {callback})
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100142
143The {expr} is converted to JSON and wrapped in an array. An example of the
144message that the receiver will get when {expr} is the string "hello":
145 [12,"hello"] ~
146
147The format of the JSON sent is:
148 [{number},{expr}]
149
150In which {number} is different every time. It must be used in the response
151(if any):
152
153 [{number},{response}]
154
155This way Vim knows which sent message matches with which received message and
156can call the right handler. Also when the messages arrive out of order.
157
158The sender must always send valid JSON to Vim. Vim can check for the end of
159the message by parsing the JSON. It will only accept the message if the end
160was received.
161
162When the process wants to send a message to Vim without first receiving a
163message, it must use the number zero:
164 [0,{response}]
165
166Then channel handler will then get {response} converted to Vim types. If the
167channel does not have a handler the message is dropped.
168
Bram Moolenaar681baaf2016-02-04 20:57:07 +0100169On read error or ch_close() the string "DETACH" is sent, if still possible.
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100170The channel will then be inactive.
171
172==============================================================================
1734. Vim commands *channel-commands*
174
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100175PARTLY IMPLEMENTED: only "ex" and "normal" work
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100176
177With a "json" channel the process can send commands to Vim that will be
178handled by Vim internally, it does not require a handler for the channel.
179
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100180Possible commands are: *E903* *E904* *E905*
181 ["redraw" {forced}]
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100182 ["ex", {Ex command}]
183 ["normal", {Normal mode command}]
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100184 ["eval", {expression}, {number}]
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100185 ["expr", {expression}]
186
187With all of these: Be careful what these commands do! You can easily
188interfere with what the user is doing. To avoid trouble use |mode()| to check
189that the editor is in the expected state. E.g., to send keys that must be
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100190inserted as text, not executed as a command:
191 ["ex","if mode() == 'i' | call feedkeys('ClassName') | endif"] ~
192
193Errors in these commands are normally not reported to avoid them messing up
194the display. If you do want to see them, set the 'verbose' option to 3 or
195higher.
196
197
198Command "redraw" ~
199
200The other commands do not update the screen, so that you can send a sequence
201of commands without the cursor moving around. You must end with the "redraw"
202command to show any changed text and show the cursor where it belongs.
203
204The argument is normally an empty string:
205 ["redraw", ""] ~
206To first clear the screen pass "force":
207 ["redraw", "force"] ~
208
209
210Command "ex" ~
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100211
212The "ex" command is executed as any Ex command. There is no response for
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100213completion or error. You could use functions in an |autoload| script:
214 ["ex","call myscript#MyFunc(arg)"]
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100215
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100216You can also use "call |feedkeys()|" to insert any key sequence.
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100217
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100218
219Command "normal" ~
220
Bram Moolenaar681baaf2016-02-04 20:57:07 +0100221The "normal" command is executed like with ":normal!", commands are not
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100222mapped. Example to open the folds under the cursor:
223 ["normal" "zO"]
224
225
226Command "eval" ~
227
228The "eval" command an be used to get the result of an expression. For
229example, to get the number of lines in the current buffer:
230 ["eval","line('$')"] ~
231
232it will send back the result of the expression:
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100233 [{number}, {result}]
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100234Here {number} is the same as what was in the request. Use a negative number
235to avoid confusion with message that Vim sends.
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100236
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100237{result} is the result of the evaluation and is JSON encoded. If the
Bram Moolenaar595e64e2016-02-07 19:19:53 +0100238evaluation fails or the result can't be encoded in JSON it is the string
239"ERROR".
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100240
241
242Command "expr" ~
243
244The "expr" command is similar to "eval", but does not send back any response.
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100245Example:
Bram Moolenaarfb1f6262016-01-31 20:24:32 +0100246 ["expr","setline('$', ['one', 'two', 'three'])"] ~
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100247
248==============================================================================
2495. Using a raw channel *channel-raw*
250
251If {mode} is "raw" then a message can be send like this: >
Bram Moolenaar681baaf2016-02-04 20:57:07 +0100252 let response = ch_sendraw(handle, {string})
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100253The {string} is sent as-is. The response will be what can be read from the
254channel right away. Since Vim doesn't know how to recognize the end of the
255message you need to take care of it yourself.
256
257To send a message, without expecting a response: >
Bram Moolenaar681baaf2016-02-04 20:57:07 +0100258 call ch_sendraw(handle, {string}, 0)
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100259The process can send back a response, the channel handler will be called with
260it.
261
262To send a message and letting the response handled by a specific function,
263asynchronously: >
Bram Moolenaar681baaf2016-02-04 20:57:07 +0100264 call ch_sendraw(handle, {string}, {callback})
Bram Moolenaar3b5f9292016-01-28 22:37:01 +0100265
266This {string} can also be JSON, use |jsonencode()| to create it and
267|jsondecode()| to handle a received JSON message.
268
269==============================================================================
2706. Job control *job-control*
271
272NOT IMPLEMENTED YET
273
274To start another process: >
275 call startjob({command})
276
277This does not wait for {command} to exit.
278
279TODO:
280
281 let handle = startjob({command}, 's') # uses stdin/stdout
282 let handle = startjob({command}, '', {address}) # uses socket
283 let handle = startjob({command}, 'd', {address}) # start if connect fails
284
285
286 vim:tw=78:ts=8:ft=help:norl: