2014-11-21 06:07:59 -07:00
|
|
|
*remote_plugin.txt* For Nvim. {Nvim}
|
2014-11-17 08:45:52 -07:00
|
|
|
|
|
|
|
|
|
|
|
NVIM REFERENCE MANUAL by Thiago de Arruda
|
|
|
|
|
|
|
|
|
2014-11-21 06:07:59 -07:00
|
|
|
Nvim support for remote plugins *remote-plugin*
|
2014-11-17 08:45:52 -07:00
|
|
|
|
2014-11-21 06:07:59 -07:00
|
|
|
1. Introduction |remote-plugin-intro|
|
|
|
|
2. Plugin hosts |remote-plugin-hosts|
|
|
|
|
3. Example |remote-plugin-example|
|
|
|
|
4. Plugin manifest |remote-plugin-manifest|
|
2014-11-17 08:45:52 -07:00
|
|
|
|
|
|
|
==============================================================================
|
2014-11-21 06:07:59 -07:00
|
|
|
1. Introduction *remote-plugin-intro*
|
2014-11-17 08:45:52 -07:00
|
|
|
|
2014-12-07 02:28:48 -07:00
|
|
|
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
|
2014-11-17 08:45:52 -07:00
|
|
|
|msgpack-rpc|) with the Nvim process.
|
|
|
|
|
2014-12-07 02:28:48 -07:00
|
|
|
Even though these plugins are running in separate processes they can call, be
|
2014-11-17 08:45:52 -07:00
|
|
|
called, and receive events just as if the code was being executed in the main
|
|
|
|
process.
|
|
|
|
|
|
|
|
==============================================================================
|
2014-11-21 06:07:59 -07:00
|
|
|
2. Plugin hosts *remote-plugin-hosts*
|
2014-11-17 08:45:52 -07:00
|
|
|
|
|
|
|
While plugins can be implemented as arbitrary programs that communicate
|
2014-12-07 02:28:48 -07:00
|
|
|
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.
|
2014-11-17 08:45:52 -07:00
|
|
|
|
|
|
|
Plugin hosts are programs that provide a high level environment for plugins,
|
2014-12-07 02:28:48 -07:00
|
|
|
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.
|
2014-11-17 08:45:52 -07:00
|
|
|
|
|
|
|
==============================================================================
|
2014-11-21 06:07:59 -07:00
|
|
|
3. Example *remote-plugin-example*
|
2014-11-17 08:45:52 -07:00
|
|
|
|
2014-11-21 06:07:59 -07:00
|
|
|
The best way to learn about remote plugins is with an example, so let's see
|
2015-02-24 15:31:42 -07:00
|
|
|
what a Python plugin looks like. This plugin exports a command, a function and
|
2014-12-07 02:28:48 -07:00
|
|
|
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:
|
2014-11-17 08:45:52 -07:00
|
|
|
>
|
|
|
|
import neovim
|
|
|
|
|
|
|
|
@neovim.plugin
|
|
|
|
class Limit(object):
|
|
|
|
def __init__(self, vim):
|
|
|
|
self.vim = vim
|
|
|
|
self.calls = 0
|
2014-12-07 02:28:48 -07:00
|
|
|
|
2014-11-17 08:45:52 -07:00
|
|
|
@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))
|
2014-12-07 02:28:48 -07:00
|
|
|
|
2014-11-17 08:45:52 -07:00
|
|
|
@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))
|
2014-12-07 02:28:48 -07:00
|
|
|
|
2014-11-17 08:45:52 -07:00
|
|
|
@neovim.function('Func')
|
|
|
|
def function_handler(self, args):
|
|
|
|
self._increment_calls()
|
|
|
|
self.vim.current.line = (
|
|
|
|
'Function: Called %d times, args: %s' % (self.calls, args))
|
2014-12-07 02:28:48 -07:00
|
|
|
|
2014-11-17 08:45:52 -07:00
|
|
|
def _increment_calls(self):
|
|
|
|
if self.calls == 5:
|
|
|
|
raise Exception('Too many calls!')
|
|
|
|
self.calls += 1
|
|
|
|
<
|
|
|
|
|
2015-02-24 15:31:42 -07:00
|
|
|
As can be seen, the plugin is implemented using pure Python idioms (classes,
|
2014-12-07 02:28:48 -07:00
|
|
|
methods, and decorators), the translation between these language-specific
|
|
|
|
idioms to vimscript occurs while the plugin manifest is being generated (see
|
2014-11-20 04:54:36 -07:00
|
|
|
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
|
2014-12-07 02:28:48 -07:00
|
|
|
approach with |rpcnotify()| (return values or exceptions raised in the handler
|
|
|
|
function are ignored).
|
2014-11-20 04:54:36 -07:00
|
|
|
|
2014-11-21 06:07:59 -07:00
|
|
|
To test the above plugin, it must be saved in "rplugin/python" in a
|
2014-12-07 02:28:48 -07:00
|
|
|
'runtimepath' directory (~/.nvim/rplugin/python/limit.py for example). Then,
|
|
|
|
the remote plugin manifest must be generated with `:UpdateRemotePlugins`.
|
2014-11-20 04:54:36 -07:00
|
|
|
|
|
|
|
==============================================================================
|
2014-12-07 02:28:48 -07:00
|
|
|
4. Remote plugin manifest *remote-plugin-manifest*
|
2014-11-20 04:54:36 -07:00
|
|
|
|
2014-12-07 02:28:48 -07:00
|
|
|
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.
|
2014-11-20 04:54:36 -07:00
|
|
|
|
2014-11-21 06:07:59 -07:00
|
|
|
`:UpdateRemotePlugins` will generate the remote plugin manifest, a special
|
2014-11-20 04:54:36 -07:00
|
|
|
vimscript file containing declarations for all vimscript entities
|
2014-11-21 06:07:59 -07:00
|
|
|
(commands/autocommands/functions) defined by all remote plugins, with each
|
2014-11-20 04:54:36 -07:00
|
|
|
entity associated with the host and plugin path. The manifest can be seen as a
|
2014-12-07 02:28:48 -07:00
|
|
|
generated extension to the user's vimrc (it even has the vimrc filename
|
2014-11-20 04:54:36 -07:00
|
|
|
prepended).
|
|
|
|
|
2014-11-21 06:07:59 -07:00
|
|
|
The manifest declarations are nothing but calls to the remote#host#RegisterPlugin
|
2014-11-20 04:54:36 -07:00
|
|
|
function, which will take care of bootstrapping the host as soon as the
|
2014-12-07 02:28:48 -07:00
|
|
|
declared command, autocommand, or function is used for the first time.
|
2014-11-20 04:54:36 -07:00
|
|
|
|
2014-12-07 02:28:48 -07:00
|
|
|
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,
|
2015-02-24 15:31:42 -07:00
|
|
|
say a user has three plugins, for Python, java and .NET hosts respectively. If
|
2014-12-07 02:28:48 -07:00
|
|
|
we were to load all three plugins at startup, then three language runtimes
|
|
|
|
would also be spawned which could take seconds!
|
2014-11-20 04:54:36 -07:00
|
|
|
|
|
|
|
With the manifest, each host will only be loaded when required. Continuing
|
2014-12-07 02:28:48 -07:00
|
|
|
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.
|
2014-11-17 08:45:52 -07:00
|
|
|
|
|
|
|
==============================================================================
|
|
|
|
vim:tw=78:ts=8:noet:ft=help:norl:
|