123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659 |
- *develop.txt* Nvim
- NVIM REFERENCE MANUAL
- Development of Nvim *development* *dev*
- This reference describes design constraints and guidelines, for developing
- Nvim applications or Nvim itself. See |dev-arch| for discussion of Nvim's
- architecture and internal concepts.
- Nvim is free and open source. Everybody is encouraged to contribute.
- https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md
- Type |gO| to see the table of contents.
- ==============================================================================
- Design goals *design-goals*
- Most important things come first (roughly). Some items conflict; this is
- intentional. A balance must be found.
- NVIM IS... IMPROVED *design-improved*
- The Neo bits of Nvim should make it a better Vim, without becoming a
- completely different editor.
- - In matters of taste, prefer Vim/Unix tradition. If there is no relevant
- Vim/Unix tradition, consider the "common case".
- - There is no limit to the features that can be added. Select new features
- based on (1) what users ask for, (2) how much effort it takes to implement
- and (3) someone actually implementing it.
- - Backwards compatibility is a feature. The RPC API in particular should
- never break.
- NVIM IS... WELL DOCUMENTED *design-documented*
- - A feature that isn't documented is a useless feature. A patch for a new
- feature must include the documentation.
- - Documentation should be comprehensive and understandable. Use examples.
- - Don't make the text unnecessarily long. Less documentation means that an
- item is easier to find.
- NVIM IS... FAST AND SMALL *design-speed-size*
- Keep Nvim small and fast. This directly affects versatility and usability.
- - Computers are becoming faster and bigger each year. Vim can grow too, but
- no faster than computers are growing. Keep Vim usable on older systems.
- - Many users start Vim from a shell very often. Startup time must be short.
- - Commands must work efficiently. The time they consume must be as small as
- possible. Useful commands may take longer.
- - Don't forget that some people use Vim over a slow connection. Minimize the
- communication overhead.
- - Vim is a component among other components. Don't turn it into a massive
- application, but have it work well together with other programs
- ("composability").
- NVIM IS... MAINTAINABLE *design-maintain*
- - The source code should not become a mess. It should be reliable code.
- - Use comments in a useful way! Quoting the function name and argument names
- is NOT useful. Do explain what they are for.
- - Porting to another platform should be made easy, without having to change
- too much platform-independent code.
- - Use the object-oriented spirit: Put data and code together. Minimize the
- knowledge spread to other parts of the code.
- NVIM IS... NOT *design-not*
- Nvim is not an operating system; instead it should be composed with other
- tools or hosted as a component. Marvim once said: "Unlike Emacs, Nvim does not
- include the kitchen sink... but it's good for plumbing."
- ==============================================================================
- Developer guidelines *dev-guidelines*
- PROVIDERS *dev-provider*
- A primary goal of Nvim is to allow extension of the editor without special
- knowledge in the core. Some core functions are delegated to "providers"
- implemented as external scripts.
- Examples:
- 1. In the Vim source code, clipboard logic accounts for more than 1k lines of
- C source code (ui.c), to perform two tasks that are now accomplished with
- shell commands such as xclip or pbcopy/pbpaste.
- 2. Python scripting support: Vim has three files dedicated to embedding the
- Python interpreter: if_python.c, if_python3.c and if_py_both.h. Together
- these files sum about 9.5k lines of C source code. In contrast, Nvim Python
- scripting is performed by an external host process implemented in ~2k lines
- of Python.
- The provider framework invokes Vimscript from C. It is composed of two
- functions in eval.c:
- - eval_call_provider({name}, {method}, {arguments}, {discard}): Calls
- `provider#{name}#Call` with {method} and {arguments}. If {discard} is true, any
- value returned by the provider will be discarded and empty value will be
- returned.
- - eval_has_provider({name}): Checks the `g:loaded_{name}_provider` variable
- which must be set to 2 by the provider script to indicate that it is
- "enabled and working". Called by |has()| to check if features are available.
- For example, the Python provider is implemented by the
- "autoload/provider/python.vim" script, which sets `g:loaded_python_provider`
- to 2 only if a valid external Python host is found. Then `has("python")`
- reflects whether Python support is working.
- *provider-reload*
- Sometimes a GUI or other application may want to force a provider to
- "reload". To reload a provider, undefine its "loaded" flag, then use
- |:runtime| to reload it: >vim
- :unlet g:loaded_clipboard_provider
- :runtime autoload/provider/clipboard.vim
- DOCUMENTATION *dev-doc*
- - "Just say it". Avoid mushy, colloquial phrasing in all documentation
- (docstrings, user manual, website materials, newsletters, …). Don't mince
- words. Personality and flavor, used sparingly, are welcome--but in general,
- optimize for the reader's time and energy: be "precise yet concise".
- - Prefer the active voice: "Foo does X", not "X is done by Foo".
- - "The words you choose are an essential part of the user experience."
- https://developer.apple.com/design/human-interface-guidelines/writing
- - "...without being overly colloquial or frivolous."
- https://developers.google.com/style/tone
- - Write docstrings (as opposed to inline comments) with present tense ("Gets"),
- not imperative ("Get"). This tends to reduce ambiguity and improve clarity
- by describing "What" instead of "How". >
- ✅ OK:
- /// Gets a highlight definition.
- ❌ NO:
- /// Get a highlight definition.
- - Avoid starting docstrings with "The" or "A" unless needed to avoid
- ambiguity. This is a visual aid and reduces noise. >
- ✅ OK:
- /// @param dirname Path fragment before `pend`
- ❌ NO:
- /// @param dirname The path fragment before `pend`
- - Vim differences:
- - Do not prefix help tags with "nvim-". Use |vim_diff.txt| to catalog
- differences from Vim; no other distinction is necessary.
- - If a Vim feature is removed, delete its help section and move its tag to
- |vim_diff.txt|.
- - Mention deprecated features in |deprecated.txt| and delete their old doc.
- - Use consistent language.
- - "terminal" in a help tag always means "the embedded terminal emulator",
- not "the user host terminal".
- - Use "tui-" to prefix help tags related to the host terminal, and "TUI"
- in prose if possible.
- - Rough guidelines on where Lua documentation should end up:
- - Nvim API functions `vim.api.nvim_*` should be in `api.txt`.
- - If the module is big and not relevant to generic and lower-level Lua
- functionality, then it's a strong candidate for separation. Example:
- `treesitter.txt`
- - Otherwise, add them to `lua.txt`
- Documentation format ~
- For Nvim-owned docs, use the following strict subset of "vimdoc" to ensure
- the help doc renders nicely in other formats (such as HTML:
- https://neovim.io/doc/user ).
- Strict "vimdoc" subset:
- - Use lists (like this!) prefixed with "-" or "•", for adjacent lines that you
- don't want to auto-wrap. Lists are always rendered with "flow" layout
- (soft-wrapped) instead of preformatted (hard-wrapped) layout common in
- legacy :help docs.
- - Limitation: currently the parser https://github.com/neovim/tree-sitter-vimdoc
- does not understand numbered listitems, so use a bullet symbol (- or •)
- before numbered items, e.g. "• 1." instead of "1.".
- - Separate blocks (paragraphs) of content by a blank line.
- - Do not use indentation in random places—that prevents the page from using
- "flow" layout. If you need a preformatted section, put it in
- a |help-codeblock| starting with ">".
- - Parameters and fields are documented as `{foo}`.
- - Optional parameters and fields are documented as `{foo}?`.
- C docstrings ~
- Nvim API documentation lives in the source code, as docstrings (doc
- comments) on the function definitions. The |api| :help is generated
- from the docstrings defined in src/nvim/api/*.c.
- Docstring format:
- - Lines start with `///`
- - Special tokens start with `@` followed by the token name:
- `@note`, `@param`, `@return`
- - Markdown is supported.
- - Tags are written as `[tag]()`.
- - References are written as `[tag]`
- - Use ``` for code samples.
- Code samples can be annotated as `vim` or `lua`
- Example: the help for |nvim_open_win()| is generated from a docstring defined
- in src/nvim/api/win_config.c like this: >
- /// Opens a new window.
- /// ...
- ///
- /// Example (Lua): window-relative float
- ///
- /// ```lua
- /// vim.api.nvim_open_win(0, false, {
- /// relative='win',
- /// row=3,
- /// col=3,
- /// width=12,
- /// height=3,
- /// })
- /// ```
- ///
- /// @param buffer Buffer to display
- /// @param enter Enter the window
- /// @param config Map defining the window configuration. Keys:
- /// - relative: Sets the window layout, relative to:
- /// - "editor" The global editor grid.
- /// - "win" Window given by the `win` field.
- /// - "cursor" Cursor position in current window.
- /// ...
- /// @param[out] err Error details, if any
- ///
- /// @return Window handle, or 0 on error
- Lua docstrings ~
- *dev-lua-doc*
- Lua documentation lives in the source code, as docstrings on the function
- definitions. The |lua-vim| :help is generated from the docstrings.
- Docstring format:
- - Use LuaCATS annotations: https://luals.github.io/wiki/annotations/
- - Markdown is supported.
- - Tags are written as `[tag]()`.
- - References are written as `[tag]`
- - Use ``` for code samples.
- Code samples can be annotated as `vim` or `lua`
- - Use `@since <api-level>` to note the |api-level| when the function became
- "stable". If `<api-level>` is greater than the current stable release (or
- 0), it is marked as "experimental".
- - See scripts/util.lua for the mapping of api-level to Nvim version.
- - Use `@nodoc` to prevent documentation generation.
- - Use `@inlinedoc` to inline `@class` blocks into `@param` blocks.
- E.g. >lua
- --- Object with fields:
- --- @class myOpts
- --- @inlinedoc
- ---
- --- Documentation for some field
- --- @field somefield? integer
- --- @param opts? myOpts
- function foo(opts)
- end
- <
- Will be rendered as: >vimdoc
- foo({opts})
- Parameters:
- - {opts}? (table) Object with the fields:
- - {somefield}? (integer) Documentation
- for some field
- <
- - Files declared as `@meta` are only used for typing and documentation (similar to "*.d.ts" typescript files).
- Example: the help for |vim.paste()| is generated from a docstring decorating
- vim.paste in runtime/lua/vim/_editor.lua like this: >
- --- Paste handler, invoked by |nvim_paste()| when a conforming UI
- --- (such as the |TUI|) pastes text into the editor.
- ---
- --- Example: To remove ANSI color codes when pasting:
- ---
- --- ```lua
- --- vim.paste = (function()
- --- local overridden = vim.paste
- --- ...
- --- end)()
- --- ```
- ---
- --- @since 12
- --- @see |paste|
- ---
- --- @param lines ...
- --- @param phase ...
- --- @returns false if client should cancel the paste.
- STDLIB DESIGN GUIDELINES *dev-lua*
- See also |dev-naming|.
- - Keep the core Lua modules |lua-stdlib| simple. Avoid elaborate OOP or
- pseudo-OOP designs. Plugin authors just want functions to call, not a big,
- fancy inheritance hierarchy.
- - Avoid requiring or returning special objects in the Nvim stdlib. Plain
- tables or values are easier to serialize, easier to construct from literals,
- easier to inspect and print, and inherently compatible with all Lua plugins.
- (This guideline doesn't apply to opaque, non-data objects like `vim.cmd`.)
- - stdlib functions should follow these common patterns:
- - Return |lua-result-or-message| (`any|nil,nil|string`) to communicate
- failure, or choose from |dev-error-patterns| when appropriate.
- - Accept iterable instead of only table.
- - Note: in some cases iterable doesn't make sense, e.g. spair() sorts the
- input by definition, so there is no reason for it to accept an iterable,
- because the input needs to be "reified"; it can't operate on a "stream".
- - Return an iterable (generator) instead of table, if possible.
- - Mimic the pairs() or ipairs() interface if the function is intended for
- use in a |for-in| loop.
- *dev-error-patterns*
- To communicate failure to a consumer, choose from these patterns (in order of
- preference):
- 1. `retval, errmsg`
- - When failure is normal, or when it is practical for the consumer to
- continue (fallback) in some other way. See |lua-result-or-message|.
- 2. optional result, no errormsg
- - Special case of 1. When there is only a single case of "doesn't exist"
- (e.g. cache lookup, dict lookup).
- 3. `error("no luck")`
- - For invalid state ("must not happen"), when failure is exceptional, or at
- a low level where the consumers are unlikely to handle it in a meaningful
- way. Advantage is that propagation happens for free and it's harder to
- accidentally swallow errors. (E.g. using
- `uv_handle/pipe:write()` without checking return values is common.)
- 4. `on_error` callback
- - For async and "visitors" traversing a graph, where many errors may be
- collected while work continues.
- 5. `vim.notify` (sometimes with optional `opts.silent` (async, visitors ^))
- - High-level / application-level messages. End-user invokes these directly.
- *dev-patterns*
- Interface conventions ~
- Where possible, these patterns apply to _both_ Lua and the API:
- - When accepting a buffer id, etc., 0 means "current buffer", nil means "all
- buffers". Likewise for window id, tabpage id, etc.
- - Examples: |vim.lsp.codelens.clear()| |vim.diagnostic.enable()|
- - Any function signature that accepts a callback (example: |table.foreach()|)
- should place it as the LAST parameter (after opts), if possible (or ALWAYS
- for "continuation callbacks"—functions called exactly once).
- - Improves readability by placing the less "noisy" arguments near the start.
- - Consistent with luv.
- - Useful for future async lib which transforms functions of the form
- `function(<args>, cb(<ret)>))` => `function(<args>) -> <ret>`.
- - Example: >lua
- -- ✅ OK:
- filter(…, opts, function() … end)
- -- ❌ NO:
- filter(function() … end, …, opts)
- -- ❌ NO:
- filter(…, function() … end, opts)
- - "Enable" ("toggle") interface and behavior:
- - `enable(…, nil)` and `enable(…, {buf=nil})` are synonyms and control the
- the "global" enablement of a feature.
- - `is_enabled(nil)` and `is_enabled({buf=nil})`, likewise, query the
- global state of the feature.
- - `enable(…, {buf: number})` sets a buffer-local "enable" flag.
- - `is_enabled({buf: number})`, likewise, queries the buffer-local state of
- the feature.
- - See |vim.lsp.inlay_hint.enable()| and |vim.lsp.inlay_hint.is_enabled()|
- for a reference implementation of these "best practices".
- - NOTE: open questions: https://github.com/neovim/neovim/issues/28603
- API DESIGN GUIDELINES *dev-api*
- See also |dev-naming|.
- - When adding an API, check the following:
- - What precedents did you draw from? How does your solution compare to them?
- - Does your new API allow future expansion? How? Or why not?
- - Is the new API similar to existing APIs? Do we need to deprecate the old ones?
- - Did you cross-reference related concepts in the docs?
- - Avoid "mutually exclusive" parameters--via constraints or limitations, if
- necessary. For example nvim_create_autocmd() has mutually exclusive
- "callback" and "command" args; but the "command" arg could be eliminated by
- simply not supporting Vimscript function names, and treating a string
- "callback" arg as an Ex command (which can call Vimscript functions). The
- "buffer" arg could also be eliminated by treating a number "pattern" as
- a buffer number.
- - Avoid functions that depend on cursor position, current buffer, etc. Instead
- the function should take a position parameter, buffer parameter, etc.
- Where things go ~
- - API (libnvim/RPC): exposes low-level internals, or fundamental things (such
- as `nvim_exec_lua()`) needed by clients or C consumers.
- - Lua stdlib = high-level functionality that builds on top of the API.
- NAMING GUIDELINES *dev-naming*
- Naming is exceedingly important: the name of a thing is the primary interface
- for uses it, discusses it, searches for it, shares it... Consistent
- naming in the stdlib, API, and UI helps both users and developers discover and
- intuitively understand related concepts ("families"), and reduces cognitive
- burden. Discoverability encourages code re-use and likewise avoids redundant,
- overlapping mechanisms, which reduces code surface-area, and thereby minimizes
- bugs...
- Naming conventions ~
- In general, look for precedent when choosing a name, that is, look at existing
- (non-deprecated) functions. In particular, see below...
- *dev-name-common*
- Use existing common {verb} names (actions) if possible:
- - add: Appends or inserts into a collection
- - attach: Listens to something to get events from it (TODO: rename to "on"?)
- - call: Calls a function
- - cancel: Cancels or dismisses an event or interaction, typically
- user-initiated and without error. (Compare "abort", which
- cancels and signals error/failure.)
- - clear: Clears state but does not destroy the container
- - create: Creates a new (non-trivial) thing (TODO: rename to "def"?)
- - del: Deletes a thing (or group of things)
- - detach: Dispose attached listener (TODO: rename to "un"?)
- - enable: Enables/disables functionality. Signature should be
- `enable(enable?:boolean, filter?:table)`.
- - eval: Evaluates an expression
- - exec: Executes code, may return a result
- - fmt: Formats
- - get: Gets things. Two variants (overloads):
- 1. `get<T>(id: int): T` returns one item.
- 2. `get<T>(filter: dict): T[]` returns a list.
- - inspect: Presents a high-level, often interactive, view
- - is_enabled: Checks if functionality is enabled.
- - open: Opens something (a buffer, window, …)
- - parse: Parses something into a structured form
- - set: Sets a thing (or group of things)
- - start: Spin up a long-lived process. Prefer "enable" except when
- "start" is obviously more appropriate.
- - stop: Inverse of "start". Teardown a long-lived process.
- - try_{verb}: Best-effort operation, failure returns null or error obj
- Do NOT use these deprecated verbs:
- - disable: Prefer `enable(enable: boolean)`.
- - exit: Prefer "cancel" (or "stop" if appropriate).
- - is_disabled: Prefer `is_enabled()`.
- - list: Redundant with "get"
- - notify: Redundant with "print", "echo"
- - show: Redundant with "print", "echo"
- - toggle: Prefer `enable(not is_enabled())`.
- Use consistent names for {topic} in API functions: buffer is called "buf"
- everywhere, not "buffer" in some places and "buf" in others.
- - buf: Buffer
- - chan: |channel|
- - cmd: Command
- - cmdline: Command-line UI or input
- - fn: Function
- - hl: Highlight
- - pos: Position
- - proc: System process
- - tabpage: Tabpage
- - win: Window
- Do NOT use these deprecated nouns:
- - buffer Use "buf" instead
- - callback Use on_foo instead
- - command Use "cmd" instead
- - window Use "win" instead
- *dev-name-events*
- Use the "on_" prefix to name event-handling callbacks and also the interface for
- "registering" such handlers (on_key). The dual nature is acceptable to avoid
- a confused collection of naming conventions for these related concepts.
- Editor |events| (autocommands) are historically named like: >
- {Noun}{Event}
- Use this format to name API (RPC) events: >
- nvim_{noun}_{event-name}_event
- Example: >
- nvim_buf_changedtick_event
- <
- *dev-api-name*
- Use this format to name new RPC |API| functions: >
- nvim_{topic}_{verb}_{arbitrary-qualifiers}
- Do not add new nvim_buf/nvim_win/nvim_tabpage APIs, unless you are certain the
- concept will NEVER be applied to more than one "scope". That is, {topic}
- should be the TOPIC ("ns", "extmark", "option", …) that acts on the scope(s)
- (buf/win/tabpage/global), it should NOT be the scope. Instead the scope should
- be a parameter (typically manifest as mutually-exclusive buf/win/… flags like
- |nvim_get_option_value()|, or less commonly as a `scope: string` field like
- |nvim_get_option_info2()|).
- - Example: `nvim_get_keymap('v')` operates in a global context (first
- parameter is not a Buffer). The "get" verb indicates that it gets anything
- matching the given filter parameter. A "list" verb is unnecessary because
- `nvim_get_keymap('')` (empty filter) returns all items.
- - Example: `nvim_buf_del_mark` acts on a `Buffer` object (the first parameter)
- and uses the "del" {verb}.
- INTERFACE PATTERNS *dev-api-patterns*
- Prefer adding a single `nvim_{topic}_{verb}_…` interface for a given topic.
- Example: >
- nvim_ns_add(
- ns_id: int,
- filter: {
- handle: integer (buf/win/tabpage id)
- scope: "global" | "win" | "buf" | "tabpage"
- }
- ): { ok: boolean }
- nvim_ns_get(
- ns_id: int,
- filter: {
- handle: integer (buf/win/tabpage id)
- scope: "global" | "win" | "buf" | "tabpage"
- }
- ): { ids: int[] }
- nvim_ns_del(
- ns_id: int,
- filter: {
- handle: integer (buf/win/tabpage id)
- scope: "global" | "win" | "buf" | "tabpage"
- }
- ): { ok: boolean }
- Anti-Example:
- Creating separate `nvim_xx`, `nvim_buf_xx`, `nvim_win_xx`, and
- `nvim_tabpage_xx`, functions all for the same `xx` topic, requires 4x the
- amount of documentation, tests, boilerplate, and interfaces, which users must
- comprehend, maintainers must maintain, etc. Thus the following is NOT
- recommended (compare these 12(!) functions to the above 3 functions): >
- nvim_add_ns(…)
- nvim_buf_add_ns(…)
- nvim_win_add_ns(…)
- nvim_tabpage_add_ns(…)
- nvim_del_ns(…)
- nvim_buf_del_ns(…)
- nvim_win_del_ns(…)
- nvim_tabpage_del_ns(…)
- nvim_get_ns(…)
- nvim_buf_get_ns(…)
- nvim_win_get_ns(…)
- nvim_tabpage_get_ns(…)
- API-CLIENT *dev-api-client*
- *api-client*
- API clients wrap the Nvim |API| to provide idiomatic "SDKs" for their
- respective platforms (see |jargon|). You can build a new API client for your
- favorite platform or programming language.
- List of API clients:
- https://github.com/neovim/neovim/wiki/Related-projects#api-clients
- *node-client* *pynvim*
- These clients can be considered the "reference implementation" for API clients:
- - https://github.com/neovim/node-client
- - https://github.com/neovim/pynvim
- Standard Features ~
- - API clients exist to hide msgpack-rpc details. The wrappers can be
- automatically generated by reading the |api-metadata| from Nvim. |api-mapping|
- - Clients should call |nvim_set_client_info()| after connecting, so users and
- plugins can detect the client by handling the |ChanInfo| event. This avoids
- the need for special variables or other client hints.
- - Clients should handle |nvim_error_event| notifications, which will be sent
- if an async request to nvim was rejected or caused an error.
- Package Naming ~
- API client packages should NOT be named something ambiguous like "neovim" or
- "python-client". Use "nvim" as a prefix/suffix to some other identifier
- following ecosystem conventions.
- For example, Python packages tend to have "py" in the name, so "pynvim" is
- a good name: it's idiomatic and unambiguous. If the package is named "neovim",
- it confuses users, and complicates documentation and discussions.
- Examples of API-client package names:
- - ✅ OK: nvim-racket
- - ✅ OK: pynvim
- - ❌ NO: python-client
- - ❌ NO: neovim_
- API client implementation guidelines ~
- - Separate the transport layer from the rest of the library. |rpc-connecting|
- - Use a MessagePack library that implements at least version 5 of the
- MessagePack spec, which supports the BIN and EXT types used by Nvim.
- - Use a single-threaded event loop library/pattern.
- - Use a fiber/coroutine library for the language being used for implementing
- a client. These greatly simplify concurrency and allow the library to
- expose a blocking API on top of a non-blocking event loop without the
- complexity that comes with preemptive multitasking.
- - Don't assume anything about the order of responses to RPC requests.
- - Clients should expect requests, which must be handled immediately because
- Nvim is blocked while waiting for the client response.
- - Clients should expect notifications, but these can be handled "ASAP" (rather
- than immediately) because they won't block Nvim.
- - For C/C++ projects, consider libmpack instead of the msgpack.org library.
- https://github.com/libmpack/libmpack/
- libmpack is small (no dependencies, can inline into your C/C++ project) and
- efficient (no allocations). It also implements msgpack-RPC, the protocol
- required by Nvim.
- https://github.com/msgpack-rpc/msgpack-rpc
- EXTERNAL UI *dev-ui*
- External UIs should be aware of the |api-contract|. In particular, future
- versions of Nvim may add new items to existing events. The API is strongly
- backwards-compatible, but clients must not break if new (optional) fields are
- added to existing events.
- Standard Features ~
- External UIs are expected to implement these common features:
- - Call |nvim_set_client_info()| after connecting, so users and plugins can
- detect the UI by handling the |ChanInfo| event. This avoids the need for
- special variables and UI-specific config files (gvimrc, macvimrc, …).
- - Cursor style (shape, color) should conform to the 'guicursor' properties
- delivered with the mode_info_set UI event.
- - Send the ALT/META ("Option" on macOS) key as a |<M-| chord.
- - Send the "super" key (Windows key, Apple key) as a |<D-| chord.
- - Avoid mappings that conflict with the Nvim keymap-space; GUIs have many new
- chords (<C-,> <C-Enter> <C-S-x> <D-x>) and patterns ("shift shift") that do
- not potentially conflict with Nvim defaults, plugins, etc.
- - Consider the "option_set" |ui-global| event as a hint for other GUI
- behaviors. Various UI-related options ('guifont', 'ambiwidth', …) are
- published in this event. See also "mouse_on", "mouse_off".
- - UIs generally should NOT set |$NVIM_APPNAME| (unless explicitly requested by
- the user).
- - Support the text decorations/attributes given by |ui-event-hl_attr_define|.
- The "url" attr should be presented as a clickable hyperlink.
- vim:tw=78:ts=8:sw=4:et:ft=help:norl:
|