aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
authorRui Abreu Ferreira <raf-ep@gmx.com>2019-06-09 18:22:10 +0100
committerJustin M. Keyes <justinkz@gmail.com>2019-08-04 13:23:46 +0200
commit2cfe4748e57bd510b98ca81bd915f801f5a50bb5 (patch)
tree7fb2e4ce22b5c800a84c1408c5357e2035c4f296 /src/nvim/eval.c
parent2860453c4f9ad6abd7a967f9278401ae84a927e2 (diff)
downloadrneovim-2cfe4748e57bd510b98ca81bd915f801f5a50bb5.tar.gz
rneovim-2cfe4748e57bd510b98ca81bd915f801f5a50bb5.tar.bz2
rneovim-2cfe4748e57bd510b98ca81bd915f801f5a50bb5.zip
provider: let providers decide their status
Instead of deciding provider status in eval_has_provider, move the decision to the provider Vim scripts. Previously, provider loading worked as follows: 1. eval_has_provider() verified provider availability by searching for the provider#providername#Call function and cached this verificaion as a static variable for some providers 2. providers short-circuited on loading to prevent the definition of the Call function (with the exception of the node provider that did not) This commit changes the expected interface between nvim and its providers to facilitate provider reloading, by splitting the verification of the provider from the availability of the Call function. eval_has_provider() now checks for a provider#providername#enabled variable. It is up to the provider script to set this to 0 or 1 accordingly. eval_call_provider() remains unchanged. All providers hosting a Call function were updated to respect this. The clipboard provider now has a Reload function to reload the provider.
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r--src/nvim/eval.c61
1 files changed, 18 insertions, 43 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index cefd351dd7..ed01ca9f99 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -23968,52 +23968,27 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
return rettv;
}
-bool eval_has_provider(const char *name)
-{
-#define CHECK_PROVIDER(name) \
- if (has_##name == -1) { \
- has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \
- if (!has_##name) { \
- script_autoload("provider#" #name "#Call", \
- sizeof("provider#" #name "#Call") - 1, \
- false); \
- has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \
- } \
- }
-
- static int has_clipboard = -1;
- static int has_python = -1;
- static int has_python3 = -1;
- static int has_ruby = -1;
- typval_T args[1];
- args[0].v_type = VAR_UNKNOWN;
-
- if (strequal(name, "clipboard")) {
- CHECK_PROVIDER(clipboard);
- return has_clipboard;
- } else if (strequal(name, "python3")) {
- CHECK_PROVIDER(python3);
- return has_python3;
- } else if (strequal(name, "python")) {
- CHECK_PROVIDER(python);
- return has_python;
- } else if (strequal(name, "ruby")) {
- bool need_check_ruby = (has_ruby == -1);
- CHECK_PROVIDER(ruby);
- if (need_check_ruby && has_ruby == 1) {
- char *rubyhost = call_func_retstr("provider#ruby#Detect", 0, args, true);
- if (rubyhost) {
- if (*rubyhost == NUL) {
- // Invalid rubyhost executable. Gem is probably not installed.
- has_ruby = 0;
- }
- xfree(rubyhost);
- }
+/// Check if a named provider is enabled
+bool eval_has_provider(const char *provider)
+{
+ char enabled_varname[256];
+ int enabled_varname_len = snprintf(enabled_varname, sizeof(enabled_varname),
+ "provider#%s#enabled", provider);
+
+ typval_T tv;
+ if (get_var_tv(enabled_varname, enabled_varname_len, &tv,
+ NULL, false, false) == FAIL) {
+ char call_varname[256];
+ snprintf(call_varname, sizeof(call_varname), "provider#%s#Call", provider);
+ int has_call = !!find_func((char_u *)call_varname);
+
+ if (has_call && p_lpl) {
+ emsgf("Provider '%s' failed to set %s", provider, enabled_varname);
}
- return has_ruby;
+ return false;
}
- return false;
+ return (tv.v_type == VAR_NUMBER) ? tv.vval.v_number != 0: true;
}
/// Writes "<sourcing_name>:<sourcing_lnum>" to `buf[bufsize]`.