docs: Update to the latest changes in the plugin infrastructure

This commit is contained in:
Thiago de Arruda 2014-11-17 12:45:52 -03:00
parent f291f41525
commit d971cb1691
5 changed files with 195 additions and 36 deletions

View File

@ -0,0 +1,104 @@
*external_plugin.txt* For Nvim. {Nvim}
NVIM REFERENCE MANUAL by Thiago de Arruda
Nvim support for external plugins *external-plugin*
1. Introduction |external-plugin-intro|
2. Plugin Hosts |external-plugin-hosts|
3. Example |external-plugin-example|
==============================================================================
1. Introduction *external-plugin-intro*
A big Nvim goal is to allow extensibility in arbitrary programming languages
without requiring direct support from the editor. This is achieved with
external 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 *external-plugin-hosts*
While plugins can be implemented as arbitrary programs that communicate
directly with 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 favorite
programming language.
Plugin hosts are programs that provide a high level environment for plugins,
and also take care of most boilerplate involved in defining commands, autocmds
and functions that are implemented over msgpack-rpc connections. They are
loaded the first time one of it's registered plugins are required, keeping
Nvim startup as fast a possible despite the number of installed plugins/hosts.
==============================================================================
3. Example *external-plugin-example*
The best way to learn how to create external plugins is with an example, so
let's see how to implement a very useless python plugin that exports a
command, a function and an autocmd(requires configuration detailed in
|nvim-python| to work).
The plugin is called 'Limit', and all it does is limit the number of "calls"
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
<
This code needs to be saved to "external/python/limit.py" in a runtime
directory(~/.nvim/plugin/external/python/limit.py for example).
As can be seen, the plugin is implemented using pure python idioms(classes,
methods and decorators). It is the host's responsibility to translate
language-specific idioms to vimscript entities. Notice that the exported
command and autocmd are defined with the "sync" flag, which tells Nvim to call
it using |rpcrequest()|. Since the "Func" doesn't set "sync", it will be
called using |rpcnotify()|.
Just installing the plugin to ~/.nvim/plugin/external/python/limit.py won't
make Nvim load it at startup. That is because external plugins are loaded
only when required, and for that Nvim must be fed with information about
installed external plugins with the `:UpdateExternalPlugins` command(must be
called whenever plugins are updated, this is analogous to the |:helptags|
command but for external plugins).
==============================================================================
vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -6,42 +6,25 @@
Clipboard integration for Nvim *nvim-clipboard*
By default, Nvim has no connection to the system clipboard. Eventually that
will be implemented by UI programs, which connect to Nvim via |msgpack-rpc|.
Nvim has no connection to the system clipboard, instead it is accessible
through the |nvim-provider| infrastructure which transparently uses shell
commands for communicating with the clipboard.
Even though externalized UIs are not available yet, there's a workaround that
enables clipboard usage through the python interface(which also uses
|msgpack-rpc| and consequently can implement the clipboard methods required
by Nvim):
To use clipboard on Nvim, make sure you have one of the following programs
installed and available on $PATH:
- Make sure you follow the setup instructions in |nvim-python-quickstart|.
- Install the `xerox` python module:
>
$ pip install xerox
<
- Create a ~/.nvim/pythonx/nvim_clipboard.py file with the following contents:
>
import xerox
- xclip
- xsel(newer alternative to xclip)
- pbcopy/pbpaste(already available on Mac OS X)
class NvimClipboard(object):
def __init__(self, vim):
self.provides = ['clipboard']
def clipboard_get(self):
return xerox.paste().split('\n')
def clipboard_set(self, lines):
xerox.copy(u'\n'.join([line.decode('utf-8') for line in lines]))
<
This should enable the '+' and '*' registers. As an optional step, set the
'unnamedclip' option to transparently access clipboard using the unnamed
register. If you use the same |vimrc| for both Vim and Nvim, make sure you
only set the option when `has('nvim')` is true:
Having any of these programs should enable the '+' and '*' registers. As an
optional step, set the 'unnamedclip' option to transparently access clipboard
using the unnamed register. If you use the same |vimrc| for both Vim and Nvim,
make sure you only set the option when `has('nvim')` is true:
>
if has('nvim')
set unnamedclip
endif
<
==============================================================================
vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -17,6 +17,8 @@ differentiate Nvim from Vim:
2. Job control |job-control|
3. Python plugins |nvim-python|
4. Clipboard integration |nvim-clipboard|
5. External plugins |external-plugin|
6. Provider infrastructure |nvim-provider|
==============================================================================
vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -0,0 +1,77 @@
*nvim_provider.txt* For Nvim. {Nvim}
NVIM REFERENCE MANUAL by Thiago de Arruda
Nvim provider infrastructure *nvim-provider*
First of all, this document is meant to be read by developers interested in
contributing to the refactoring effort. If you are a normal user or plugin
developer looking to learn about Nvim |msgpack-rpc| infrastructure for
implementing plugins in other programming languages, see |external-plugin|.
For instructions on how to enable python plugins, see |nvim-python|. For
clipboard, see |nvim-clipboard|.
Instead of doing everything by itself, Nvim aims to simplify it's own
maintenance by delegating as much work as possible to external systems. But
some Vim components are too tightly coupled and in some cases the refactoring
work necessary to swap in-house implementations by code that integrates to
other systems is too great. Nvim provider infrastructure is a facility that
aims to make this task simpler.
To understand why the provider infrastructure is useful, let us consider two
examples of integration with external systems that are implemented in Vim and
are now decoupled from Nvim core as providers:
The first example is clipboard integration: On the original Vim source code,
clipboard functions account for more than 1k lines of C source code(and that
is just on ui.c). All to peform two tasks that are now accomplished with
simple shell commands such as xclip or pbcopy/pbpaste.
The other example is python scripting support: Vim has three files dedicated
to embed 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. On Nvim, python
scripting is performed by an external host process that is running 2k sloc
python program.
In a perfect world, we would implement python and clipboard integration in
pure vimscript and without touching the C code. Unfortunately we can't achieve
these goals without severly compromising backwards compatibility with Vim.
Thats where providers comes to rescue.
In essence, this infrastructure a simple framework that simplifies the task of
calling vimscript from C code, making it simpler to rewrite C functions that
interact with external systems in pure vimscript. It is composed of two
functions in eval.c:
- eval_call_provider(name, method, arguments): Call a provider(name) method
with arguments
- eval_has_provider(name): Checks if a provider is implemented
What these functions do is simple:
- eval_call_provider will call the provider#(name)#Call function passing in
the method and arguments.
- eval_has_provider will return true if the provider#(name)#Call function is
implemented, and is called by the "has" vimscript function to check if
features are available.
The basic idea is that the provider#(name)#Call function should implement
integration with an external system, because calling shell commands and
|msgpack-rpc| clients(Nvim only) is easier to do in vimscript.
Now, back to the python example. Instead of modifying vimscript to allow the
definition of lowercase functions and commands(for the |:python|, |:pyfile|
and |:pydo| commands, and the |pyeval()| function), which would break
backwards compatibility with Vim, we implemented the
autoload/provider/python.vim script and the provider#python#Call function
that is only defined if an external python host is started successfully.
That works well with the has('python') expression (normally used by python
plugins) because if the python host isn't installed then the plugin will
"think" it is running in a Vim compiled without +python feature.
==============================================================================
vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -27,13 +27,6 @@ simple step-by-step:
>
$ pip install neovim
<
- Add the following snippet to your `vimrc`, before any python plugins are
loaded:
>
if has('nvim')
runtime! python_setup.vim
endif
<
Most python plugins created for Vim 7.3 should work after these steps.
==============================================================================