mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
docs: Update to the latest changes in the plugin infrastructure
This commit is contained in:
parent
f291f41525
commit
d971cb1691
104
runtime/doc/external_plugin.txt
Normal file
104
runtime/doc/external_plugin.txt
Normal 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:
|
@ -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:
|
||||
|
@ -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:
|
||||
|
77
runtime/doc/nvim_provider.txt
Normal file
77
runtime/doc/nvim_provider.txt
Normal 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:
|
@ -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.
|
||||
|
||||
==============================================================================
|
||||
|
Loading…
Reference in New Issue
Block a user