channel.txt 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. *channel.txt* Nvim
  2. NVIM REFERENCE MANUAL by Thiago de Arruda
  3. Nvim asynchronous IO *channel*
  4. Type |gO| to see the table of contents.
  5. ==============================================================================
  6. 1. Introduction *channel-intro*
  7. Channels are Nvim's way of communicating with external processes.
  8. There are several ways to open a channel:
  9. 1. Through stdin/stdout when `nvim` is started with `--headless` and a startup
  10. script or `--cmd` command opens the stdio channel using |stdioopen()|.
  11. 2. Through stdin, stdout and stderr of a process spawned by |jobstart()|.
  12. 3. Through the PTY master end opened with `jobstart(…, {'pty': v:true})`.
  13. 4. By connecting to a TCP/IP socket or named pipe with |sockconnect()|.
  14. 5. By another process connecting to a socket listened to by Nvim. This only
  15. supports RPC channels, see |rpc-connecting|.
  16. Channels support multiple modes or protocols. In the most basic
  17. mode of operation, raw bytes are read and written to the channel.
  18. The |RPC| protocol, based on the msgpack-rpc standard, enables nvim and the
  19. process at the other end to send remote calls and events to each other.
  20. The builtin |terminal-emulator| is also implemented on top of PTY channels.
  21. Channel Id *channel-id*
  22. Each channel is identified by an integer id, unique for the life of the
  23. current Nvim session. Functions like |stdioopen()| return channel ids;
  24. functions like |chansend()| consume channel ids.
  25. ==============================================================================
  26. 2. Reading and writing raw bytes *channel-bytes*
  27. Channels opened by Vimscript functions operate with raw bytes by default. For
  28. a job channel using RPC, bytes can still be read over its stderr. Similarly,
  29. only bytes can be written to Nvim's own stderr.
  30. *channel-callback*
  31. - on_stdout({chan-id}, {data}, {name}) *on_stdout*
  32. - on_stderr({chan-id}, {data}, {name}) *on_stderr*
  33. - on_stdin({chan-id}, {data}, {name}) *on_stdin*
  34. - on_data({chan-id}, {data}, {name}) *on_data*
  35. Scripts can react to channel activity (received data) via callback
  36. functions assigned to the `on_stdout`, `on_stderr`, `on_stdin`, or
  37. `on_data` option keys. Callbacks should be fast: avoid potentially
  38. slow/expensive work.
  39. Parameters: ~
  40. - {chan-id} Channel handle. |channel-id|
  41. - {data} Raw data (|readfile()|-style list of strings) read from
  42. the channel. EOF is a single-item list: `['']`. First and
  43. last items may be partial lines! |channel-lines|
  44. - {name} Stream name (string) like "stdout", so the same function
  45. can handle multiple streams. Event names depend on how the
  46. channel was opened and in what mode/protocol.
  47. *channel-buffered*
  48. The callback is invoked immediately as data is available, where
  49. a single-item list `['']` indicates EOF (stream closed). Alternatively
  50. set the `stdout_buffered`, `stderr_buffered`, `stdin_buffered`, or
  51. `data_buffered` option keys to invoke the callback only after all output
  52. was gathered and the stream was closed.
  53. *E5210*
  54. If a buffering mode is used without a callback, the data is saved in the
  55. stream {name} key of the options dict. It is an error if the key exists.
  56. *channel-lines*
  57. Stream event handlers receive data as it becomes available from the OS,
  58. thus the first and last items in the {data} list may be partial lines.
  59. Empty string completes the previous partial line. Examples (not including
  60. the final `['']` emitted at EOF):
  61. - `foobar` may arrive as `['fo'], ['obar']`
  62. - `foo\nbar` may arrive as
  63. - `['foo','bar']`
  64. - or `['foo',''], ['bar']`
  65. - or `['foo'], ['','bar']`
  66. - or `['fo'], ['o','bar']`
  67. There are two ways to deal with this:
  68. - 1. To wait for the entire output, use |channel-buffered| mode.
  69. - 2. To read line-by-line, use the following code: >vim
  70. let s:lines = ['']
  71. func! s:on_event(job_id, data, event) dict
  72. let eof = (a:data == [''])
  73. " Complete the previous line.
  74. let s:lines[-1] .= a:data[0]
  75. " Append (last item may be a partial line, until EOF).
  76. call extend(s:lines, a:data[1:])
  77. endf
  78. <
  79. If the callback functions are |Dictionary-function|s, |self| refers to the
  80. options dictionary containing the callbacks. |Partial|s can also be used as
  81. callbacks.
  82. Data can be sent to the channel using the |chansend()| function. Here is a
  83. simple example, echoing some data through a cat-process:
  84. >vim
  85. function! s:OnEvent(id, data, event) dict
  86. let str = join(a:data, "\n")
  87. echomsg str
  88. endfunction
  89. let id = jobstart(['cat'], {'on_stdout': function('s:OnEvent') } )
  90. call chansend(id, "hello!")
  91. <
  92. Here is an example of setting a buffer to the result of grep, but only after
  93. all data has been processed:
  94. >vim
  95. function! s:OnEvent(id, data, event) dict
  96. call nvim_buf_set_lines(2, 0, -1, v:true, a:data)
  97. endfunction
  98. let id = jobstart(['grep', '^[0-9]'], { 'on_stdout': function('s:OnEvent'),
  99. \ 'stdout_buffered':v:true } )
  100. call chansend(id, "stuff\n10 PRINT \"NVIM\"\nxx")
  101. " no output is received, buffer is empty
  102. call chansend(id, "xx\n20 GOTO 10\nzz\n")
  103. call chanclose(id, 'stdin')
  104. " now buffer has result
  105. <
  106. For additional examples with jobs, see |job-control|.
  107. *channel-pty*
  108. Special case: PTY channels opened with `jobstart(..., {'pty': v:true})` do not
  109. preprocess ANSI escape sequences, these will be sent raw to the callback.
  110. However, change of PTY size can be signaled to the slave using |jobresize()|.
  111. See also |terminal-emulator|.
  112. Terminal characteristics (termios) for |:terminal| and PTY channels are copied
  113. from the host TTY, or if Nvim is |--headless| it uses default values: >vim
  114. :echo system('nvim --headless +"te stty -a" +"sleep 1" +"1,/^$/print" +q')
  115. ==============================================================================
  116. 3. Communicating with msgpack RPC *channel-rpc*
  117. When channels are opened with the `rpc` option set to true, the channel can be
  118. used for remote method calls in both directions, see |msgpack-rpc|. Note that
  119. rpc channels are implicitly trusted and the process at the other end can
  120. invoke any |API| function!
  121. ==============================================================================
  122. 4. Standard IO channel *channel-stdio*
  123. Nvim uses stdin/stdout to interact with the user over the terminal interface
  124. (TUI). If Nvim is |--headless| the TUI is not started and stdin/stdout can be
  125. used as a channel. See also |--embed|.
  126. Call |stdioopen()| during |startup| to open the stdio channel as |channel-id| 1.
  127. Nvim's stderr is always available as |v:stderr|, a write-only bytes channel.
  128. Example: >vim
  129. func! OnEvent(id, data, event)
  130. if a:data == [""]
  131. quit
  132. end
  133. call chansend(a:id, map(a:data, {i,v -> toupper(v)}))
  134. endfunc
  135. call stdioopen({'on_stdin': 'OnEvent'})
  136. <
  137. Put this in `uppercase.vim` and run: >bash
  138. nvim --headless --cmd "source uppercase.vim"
  139. ==============================================================================
  140. 5. Using a prompt buffer *prompt-buffer*
  141. If you want to type input for the job in a Vim window you have a few options:
  142. - Use a normal buffer and handle all possible commands yourself.
  143. This will be complicated, since there are so many possible commands.
  144. - Use a terminal window. This works well if what you type goes directly to
  145. the job and the job output is directly displayed in the window.
  146. See |terminal|.
  147. - Use a window with a prompt buffer. This works well when entering a line for
  148. the job in Vim while displaying (possibly filtered) output from the job.
  149. A prompt buffer is created by setting 'buftype' to "prompt". You would
  150. normally only do that in a newly created buffer.
  151. The user can edit and enter one line of text at the very last line of the
  152. buffer. When pressing Enter in the prompt line the callback set with
  153. |prompt_setcallback()| is invoked. It would normally send the line to a job.
  154. Another callback would receive the output from the job and display it in the
  155. buffer, below the prompt (and above the next prompt).
  156. Only the text in the last line, after the prompt, is editable. The rest of the
  157. buffer is not modifiable with Normal mode commands. It can be modified by
  158. calling functions, such as |append()|. Using other commands may mess up the
  159. buffer.
  160. After setting 'buftype' to "prompt" Vim does not automatically start Insert
  161. mode, use `:startinsert` if you want to enter Insert mode, so that the user
  162. can start typing a line.
  163. The text of the prompt can be set with the |prompt_setprompt()| function. If
  164. no prompt is set with |prompt_setprompt()|, "% " is used. You can get the
  165. effective prompt text for a buffer, with |prompt_getprompt()|.
  166. The user can go to Normal mode and navigate through the buffer. This can be
  167. useful to see older output or copy text.
  168. The CTRL-W key can be used to start a window command, such as CTRL-W w to
  169. switch to the next window. This also works in Insert mode (use Shift-CTRL-W
  170. to delete a word). When leaving the window Insert mode will be stopped. When
  171. coming back to the prompt window Insert mode will be restored.
  172. Any command that starts Insert mode, such as "a", "i", "A" and "I", will move
  173. the cursor to the last line. "A" will move to the end of the line, "I" to the
  174. start of the line.
  175. Here is an example for Unix. It starts a shell in the background and prompts
  176. for the next shell command. Output from the shell is displayed above the
  177. prompt. >vim
  178. " Function handling a line of text that has been typed.
  179. func TextEntered(text)
  180. " Send the text to a shell with Enter appended.
  181. call chansend(g:shell_job, [a:text, ''])
  182. endfunc
  183. " Function handling output from the shell: Add it above the prompt.
  184. func GotOutput(channel, msg, name)
  185. call append(line("$") - 1, a:msg)
  186. endfunc
  187. " Function handling the shell exits: close the window.
  188. func JobExit(job, status, event)
  189. quit!
  190. endfunc
  191. " Start a shell in the background.
  192. let shell_job = jobstart(["/bin/sh"], #{
  193. \ on_stdout: function('GotOutput'),
  194. \ on_stderr: function('GotOutput'),
  195. \ on_exit: function('JobExit'),
  196. \ })
  197. new
  198. set buftype=prompt
  199. let buf = bufnr('')
  200. call prompt_setcallback(buf, function("TextEntered"))
  201. call prompt_setprompt(buf, "shell command: ")
  202. " start accepting shell commands
  203. startinsert
  204. <
  205. vim:tw=78:ts=8:noet:ft=help:norl: