runtime: Refer to plugins running outside Nvim as "remote plugins"

- Rename autoload/rpc to autoload/remote
- External plugins are now remote plugins
- External plugins directory is "rplugin"
This commit is contained in:
Thiago de Arruda 2014-11-21 10:07:59 -03:00
parent 9a774e726c
commit 6b17082d3c
9 changed files with 90 additions and 90 deletions

View File

@ -11,11 +11,11 @@ let s:loaded_python_provider = 1
let s:plugin_path = expand('<sfile>:p:h').'/script_host.py' let s:plugin_path = expand('<sfile>:p:h').'/script_host.py'
" The python provider plugin will run in a separate instance of the python " The python provider plugin will run in a separate instance of the python
" host. " host.
call rpc#host#RegisterClone('legacy-python-provider', 'python') call remote#host#RegisterClone('legacy-python-provider', 'python')
call rpc#host#RegisterPlugin('legacy-python-provider', s:plugin_path, []) call remote#host#RegisterPlugin('legacy-python-provider', s:plugin_path, [])
" Ensure that we can load the python host before bootstrapping " Ensure that we can load the python host before bootstrapping
try try
let s:host = rpc#host#Require('legacy-python-provider') let s:host = remote#host#Require('legacy-python-provider')
catch catch
echomsg v:exception echomsg v:exception
finish finish

View File

@ -1,4 +1,4 @@
function! rpc#define#CommandOnHost(host, method, sync, name, opts) function! remote#define#CommandOnHost(host, method, sync, name, opts)
let prefix = '' let prefix = ''
if has_key(a:opts, 'range') if has_key(a:opts, 'range')
@ -28,7 +28,7 @@ function! rpc#define#CommandOnHost(host, method, sync, name, opts)
endif endif
exe s:GetCommandPrefix(a:name, a:opts) exe s:GetCommandPrefix(a:name, a:opts)
\ .' call rpc#define#CommandBootstrap("'.a:host.'"' \ .' call remote#define#CommandBootstrap("'.a:host.'"'
\ . ', "'.a:method.'"' \ . ', "'.a:method.'"'
\ . ', "'.a:sync.'"' \ . ', "'.a:sync.'"'
\ . ', "'.a:name.'"' \ . ', "'.a:name.'"'
@ -38,11 +38,11 @@ function! rpc#define#CommandOnHost(host, method, sync, name, opts)
endfunction endfunction
function! rpc#define#CommandBootstrap(host, method, sync, name, opts, forward) function! remote#define#CommandBootstrap(host, method, sync, name, opts, forward)
let channel = rpc#host#Require(a:host) let channel = remote#host#Require(a:host)
if channel 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 exe a:forward
else else
exe 'delcommand '.a:name exe 'delcommand '.a:name
@ -51,7 +51,7 @@ function! rpc#define#CommandBootstrap(host, method, sync, name, opts, forward)
endfunction 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.'"'] let rpcargs = [a:channel, '"'.a:method.'"']
if has_key(a:opts, 'nargs') if has_key(a:opts, 'nargs')
" -nargs, pass arguments in a list " -nargs, pass arguments in a list
@ -87,12 +87,12 @@ function! rpc#define#CommandOnChannel(channel, method, sync, name, opts)
endfunction endfunction
function! rpc#define#AutocmdOnHost(host, method, sync, name, opts) function! remote#define#AutocmdOnHost(host, method, sync, name, opts)
let group = s:GetNextAutocmdGroup() let group = s:GetNextAutocmdGroup()
let forward = '"doau '.group.' '.a:name.' ".'.'expand("<amatch>")' let forward = '"doau '.group.' '.a:name.' ".'.'expand("<amatch>")'
let a:opts.group = group let a:opts.group = group
let bootstrap_def = s:GetAutocmdPrefix(a:name, a:opts) let bootstrap_def = s:GetAutocmdPrefix(a:name, a:opts)
\ .' call rpc#define#AutocmdBootstrap("'.a:host.'"' \ .' call remote#define#AutocmdBootstrap("'.a:host.'"'
\ . ', "'.a:method.'"' \ . ', "'.a:method.'"'
\ . ', "'.a:sync.'"' \ . ', "'.a:sync.'"'
\ . ', "'.a:name.'"' \ . ', "'.a:name.'"'
@ -103,12 +103,12 @@ function! rpc#define#AutocmdOnHost(host, method, sync, name, opts)
endfunction endfunction
function! rpc#define#AutocmdBootstrap(host, method, sync, name, opts, forward) function! remote#define#AutocmdBootstrap(host, method, sync, name, opts, forward)
let channel = rpc#host#Require(a:host) let channel = remote#host#Require(a:host)
exe 'autocmd! '.a:opts.group exe 'autocmd! '.a:opts.group
if channel 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) \ a:opts)
exe eval(a:forward) exe eval(a:forward)
else else
@ -118,7 +118,7 @@ function! rpc#define#AutocmdBootstrap(host, method, sync, name, opts, forward)
endfunction 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.'"'] let rpcargs = [a:channel, '"'.a:method.'"']
call s:AddEval(rpcargs, a:opts) call s:AddEval(rpcargs, a:opts)
@ -128,10 +128,10 @@ function! rpc#define#AutocmdOnChannel(channel, method, sync, name, opts)
endfunction endfunction
function! rpc#define#FunctionOnHost(host, method, sync, name, opts) function! remote#define#FunctionOnHost(host, method, sync, name, opts)
let group = s:GetNextAutocmdGroup() let group = s:GetNextAutocmdGroup()
exe 'autocmd! '.group.' FuncUndefined '.a:name exe 'autocmd! '.group.' FuncUndefined '.a:name
\ .' call rpc#define#FunctionBootstrap("'.a:host.'"' \ .' call remote#define#FunctionBootstrap("'.a:host.'"'
\ . ', "'.a:method.'"' \ . ', "'.a:method.'"'
\ . ', "'.a:sync.'"' \ . ', "'.a:sync.'"'
\ . ', "'.a:name.'"' \ . ', "'.a:name.'"'
@ -141,13 +141,13 @@ function! rpc#define#FunctionOnHost(host, method, sync, name, opts)
endfunction endfunction
function! rpc#define#FunctionBootstrap(host, method, sync, name, opts, group) function! remote#define#FunctionBootstrap(host, method, sync, name, opts, group)
let channel = rpc#host#Require(a:host) let channel = remote#host#Require(a:host)
exe 'autocmd! '.a:group exe 'autocmd! '.a:group
exe 'augroup! '.a:group exe 'augroup! '.a:group
if channel 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) \ a:opts)
else else
echoerr 'Host "'a:host.'" for "'.a:name.'" function is not available' 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 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'] let rpcargs = [a:channel, '"'.a:method.'"', 'a:000']
call s:AddEval(rpcargs, a:opts) call s:AddEval(rpcargs, a:opts)

View File

@ -2,12 +2,12 @@ let s:hosts = {}
let s:plugin_patterns = { let s:plugin_patterns = {
\ 'python': '*.py' \ 'python': '*.py'
\ } \ }
let s:external_plugins = fnamemodify($MYVIMRC, ':p:h') let s:remote_plugins_manifest = fnamemodify($MYVIMRC, ':p:h')
\.'/.'.fnamemodify($MYVIMRC, ':t').'-external-plugins~' \.'/.'.fnamemodify($MYVIMRC, ':t').'-rplugin~'
" Register a host by associating it with a factory(funcref) " 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} let s:hosts[a:name] = {'factory': a:factory, 'channel': 0, 'initialized': 0}
if type(a:factory) == type(1) && a:factory if type(a:factory) == type(1) && a:factory
" Passed a channel directly " Passed a channel directly
@ -20,7 +20,7 @@ endfunction
" as `source`, but it will run as a different process. This can be used by " 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 " plugins that should run isolated from other plugins created for the same host
" type " type
function! rpc#host#RegisterClone(name, orig_name) function! remote#host#RegisterClone(name, orig_name)
if !has_key(s:hosts, a:orig_name) if !has_key(s:hosts, a:orig_name)
throw 'No host named "'.a:orig_name.'" is registered' throw 'No host named "'.a:orig_name.'" is registered'
endif endif
@ -30,7 +30,7 @@ endfunction
" Get a host channel, bootstrapping it if necessary " 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) if !has_key(s:hosts, a:name)
throw 'No host named "'.a:name.'" is registered' throw 'No host named "'.a:name.'" is registered'
endif endif
@ -43,7 +43,7 @@ function! rpc#host#Require(name)
endfunction endfunction
function! rpc#host#IsRunning(name) function! remote#host#IsRunning(name)
if !has_key(s:hosts, a:name) if !has_key(s:hosts, a:name)
throw 'No host named "'.a:name.'" is registered' throw 'No host named "'.a:name.'" is registered'
endif endif
@ -55,7 +55,7 @@ endfunction
" autocmd(async) and one function(sync): " autocmd(async) and one function(sync):
" "
" let s:plugin_path = expand('<sfile>:p:h').'/nvim_plugin.py' " 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': 'PyCmd', 'sync': 1, 'opts': {}},
" \ {'type': 'command', 'name': 'PyAsyncCmd', 'sync': 0, 'opts': {'eval': 'cursor()'}}, " \ {'type': 'command', 'name': 'PyAsyncCmd', 'sync': 0, 'opts': {'eval': 'cursor()'}},
" \ {'type': 'autocmd', 'name': 'BufEnter', 'sync': 0, 'opts': {'eval': 'expand("<afile>")'}}, " \ {'type': 'autocmd', 'name': 'BufEnter', 'sync': 0, 'opts': {'eval': 'expand("<afile>")'}},
@ -64,7 +64,7 @@ endfunction
" "
" The third item in a declaration is a boolean: non zero means the command, " The third item in a declaration is a boolean: non zero means the command,
" autocommand or function will be executed synchronously with rpcrequest. " 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) let plugins = s:PluginsForHost(a:host)
for plugin in plugins for plugin in plugins
@ -73,7 +73,7 @@ function! rpc#host#RegisterPlugin(host, path, specs)
endif endif
endfor 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 " For now we won't allow registration of plugins when the host is already
" running. " running.
throw 'Host "'.a:host.'" is already running' throw 'Host "'.a:host.'" is already running'
@ -87,7 +87,7 @@ function! rpc#host#RegisterPlugin(host, path, specs)
let rpc_method = a:path let rpc_method = a:path
if type == 'command' if type == 'command'
let rpc_method .= ':command:'.name 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' elseif type == 'autocmd'
" Since multiple handlers can be attached to the same autocmd event by a " 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 " single plugin, we need a way to uniquely identify the rpc method to
@ -95,10 +95,10 @@ function! rpc#host#RegisterPlugin(host, path, specs)
" name(This still has a limit: one handler per event/pattern combo, but " 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) " there's no need to allow plugins define multiple handlers in that case)
let rpc_method .= ':autocmd:'.name.':'.get(opts, 'pattern', '*') 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' elseif type == 'function'
let rpc_method .= ':function:'.name 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 else
echoerr 'Invalid declaration type: '.type echoerr 'Invalid declaration type: '.type
endif endif
@ -108,9 +108,9 @@ function! rpc#host#RegisterPlugin(host, path, specs)
endfunction endfunction
function! rpc#host#LoadExternalPlugins() function! remote#host#LoadRemotePlugins()
if filereadable(s:external_plugins) if filereadable(s:remote_plugins_manifest)
exe 'source '.s:external_plugins exe 'source '.s:remote_plugins_manifest
endif endif
endfunction endfunction
@ -118,17 +118,17 @@ endfunction
function! s:RegistrationCommands(host) function! s:RegistrationCommands(host)
" Register a temporary host clone for discovering specs " Register a temporary host clone for discovering specs
let host_id = a:host.'-registration-clone' 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 pattern = s:plugin_patterns[a:host]
let paths = globpath(&rtp, 'external-plugin/'.a:host.'/'.pattern, 0, 1) let paths = globpath(&rtp, 'rplugin/'.a:host.'/'.pattern, 0, 1)
for path in paths for path in paths
call rpc#host#RegisterPlugin(host_id, path, []) call remote#host#RegisterPlugin(host_id, path, [])
endfor endfor
let channel = rpc#host#Require(host_id) let channel = remote#host#Require(host_id)
let lines = [] let lines = []
for path in paths for path in paths
let specs = rpcrequest(channel, 'specs', path) 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."', [") \ ."', '".path."', [")
for spec in specs for spec in specs
call add(lines, " \\ ".string(spec).",") call add(lines, " \\ ".string(spec).",")
@ -143,7 +143,7 @@ function! s:RegistrationCommands(host)
endfunction endfunction
function! s:UpdateExternalPlugins() function! s:UpdateRemotePlugins()
let commands = [] let commands = []
let hosts = keys(s:hosts) let hosts = keys(s:hosts)
for host in hosts for host in hosts
@ -154,11 +154,11 @@ function! s:UpdateExternalPlugins()
\ + ['', ''] \ + ['', '']
endif endif
endfor endfor
call writefile(commands, s:external_plugins) call writefile(commands, s:remote_plugins_manifest)
endfunction endfunction
command! UpdateExternalPlugins call s:UpdateExternalPlugins() command! UpdateRemotePlugins call s:UpdateRemotePlugins()
let s:plugins_for_host = {} let s:plugins_for_host = {}
@ -239,5 +239,5 @@ function! s:RequirePythonHost(name)
throw 'Failed to load python host' throw 'Failed to load python host'
endfunction endfunction
call rpc#host#Register('python', function('s:RequirePythonHost')) call remote#host#Register('python', function('s:RequirePythonHost'))
" }}} " }}}

View File

@ -21,7 +21,7 @@ DOCS = \
digraph.txt \ digraph.txt \
editing.txt \ editing.txt \
eval.txt \ eval.txt \
external_plugin.txt \ remote_plugin.txt \
farsi.txt \ farsi.txt \
filetype.txt \ filetype.txt \
fold.txt \ fold.txt \
@ -142,7 +142,7 @@ HTMLS = \
digraph.html \ digraph.html \
editing.html \ editing.html \
eval.html \ eval.html \
external_plugin.html \ remote_plugin.html \
farsi.html \ farsi.html \
filetype.html \ filetype.html \
fold.html \ fold.html \

View File

@ -17,7 +17,7 @@ differentiate Nvim from Vim:
2. Job control |job-control| 2. Job control |job-control|
3. Python plugins |nvim-python| 3. Python plugins |nvim-python|
4. Clipboard integration |nvim-clipboard| 4. Clipboard integration |nvim-clipboard|
5. External plugins |external-plugin| 5. Remote plugins |remote-plugin|
6. Provider infrastructure |nvim-provider| 6. Provider infrastructure |nvim-provider|
============================================================================== ==============================================================================

View File

@ -1,22 +1,22 @@
*external_plugin.txt* For Nvim. {Nvim} *remote_plugin.txt* For Nvim. {Nvim}
NVIM REFERENCE MANUAL by Thiago de Arruda NVIM REFERENCE MANUAL by Thiago de Arruda
Nvim support for external plugins *external-plugin* Nvim support for remote plugins *remote-plugin*
1. Introduction |external-plugin-intro| 1. Introduction |remote-plugin-intro|
2. Plugin hosts |external-plugin-hosts| 2. Plugin hosts |remote-plugin-hosts|
3. Example |external-plugin-example| 3. Example |remote-plugin-example|
4. Plugin manifest |external-plugin-manifest| 4. Plugin manifest |remote-plugin-manifest|
============================================================================== ==============================================================================
1. Introduction *external-plugin-intro* 1. Introduction *remote-plugin-intro*
A big Nvim goal is to allow extensibility in arbitrary programming languages A big Nvim goal is to allow extensibility in arbitrary programming languages
without requiring direct support from the editor. This is achieved with without requiring direct support from the editor. This is achieved with
external plugins, coprocesses that have a direct communication channel(via remote plugins, coprocesses that have a direct communication channel(via
|msgpack-rpc|) with the Nvim process. |msgpack-rpc|) with the Nvim process.
Even though these plugins are running in separate processes, they can call, be Even though these plugins are running in separate processes, they can call, be
@ -24,7 +24,7 @@ called, and receive events just as if the code was being executed in the main
process. process.
============================================================================== ==============================================================================
2. Plugin hosts *external-plugin-hosts* 2. Plugin hosts *remote-plugin-hosts*
While plugins can be implemented as arbitrary programs that communicate While plugins can be implemented as arbitrary programs that communicate
directly with Nvim API and are called via |rpcrequest()| and |rpcnotify()|, directly with Nvim API and are called via |rpcrequest()| and |rpcnotify()|,
@ -39,9 +39,9 @@ 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. Nvim startup as fast a possible despite the number of installed plugins/hosts.
============================================================================== ==============================================================================
3. Example *external-plugin-example* 3. Example *remote-plugin-example*
The best way to learn about external plugins is with an example, so let's see 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 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 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: limit the number of requests made to it. Here's the plugin source code:
@ -93,31 +93,31 @@ 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 approach with |rpcnotify()|(return values or exceptions raised in the handler
function are ignored) function are ignored)
To test the above plugin, it must be saved in "external-plugin/python" in a To test the above plugin, it must be saved in "rplugin/python" in a
'runtimepath' directory(~/.nvim/external-plugin/python/limit.py for example). 'runtimepath' directory(~/.nvim/rplugin/python/limit.py for example).
Then, the external plugin manifest must be generated with Then, the remote plugin manifest must be generated with
`:UpdateExternalPlugins`. `:UpdateRemotePlugins`.
============================================================================== ==============================================================================
4. External plugin manifest *external-plugin-manifest* 4. remote plugin manifest *remote-plugin-manifest*
Just installing external plugins to "external-plugin/{host}" isn't enough to Just installing remote plugins to "rplugin/{host}" isn't enough to
load them at startup. The `:UpdateExternalPlugins` command must be executed load them at startup. The `:UpdateRemotePlugins` command must be executed
every time an external plugin is installed, updated, or deleted. every time a remote plugin is installed, updated, or deleted.
`:UpdateExternalPlugins` will generate the external plugin manifest, a special `:UpdateRemotePlugins` will generate the remote plugin manifest, a special
vimscript file containing declarations for all vimscript entities vimscript file containing declarations for all vimscript entities
(commands/autocommands/functions) defined by all external plugins, with each (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 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 generated extension to the user's vimrc(it even has the vimrc filename
prepended). prepended).
The manifest declarations are nothing but calls to the rpc#host#RegisterPlugin 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 function, which will take care of bootstrapping the host as soon as the
declared command, autocommand or function is used for the first time. declared command, autocommand or function is used for the first time.
The manifest generation step is necessary to keep editor startup fast in The manifest generation step is necessary to keep editor startup fast in
situations where a user has external plugins with different hosts. For situations where a user has remote plugins with different hosts. For
example, imagine a user that has three plugins, for python, java and .NET 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 hosts respectively, if we were to load all three plugins at startup, then
three language runtimes would also be spawned which could take seconds! three language runtimes would also be spawned which could take seconds!
@ -127,7 +127,7 @@ 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 java files, if it defines an BufEnter *.java autocommand then the java host
will only be spawned when java source files are loaded. will only be spawned when java source files are loaded.
If the explicit call to `:UpdateExternalPlugins` seems incovenient, try 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 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 still keeping it a fast/lightweight editor for general use. It can also be
seen as an analogous to the |:helptags| facility. seen as an analogous to the |:helptags| facility.

View File

@ -1,5 +0,0 @@
if exists('loaded_external_plugins') || &cp
finish
endif
let loaded_external_plugins = 1
call rpc#host#LoadExternalPlugins()

View File

@ -0,0 +1,5 @@
if exists('loaded_remote_plugins') || &cp
finish
endif
let loaded_remote_plugins = 1
call remote#host#LoadRemotePlugins()

View File

@ -346,20 +346,20 @@ local function host()
end end
local function register() local function register()
eval('rpc#host#Register("busted", '..channel()..')') eval('remote#host#Register("busted", '..channel()..')')
end end
command_specs_for('rpc#define#CommandOnChannel', true, channel) command_specs_for('remote#define#CommandOnChannel', true, channel)
command_specs_for('rpc#define#CommandOnChannel', false, channel) command_specs_for('remote#define#CommandOnChannel', false, channel)
command_specs_for('rpc#define#CommandOnHost', true, host, register) command_specs_for('remote#define#CommandOnHost', true, host, register)
command_specs_for('rpc#define#CommandOnHost', false, host, register) command_specs_for('remote#define#CommandOnHost', false, host, register)
autocmd_specs_for('rpc#define#AutocmdOnChannel', true, channel) autocmd_specs_for('remote#define#AutocmdOnChannel', true, channel)
autocmd_specs_for('rpc#define#AutocmdOnChannel', false, channel) autocmd_specs_for('remote#define#AutocmdOnChannel', false, channel)
autocmd_specs_for('rpc#define#AutocmdOnHost', true, host, register) autocmd_specs_for('remote#define#AutocmdOnHost', true, host, register)
autocmd_specs_for('rpc#define#AutocmdOnHost', false, host, register) autocmd_specs_for('remote#define#AutocmdOnHost', false, host, register)
function_specs_for('rpc#define#FunctionOnChannel', true, channel) function_specs_for('remote#define#FunctionOnChannel', true, channel)
function_specs_for('rpc#define#FunctionOnChannel', false, channel) function_specs_for('remote#define#FunctionOnChannel', false, channel)
function_specs_for('rpc#define#FunctionOnHost', true, host, register) function_specs_for('remote#define#FunctionOnHost', true, host, register)
function_specs_for('rpc#define#FunctionOnHost', false, host, register) function_specs_for('remote#define#FunctionOnHost', false, host, register)