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
|
2015-06-22 19:51:15 -07:00
|
|
|
to extend Nvim without changes to Nvim itself. This is achieved with remote
|
2016-06-14 22:59:28 -07:00
|
|
|
plugins, coprocesses that have a direct communication channel (via |RPC|) with
|
2016-06-12 23:11:12 -07:00
|
|
|
the Nvim process.
|
2014-11-17 08:45:52 -07:00
|
|
|
|
2015-06-22 19:51:15 -07:00
|
|
|
Even though these plugins run in separate processes they can call, be called,
|
|
|
|
and receive events just as if the plugin's code were executed in the main
|
2014-11-17 08:45:52 -07:00
|
|
|
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
|
2015-06-22 19:51:15 -07:00
|
|
|
|rpcnotify()|, that is not the best approach. Instead, developers should first
|
|
|
|
check whether a plugin host is available for their chosen programming language.
|
2014-11-17 08:45:52 -07:00
|
|
|
|
2015-06-22 19:51:15 -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
|
2016-06-14 22:59:28 -07:00
|
|
|
functions that are implemented over |RPC| connections. Hosts are loaded only
|
2016-06-12 23:11:12 -07:00
|
|
|
when one of their registered plugins require it, keeping Nvim's startup as
|
|
|
|
fast as possible, even 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-06-22 19:51:15 -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-06-24 17:22:56 -07:00
|
|
|
As can be seen, the plugin is implemented using idiomatic Python (classes,
|
2015-06-22 19:51:15 -07:00
|
|
|
methods, and decorators). The translation between these language-specific
|
|
|
|
idioms to Vimscript occurs while the plugin manifest is being generated (see
|
|
|
|
the next section).
|
2014-11-20 04:54:36 -07:00
|
|
|
|
|
|
|
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
|
2015-06-22 19:51:15 -07:00
|
|
|
approach with |rpcnotify()|, meaning 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
|
2016-07-11 23:17:58 -07:00
|
|
|
'runtimepath' directory (~/.config/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*
|
2016-07-11 23:17:58 -07:00
|
|
|
*:UpdateRemotePlugins*
|
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
|
2016-07-11 23:17:58 -07:00
|
|
|
automatically loaded when required. You must execute |:UpdateRemotePlugins|
|
2015-06-22 19:51:15 -07:00
|
|
|
every time a remote plugin is installed, updated, or deleted.
|
2014-11-20 04:54:36 -07:00
|
|
|
|
2016-07-11 23:17:58 -07:00
|
|
|
|:UpdateRemotePlugins| generates the remote plugin manifest, a special
|
2015-06-22 19:51:15 -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
|
2016-07-11 23:17:58 -07:00
|
|
|
entity associated with the host and plugin path.
|
2014-11-20 04:54:36 -07:00
|
|
|
|
2015-06-22 19:51:15 -07:00
|
|
|
Manifest declarations are just calls to the `remote#host#RegisterPlugin`
|
|
|
|
function, which takes care of bootstrapping the host as soon as the 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-06-22 19:51:15 -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
|
2015-06-22 19:51:15 -07:00
|
|
|
would also be spawned, which could take seconds!
|
2014-11-20 04:54:36 -07:00
|
|
|
|
2015-06-22 19:51:15 -07:00
|
|
|
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 code.
|
|
|
|
If it defines the autocommand "BufEnter *.java", then the Java host is spawned
|
|
|
|
only when Nvim loads a buffer matching "*.java".
|
2014-12-07 02:28:48 -07:00
|
|
|
|
2016-07-11 23:17:58 -07:00
|
|
|
If the explicit call to |:UpdateRemotePlugins| seems incovenient, try to see it
|
2015-06-22 19:51:15 -07:00
|
|
|
like this: It's a way to provide IDE capabilities in Nvim while still keeping
|
|
|
|
it fast and lightweight for general use. It's also analogous to the |:helptags|
|
|
|
|
command.
|
2014-11-17 08:45:52 -07:00
|
|
|
|
2016-07-11 23:17:58 -07:00
|
|
|
Unless a path is set in the `$NVIM_RPLUGIN_MANIFEST` environment variable, the
|
|
|
|
manifest will be written to a file named `rplugin.vim` in one of the following
|
|
|
|
directories:
|
|
|
|
|
|
|
|
Unix ~
|
|
|
|
$XDG_DATA_HOME/nvim/ or ~/.local/share/nvim/
|
|
|
|
|
|
|
|
Windows ~
|
|
|
|
$LOCALAPPDATA/nvim/ or ~/AppData/Local/nvim/
|
|
|
|
|
2014-11-17 08:45:52 -07:00
|
|
|
==============================================================================
|
|
|
|
vim:tw=78:ts=8:noet:ft=help:norl:
|