comparison runtime/doc/channel.txt @ 7788:192ae655ac91 v7.4.1191

commit https://github.com/vim/vim/commit/3b5f929b18492fec291d1ec95a91f54e5912c03b Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jan 28 22:37:01 2016 +0100 patch 7.4.1191 Problem: The channel feature isn't working yet. Solution: Add the connect(), disconnect(), sendexpr() and sendraw() functions. Add initial documentation. Add a demo server.
author Christian Brabandt <cb@256bit.org>
date Thu, 28 Jan 2016 22:45:04 +0100
parents
children 6b0891de44a9
comparison
equal deleted inserted replaced
7787:a0ae64e7006f 7788:192ae655ac91
1 *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
9 DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT
10
11 Vim uses channels to communicate with other processes.
12 A channel uses a socket. *socket-interface*
13
14 Vim current supports up to 10 simultanious channels.
15 The Netbeans interface also uses a channel. |netbeans|
16
17 1. Demo |channel-demo|
18 2. Opening a channel |channel-open|
19 3. Using a JSON channel |channel-use|
20 4. Vim commands |channel-commands|
21 5. Using a raw channel |channel-use|
22 6. 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 ==============================================================================
28 1. Demo *channel-demo*
29
30 This requires Python. The demo program can be found in
31 $VIMRUNTIME/tools/demoserver.py
32 Run it in one terminal. We will call this T1.
33
34 Run Vim in another terminal. Connect to the demo server with: >
35 let handle = connect('localhost:8765', 'json')
36
37 In T1 you should see:
38 === socket opened === ~
39
40 You can now send a message to the server: >
41 echo sendexpr(handle, 'hello!')
42
43 The message is received in T1 and a response is sent back to Vim.
44 You can see the raw messages in T1. What Vim sends is:
45 [1,"hello!"] ~
46 And the response is:
47 [1,"got it"] ~
48 The number will increase every time you send a message.
49
50 The server can send a command to Vim. Type this on T1 (literally, including
51 the quotes): >
52 NOT IMPLEMENTED YET
53 ["ex","echo 'hi there'"]
54 And you should see the message in Vim.
55
56 To 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
62 Instead of giving a callback with every send call, it can also be specified
63 when opening the channel: >
64 call disconnect(handle)
65 let handle = connect('localhost:8765', 'json', "MyHandler")
66 call sendexpr(handle, 'hello!', 0)
67
68 ==============================================================================
69 2. Opening a channel *channel-open*
70
71 To 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
82 handled otherwise. It gets two arguments: the channel handle and the received
83 message. Example: >
84 func Handle(handle, msg)
85 echo 'Received: ' . a:msg
86 endfunc
87 let handle = connect("localhost:8765", 'json', "Handle")
88
89 When {mode} is "json" the "msg" argument is the body of the received message,
90 converted to Vim types.
91 When {mode} is "raw" the "msg" argument is the whole message as a string.
92
93 When {mode} is "json" the {callback} is optional. When omitted it is only
94 possible to receive a message after sending one.
95
96 The handler can be added or changed later: >
97 call sethandler(handle, {callback})
98 When {callback} is empty (zero or an empty string) the handler is removed.
99
100 Once done with the channel, disconnect it like this: >
101 call disconnect(handle)
102
103 ==============================================================================
104 3. Using a JSON channel *channel-use*
105
106 If {mode} is "json" then a message can be sent synchronously like this: >
107 let response = sendexpr(handle, {expr})
108 This awaits a response from the other side.
109
110 To send a message, without handling a response: >
111 call sendexpr(handle, {expr}, 0)
112
113 To send a message and letting the response handled by a specific function,
114 asynchronously: >
115 call sendexpr(handle, {expr}, {callback})
116
117 The {expr} is converted to JSON and wrapped in an array. An example of the
118 message that the receiver will get when {expr} is the string "hello":
119 [12,"hello"] ~
120
121 The format of the JSON sent is:
122 [{number},{expr}]
123
124 In which {number} is different every time. It must be used in the response
125 (if any):
126
127 [{number},{response}]
128
129 This way Vim knows which sent message matches with which received message and
130 can call the right handler. Also when the messages arrive out of order.
131
132 The sender must always send valid JSON to Vim. Vim can check for the end of
133 the message by parsing the JSON. It will only accept the message if the end
134 was received.
135
136 When the process wants to send a message to Vim without first receiving a
137 message, it must use the number zero:
138 [0,{response}]
139
140 Then channel handler will then get {response} converted to Vim types. If the
141 channel does not have a handler the message is dropped.
142
143 On read error or disconnect() the string "DETACH" is sent, if still possible.
144 The channel will then be inactive.
145
146 ==============================================================================
147 4. Vim commands *channel-commands*
148
149 NOT IMPLEMENTED YET
150
151 With a "json" channel the process can send commands to Vim that will be
152 handled by Vim internally, it does not require a handler for the channel.
153
154 Possible commands are:
155 ["ex", {Ex command}]
156 ["normal", {Normal mode command}]
157 ["eval", {number}, {expression}]
158 ["expr", {expression}]
159
160 With all of these: Be careful what these commands do! You can easily
161 interfere with what the user is doing. To avoid trouble use |mode()| to check
162 that the editor is in the expected state. E.g., to send keys that must be
163 inserted as text, not executed as a command: >
164 ["ex","if mode() == 'i' | call feedkeys('ClassName') | endif"]
165
166 The "ex" command is executed as any Ex command. There is no response for
167 completion or error. You could use functions in an |autoload| script.
168 You can also invoke |feedkeys()| to insert anything.
169
170 The "normal" command is executed like with |:normal|.
171
172 The "eval" command will result in sending back the result of the expression:
173 [{number}, {result}]
174 Here {number} is the same as what was in the request.
175
176 The "expr" command is similar, but does not send back any response.
177 Example:
178 ["expr","setline('$', ['one', 'two', 'three'])"]
179
180 ==============================================================================
181 5. Using a raw channel *channel-raw*
182
183 If {mode} is "raw" then a message can be send like this: >
184 let response = sendraw(handle, {string})
185 The {string} is sent as-is. The response will be what can be read from the
186 channel right away. Since Vim doesn't know how to recognize the end of the
187 message you need to take care of it yourself.
188
189 To send a message, without expecting a response: >
190 call sendraw(handle, {string}, 0)
191 The process can send back a response, the channel handler will be called with
192 it.
193
194 To send a message and letting the response handled by a specific function,
195 asynchronously: >
196 call sendraw(handle, {string}, {callback})
197
198 This {string} can also be JSON, use |jsonencode()| to create it and
199 |jsondecode()| to handle a received JSON message.
200
201 ==============================================================================
202 6. Job control *job-control*
203
204 NOT IMPLEMENTED YET
205
206 To start another process: >
207 call startjob({command})
208
209 This does not wait for {command} to exit.
210
211 TODO:
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: