aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/external_plugin.txt104
-rw-r--r--runtime/doc/nvim_clipboard.txt41
-rw-r--r--runtime/doc/nvim_intro.txt2
-rw-r--r--runtime/doc/nvim_provider.txt77
-rw-r--r--runtime/doc/nvim_python.txt7
5 files changed, 195 insertions, 36 deletions
diff --git a/runtime/doc/external_plugin.txt b/runtime/doc/external_plugin.txt
new file mode 100644
index 0000000000..3f7772c906
--- /dev/null
+++ b/runtime/doc/external_plugin.txt
@@ -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:
diff --git a/runtime/doc/nvim_clipboard.txt b/runtime/doc/nvim_clipboard.txt
index 74c9254c70..cf38dea3d6 100644
--- a/runtime/doc/nvim_clipboard.txt
+++ b/runtime/doc/nvim_clipboard.txt
@@ -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|.
-
-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):
-
-- 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
+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.
- class NvimClipboard(object):
- def __init__(self, vim):
- self.provides = ['clipboard']
+To use clipboard on Nvim, make sure you have one of the following programs
+installed and available on $PATH:
- def clipboard_get(self):
- return xerox.paste().split('\n')
+- xclip
+- xsel(newer alternative to xclip)
+- pbcopy/pbpaste(already available on Mac OS X)
- 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:
diff --git a/runtime/doc/nvim_intro.txt b/runtime/doc/nvim_intro.txt
index 7b115b1912..177c906db6 100644
--- a/runtime/doc/nvim_intro.txt
+++ b/runtime/doc/nvim_intro.txt
@@ -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:
diff --git a/runtime/doc/nvim_provider.txt b/runtime/doc/nvim_provider.txt
new file mode 100644
index 0000000000..e67a5c174c
--- /dev/null
+++ b/runtime/doc/nvim_provider.txt
@@ -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:
diff --git a/runtime/doc/nvim_python.txt b/runtime/doc/nvim_python.txt
index 9e6f408657..e60cc93b19 100644
--- a/runtime/doc/nvim_python.txt
+++ b/runtime/doc/nvim_python.txt
@@ -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.
==============================================================================