mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	Merge #10161 from equalsraf/tb-clipboard-reload
Support "reload" of providers
This commit is contained in:
		@@ -123,7 +123,7 @@ function! s:check_performance() abort
 | 
				
			|||||||
  else
 | 
					  else
 | 
				
			||||||
    call health#report_info(buildtype)
 | 
					    call health#report_info(buildtype)
 | 
				
			||||||
    call health#report_warn(
 | 
					    call health#report_warn(
 | 
				
			||||||
          \ 'Non-optimized build-type. Nvim will be slower.',
 | 
					          \ 'Non-optimized '.(has('debug')?'(DEBUG) ':'').'build. Nvim will be slower.',
 | 
				
			||||||
          \ ['Install a different Nvim package, or rebuild with `CMAKE_BUILD_TYPE=RelWithDebInfo`.',
 | 
					          \ ['Install a different Nvim package, or rebuild with `CMAKE_BUILD_TYPE=RelWithDebInfo`.',
 | 
				
			||||||
          \  s:suggest_faq])
 | 
					          \  s:suggest_faq])
 | 
				
			||||||
  endif
 | 
					  endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,16 @@
 | 
				
			|||||||
" The clipboard provider uses shell commands to communicate with the clipboard.
 | 
					" The clipboard provider uses shell commands to communicate with the clipboard.
 | 
				
			||||||
" The provider function will only be registered if a supported command is
 | 
					" The provider function will only be registered if a supported command is
 | 
				
			||||||
" available.
 | 
					" available.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if exists('g:loaded_clipboard_provider')
 | 
				
			||||||
 | 
					  finish
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					" Default to 1.  provider#clipboard#Executable() may set 2.
 | 
				
			||||||
 | 
					" To force a reload:
 | 
				
			||||||
 | 
					"   :unlet g:loaded_clipboard_provider
 | 
				
			||||||
 | 
					"   :runtime autoload/provider/clipboard.vim
 | 
				
			||||||
 | 
					let g:loaded_clipboard_provider = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let s:copy = {}
 | 
					let s:copy = {}
 | 
				
			||||||
let s:paste = {}
 | 
					let s:paste = {}
 | 
				
			||||||
let s:clipboard = {}
 | 
					let s:clipboard = {}
 | 
				
			||||||
@@ -120,13 +130,6 @@ function! provider#clipboard#Executable() abort
 | 
				
			|||||||
  return ''
 | 
					  return ''
 | 
				
			||||||
endfunction
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if empty(provider#clipboard#Executable())
 | 
					 | 
				
			||||||
  " provider#clipboard#Call() *must not* be defined if the provider is broken.
 | 
					 | 
				
			||||||
  " Otherwise eval_has_provider() thinks the clipboard provider is
 | 
					 | 
				
			||||||
  " functioning, and eval_call_provider() will happily call it.
 | 
					 | 
				
			||||||
  finish
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function! s:clipboard.get(reg) abort
 | 
					function! s:clipboard.get(reg) abort
 | 
				
			||||||
  if type(s:paste[a:reg]) == v:t_func
 | 
					  if type(s:paste[a:reg]) == v:t_func
 | 
				
			||||||
    return s:paste[a:reg]()
 | 
					    return s:paste[a:reg]()
 | 
				
			||||||
@@ -192,3 +195,6 @@ function! provider#clipboard#Call(method, args) abort
 | 
				
			|||||||
    let s:here = v:false
 | 
					    let s:here = v:false
 | 
				
			||||||
  endtry
 | 
					  endtry
 | 
				
			||||||
endfunction
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" eval_has_provider() decides based on this variable.
 | 
				
			||||||
 | 
					let g:loaded_clipboard_provider = empty(provider#clipboard#Executable()) ? 1 : 2
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -140,8 +140,9 @@ endfunction
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
let s:err = ''
 | 
					let s:err = ''
 | 
				
			||||||
let s:prog = provider#node#Detect()
 | 
					let s:prog = provider#node#Detect()
 | 
				
			||||||
 | 
					let g:loaded_node_provider = empty(s:prog) ? 1 : 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if empty(s:prog)
 | 
					if g:loaded_node_provider != 2
 | 
				
			||||||
  let s:err = 'Cannot find the "neovim" node package. Try :checkhealth'
 | 
					  let s:err = 'Cannot find the "neovim" node package. Try :checkhealth'
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,9 +7,8 @@
 | 
				
			|||||||
if exists('g:loaded_python_provider')
 | 
					if exists('g:loaded_python_provider')
 | 
				
			||||||
  finish
 | 
					  finish
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
let g:loaded_python_provider = 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
let [s:prog, s:err] = provider#pythonx#Detect(2)
 | 
					let [s:prog, s:err] = provider#pythonx#Detect(2)
 | 
				
			||||||
 | 
					let g:loaded_python_provider = empty(s:prog) ? 1 : 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function! provider#python#Prog() abort
 | 
					function! provider#python#Prog() abort
 | 
				
			||||||
  return s:prog
 | 
					  return s:prog
 | 
				
			||||||
@@ -19,11 +18,6 @@ function! provider#python#Error() abort
 | 
				
			|||||||
  return s:err
 | 
					  return s:err
 | 
				
			||||||
endfunction
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if s:prog == ''
 | 
					 | 
				
			||||||
  " Detection failed
 | 
					 | 
				
			||||||
  finish
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
" 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 remote#host#RegisterClone('legacy-python-provider', 'python')
 | 
					call remote#host#RegisterClone('legacy-python-provider', 'python')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,9 +7,8 @@
 | 
				
			|||||||
if exists('g:loaded_python3_provider')
 | 
					if exists('g:loaded_python3_provider')
 | 
				
			||||||
  finish
 | 
					  finish
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
let g:loaded_python3_provider = 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
let [s:prog, s:err] = provider#pythonx#Detect(3)
 | 
					let [s:prog, s:err] = provider#pythonx#Detect(3)
 | 
				
			||||||
 | 
					let g:loaded_python3_provider = empty(s:prog) ? 1 : 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function! provider#python3#Prog() abort
 | 
					function! provider#python3#Prog() abort
 | 
				
			||||||
  return s:prog
 | 
					  return s:prog
 | 
				
			||||||
@@ -19,11 +18,6 @@ function! provider#python3#Error() abort
 | 
				
			|||||||
  return s:err
 | 
					  return s:err
 | 
				
			||||||
endfunction
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if s:prog == ''
 | 
					 | 
				
			||||||
  " Detection failed
 | 
					 | 
				
			||||||
  finish
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
" The Python3 provider plugin will run in a separate instance of the Python3
 | 
					" The Python3 provider plugin will run in a separate instance of the Python3
 | 
				
			||||||
" host.
 | 
					" host.
 | 
				
			||||||
call remote#host#RegisterClone('legacy-python3-provider', 'python3')
 | 
					call remote#host#RegisterClone('legacy-python3-provider', 'python3')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,8 +62,9 @@ endfunction
 | 
				
			|||||||
let s:err = ''
 | 
					let s:err = ''
 | 
				
			||||||
let s:prog = s:detect()
 | 
					let s:prog = s:detect()
 | 
				
			||||||
let s:plugin_path = expand('<sfile>:p:h') . '/script_host.rb'
 | 
					let s:plugin_path = expand('<sfile>:p:h') . '/script_host.rb'
 | 
				
			||||||
 | 
					let g:loaded_ruby_provider = empty(s:prog) ? 1 : 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if empty(s:prog)
 | 
					if g:loaded_ruby_provider != 2
 | 
				
			||||||
  let s:err = 'Cannot find the neovim RubyGem. Try :checkhealth'
 | 
					  let s:err = 'Cannot find the neovim RubyGem. Try :checkhealth'
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,12 +84,11 @@ Developer guidelines				        *dev-guidelines*
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
PROVIDERS 						*dev-provider*
 | 
					PROVIDERS 						*dev-provider*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
A goal of Nvim is to allow extension of the editor without special knowledge
 | 
					A primary goal of Nvim is to allow extension of the editor without special
 | 
				
			||||||
in the core. But some Vim components are too tightly coupled; in those cases
 | 
					knowledge in the core.  Some core functions are delegated to "providers"
 | 
				
			||||||
a "provider" hook is exposed.
 | 
					implemented as external scripts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Consider two examples of integration with external systems that are
 | 
					Examples:
 | 
				
			||||||
implemented in Vim and are now decoupled from Nvim core as providers:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. In the Vim source code, clipboard logic accounts for more than 1k lines of
 | 
					1. In the Vim source code, clipboard logic accounts for more than 1k lines of
 | 
				
			||||||
   C source code (ui.c), to perform two tasks that are now accomplished with
 | 
					   C source code (ui.c), to perform two tasks that are now accomplished with
 | 
				
			||||||
@@ -101,29 +100,28 @@ implemented in Vim and are now decoupled from Nvim core as providers:
 | 
				
			|||||||
   scripting is performed by an external host process implemented in ~2k lines
 | 
					   scripting is performed by an external host process implemented in ~2k lines
 | 
				
			||||||
   of Python.
 | 
					   of Python.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Ideally we could implement Python and clipboard integration in pure vimscript
 | 
					The provider framework invokes VimL from C.  It is composed of two functions
 | 
				
			||||||
and without touching the C code. But this is infeasible without compromising
 | 
					in eval.c:
 | 
				
			||||||
backwards compatibility with Vim; that's where providers help.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
The provider framework helps call vimscript from C. It is composed of two
 | 
					- eval_call_provider(name, method, arguments): calls provider#{name}#Call
 | 
				
			||||||
functions in eval.c:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- eval_call_provider(name, method, arguments): calls provider#(name)#Call
 | 
					 | 
				
			||||||
  with the method and arguments.
 | 
					  with the method and arguments.
 | 
				
			||||||
- eval_has_provider(name): Checks if a provider is implemented. Returns true
 | 
					- eval_has_provider(name): Checks the `g:loaded_{name}_provider` variable
 | 
				
			||||||
  if the provider#(name)#Call function is implemented. Called by |has()|
 | 
					  which must be set to 2 by the provider script to indicate that it is
 | 
				
			||||||
  (vimscript) to check if features are available.
 | 
					  "enabled and working". Called by |has()| to check if features are available.
 | 
				
			||||||
 | 
					 | 
				
			||||||
The provider#(name)#Call function implements integration with an external
 | 
					 | 
				
			||||||
system, because shell commands and |RPC| clients are easier to work with in
 | 
					 | 
				
			||||||
vimscript.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
For example, the Python provider is implemented by the
 | 
					For example, the Python provider is implemented by the
 | 
				
			||||||
autoload/provider/python.vim script; the provider#python#Call function is only
 | 
					"autoload/provider/python.vim" script, which sets `g:loaded_python_provider`
 | 
				
			||||||
defined if a valid external Python host is found. That works well with the
 | 
					to 2 only if a valid external Python host is found.  Then `has("python")`
 | 
				
			||||||
`has('python')` expression (normally used by Python plugins) because if the
 | 
					reflects whether Python support is working.
 | 
				
			||||||
Python host isn't installed then the plugin will "think" it is running in
 | 
					
 | 
				
			||||||
a Vim compiled without the "+python" feature.
 | 
												*provider-reload*
 | 
				
			||||||
 | 
					Sometimes a GUI or other application may want to force a provider to
 | 
				
			||||||
 | 
					"reload".  To reload a provider, undefine its "loaded" flag, then use
 | 
				
			||||||
 | 
					|:runtime| to reload it: >
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :unlet g:loaded_clipboard_provider
 | 
				
			||||||
 | 
					    :runtime autoload/provider/clipboard.vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DOCUMENTATION						*dev-doc*
 | 
					DOCUMENTATION						*dev-doc*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,11 +68,11 @@ startup faster. Useful for working with virtualenvs.  >
 | 
				
			|||||||
<
 | 
					<
 | 
				
			||||||
						*g:loaded_python_provider*
 | 
											*g:loaded_python_provider*
 | 
				
			||||||
To disable Python 2 support: >
 | 
					To disable Python 2 support: >
 | 
				
			||||||
    let g:loaded_python_provider = 1
 | 
					    let g:loaded_python_provider = 0
 | 
				
			||||||
<
 | 
					<
 | 
				
			||||||
						*g:loaded_python3_provider*
 | 
											*g:loaded_python3_provider*
 | 
				
			||||||
To disable Python 3 support: >
 | 
					To disable Python 3 support: >
 | 
				
			||||||
    let g:loaded_python3_provider = 1
 | 
					    let g:loaded_python3_provider = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PYTHON VIRTUALENVS ~
 | 
					PYTHON VIRTUALENVS ~
 | 
				
			||||||
@@ -111,7 +111,7 @@ Run |:checkhealth| to see if your system is up-to-date.
 | 
				
			|||||||
RUBY PROVIDER CONFIGURATION ~
 | 
					RUBY PROVIDER CONFIGURATION ~
 | 
				
			||||||
						*g:loaded_ruby_provider*
 | 
											*g:loaded_ruby_provider*
 | 
				
			||||||
To disable Ruby support: >
 | 
					To disable Ruby support: >
 | 
				
			||||||
    let g:loaded_ruby_provider = 1
 | 
					    let g:loaded_ruby_provider = 0
 | 
				
			||||||
<
 | 
					<
 | 
				
			||||||
						*g:ruby_host_prog*
 | 
											*g:ruby_host_prog*
 | 
				
			||||||
Command to start the Ruby host. By default this is "neovim-ruby-host". With
 | 
					Command to start the Ruby host. By default this is "neovim-ruby-host". With
 | 
				
			||||||
@@ -142,7 +142,7 @@ Run |:checkhealth| to see if your system is up-to-date.
 | 
				
			|||||||
NODEJS PROVIDER CONFIGURATION~
 | 
					NODEJS PROVIDER CONFIGURATION~
 | 
				
			||||||
						*g:loaded_node_provider*
 | 
											*g:loaded_node_provider*
 | 
				
			||||||
To disable Node.js support: >
 | 
					To disable Node.js support: >
 | 
				
			||||||
    :let g:loaded_node_provider = 1
 | 
					    :let g:loaded_node_provider = 0
 | 
				
			||||||
<
 | 
					<
 | 
				
			||||||
						*g:node_host_prog*
 | 
											*g:node_host_prog*
 | 
				
			||||||
Command to start the Node.js host. Setting this makes startup faster.
 | 
					Command to start the Node.js host. Setting this makes startup faster.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23968,52 +23968,57 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
 | 
				
			|||||||
  return rettv;
 | 
					  return rettv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Checks if a named provider is enabled.
 | 
				
			||||||
bool eval_has_provider(const char *name)
 | 
					bool eval_has_provider(const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#define CHECK_PROVIDER(name) \
 | 
					  if (!strequal(name, "clipboard")
 | 
				
			||||||
  if (has_##name == -1) { \
 | 
					      && !strequal(name, "python")
 | 
				
			||||||
    has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \
 | 
					      && !strequal(name, "python3")
 | 
				
			||||||
    if (!has_##name) { \
 | 
					      && !strequal(name, "ruby")
 | 
				
			||||||
      script_autoload("provider#" #name "#Call", \
 | 
					      && !strequal(name, "node")) {
 | 
				
			||||||
                      sizeof("provider#" #name "#Call") - 1, \
 | 
					    // Avoid autoload for non-provider has() features.
 | 
				
			||||||
                      false); \
 | 
					    return false;
 | 
				
			||||||
      has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \
 | 
					 | 
				
			||||||
    } \
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static int has_clipboard = -1;
 | 
					  char buf[256];
 | 
				
			||||||
  static int has_python = -1;
 | 
					  int len;
 | 
				
			||||||
  static int has_python3 = -1;
 | 
					  typval_T tv;
 | 
				
			||||||
  static int has_ruby = -1;
 | 
					 | 
				
			||||||
  typval_T args[1];
 | 
					 | 
				
			||||||
  args[0].v_type = VAR_UNKNOWN;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (strequal(name, "clipboard")) {
 | 
					  // Get the g:loaded_xx_provider variable.
 | 
				
			||||||
    CHECK_PROVIDER(clipboard);
 | 
					  len = snprintf(buf, sizeof(buf), "g:loaded_%s_provider", name);
 | 
				
			||||||
    return has_clipboard;
 | 
					  if (get_var_tv(buf, len, &tv, NULL, false, true) == FAIL) {
 | 
				
			||||||
  } else if (strequal(name, "python3")) {
 | 
					    // Trigger autoload once.
 | 
				
			||||||
    CHECK_PROVIDER(python3);
 | 
					    len = snprintf(buf, sizeof(buf), "provider#%s#bogus", name);
 | 
				
			||||||
    return has_python3;
 | 
					    script_autoload(buf, len, false);
 | 
				
			||||||
  } else if (strequal(name, "python")) {
 | 
					
 | 
				
			||||||
    CHECK_PROVIDER(python);
 | 
					    // Retry the (non-autoload-style) variable.
 | 
				
			||||||
    return has_python;
 | 
					    len = snprintf(buf, sizeof(buf), "g:loaded_%s_provider", name);
 | 
				
			||||||
  } else if (strequal(name, "ruby")) {
 | 
					    if (get_var_tv(buf, len, &tv, NULL, false, true) == FAIL) {
 | 
				
			||||||
    bool need_check_ruby = (has_ruby == -1);
 | 
					      // Show a hint if Call() is defined but g:loaded_xx_provider is missing.
 | 
				
			||||||
    CHECK_PROVIDER(ruby);
 | 
					      snprintf(buf, sizeof(buf), "provider#%s#Call", name);
 | 
				
			||||||
    if (need_check_ruby && has_ruby == 1) {
 | 
					      if (!!find_func((char_u *)buf) && p_lpl) {
 | 
				
			||||||
      char *rubyhost = call_func_retstr("provider#ruby#Detect", 0, args, true);
 | 
					        emsgf("provider: %s: missing required variable g:loaded_%s_provider",
 | 
				
			||||||
      if (rubyhost) {
 | 
					              name, name);
 | 
				
			||||||
        if (*rubyhost == NUL) {
 | 
					 | 
				
			||||||
          // Invalid rubyhost executable. Gem is probably not installed.
 | 
					 | 
				
			||||||
          has_ruby = 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        xfree(rubyhost);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return has_ruby;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return false;
 | 
					  bool ok = (tv.v_type == VAR_NUMBER)
 | 
				
			||||||
 | 
					    ? 2 == tv.vval.v_number  // Value of 2 means "loaded and working".
 | 
				
			||||||
 | 
					    : false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (ok) {
 | 
				
			||||||
 | 
					    // Call() must be defined if provider claims to be working.
 | 
				
			||||||
 | 
					    snprintf(buf, sizeof(buf), "provider#%s#Call", name);
 | 
				
			||||||
 | 
					    if (!find_func((char_u *)buf)) {
 | 
				
			||||||
 | 
					      emsgf("provider: %s: g:loaded_%s_provider=2 but %s is not defined",
 | 
				
			||||||
 | 
					            name, name, buf);
 | 
				
			||||||
 | 
					      ok = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ok;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Writes "<sourcing_name>:<sourcing_lnum>" to `buf[bufsize]`.
 | 
					/// Writes "<sourcing_name>:<sourcing_lnum>" to `buf[bufsize]`.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					let g:loaded_clipboard_provider = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let g:test_clip = { '+': [''], '*': [''], }
 | 
					let g:test_clip = { '+': [''], '*': [''], }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let s:methods = {}
 | 
					let s:methods = {}
 | 
				
			||||||
@@ -35,7 +37,6 @@ function! s:methods.set(lines, regtype, reg)
 | 
				
			|||||||
  let g:test_clip[a:reg] = [a:lines, a:regtype]
 | 
					  let g:test_clip[a:reg] = [a:lines, a:regtype]
 | 
				
			||||||
endfunction
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
function! provider#clipboard#Call(method, args)
 | 
					function! provider#clipboard#Call(method, args)
 | 
				
			||||||
  return call(s:methods[a:method],a:args,s:methods)
 | 
					  return call(s:methods[a:method],a:args,s:methods)
 | 
				
			||||||
endfunction
 | 
					endfunction
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								test/functional/fixtures/autoload/provider/python.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/functional/fixtures/autoload/provider/python.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					" Dummy test provider, missing this required variable:
 | 
				
			||||||
 | 
					"   let g:loaded_brokenenabled_provider = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! provider#python#Call(method, args)
 | 
				
			||||||
 | 
					  return 42
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
							
								
								
									
										2
									
								
								test/functional/fixtures/autoload/provider/ruby.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								test/functional/fixtures/autoload/provider/ruby.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					" A dummy test provider
 | 
				
			||||||
 | 
					let g:loaded_ruby_provider = 2
 | 
				
			||||||
							
								
								
									
										26
									
								
								test/functional/provider/provider_spec.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								test/functional/provider/provider_spec.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					local helpers = require('test.functional.helpers')(after_each)
 | 
				
			||||||
 | 
					local clear, eval = helpers.clear, helpers.eval
 | 
				
			||||||
 | 
					local command = helpers.command
 | 
				
			||||||
 | 
					local expect_err = helpers.expect_err
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('providers', function()
 | 
				
			||||||
 | 
					  before_each(function()
 | 
				
			||||||
 | 
					    clear('--cmd', 'let &rtp = "test/functional/fixtures,".&rtp')
 | 
				
			||||||
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('with #Call(), missing g:loaded_xx_provider', function()
 | 
				
			||||||
 | 
					    command('set loadplugins')
 | 
				
			||||||
 | 
					    -- Using test-fixture with broken impl:
 | 
				
			||||||
 | 
					    -- test/functional/fixtures/autoload/provider/python.vim
 | 
				
			||||||
 | 
					    expect_err('Vim:provider: python: missing required variable g:loaded_python_provider',
 | 
				
			||||||
 | 
					      eval, "has('python')")
 | 
				
			||||||
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('with g:loaded_xx_provider, missing #Call()', function()
 | 
				
			||||||
 | 
					    -- Using test-fixture with broken impl:
 | 
				
			||||||
 | 
					    -- test/functional/fixtures/autoload/provider/ruby.vim
 | 
				
			||||||
 | 
					    expect_err('Vim:provider: ruby: g:loaded_ruby_provider=2 but provider#ruby#Call is not defined',
 | 
				
			||||||
 | 
					      eval, "has('ruby')")
 | 
				
			||||||
 | 
					  end)
 | 
				
			||||||
 | 
					end)
 | 
				
			||||||
		Reference in New Issue
	
	Block a user