Mercurial > vim
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: |