mirror of
https://github.com/neovim/neovim.git
synced 2024-12-29 14:41:06 -07:00
593d63f1d5
- Improved wording in a few places for clarity - Various capitalization/grammar fixes - Change references to Neovim as 'editor' to 'Nvim' - Be consistent regarding utilization of vim's documentation features, e.g. unnamedclip -> |unnamedclip| - Reflowed all changed paragraphs accordingly - Add spaces before parentheses - Remove trailing whitespace - Standardize single spaces after periods. Vim's docs use two for the most part, but Nvim's use one mainly, so just follow Nvim's conventions
136 lines
6.1 KiB
Plaintext
136 lines
6.1 KiB
Plaintext
*remote_plugin.txt* For Nvim. {Nvim}
|
|
|
|
|
|
NVIM REFERENCE MANUAL by Thiago de Arruda
|
|
|
|
|
|
Nvim support for remote plugins *remote-plugin*
|
|
|
|
1. Introduction |remote-plugin-intro|
|
|
2. Plugin hosts |remote-plugin-hosts|
|
|
3. Example |remote-plugin-example|
|
|
4. Plugin manifest |remote-plugin-manifest|
|
|
|
|
==============================================================================
|
|
1. Introduction *remote-plugin-intro*
|
|
|
|
Extensibility is a primary goal of Nvim. Any programming language may be used
|
|
to extend nvim without changes to nvim itself. This is achieved with remote
|
|
plugins, coprocesses that have a direct communication channel (via
|
|
|msgpack-rpc|) with the Nvim process.
|
|
|
|
Even though these plugins are running in separate processes they can call, be
|
|
called, and receive events just as if the code was being executed in the main
|
|
process.
|
|
|
|
==============================================================================
|
|
2. Plugin hosts *remote-plugin-hosts*
|
|
|
|
While plugins can be implemented as arbitrary programs that communicate
|
|
directly with the high-level Nvim API and are called via |rpcrequest()| and
|
|
|rpcnotify()|, that is not the best approach available. Instead, developers
|
|
should first check if a plugin host implementation is available for their
|
|
chosen programming language.
|
|
|
|
Plugin hosts are programs that provide a high level environment for plugins,
|
|
taking care of most boilerplate involved in defining commands, autocmds, and
|
|
functions that are implemented over |msgpack-rpc| connections. Hosts are
|
|
loaded only when one of their registered plugins require it, keeping Nvim's
|
|
startup as fast as possible if many plugins/hosts are installed.
|
|
|
|
==============================================================================
|
|
3. Example *remote-plugin-example*
|
|
|
|
The best way to learn about remote plugins is with an example, so let's see
|
|
what a python plugin looks like. This plugin exports a command, a function and
|
|
an autocmd. The plugin is called 'Limit', and all it does is limit the number
|
|
of requests made to it. Here's the plugin source code:
|
|
>
|
|
import neovim
|
|
|
|
@neovim.plugin
|
|
class Limit(object):
|
|
def __init__(self, vim):
|
|
self.vim = vim
|
|
self.calls = 0
|
|
|
|
@neovim.command('Cmd', range='', nargs='*', sync=True)
|
|
def command_handler(self, args, range):
|
|
self._increment_calls()
|
|
self.vim.current.line = (
|
|
'Command: Called %d times, args: %s, range: %s' % (self.calls,
|
|
args,
|
|
range))
|
|
|
|
@neovim.autocmd('BufEnter', pattern='*.py', eval='expand("<afile>")',
|
|
sync=True)
|
|
def autocmd_handler(self, filename):
|
|
self._increment_calls()
|
|
self.vim.current.line = (
|
|
'Autocmd: Called %s times, file: %s' % (self.calls, filename))
|
|
|
|
@neovim.function('Func')
|
|
def function_handler(self, args):
|
|
self._increment_calls()
|
|
self.vim.current.line = (
|
|
'Function: Called %d times, args: %s' % (self.calls, args))
|
|
|
|
def _increment_calls(self):
|
|
if self.calls == 5:
|
|
raise Exception('Too many calls!')
|
|
self.calls += 1
|
|
<
|
|
|
|
As can be seen, the plugin is implemented using pure python idioms (classes,
|
|
methods, and decorators), the translation between these language-specific
|
|
idioms to vimscript occurs while the plugin manifest is being generated (see
|
|
below).
|
|
|
|
Notice that the exported command and autocmd are defined with the "sync" flag,
|
|
which affects how Nvim calls the plugin: with "sync" the |rpcrequest()|
|
|
function is used, which will block Nvim until the handler function returns a
|
|
value. Without the "sync" flag, the call is made using a fire and forget
|
|
approach with |rpcnotify()| (return values or exceptions raised in the handler
|
|
function are ignored).
|
|
|
|
To test the above plugin, it must be saved in "rplugin/python" in a
|
|
'runtimepath' directory (~/.nvim/rplugin/python/limit.py for example). Then,
|
|
the remote plugin manifest must be generated with `:UpdateRemotePlugins`.
|
|
|
|
==============================================================================
|
|
4. Remote plugin manifest *remote-plugin-manifest*
|
|
|
|
Just installing remote plugins to "rplugin/{host}" isn't enough for them to be
|
|
automatically loaded when required. The `:UpdateRemotePlugins` command must be
|
|
executed every time a remote plugin is installed, updated, or deleted.
|
|
|
|
`:UpdateRemotePlugins` will generate the remote plugin manifest, a special
|
|
vimscript file containing declarations for all vimscript entities
|
|
(commands/autocommands/functions) defined by all remote plugins, with each
|
|
entity associated with the host and plugin path. The manifest can be seen as a
|
|
generated extension to the user's vimrc (it even has the vimrc filename
|
|
prepended).
|
|
|
|
The manifest declarations are nothing but calls to the remote#host#RegisterPlugin
|
|
function, which will take care of bootstrapping the host as soon as the
|
|
declared command, autocommand, or function is used for the first time.
|
|
|
|
The manifest generation step is necessary to keep Nvim's startup fast in
|
|
situations where a user has remote plugins with different hosts. For example,
|
|
say a user has three plugins, for python, java and .NET hosts respectively. If
|
|
we were to load all three plugins at startup, then three language runtimes
|
|
would also be spawned which could take seconds!
|
|
|
|
With the manifest, each host will only be loaded when required. Continuing
|
|
with the example, say the java plugin is a semantic completion engine for java
|
|
source files. If it defines the autocommand "BufEnter *.java", then the java
|
|
host will only be spawned when files ending with ".java" are loaded.
|
|
|
|
If the explicit call to `:UpdateRemotePlugins` seems incovenient, try to see
|
|
it like this: It's a way to give IDE-like capabilities to nvim while still
|
|
keeping it fast and lightweight for general use. It can also be seen as
|
|
analogous to the |:helptags| facility.
|
|
|
|
==============================================================================
|
|
vim:tw=78:ts=8:noet:ft=help:norl:
|