aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/autoload/provider/python.vim6
-rw-r--r--runtime/autoload/remote/define.vim (renamed from runtime/autoload/rpc/define.vim)36
-rw-r--r--runtime/autoload/remote/host.vim (renamed from runtime/autoload/rpc/host.vim)47
-rw-r--r--runtime/doc/Makefile4
-rw-r--r--runtime/doc/external_plugin.txt104
-rw-r--r--runtime/doc/msgpack_rpc.txt4
-rw-r--r--runtime/doc/nvim_intro.txt2
-rw-r--r--runtime/doc/remote_plugin.txt136
-rw-r--r--runtime/plugin/external_plugins.vim5
-rw-r--r--runtime/plugin/rplugin.vim5
10 files changed, 194 insertions, 155 deletions
diff --git a/runtime/autoload/provider/python.vim b/runtime/autoload/provider/python.vim
index 9ca81c35f4..53b984dfe2 100644
--- a/runtime/autoload/provider/python.vim
+++ b/runtime/autoload/provider/python.vim
@@ -11,11 +11,11 @@ let s:loaded_python_provider = 1
let s:plugin_path = expand('<sfile>:p:h').'/script_host.py'
" The python provider plugin will run in a separate instance of the python
" host.
-call rpc#host#RegisterClone('legacy-python-provider', 'python')
-call rpc#host#RegisterPlugin('legacy-python-provider', s:plugin_path, [])
+call remote#host#RegisterClone('legacy-python-provider', 'python')
+call remote#host#RegisterPlugin('legacy-python-provider', s:plugin_path, [])
" Ensure that we can load the python host before bootstrapping
try
- let s:host = rpc#host#Require('legacy-python-provider')
+ let s:host = remote#host#Require('legacy-python-provider')
catch
echomsg v:exception
finish
diff --git a/runtime/autoload/rpc/define.vim b/runtime/autoload/remote/define.vim
index e7817c5fac..dd2482998d 100644
--- a/runtime/autoload/rpc/define.vim
+++ b/runtime/autoload/remote/define.vim
@@ -1,4 +1,4 @@
-function! rpc#define#CommandOnHost(host, method, sync, name, opts)
+function! remote#define#CommandOnHost(host, method, sync, name, opts)
let prefix = ''
if has_key(a:opts, 'range')
@@ -28,7 +28,7 @@ function! rpc#define#CommandOnHost(host, method, sync, name, opts)
endif
exe s:GetCommandPrefix(a:name, a:opts)
- \ .' call rpc#define#CommandBootstrap("'.a:host.'"'
+ \ .' call remote#define#CommandBootstrap("'.a:host.'"'
\ . ', "'.a:method.'"'
\ . ', "'.a:sync.'"'
\ . ', "'.a:name.'"'
@@ -38,11 +38,11 @@ function! rpc#define#CommandOnHost(host, method, sync, name, opts)
endfunction
-function! rpc#define#CommandBootstrap(host, method, sync, name, opts, forward)
- let channel = rpc#host#Require(a:host)
+function! remote#define#CommandBootstrap(host, method, sync, name, opts, forward)
+ let channel = remote#host#Require(a:host)
if channel
- call rpc#define#CommandOnChannel(channel, a:method, a:sync, a:name, a:opts)
+ call remote#define#CommandOnChannel(channel, a:method, a:sync, a:name, a:opts)
exe a:forward
else
exe 'delcommand '.a:name
@@ -51,7 +51,7 @@ function! rpc#define#CommandBootstrap(host, method, sync, name, opts, forward)
endfunction
-function! rpc#define#CommandOnChannel(channel, method, sync, name, opts)
+function! remote#define#CommandOnChannel(channel, method, sync, name, opts)
let rpcargs = [a:channel, '"'.a:method.'"']
if has_key(a:opts, 'nargs')
" -nargs, pass arguments in a list
@@ -87,12 +87,12 @@ function! rpc#define#CommandOnChannel(channel, method, sync, name, opts)
endfunction
-function! rpc#define#AutocmdOnHost(host, method, sync, name, opts)
+function! remote#define#AutocmdOnHost(host, method, sync, name, opts)
let group = s:GetNextAutocmdGroup()
let forward = '"doau '.group.' '.a:name.' ".'.'expand("<amatch>")'
let a:opts.group = group
let bootstrap_def = s:GetAutocmdPrefix(a:name, a:opts)
- \ .' call rpc#define#AutocmdBootstrap("'.a:host.'"'
+ \ .' call remote#define#AutocmdBootstrap("'.a:host.'"'
\ . ', "'.a:method.'"'
\ . ', "'.a:sync.'"'
\ . ', "'.a:name.'"'
@@ -103,12 +103,12 @@ function! rpc#define#AutocmdOnHost(host, method, sync, name, opts)
endfunction
-function! rpc#define#AutocmdBootstrap(host, method, sync, name, opts, forward)
- let channel = rpc#host#Require(a:host)
+function! remote#define#AutocmdBootstrap(host, method, sync, name, opts, forward)
+ let channel = remote#host#Require(a:host)
exe 'autocmd! '.a:opts.group
if channel
- call rpc#define#AutocmdOnChannel(channel, a:method, a:sync, a:name,
+ call remote#define#AutocmdOnChannel(channel, a:method, a:sync, a:name,
\ a:opts)
exe eval(a:forward)
else
@@ -118,7 +118,7 @@ function! rpc#define#AutocmdBootstrap(host, method, sync, name, opts, forward)
endfunction
-function! rpc#define#AutocmdOnChannel(channel, method, sync, name, opts)
+function! remote#define#AutocmdOnChannel(channel, method, sync, name, opts)
let rpcargs = [a:channel, '"'.a:method.'"']
call s:AddEval(rpcargs, a:opts)
@@ -128,10 +128,10 @@ function! rpc#define#AutocmdOnChannel(channel, method, sync, name, opts)
endfunction
-function! rpc#define#FunctionOnHost(host, method, sync, name, opts)
+function! remote#define#FunctionOnHost(host, method, sync, name, opts)
let group = s:GetNextAutocmdGroup()
exe 'autocmd! '.group.' FuncUndefined '.a:name
- \ .' call rpc#define#FunctionBootstrap("'.a:host.'"'
+ \ .' call remote#define#FunctionBootstrap("'.a:host.'"'
\ . ', "'.a:method.'"'
\ . ', "'.a:sync.'"'
\ . ', "'.a:name.'"'
@@ -141,13 +141,13 @@ function! rpc#define#FunctionOnHost(host, method, sync, name, opts)
endfunction
-function! rpc#define#FunctionBootstrap(host, method, sync, name, opts, group)
- let channel = rpc#host#Require(a:host)
+function! remote#define#FunctionBootstrap(host, method, sync, name, opts, group)
+ let channel = remote#host#Require(a:host)
exe 'autocmd! '.a:group
exe 'augroup! '.a:group
if channel
- call rpc#define#FunctionOnChannel(channel, a:method, a:sync, a:name,
+ call remote#define#FunctionOnChannel(channel, a:method, a:sync, a:name,
\ a:opts)
else
echoerr 'Host "'a:host.'" for "'.a:name.'" function is not available'
@@ -155,7 +155,7 @@ function! rpc#define#FunctionBootstrap(host, method, sync, name, opts, group)
endfunction
-function! rpc#define#FunctionOnChannel(channel, method, sync, name, opts)
+function! remote#define#FunctionOnChannel(channel, method, sync, name, opts)
let rpcargs = [a:channel, '"'.a:method.'"', 'a:000']
call s:AddEval(rpcargs, a:opts)
diff --git a/runtime/autoload/rpc/host.vim b/runtime/autoload/remote/host.vim
index 177d816df0..54a8bb3c41 100644
--- a/runtime/autoload/rpc/host.vim
+++ b/runtime/autoload/remote/host.vim
@@ -2,11 +2,12 @@ let s:hosts = {}
let s:plugin_patterns = {
\ 'python': '*.py'
\ }
-let s:external_plugins = fnamemodify($MYVIMRC, ':p:h').'/.external_plugins~'
+let s:remote_plugins_manifest = fnamemodify($MYVIMRC, ':p:h')
+ \.'/.'.fnamemodify($MYVIMRC, ':t').'-rplugin~'
" Register a host by associating it with a factory(funcref)
-function! rpc#host#Register(name, factory)
+function! remote#host#Register(name, factory)
let s:hosts[a:name] = {'factory': a:factory, 'channel': 0, 'initialized': 0}
if type(a:factory) == type(1) && a:factory
" Passed a channel directly
@@ -19,7 +20,7 @@ endfunction
" as `source`, but it will run as a different process. This can be used by
" plugins that should run isolated from other plugins created for the same host
" type
-function! rpc#host#RegisterClone(name, orig_name)
+function! remote#host#RegisterClone(name, orig_name)
if !has_key(s:hosts, a:orig_name)
throw 'No host named "'.a:orig_name.'" is registered'
endif
@@ -29,7 +30,7 @@ endfunction
" Get a host channel, bootstrapping it if necessary
-function! rpc#host#Require(name)
+function! remote#host#Require(name)
if !has_key(s:hosts, a:name)
throw 'No host named "'.a:name.'" is registered'
endif
@@ -42,7 +43,7 @@ function! rpc#host#Require(name)
endfunction
-function! rpc#host#IsRunning(name)
+function! remote#host#IsRunning(name)
if !has_key(s:hosts, a:name)
throw 'No host named "'.a:name.'" is registered'
endif
@@ -54,7 +55,7 @@ endfunction
" autocmd(async) and one function(sync):
"
" let s:plugin_path = expand('<sfile>:p:h').'/nvim_plugin.py'
-" call rpc#host#RegisterPlugin('python', s:plugin_path, [
+" call remote#host#RegisterPlugin('python', s:plugin_path, [
" \ {'type': 'command', 'name': 'PyCmd', 'sync': 1, 'opts': {}},
" \ {'type': 'command', 'name': 'PyAsyncCmd', 'sync': 0, 'opts': {'eval': 'cursor()'}},
" \ {'type': 'autocmd', 'name': 'BufEnter', 'sync': 0, 'opts': {'eval': 'expand("<afile>")'}},
@@ -63,7 +64,7 @@ endfunction
"
" The third item in a declaration is a boolean: non zero means the command,
" autocommand or function will be executed synchronously with rpcrequest.
-function! rpc#host#RegisterPlugin(host, path, specs)
+function! remote#host#RegisterPlugin(host, path, specs)
let plugins = s:PluginsForHost(a:host)
for plugin in plugins
@@ -72,7 +73,7 @@ function! rpc#host#RegisterPlugin(host, path, specs)
endif
endfor
- if rpc#host#IsRunning(a:host)
+ if remote#host#IsRunning(a:host)
" For now we won't allow registration of plugins when the host is already
" running.
throw 'Host "'.a:host.'" is already running'
@@ -86,7 +87,7 @@ function! rpc#host#RegisterPlugin(host, path, specs)
let rpc_method = a:path
if type == 'command'
let rpc_method .= ':command:'.name
- call rpc#define#CommandOnHost(a:host, rpc_method, sync, name, opts)
+ call remote#define#CommandOnHost(a:host, rpc_method, sync, name, opts)
elseif type == 'autocmd'
" Since multiple handlers can be attached to the same autocmd event by a
" single plugin, we need a way to uniquely identify the rpc method to
@@ -94,10 +95,10 @@ function! rpc#host#RegisterPlugin(host, path, specs)
" name(This still has a limit: one handler per event/pattern combo, but
" there's no need to allow plugins define multiple handlers in that case)
let rpc_method .= ':autocmd:'.name.':'.get(opts, 'pattern', '*')
- call rpc#define#AutocmdOnHost(a:host, rpc_method, sync, name, opts)
+ call remote#define#AutocmdOnHost(a:host, rpc_method, sync, name, opts)
elseif type == 'function'
let rpc_method .= ':function:'.name
- call rpc#define#FunctionOnHost(a:host, rpc_method, sync, name, opts)
+ call remote#define#FunctionOnHost(a:host, rpc_method, sync, name, opts)
else
echoerr 'Invalid declaration type: '.type
endif
@@ -107,9 +108,9 @@ function! rpc#host#RegisterPlugin(host, path, specs)
endfunction
-function! rpc#host#LoadExternalPlugins()
- if filereadable(s:external_plugins)
- exe 'source '.s:external_plugins
+function! remote#host#LoadRemotePlugins()
+ if filereadable(s:remote_plugins_manifest)
+ exe 'source '.s:remote_plugins_manifest
endif
endfunction
@@ -117,17 +118,17 @@ endfunction
function! s:RegistrationCommands(host)
" Register a temporary host clone for discovering specs
let host_id = a:host.'-registration-clone'
- call rpc#host#RegisterClone(host_id, a:host)
+ call remote#host#RegisterClone(host_id, a:host)
let pattern = s:plugin_patterns[a:host]
- let paths = globpath(&rtp, 'plugin/external/'.a:host.'/'.pattern, 0, 1)
+ let paths = globpath(&rtp, 'rplugin/'.a:host.'/'.pattern, 0, 1)
for path in paths
- call rpc#host#RegisterPlugin(host_id, path, [])
+ call remote#host#RegisterPlugin(host_id, path, [])
endfor
- let channel = rpc#host#Require(host_id)
+ let channel = remote#host#Require(host_id)
let lines = []
for path in paths
let specs = rpcrequest(channel, 'specs', path)
- call add(lines, "call rpc#host#RegisterPlugin('".a:host
+ call add(lines, "call remote#host#RegisterPlugin('".a:host
\ ."', '".path."', [")
for spec in specs
call add(lines, " \\ ".string(spec).",")
@@ -142,7 +143,7 @@ function! s:RegistrationCommands(host)
endfunction
-function! s:UpdateExternalPlugins()
+function! s:UpdateRemotePlugins()
let commands = []
let hosts = keys(s:hosts)
for host in hosts
@@ -153,11 +154,11 @@ function! s:UpdateExternalPlugins()
\ + ['', '']
endif
endfor
- call writefile(commands, s:external_plugins)
+ call writefile(commands, s:remote_plugins_manifest)
endfunction
-command! UpdateExternalPlugins call s:UpdateExternalPlugins()
+command! UpdateRemotePlugins call s:UpdateRemotePlugins()
let s:plugins_for_host = {}
@@ -238,5 +239,5 @@ function! s:RequirePythonHost(name)
throw 'Failed to load python host'
endfunction
-call rpc#host#Register('python', function('s:RequirePythonHost'))
+call remote#host#Register('python', function('s:RequirePythonHost'))
" }}}
diff --git a/runtime/doc/Makefile b/runtime/doc/Makefile
index 48674a773f..82fd921038 100644
--- a/runtime/doc/Makefile
+++ b/runtime/doc/Makefile
@@ -21,6 +21,7 @@ DOCS = \
digraph.txt \
editing.txt \
eval.txt \
+ remote_plugin.txt \
farsi.txt \
filetype.txt \
fold.txt \
@@ -53,6 +54,7 @@ DOCS = \
msgpack_rpc.txt \
nvim_clipboard.txt \
nvim_intro.txt \
+ nvim_provider.txt \
nvim_python.txt \
options.txt \
os_dos.txt \
@@ -140,6 +142,7 @@ HTMLS = \
digraph.html \
editing.html \
eval.html \
+ remote_plugin.html \
farsi.html \
filetype.html \
fold.html \
@@ -171,6 +174,7 @@ HTMLS = \
msgpack_rpc.html \
nvim_clipboard.html \
nvim_intro.html \
+ nvim_provider.html \
nvim_python.html \
options.html \
os_dos.html \
diff --git a/runtime/doc/external_plugin.txt b/runtime/doc/external_plugin.txt
deleted file mode 100644
index 3f7772c906..0000000000
--- a/runtime/doc/external_plugin.txt
+++ /dev/null
@@ -1,104 +0,0 @@
-*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/msgpack_rpc.txt b/runtime/doc/msgpack_rpc.txt
index 41f387b452..8e53241775 100644
--- a/runtime/doc/msgpack_rpc.txt
+++ b/runtime/doc/msgpack_rpc.txt
@@ -113,7 +113,9 @@ string 'hello world!' on the current nvim instance:
A better way is to use the python REPL with the `neovim` package, where API
functions can be called interactively:
>
- >>> import neovim; nvim = neovim.connect('[address]')
+ >>> from neovim import socket_session, Nvim
+ >>> session = socket_session('[address]')
+ >>> nvim = Nvim.from_session(session)
>>> nvim.command('echo "hello world!"')
<
==============================================================================
diff --git a/runtime/doc/nvim_intro.txt b/runtime/doc/nvim_intro.txt
index 177c906db6..8a82a09890 100644
--- a/runtime/doc/nvim_intro.txt
+++ b/runtime/doc/nvim_intro.txt
@@ -17,7 +17,7 @@ differentiate Nvim from Vim:
2. Job control |job-control|
3. Python plugins |nvim-python|
4. Clipboard integration |nvim-clipboard|
-5. External plugins |external-plugin|
+5. Remote plugins |remote-plugin|
6. Provider infrastructure |nvim-provider|
==============================================================================
diff --git a/runtime/doc/remote_plugin.txt b/runtime/doc/remote_plugin.txt
new file mode 100644
index 0000000000..ca7e763d1b
--- /dev/null
+++ b/runtime/doc/remote_plugin.txt
@@ -0,0 +1,136 @@
+*remote_plugin.txt* For Nvim. {Nvim}
+
+
+ NVIM REFERENCE MANUAL by Thiago de Arruda
+
+
+Nvim support for remote plugins *remote-plugin*
+
+1. Introduction |remote-plugin-intro|
+2. Plugin hosts |remote-plugin-hosts|
+3. Example |remote-plugin-example|
+4. Plugin manifest |remote-plugin-manifest|
+
+==============================================================================
+1. Introduction *remote-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
+remote 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 *remote-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 its registered plugins are required, keeping
+Nvim startup as fast a possible despite the number of installed plugins/hosts.
+
+==============================================================================
+3. Example *remote-plugin-example*
+
+The best way to learn about remote plugins is with an example, so let's see
+how a very useless python plugin looks like. This plugin exports a command, a
+function and 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:
+>
+ 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
+<
+
+As can be seen, the plugin is implemented using pure python idioms(classes,
+methods and decorators), the translation between these language-specific
+idioms to vimscript occurs while the plugin manifest is being generated(see
+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
+approach with |rpcnotify()|(return values or exceptions raised in the handler
+function are ignored)
+
+To test the above plugin, it must be saved in "rplugin/python" in a
+'runtimepath' directory(~/.nvim/rplugin/python/limit.py for example).
+Then, the remote plugin manifest must be generated with
+`:UpdateRemotePlugins`.
+
+==============================================================================
+4. remote plugin manifest *remote-plugin-manifest*
+
+Just installing remote plugins to "rplugin/{host}" isn't enough to
+load them at startup. The `:UpdateRemotePlugins` command must be executed
+every time a remote plugin is installed, updated, or deleted.
+
+`:UpdateRemotePlugins` will generate the remote plugin manifest, a special
+vimscript file containing declarations for all vimscript entities
+(commands/autocommands/functions) defined by all remote plugins, with each
+entity associated with the host and plugin path. The manifest can be seen as a
+generated extension to the user's vimrc(it even has the vimrc filename
+prepended).
+
+The manifest declarations are nothing but calls to the remote#host#RegisterPlugin
+function, which will take care of bootstrapping the host as soon as the
+declared command, autocommand or function is used for the first time.
+
+The manifest generation step is necessary to keep editor startup fast in
+situations where a user has remote plugins with different hosts. For
+example, imagine a user that has three plugins, for python, java and .NET
+hosts respectively, if we were to load all three plugins at startup, then
+three language runtimes would also be spawned which could take seconds!
+
+With the manifest, each host will only be loaded when required. Continuing
+with the example, imagine the java plugin is a semantic completion engine for
+java files, if it defines an BufEnter *.java autocommand then the java host
+will only be spawned when java source files are loaded.
+
+If the explicit call to `:UpdateRemotePlugins` seems incovenient, try
+to see it like this: Its a way to give IDE-like capabilities to nvim while
+still keeping it a fast/lightweight editor for general use. It can also be
+seen as an analogous to the |:helptags| facility.
+
+==============================================================================
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/plugin/external_plugins.vim b/runtime/plugin/external_plugins.vim
deleted file mode 100644
index 1c5fa1ab8e..0000000000
--- a/runtime/plugin/external_plugins.vim
+++ /dev/null
@@ -1,5 +0,0 @@
-if exists('loaded_external_plugins') || &cp
- finish
-endif
-let loaded_external_plugins = 1
-call rpc#host#LoadExternalPlugins()
diff --git a/runtime/plugin/rplugin.vim b/runtime/plugin/rplugin.vim
new file mode 100644
index 0000000000..2b2d333738
--- /dev/null
+++ b/runtime/plugin/rplugin.vim
@@ -0,0 +1,5 @@
+if exists('loaded_remote_plugins') || &cp
+ finish
+endif
+let loaded_remote_plugins = 1
+call remote#host#LoadRemotePlugins()