msgpack_rpc.txt 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. NVIM REFERENCE MANUAL by Thiago de Arruda
  2. RPC API for Nvim *RPC* *rpc* *msgpack-rpc*
  3. Type |gO| to see the table of contents.
  4. ==============================================================================
  5. 1. Introduction *rpc-intro*
  6. The primary way to control Nvim programmatically is the RPC API, which speaks
  7. MessagePack-RPC ("msgpack-rpc"), a messaging protocol that uses the
  8. MessagePack serialization format:
  9. https://github.com/msgpack/msgpack/blob/0b8f5ac/spec.md
  10. All kinds of Nvim "clients" use the RPC API: user interfaces (GUIs), remote
  11. plugins, scripts like "nvr" (https://github.com/mhinz/neovim-remote), and even
  12. `nvim` itself can control other `nvim` instances. By connecting to the RPC API
  13. programs can:
  14. - Call any API function
  15. - Listen for events
  16. - Receive remote calls from Nvim
  17. The RPC API is like a more powerful version of Vim's `clientserver` feature.
  18. ==============================================================================
  19. 2. API mapping *rpc-api*
  20. The Nvim C |API| is automatically exposed to the RPC API by the build system,
  21. which parses headers at src/nvim/api/*. A dispatch function is generated which
  22. matches RPC API method names with public API functions, converting/validating
  23. arguments and return values back to msgpack.
  24. Client libraries (|api-client|s) normally provide wrappers that hide
  25. msgpack-rpc details from application developers. The wrappers can be
  26. automatically generated by reading bundled API metadata from a compiled Nvim
  27. instance.
  28. There are three ways to obtain API metadata:
  29. 1. Connect to a running Nvim instance and call `nvim_get_api_info` via
  30. msgpack-rpc. This is best for clients written in dynamic languages which
  31. can define functions at runtime.
  32. 2. Start Nvim with the |--api-info| option. Useful for clients written in
  33. statically-compiled languages.
  34. 3. Use the |api_info()| vimscript function.
  35. To get a human-readable list of API functions: >
  36. :new|put =map(api_info().functions, 'v:val.name')
  37. <
  38. To get a formatted dump of the API using python (requires the `pyyaml` and
  39. `msgpack-python` packages): >
  40. nvim --api-info | python -c 'import msgpack, sys, yaml; print yaml.dump(msgpack.unpackb(sys.stdin.read()))'
  41. <
  42. ==============================================================================
  43. 3. Connecting *rpc-connecting*
  44. See |channel-intro|, for various ways to open a channel. Most of the channel
  45. opening functions take an `rpc` key in the options dictionary, to enable RPC.
  46. Additionally, RPC channels can be opened by other processes connecting to
  47. TCP/IP sockets or named pipes listened to by nvim.
  48. Nvim creates a default RPC socket at |startup|, given by |v:servername|. To
  49. start with a TCP/IP socket instead, use |--listen| with a TCP-style address: >
  50. nvim --listen 127.0.0.1:6666
  51. Additional sockets and named pipes can be started with |serverstart()|.
  52. Note that localhost TCP sockets are generally less secure than named pipes,
  53. and can lead to vunerabilities like remote code execution.
  54. Connecting to the socket is the easiest way a programmer can test the API,
  55. which can be done through any msgpack-rpc client library or full-featured
  56. |api-client|. Here's a Ruby script that prints 'hello world!' in the current
  57. Nvim instance:
  58. >
  59. #!/usr/bin/env ruby
  60. # Requires msgpack-rpc: gem install msgpack-rpc
  61. #
  62. # To run this script, execute it from a running Nvim instance (notice the
  63. # trailing '&' which is required since Nvim won't process events while
  64. # running a blocking command):
  65. #
  66. # :!./hello.rb &
  67. #
  68. # Or from another shell by setting NVIM_LISTEN_ADDRESS:
  69. # $ NVIM_LISTEN_ADDRESS=[address] ./hello.rb
  70. require 'msgpack/rpc'
  71. require 'msgpack/rpc/transport/unix'
  72. nvim = MessagePack::RPC::Client.new(MessagePack::RPC::UNIXTransport.new, ENV['NVIM_LISTEN_ADDRESS'])
  73. result = nvim.call(:nvim_command, 'echo "hello world!"')
  74. <
  75. A better way is to use the Python REPL with the `neovim` package, where API
  76. functions can be called interactively:
  77. >
  78. >>> from neovim import attach
  79. >>> nvim = attach('socket', path='[address]')
  80. >>> nvim.command('echo "hello world!"')
  81. <
  82. You can also embed an Nvim instance via |jobstart()|, and communicate using
  83. |rpcrequest()| and |rpcnotify()|:
  84. >
  85. let nvim = jobstart(['nvim', '--embed'], {'rpc': v:true})
  86. echo rpcrequest(nvim, 'nvim_eval', '"Hello " . "world!"')
  87. call jobstop(nvim)
  88. <
  89. ==============================================================================
  90. 4. Implementing API clients *rpc-api-client* *api-client*
  91. "API clients" wrap the Nvim API to provide idiomatic "SDKs" for their
  92. respective platforms (see |dev-jargon|). You can build a new API client for
  93. your favorite platform or programming language.
  94. Existing API clients are listed here:
  95. https://github.com/neovim/neovim/wiki/Related-projects#api-clients
  96. The Python client is the reference implementation for API clients. It is
  97. always up-to-date with the Nvim API, so its source code and test suite are
  98. authoritative references.
  99. https://github.com/neovim/python-client
  100. API client implementation guidelines ~
  101. - Separate the transport layer from the rest of the library. See
  102. |rpc-connecting| for details on how clients can connect to Nvim.
  103. - Use a MessagePack library that implements at least version 5 of the
  104. MessagePack spec, which supports the `bin` and `ext` types used by Nvim.
  105. - Read API metadata in order to create client-side wrappers for all
  106. msgpack-rpc methods.
  107. - Use a single-threaded event loop library/pattern.
  108. - Use a fiber/coroutine library for the language being used for implementing
  109. a client. These greatly simplify concurrency and allow the library to
  110. expose a blocking API on top of a non-blocking event loop without the
  111. complexity that comes with preemptive multitasking.
  112. - Don't assume anything about the order that responses to msgpack-rpc
  113. requests will arrive.
  114. - Clients should expect msgpack-rpc requests, which need to be handled
  115. immediately because Nvim is blocked while waiting for the client response.
  116. - Clients should expect to receive msgpack-rpc notifications, but these
  117. don't need to be handled immediately because they won't block Nvim
  118. (although they should probably be handled immediately anyway).
  119. Note: Most of the complexity could be handled by a msgpack-rpc library that
  120. supports server to client requests and notifications, but it's not clear if
  121. this is part of the msgpack-rpc spec. At least the Ruby msgpack-rpc library
  122. does not seem to support it:
  123. https://github.com/msgpack-rpc/msgpack-rpc-ruby/blob/master/lib/msgpack/rpc/transport/tcp.rb#L150-L158
  124. API metadata object ~
  125. API clients exist to hide msgpack-rpc details. The API metadata object
  126. contains information that makes this task easier (see also |rpc-types|):
  127. - The "version" key contains the Nvim version, API level, and API
  128. backwards-compatibility level.
  129. - The "functions" key contains a list of metadata objects for individual
  130. functions.
  131. - Each function metadata object has |rpc-types| information about the return
  132. value and parameters. These can be used for generating strongly-typed APIs
  133. in static languages.
  134. - Container types may be decorated with type/size constraints, e.g.
  135. ArrayOf(Buffer) or ArrayOf(Integer, 2). This can be useful to generate
  136. even more strongly-typed APIs.
  137. - Functions that are considered to be methods that operate on instances of
  138. Nvim special types (msgpack EXT) will have the `"method"` attribute set to
  139. `true`. The receiver type is the type of the first argument. The method
  140. names are prefixed with `nvim_` plus a shortened type name, e.g.
  141. `nvim_buf_get_lines` represents the `get_lines` method of a Buffer instance.
  142. - Global functions have `"method"` set to `false` and are prefixed with just
  143. `nvim_`, e.g. `nvim_get_buffers`.
  144. So for an object-oriented language, an API client contains the classes
  145. representing Nvim special types, and the methods of each class could be
  146. defined by stripping the prefix for the type as defined in the `types` metadata
  147. (this will always be the first two "_"-separated parts of the function name).
  148. There could also be a singleton Vim class with methods where the `nvim_`
  149. prefix is stripped off.
  150. ==============================================================================
  151. 5. Types *rpc-types*
  152. The Nvim C API uses custom types for all functions. |api-types|
  153. At the RPC layer, types form two groups:
  154. - Basic types that map natively to msgpack (and have a default
  155. representation in most msgpack-supported programming languages)
  156. - Special Nvim types that map to msgpack EXT with custom type codes.
  157. Basic types ~
  158. Nil -> msgpack nil
  159. Boolean -> msgpack boolean
  160. Integer (signed 64-bit integer) -> msgpack integer
  161. Float (IEEE 754 double precision) -> msgpack float
  162. String -> msgpack string
  163. Array -> msgpack array
  164. Dictionary -> msgpack map
  165. Note: in function calls, empty Array is accepted for Dictionary parameter.
  166. Special types (msgpack EXT) ~
  167. Buffer -> enum value kObjectTypeBuffer
  168. Window -> enum value kObjectTypeWindow
  169. Tabpage -> enum value kObjectTypeTabpage
  170. API functions expecting one of the special EXT types may be passed an integer
  171. instead, but not another EXT type. E.g. Buffer may be passed as an integer but
  172. not as a Window or Tabpage. The EXT object data is the object id encoded as
  173. a msgpack integer: For buffers this is the |bufnr()| and for windows the
  174. |window-ID|. For tabpages the id is an internal handle, not the tabpage
  175. number.
  176. To determine the type codes of the special EXT types, inspect the `types` key
  177. of the |api-metadata| at runtime. Example JSON representation: >
  178. "types": {
  179. "Buffer": {
  180. "id": 0,
  181. "prefix": "nvim_buf_"
  182. },
  183. "Window": {
  184. "id": 1,
  185. "prefix": "nvim_win_"
  186. },
  187. "Tabpage": {
  188. "id": 2,
  189. "prefix": "nvim_tabpage_"
  190. }
  191. }
  192. Even for statically compiled clients it is good practice to avoid hardcoding
  193. the type codes, because a client may be built against one Nvim version but
  194. connect to another with different type codes.
  195. vim:tw=78:ts=8:ft=help:norl: