mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	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:
		| @@ -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 | ||||||
|   | |||||||
| @@ -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 |  | ||||||
|   | |||||||
| @@ -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(...) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Justin M. Keyes
					Justin M. Keyes