@@ -180,6 +180,59 @@ print(proc:read_stdout())
180
180
print (proc :read_stderr ())
181
181
```
182
182
183
+ ### Writing data to a process
184
+
185
+ If the child process is created with the correct input mode,
186
+ you can write to the standard input of the process with ` process:write() ` .
187
+
188
+ ``` lua
189
+ function process :write (data : string ): integer |nil , string |nil end
190
+ ```
191
+
192
+ The function accepts a byte string containing the data to write,
193
+ and returns the number of bytes successfully written.
194
+ If it encounters an error, it will return nil and an error message.
195
+
196
+ The function is asynchronous and will return immediately, even when data is not written.
197
+ As such, the number of bytes written may be less than the number of bytes in the input.
198
+ You should handle this by chunking the data manually and implement exponetial backoff.
199
+
200
+ ``` lua
201
+ --- Writes data asynchronously to a process, with chunking and exponetial backoff.
202
+ --- The exponetial backoff will only work when calling this function inside a thread created with core.add_thread().
203
+ --- adapted from https://github.com/lite-xl/lite-xl-lsp/blob/b2523423b34712dd5cefc5d7ee6f7a500f4ac2ed/server.lua#L907
204
+ ---
205
+ --- @param proc process The child process to write to.
206
+ --- @param data string The data to write.
207
+ --- @return boolean success
208
+ --- @return string error
209
+ local function write_data (proc , data )
210
+ local failures , data_len = 0 , # data
211
+ local written , errmsg = proc :write (data )
212
+ local total_written = written or 0
213
+
214
+ while total_written < data_len and not errmsg do
215
+ written , errmsg = proc :write (data :sub (total_written + 1 ))
216
+ total_written = total_written + (written or 0 )
217
+
218
+ if (not written or written <= 0 ) and not errmsg and coroutine.running () then
219
+ -- with each consecutive fail the yield timeout is increased by 5ms
220
+ coroutine.yield ((failures * 5 ) / 1000 )
221
+
222
+ failures = failures + 1
223
+ if failures > 19 then -- after ~1000ms we error out
224
+ errmsg = " maximum amount of consecutive failures reached"
225
+ break
226
+ end
227
+ else
228
+ failures = 0
229
+ end
230
+ end
231
+
232
+ return total_written == data_len , errmsg
233
+ end
234
+ ```
235
+
183
236
### Waiting for a child process
184
237
185
238
You might want to wait for a child process to end.
0 commit comments