rplugin: Call s:LoadRemotePlugins() on startup.

Dispense with the FuncUndefined/CmdUndefined quasi-optimization.
If there are no rplugins, plugin/rplugin.vim takes less than 1ms.

Closes #5821
Closes #6250

Helped-by: Qiming zhao <chemzqm@gmail.com>
This commit is contained in:
Justin M. Keyes 2017-03-10 22:01:34 +01:00
parent 1743df82f9
commit d1afd434f3
3 changed files with 55 additions and 95 deletions

View File

@ -2,7 +2,6 @@ let s:hosts = {}
let s:plugin_patterns = {} let s:plugin_patterns = {}
let s:plugins_for_host = {} let s:plugins_for_host = {}
" Register a host by associating it with a factory(funcref) " Register a host by associating it with a factory(funcref)
function! remote#host#Register(name, pattern, factory) abort function! remote#host#Register(name, pattern, factory) abort
let s:hosts[a:name] = {'factory': a:factory, 'channel': 0, 'initialized': 0} let s:hosts[a:name] = {'factory': a:factory, 'channel': 0, 'initialized': 0}
@ -13,7 +12,6 @@ function! remote#host#Register(name, pattern, factory) abort
endif endif
endfunction endfunction
" Register a clone to an existing host. The new host will use the same factory " Register a clone to an existing host. The new host will use the same factory
" 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
@ -31,12 +29,8 @@ function! remote#host#RegisterClone(name, orig_name) abort
\ } \ }
endfunction endfunction
" Get a host channel, bootstrapping it if necessary " Get a host channel, bootstrapping it if necessary
function! remote#host#Require(name) abort function! remote#host#Require(name) abort
if empty(s:plugins_for_host)
call remote#host#LoadRemotePlugins()
endif
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
@ -52,7 +46,6 @@ function! remote#host#Require(name) abort
return host.channel return host.channel
endfunction endfunction
function! remote#host#IsRunning(name) abort function! remote#host#IsRunning(name) abort
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'
@ -60,7 +53,6 @@ function! remote#host#IsRunning(name) abort
return s:hosts[a:name].channel != 0 return s:hosts[a:name].channel != 0
endfunction endfunction
" Example of registering a Python plugin with two commands (one async), one " Example of registering a Python plugin with two commands (one async), one
" autocmd (async) and one function (sync): " autocmd (async) and one function (sync):
" "
@ -117,73 +109,6 @@ function! remote#host#RegisterPlugin(host, path, specs) abort
call add(plugins, {'path': a:path, 'specs': a:specs}) call add(plugins, {'path': a:path, 'specs': a:specs})
endfunction endfunction
" Get the path to the rplugin manifest file.
function! s:GetManifestPath() abort
let manifest_base = ''
if exists('$NVIM_RPLUGIN_MANIFEST')
return fnamemodify($NVIM_RPLUGIN_MANIFEST, ':p')
endif
let dest = has('win32') ? '$LOCALAPPDATA' : '$XDG_DATA_HOME'
if !exists(dest)
let dest = has('win32') ? '~/AppData/Local' : '~/.local/share'
endif
let dest = fnamemodify(expand(dest), ':p')
if !empty(dest) && !filereadable(dest)
let dest .= ('/' ==# dest[-1:] ? '' : '/') . 'nvim'
call mkdir(dest, 'p', 0700)
let manifest_base = dest
endif
return manifest_base.'/rplugin.vim'
endfunction
" Old manifest file based on known script locations.
function! s:GetOldManifestPath() abort
let prefix = exists('$MYVIMRC')
\ ? $MYVIMRC
\ : matchstr(get(split(execute('scriptnames'), '\n'), 0, ''), '\f\+$')
return fnamemodify(expand(prefix, 1), ':h')
\.'/.'.fnamemodify(prefix, ':t').'-rplugin~'
endfunction
function! s:GetManifest() abort
let manifest = s:GetManifestPath()
if !filereadable(manifest)
" Check if an old manifest file exists and move it to the new location.
let old_manifest = s:GetOldManifestPath()
if filereadable(old_manifest)
call rename(old_manifest, manifest)
endif
endif
return manifest
endfunction
function! remote#host#LoadRemotePlugins() abort
let manifest = s:GetManifest()
if filereadable(manifest)
execute 'source' fnameescape(manifest)
endif
endfunction
function! remote#host#LoadRemotePluginsEvent(event, pattern) abort
autocmd! nvim-rplugin
call remote#host#LoadRemotePlugins()
if exists('#'.a:event.'#'.a:pattern) " Avoid 'No matching autocommands'.
execute 'silent doautocmd <nomodeline>' a:event a:pattern
endif
endfunction
function! s:RegistrationCommands(host) abort function! s:RegistrationCommands(host) abort
" 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'
@ -228,7 +153,6 @@ function! s:RegistrationCommands(host) abort
return lines return lines
endfunction endfunction
function! remote#host#UpdateRemotePlugins() abort function! remote#host#UpdateRemotePlugins() abort
let commands = [] let commands = []
let hosts = keys(s:hosts) let hosts = keys(s:hosts)
@ -245,12 +169,11 @@ function! remote#host#UpdateRemotePlugins() abort
endtry endtry
endif endif
endfor endfor
call writefile(commands, s:GetManifest()) call writefile(commands, g:loaded_remote_plugins)
echomsg printf('remote/host: generated rplugin manifest: %s', echomsg printf('remote/host: generated rplugin manifest: %s',
\ s:GetManifest()) \ g:loaded_remote_plugins)
endfunction endfunction
function! remote#host#PluginsForHost(host) abort function! remote#host#PluginsForHost(host) abort
if !has_key(s:plugins_for_host, a:host) if !has_key(s:plugins_for_host, a:host)
let s:plugins_for_host[a:host] = [] let s:plugins_for_host[a:host] = []
@ -258,7 +181,6 @@ function! remote#host#PluginsForHost(host) abort
return s:plugins_for_host[a:host] return s:plugins_for_host[a:host]
endfunction endfunction
function! remote#host#LoadErrorForHost(host, log) abort function! remote#host#LoadErrorForHost(host, log) abort
return 'Failed to load '. a:host . ' host. '. return 'Failed to load '. a:host . ' host. '.
\ 'You can try to see what happened by starting nvim with '. \ 'You can try to see what happened by starting nvim with '.
@ -266,7 +188,6 @@ function! remote#host#LoadErrorForHost(host, log) abort
\ ' Also, the host stderr is available in messages.' \ ' Also, the host stderr is available in messages.'
endfunction endfunction
" Registration of standard hosts " Registration of standard hosts
" Python/Python3 " Python/Python3

View File

@ -1,16 +1,59 @@
if exists('g:loaded_remote_plugins') if exists('g:loaded_remote_plugins')
finish finish
endif endif
let g:loaded_remote_plugins = 1 let g:loaded_remote_plugins = '/path/to/manifest'
" Get the path to the rplugin manifest file.
function! s:GetManifestPath() abort
let manifest_base = ''
if exists('$NVIM_RPLUGIN_MANIFEST')
return fnamemodify($NVIM_RPLUGIN_MANIFEST, ':p')
endif
let dest = has('win32') ? '$LOCALAPPDATA' : '$XDG_DATA_HOME'
if !exists(dest)
let dest = has('win32') ? '~/AppData/Local' : '~/.local/share'
endif
let dest = fnamemodify(expand(dest), ':p')
if !empty(dest) && !filereadable(dest)
let dest .= ('/' ==# dest[-1:] ? '' : '/') . 'nvim'
call mkdir(dest, 'p', 0700)
let manifest_base = dest
endif
return manifest_base.'/rplugin.vim'
endfunction
" Old manifest file based on known script locations.
function! s:GetOldManifestPath() abort
let prefix = exists('$MYVIMRC')
\ ? $MYVIMRC
\ : matchstr(get(split(execute('scriptnames'), '\n'), 0, ''), '\f\+$')
return fnamemodify(expand(prefix, 1), ':h')
\.'/.'.fnamemodify(prefix, ':t').'-rplugin~'
endfunction
function! s:GetManifest() abort
let manifest = s:GetManifestPath()
if !filereadable(manifest)
" Check if an old manifest file exists and move it to the new location.
let old_manifest = s:GetOldManifestPath()
if filereadable(old_manifest)
call rename(old_manifest, manifest)
endif
endif
return manifest
endfunction
function! s:LoadRemotePlugins() abort
let g:loaded_remote_plugins = s:GetManifest()
if filereadable(g:loaded_remote_plugins)
execute 'source' fnameescape(g:loaded_remote_plugins)
endif
endfunction
command! UpdateRemotePlugins call remote#host#UpdateRemotePlugins() command! UpdateRemotePlugins call remote#host#UpdateRemotePlugins()
augroup nvim-rplugin call s:LoadRemotePlugins()
autocmd!
autocmd FuncUndefined *
\ call remote#host#LoadRemotePluginsEvent(
\ 'FuncUndefined', expand('<amatch>'))
autocmd CmdUndefined *
\ call remote#host#LoadRemotePluginsEvent(
\ 'CmdUndefined', expand('<amatch>'))
augroup END

View File

@ -3,7 +3,6 @@ local eval, command, nvim = helpers.eval, helpers.command, helpers.nvim
local eq, run, stop = helpers.eq, helpers.run, helpers.stop local eq, run, stop = helpers.eq, helpers.run, helpers.stop
local clear = helpers.clear local clear = helpers.clear
local function get_prefix(sync) local function get_prefix(sync)
if sync then if sync then
return 'sync' return 'sync'
@ -11,12 +10,10 @@ local function get_prefix(sync)
return 'async' return 'async'
end end
local function call(fn, arguments) local function call(fn, arguments)
command('call '..fn..'('..arguments..')') command('call '..fn..'('..arguments..')')
end end
local function clear_and_init(init) local function clear_and_init(init)
return function() return function()
clear() clear()
@ -26,7 +23,6 @@ local function clear_and_init(init)
end end
end end
local function runx(sync, handler, on_setup) local function runx(sync, handler, on_setup)
local function setup_cb(...) local function setup_cb(...)
on_setup(...) on_setup(...)