provider: skip non-provider has() feature-names

We don't want to retry autoload sourcing (slow) for every random has()
query that finds it way to eval_call_provider().
This commit is contained in:
Justin M. Keyes
2019-08-04 12:20:30 +02:00
parent 241956720d
commit 5e6a08f2e6
5 changed files with 25 additions and 12 deletions

View File

@@ -23969,28 +23969,37 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
} }
/// Checks if a named provider is enabled. /// Checks if a named provider is enabled.
bool eval_has_provider(const char *provider) bool eval_has_provider(const char *name)
{ {
if (!strequal(name, "clipboard")
&& !strequal(name, "python")
&& !strequal(name, "python3")
&& !strequal(name, "ruby")
&& !strequal(name, "node")) {
// Avoid autoload for non-provider has() features.
return false;
}
char buf[256]; char buf[256];
int len; int len;
typval_T tv; typval_T tv;
// Get the g:loaded_xx_provider variable. // Get the g:loaded_xx_provider variable.
len = snprintf(buf, sizeof(buf), "g:loaded_%s_provider", provider); len = snprintf(buf, sizeof(buf), "g:loaded_%s_provider", name);
if (get_var_tv(buf, len, &tv, NULL, false, true) == FAIL) { if (get_var_tv(buf, len, &tv, NULL, false, true) == FAIL) {
// Trigger autoload once. // Trigger autoload once.
len = snprintf(buf, sizeof(buf), "provider#%s#bogus", provider); len = snprintf(buf, sizeof(buf), "provider#%s#bogus", name);
script_autoload(buf, len, false); script_autoload(buf, len, false);
// Retry the (non-autoload-style) variable. // Retry the (non-autoload-style) variable.
len = snprintf(buf, sizeof(buf), "g:loaded_%s_provider", provider); len = snprintf(buf, sizeof(buf), "g:loaded_%s_provider", name);
if (get_var_tv(buf, len, &tv, NULL, false, true) == FAIL) { if (get_var_tv(buf, len, &tv, NULL, false, true) == FAIL) {
// Show a hint if Call() is defined but g:loaded_xx_provider is missing. // Show a hint if Call() is defined but g:loaded_xx_provider is missing.
snprintf(buf, sizeof(buf), "provider#%s#Call", provider); snprintf(buf, sizeof(buf), "provider#%s#Call", name);
bool has_call = !!find_func((char_u *)buf); bool has_call = !!find_func((char_u *)buf);
if (has_call && p_lpl) { if (has_call && p_lpl) {
emsgf("provider: %s: missing required variable g:loaded_%s_provider", emsgf("provider: %s: missing required variable g:loaded_%s_provider",
provider, provider); name, name);
} }
return false; return false;
} }

View File

@@ -1,2 +0,0 @@
" A dummy test provider
let g:loaded_brokencall_provider = 2

View File

@@ -1,6 +1,6 @@
" Dummy test provider, missing this required variable: " Dummy test provider, missing this required variable:
" let g:loaded_brokenenabled_provider = 0 " let g:loaded_brokenenabled_provider = 0
function! provider#brokenenabled#Call(method, args) function! provider#python#Call(method, args)
return 42 return 42
endfunction endfunction

View File

@@ -0,0 +1,2 @@
" A dummy test provider
let g:loaded_ruby_provider = 2

View File

@@ -11,11 +11,15 @@ describe('providers', function()
it('must define g:loaded_xx_provider', function() it('must define g:loaded_xx_provider', function()
command('set loadplugins') command('set loadplugins')
expect_err('Vim:provider: brokenenabled: missing required variable g:loaded_brokenenabled_provider', -- Using test-fixture with broken impl:
eval, "has('brokenenabled')") -- test/functional/fixtures/autoload/provider/python.vim
expect_err('Vim:provider: python: missing required variable g:loaded_python_provider',
eval, "has('python')")
end) end)
it('without Call() but with g:loaded_xx_provider', function() it('without Call() but with g:loaded_xx_provider', function()
eq(1, eval("has('brokencall')")) -- Using test-fixture with broken impl:
-- test/functional/fixtures/autoload/provider/ruby.vim
eq(1, eval("has('ruby')"))
end) end)
end) end)