blob: 21ce4ebda8203b838eed9a1ace12dad5ee61307c [file] [log] [blame]
Bram Moolenaar3b5f9292016-01-28 22:37:01 +01001*channel.txt* For Vim version 7.4. Last change: 2016 Jan 28
2
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
14Vim current supports up to 10 simultanious channels.
15The Netbeans interface also uses a channel. |netbeans|
16
171. Demo |channel-demo|
182. Opening a channel |channel-open|
193. Using a JSON channel |channel-use|
204. 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: >
35 let handle = connect('localhost:8765', 'json')
36
37In T1 you should see:
38 === socket opened === ~
39
40You can now send a message to the server: >
41 echo sendexpr(handle, 'hello!')
42
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
51the quotes): >
52 NOT IMPLEMENTED YET
53 ["ex","echo 'hi there'"]
54And you should see the message in Vim.
55
56To handle asynchronous communication a callback needs to be used: >
57 func MyHandler(handle, msg)
58 echo "from the handler: " . a:msg
59 endfunc
60 call sendexpr(handle, 'hello!', "MyHandler")
61
62Instead of giving a callback with every send call, it can also be specified
63when opening the channel: >
64 call disconnect(handle)
65 let handle = connect('localhost:8765', 'json', "MyHandler")
66 call sendexpr(handle, 'hello!', 0)
67
68==============================================================================
692. Opening a channel *channel-open*
70
71To open a channel:
72 let handle = connect({address}, {mode}, {callback})
73
74{address} has the form "hostname:port". E.g., "localhost:8765".
75
76{mode} can be: *channel-mode*
77 "json" - Use JSON, see below; most convenient way
78 "raw" - Use raw messages
79
80 *channel-callback*
81{callback} is a function that is called when a message is received that is not
82handled otherwise. It gets two arguments: the channel handle and the received
83message. Example: >
84 func Handle(handle, msg)
85 echo 'Received: ' . a:msg
86 endfunc
87 let handle = connect("localhost:8765", 'json', "Handle")
88
89When {mode} is "json" the "msg" argument is the body of the received message,
90converted to Vim types.
91When {mode} is "raw" the "msg" argument is the whole message as a string.
92
93When {mode} is "json" the {callback} is optional. When omitted it is only
94possible to receive a message after sending one.
95
96The handler can be added or changed later: >
97 call sethandler(handle, {callback})
98When {callback} is empty (zero or an empty string) the handler is removed.
99
100Once done with the channel, disconnect it like this: >
101 call disconnect(handle)
102
103==============================================================================
1043. Using a JSON channel *channel-use*
105
106If {mode} is "json" then a message can be sent synchronously like this: >
107 let response = sendexpr(handle, {expr})
108This awaits a response from the other side.
109
110To send a message, without handling a response: >
111 call sendexpr(handle, {expr}, 0)
112
113To send a message and letting the response handled by a specific function,
114asynchronously: >
115 call sendexpr(handle, {expr}, {callback})
116
117The {expr} is converted to JSON and wrapped in an array. An example of the
118message that the receiver will get when {expr} is the string "hello":
119 [12,"hello"] ~
120
121The format of the JSON sent is:
122 [{number},{expr}]
123
124In which {number} is different every time. It must be used in the response
125(if any):
126
127 [{number},{response}]
128
129This way Vim knows which sent message matches with which received message and
130can call the right handler. Also when the messages arrive out of order.
131
132The sender must always send valid JSON to Vim. Vim can check for the end of
133the message by parsing the JSON. It will only accept the message if the end
134was received.
135
136When the process wants to send a message to Vim without first receiving a
137message, it must use the number zero:
138 [0,{response}]
139
140Then channel handler will then get {response} converted to Vim types. If the
141channel does not have a handler the message is dropped.
142
143On read error or disconnect() the string "DETACH" is sent, if still possible.
144The channel will then be inactive.
145
146==============================================================================
1474. Vim commands *channel-commands*
148
149NOT IMPLEMENTED YET
150
151With a "json" channel the process can send commands to Vim that will be
152handled by Vim internally, it does not require a handler for the channel.
153
154Possible commands are:
155 ["ex", {Ex command}]
156 ["normal", {Normal mode command}]
157 ["eval", {number}, {expression}]
158 ["expr", {expression}]
159
160With all of these: Be careful what these commands do! You can easily
161interfere with what the user is doing. To avoid trouble use |mode()| to check
162that the editor is in the expected state. E.g., to send keys that must be
163inserted as text, not executed as a command: >
164 ["ex","if mode() == 'i' | call feedkeys('ClassName') | endif"]
165
166The "ex" command is executed as any Ex command. There is no response for
167completion or error. You could use functions in an |autoload| script.
168You can also invoke |feedkeys()| to insert anything.
169
170The "normal" command is executed like with |:normal|.
171
172The "eval" command will result in sending back the result of the expression:
173 [{number}, {result}]
174Here {number} is the same as what was in the request.
175
176The "expr" command is similar, but does not send back any response.
177Example:
178 ["expr","setline('$', ['one', 'two', 'three'])"]
179
180==============================================================================
1815. Using a raw channel *channel-raw*
182
183If {mode} is "raw" then a message can be send like this: >
184 let response = sendraw(handle, {string})
185The {string} is sent as-is. The response will be what can be read from the
186channel right away. Since Vim doesn't know how to recognize the end of the
187message you need to take care of it yourself.
188
189To send a message, without expecting a response: >
190 call sendraw(handle, {string}, 0)
191The process can send back a response, the channel handler will be called with
192it.
193
194To send a message and letting the response handled by a specific function,
195asynchronously: >
196 call sendraw(handle, {string}, {callback})
197
198This {string} can also be JSON, use |jsonencode()| to create it and
199|jsondecode()| to handle a received JSON message.
200
201==============================================================================
2026. Job control *job-control*
203
204NOT IMPLEMENTED YET
205
206To start another process: >
207 call startjob({command})
208
209This does not wait for {command} to exit.
210
211TODO:
212
213 let handle = startjob({command}, 's') # uses stdin/stdout
214 let handle = startjob({command}, '', {address}) # uses socket
215 let handle = startjob({command}, 'd', {address}) # start if connect fails
216
217
218 vim:tw=78:ts=8:ft=help:norl: