aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/private/helpers.c2
-rw-r--r--src/nvim/api/vim.c17
-rw-r--r--src/nvim/eval.c144
-rw-r--r--src/nvim/ex_cmds2.c60
-rw-r--r--src/nvim/globals.h10
-rw-r--r--src/nvim/msgpack_rpc/channel.c11
-rw-r--r--src/nvim/ops.c44
-rw-r--r--src/nvim/os/event.c3
-rw-r--r--src/nvim/os/provider.c152
-rw-r--r--src/nvim/os/provider.h11
10 files changed, 193 insertions, 261 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index a7b48f3b7e..750b151d10 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -7,7 +7,6 @@
#include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/handle.h"
-#include "nvim/os/provider.h"
#include "nvim/ascii.h"
#include "nvim/vim.h"
#include "nvim/buffer.h"
@@ -548,7 +547,6 @@ Dictionary api_metadata(void)
msgpack_rpc_init_function_metadata(&metadata);
init_error_type_metadata(&metadata);
init_type_metadata(&metadata);
- provider_init_feature_metadata(&metadata);
}
return copy_object(DICTIONARY_OBJ(metadata)).data.dictionary;
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index b6bac1588a..addcbf62e9 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -11,7 +11,6 @@
#include "nvim/api/private/defs.h"
#include "nvim/api/buffer.h"
#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/os/provider.h"
#include "nvim/vim.h"
#include "nvim/buffer.h"
#include "nvim/window.h"
@@ -538,22 +537,6 @@ void vim_unsubscribe(uint64_t channel_id, String event)
channel_unsubscribe(channel_id, e);
}
-/// Registers the channel as the provider for `feature`. This fails if
-/// a provider for `feature` is already provided by another channel.
-///
-/// @param channel_id The channel id
-/// @param feature The feature name
-/// @param[out] err Details of an error that may have occurred
-void vim_register_provider(uint64_t channel_id, String feature, Error *err)
-{
- char buf[METHOD_MAXLEN];
- xstrlcpy(buf, feature.data, sizeof(buf));
-
- if (!provider_register(buf, channel_id)) {
- api_set_error(err, Validation, _("Feature doesn't exist"));
- }
-}
-
Array vim_get_api_info(uint64_t channel_id)
{
Array rv = ARRAY_DICT_INIT;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index a0e6f84259..498795dc38 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -89,7 +89,6 @@
#include "nvim/api/private/helpers.h"
#include "nvim/api/vim.h"
#include "nvim/os/dl.h"
-#include "nvim/os/provider.h"
#include "nvim/os/event.h"
#define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */
@@ -457,7 +456,7 @@ typedef struct {
} JobEvent;
#define JobEventFreer(x)
KMEMPOOL_INIT(JobEventPool, JobEvent, JobEventFreer)
-kmempool_t(JobEventPool) *job_event_pool = NULL;
+static kmempool_t(JobEventPool) *job_event_pool = NULL;
/*
* Initialize the global and v: variables.
@@ -5152,7 +5151,7 @@ void list_append_string(list_T *l, char_u *str, int len)
/*
* Append "n" to list "l".
*/
-static void list_append_number(list_T *l, varnumber_T n)
+void list_append_number(list_T *l, varnumber_T n)
{
listitem_T *li = listitem_alloc();
li->li_tv.v_type = VAR_NUMBER;
@@ -9987,7 +9986,7 @@ static void f_has(typval_T *argvars, typval_T *rettv)
}
}
- if (n == FALSE && provider_has_feature((char *)name)) {
+ if (n == FALSE && eval_has_provider((char *)name)) {
n = TRUE;
}
@@ -11695,7 +11694,7 @@ static void f_pumvisible(typval_T *argvars, typval_T *rettv)
*/
static void f_pyeval(typval_T *argvars, typval_T *rettv)
{
- script_host_eval("python_eval", argvars, rettv);
+ script_host_eval("python", argvars, rettv);
}
/*
@@ -12540,11 +12539,52 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv)
ADD(args, vim_to_object(tv));
}
+ scid_T save_current_SID;
+ uint8_t *save_sourcing_name, *save_autocmd_fname, *save_autocmd_match;
+ linenr_T save_sourcing_lnum;
+ int save_autocmd_fname_full, save_autocmd_bufnr;
+ void *save_funccalp;
+
+ if (provider_call_nesting) {
+ // If this is called from a provider function, restore the scope
+ // information of the caller.
+ save_current_SID = current_SID;
+ save_sourcing_name = sourcing_name;
+ save_sourcing_lnum = sourcing_lnum;
+ save_autocmd_fname = autocmd_fname;
+ save_autocmd_match = autocmd_match;
+ save_autocmd_fname_full = autocmd_fname_full;
+ save_autocmd_bufnr = autocmd_bufnr;
+ save_funccalp = save_funccal();
+ //
+ current_SID = provider_caller_scope.SID;
+ sourcing_name = provider_caller_scope.sourcing_name;
+ sourcing_lnum = provider_caller_scope.sourcing_lnum;
+ autocmd_fname = provider_caller_scope.autocmd_fname;
+ autocmd_match = provider_caller_scope.autocmd_match;
+ autocmd_fname_full = provider_caller_scope.autocmd_fname_full;
+ autocmd_bufnr = provider_caller_scope.autocmd_bufnr;
+ restore_funccal(provider_caller_scope.funccalp);
+ }
+
+
Error err = ERROR_INIT;
Object result = channel_send_call((uint64_t)argvars[0].vval.v_number,
(char *)argvars[1].vval.v_string,
args,
&err);
+
+ if (provider_call_nesting) {
+ current_SID = save_current_SID;
+ sourcing_name = save_sourcing_name;
+ sourcing_lnum = save_sourcing_lnum;
+ autocmd_fname = save_autocmd_fname;
+ autocmd_match = save_autocmd_match;
+ autocmd_fname_full = save_autocmd_fname_full;
+ autocmd_bufnr = save_autocmd_bufnr;
+ restore_funccal(save_funccalp);
+ }
+
if (err.set) {
vim_report_error(cstr_as_string(err.msg));
goto end;
@@ -19671,22 +19711,94 @@ static void apply_job_autocmds(int id, char *name, char *type,
}
}
-static void script_host_eval(char *method, typval_T *argvars, typval_T *rettv)
+static void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
{
- Array args = ARRAY_DICT_INIT;
- ADD(args, vim_to_object(argvars));
- Object result = provider_call(method, args);
-
- if (result.type == kObjectTypeNil) {
+ if (check_restricted() || check_secure()) {
return;
}
- Error err = ERROR_INIT;
-
- if (!object_to_vim(result, rettv, &err)){
- EMSG("Error converting value back to vim");
+ if (argvars[0].v_type != VAR_STRING) {
+ EMSG(_(e_invarg));
}
- api_free_object(result);
+ list_T *args = list_alloc();
+ list_append_string(args, argvars[0].vval.v_string, -1);
+ *rettv = eval_call_provider(name, "eval", args);
}
+typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
+{
+ char func[256];
+ int name_len = snprintf(func, sizeof(func), "provider#%s#Call", provider);
+
+ // Save caller scope information
+ struct caller_scope saved_provider_caller_scope = provider_caller_scope;
+ provider_caller_scope = (struct caller_scope) {
+ .SID = current_SID,
+ .sourcing_name = sourcing_name,
+ .sourcing_lnum = sourcing_lnum,
+ .autocmd_fname = autocmd_fname,
+ .autocmd_match = autocmd_match,
+ .autocmd_fname_full = autocmd_fname_full,
+ .autocmd_bufnr = autocmd_bufnr,
+ .funccalp = save_funccal()
+ };
+ provider_call_nesting++;
+
+ typval_T argvars[3] = {
+ {.v_type = VAR_STRING, .vval.v_string = (uint8_t *)method, .v_lock = 0},
+ {.v_type = VAR_LIST, .vval.v_list = arguments, .v_lock = 0},
+ {.v_type = VAR_UNKNOWN}
+ };
+ typval_T rettv = {.v_type = VAR_UNKNOWN, .v_lock = 0};
+ arguments->lv_refcount++;
+
+ int dummy;
+ (void)call_func((uint8_t *)func,
+ name_len,
+ &rettv,
+ 2,
+ argvars,
+ curwin->w_cursor.lnum,
+ curwin->w_cursor.lnum,
+ &dummy,
+ true,
+ NULL);
+
+ arguments->lv_refcount--;
+ // Restore caller scope information
+ restore_funccal(provider_caller_scope.funccalp);
+ provider_caller_scope = saved_provider_caller_scope;
+ provider_call_nesting--;
+
+ return rettv;
+}
+
+bool eval_has_provider(char *name)
+{
+#define source_provider(name) \
+ do_source((uint8_t *)"$VIMRUNTIME/autoload/provider/" name ".vim", \
+ false, \
+ false)
+
+#define check_provider(name) \
+ if (has_##name == -1) { \
+ has_##name = !!find_func((uint8_t *)"provider#" #name "#Call"); \
+ if (!has_##name) { \
+ source_provider(#name); \
+ has_##name = !!find_func((uint8_t *)"provider#" #name "#Call"); \
+ } \
+ }
+
+ static int has_clipboard = -1, has_python = -1;
+
+ if (!strcmp(name, "clipboard")) {
+ check_provider(clipboard);
+ return has_clipboard;
+ } else if (!strcmp(name, "python")) {
+ check_provider(python);
+ return has_python;
+ }
+
+ return false;
+}
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 1636d62c74..96410897df 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -55,7 +55,6 @@
#include "nvim/os/os.h"
#include "nvim/os/shell.h"
#include "nvim/os/fs_defs.h"
-#include "nvim/os/provider.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h"
@@ -791,17 +790,17 @@ void ex_profile(exarg_T *eap)
void ex_python(exarg_T *eap)
{
- script_host_execute("python_execute", eap);
+ script_host_execute("python", eap);
}
void ex_pyfile(exarg_T *eap)
{
- script_host_execute_file("python_execute_file", eap);
+ script_host_execute_file("python", eap);
}
void ex_pydo(exarg_T *eap)
{
- script_host_do_range("python_do_range", eap);
+ script_host_do_range("python", eap);
}
@@ -3254,46 +3253,43 @@ char_u *get_locales(expand_T *xp, int idx)
#endif
-static void script_host_execute(char *method, exarg_T *eap)
+static void script_host_execute(char *name, exarg_T *eap)
{
- char *script = (char *)script_get(eap, eap->arg);
+ uint8_t *script = script_get(eap, eap->arg);
if (!eap->skip) {
- Array args = ARRAY_DICT_INIT;
- ADD(args, STRING_OBJ(cstr_to_string(script ? script : (char *)eap->arg)));
- // add current range
- ADD(args, INTEGER_OBJ(eap->line1));
- ADD(args, INTEGER_OBJ(eap->line2));
- Object result = provider_call(method, args);
- // We don't care about the result, so free it just in case a bad provider
- // returned something
- api_free_object(result);
+ list_T *args = list_alloc();
+ // script
+ list_append_string(args, script ? script : eap->arg, -1);
+ // current range
+ list_append_number(args, eap->line1);
+ list_append_number(args, eap->line2);
+ (void)eval_call_provider(name, "execute", args);
}
free(script);
}
-static void script_host_execute_file(char *method, exarg_T *eap)
+static void script_host_execute_file(char *name, exarg_T *eap)
{
- char buffer[MAXPATHL];
- vim_FullName(eap->arg, (uint8_t *)buffer, sizeof(buffer), false);
+ uint8_t buffer[MAXPATHL];
+ vim_FullName(eap->arg, buffer, sizeof(buffer), false);
- Array args = ARRAY_DICT_INIT;
- ADD(args, STRING_OBJ(cstr_to_string(buffer)));
- // add current range
- ADD(args, INTEGER_OBJ(eap->line1));
- ADD(args, INTEGER_OBJ(eap->line2));
- Object result = provider_call(method, args);
- api_free_object(result);
+ list_T *args = list_alloc();
+ // filename
+ list_append_string(args, buffer, -1);
+ // current range
+ list_append_number(args, eap->line1);
+ list_append_number(args, eap->line2);
+ (void)eval_call_provider(name, "execute_file", args);
}
-static void script_host_do_range(char *method, exarg_T *eap)
+static void script_host_do_range(char *name, exarg_T *eap)
{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(eap->line1));
- ADD(args, INTEGER_OBJ(eap->line2));
- ADD(args, STRING_OBJ(cstr_to_string((char *)eap->arg)));
- Object result = provider_call(method, args);
- api_free_object(result);
+ list_T *args = list_alloc();
+ list_append_number(args, eap->line1);
+ list_append_number(args, eap->line2);
+ list_append_string(args, eap->arg, -1);
+ (void)eval_call_provider(name, "do_range", args);
}
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 2a4d6da8dc..cd9f7a648f 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -360,6 +360,16 @@ EXTERN int garbage_collect_at_exit INIT(= FALSE);
/* ID of script being sourced or was sourced to define the current function. */
EXTERN scid_T current_SID INIT(= 0);
+// Scope information for the code that indirectly triggered the current
+// provider function call
+EXTERN struct caller_scope {
+ scid_T SID;
+ uint8_t *sourcing_name, *autocmd_fname, *autocmd_match;
+ linenr_T sourcing_lnum;
+ int autocmd_fname_full, autocmd_bufnr;
+ void *funccalp;
+} provider_caller_scope;
+EXTERN int provider_call_nesting INIT(= 0);
/* Magic number used for hashitem "hi_key" value indicating a deleted item.
* Only the address is used. */
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index da1dc8d1b5..0c04a7b23e 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -137,7 +137,6 @@ uint64_t channel_from_job(char **argv)
&status);
if (status <= 0) {
- free_channel(channel);
return 0;
}
@@ -381,7 +380,7 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof)
bool is_response = is_rpc_response(&unpacked.data);
log_client_msg(channel->id, !is_response, unpacked.data);
- if (kv_size(channel->call_stack) && is_response) {
+ if (is_response) {
if (is_valid_rpc_response(&unpacked.data, channel)) {
complete_call(&unpacked.data, channel);
} else {
@@ -389,8 +388,8 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof)
snprintf(buf,
sizeof(buf),
"Channel %" PRIu64 " returned a response that doesn't have "
- " a matching id for the current RPC call. Ensure the client "
- " is properly synchronized",
+ "a matching request id. Ensure the client is properly "
+ "synchronized",
channel->id);
call_set_error(channel, buf);
}
@@ -685,8 +684,8 @@ static bool is_valid_rpc_response(msgpack_object *obj, Channel *channel)
{
uint64_t response_id = obj->via.array.ptr[1].via.u64;
// Must be equal to the frame at the stack's bottom
- return response_id == kv_A(channel->call_stack,
- kv_size(channel->call_stack) - 1)->request_id;
+ return kv_size(channel->call_stack) && response_id
+ == kv_A(channel->call_stack, kv_size(channel->call_stack) - 1)->request_id;
}
static void complete_call(msgpack_object *obj, Channel *channel)
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 2523e21c42..5ef605bb3b 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -48,7 +48,6 @@
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/window.h"
-#include "nvim/os/provider.h"
#include "nvim/api/private/helpers.h"
/*
@@ -1308,7 +1307,7 @@ bool adjust_clipboard_register(int *rp)
{
// If no reg. specified and 'unnamedclip' is set, use the
// clipboard register.
- if (*rp == 0 && p_unc && provider_has_feature("clipboard")) {
+ if (*rp == 0 && p_unc && eval_has_provider("clipboard")) {
*rp = '+';
return true;
}
@@ -5240,28 +5239,29 @@ static void copy_register(struct yankreg *dest, struct yankreg *src)
static void get_clipboard(int name)
{
if (!(name == '*' || name == '+'
- || (p_unc && !name && provider_has_feature("clipboard")))) {
+ || (p_unc && !name && eval_has_provider("clipboard")))) {
return;
}
struct yankreg *reg = &y_regs[CLIP_REGISTER];
free_register(reg);
- Array args = ARRAY_DICT_INIT;
- Object result = provider_call("clipboard_get", args);
+ list_T *args = list_alloc();
+ typval_T result = eval_call_provider("clipboard", "get", args);
- if (result.type != kObjectTypeArray) {
+ if (result.v_type != VAR_LIST) {
goto err;
}
- Array lines = result.data.array;
- reg->y_array = xcalloc(lines.size, sizeof(uint8_t *));
- reg->y_size = lines.size;
+ list_T *lines = result.vval.v_list;
+ reg->y_array = xcalloc(lines->lv_len, sizeof(uint8_t *));
+ reg->y_size = lines->lv_len;
- for (size_t i = 0; i < lines.size; i++) {
- if (lines.items[i].type != kObjectTypeString) {
+ int i = 0;
+ for (listitem_T *li = lines->lv_first; li != NULL; li = li->li_next) {
+ if (li->li_tv.v_type != VAR_STRING) {
goto err;
}
- reg->y_array[i] = (uint8_t *)lines.items[i].data.string.data;
+ reg->y_array[i++] = (uint8_t *)xstrdup((char *)li->li_tv.vval.v_string);
}
if (!name && p_unc) {
@@ -5272,8 +5272,12 @@ static void get_clipboard(int name)
return;
err:
- api_free_object(result);
- free(reg->y_array);
+ if (reg->y_array) {
+ for (int i = 0; i < reg->y_size; i++) {
+ free(reg->y_array[i]);
+ }
+ free(reg->y_array);
+ }
reg->y_array = NULL;
reg->y_size = 0;
EMSG("Clipboard provider returned invalid data");
@@ -5282,7 +5286,7 @@ err:
static void set_clipboard(int name)
{
if (!(name == '*' || name == '+'
- || (p_unc && !name && provider_has_feature("clipboard")))) {
+ || (p_unc && !name && eval_has_provider("clipboard")))) {
return;
}
@@ -5293,15 +5297,11 @@ static void set_clipboard(int name)
copy_register(reg, &y_regs[0]);
}
- Array lines = ARRAY_DICT_INIT;
+ list_T *lines = list_alloc();
for (int i = 0; i < reg->y_size; i++) {
- ADD(lines, STRING_OBJ(cstr_to_string((char *)reg->y_array[i])));
+ list_append_string(lines, reg->y_array[i], -1);
}
- Array args = ARRAY_DICT_INIT;
- ADD(args, ARRAY_OBJ(lines));
-
- Object result = provider_call("clipboard_set", args);
- api_free_object(result);
+ (void)eval_call_provider("clipboard", "set", lines);
}
diff --git a/src/nvim/os/event.c b/src/nvim/os/event.c
index 5a5da5cd63..1477072f4f 100644
--- a/src/nvim/os/event.c
+++ b/src/nvim/os/event.c
@@ -11,7 +11,6 @@
#include "nvim/msgpack_rpc/channel.h"
#include "nvim/msgpack_rpc/server.h"
#include "nvim/msgpack_rpc/helpers.h"
-#include "nvim/os/provider.h"
#include "nvim/os/signal.h"
#include "nvim/os/rstream.h"
#include "nvim/os/wstream.h"
@@ -62,8 +61,6 @@ void event_init(void)
// finish mspgack-rpc initialization
channel_init();
server_init();
- // Providers
- provider_init();
}
void event_teardown(void)
diff --git a/src/nvim/os/provider.c b/src/nvim/os/provider.c
deleted file mode 100644
index 414c8841fa..0000000000
--- a/src/nvim/os/provider.c
+++ /dev/null
@@ -1,152 +0,0 @@
-#include <stdint.h>
-#include <inttypes.h>
-#include <stdbool.h>
-#include <assert.h>
-
-#include "nvim/os/provider.h"
-#include "nvim/memory.h"
-#include "nvim/api/vim.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/api/private/defs.h"
-#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/os/shell.h"
-#include "nvim/os/os.h"
-#include "nvim/log.h"
-#include "nvim/map.h"
-#include "nvim/message.h"
-
-#define FEATURE_COUNT (sizeof(features) / sizeof(features[0]))
-
-#define FEATURE(feature_name, ...) { \
- .name = feature_name, \
- .channel_id = 0, \
- .methods = (char *[]){__VA_ARGS__, NULL} \
-}
-
-typedef struct {
- char *name, **methods;
- size_t name_length;
- uint64_t channel_id;
-} Feature;
-
-static Feature features[] = {
- FEATURE("python",
- "python_execute",
- "python_execute_file",
- "python_do_range",
- "python_eval"),
-
- FEATURE("clipboard",
- "clipboard_get",
- "clipboard_set")
-};
-
-static PMap(cstr_t) *registered_providers = NULL;
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "os/provider.c.generated.h"
-#endif
-
-
-void provider_init(void)
-{
- registered_providers = pmap_new(cstr_t)();
-}
-
-bool provider_has_feature(char *name)
-{
- Feature *f = find_feature(name);
- return f != NULL && channel_exists(f->channel_id);
-}
-
-bool provider_register(char *name, uint64_t channel_id)
-{
- Feature *f = find_feature(name);
-
- if (!f) {
- return false;
- }
-
- if (f->channel_id && channel_exists(f->channel_id)) {
- ILOG("Feature \"%s\" is already provided by another channel"
- "(will be replaced)", name);
- }
-
- DLOG("Registering provider for \"%s\"", name);
- f->channel_id = channel_id;
-
- // Associate all method names with the feature struct
- size_t i;
- char *method;
- for (method = f->methods[i = 0]; method; method = f->methods[++i]) {
- pmap_put(cstr_t)(registered_providers, method, f);
- DLOG("Channel \"%" PRIu64 "\" will be sent requests for \"%s\"",
- channel_id,
- method);
- }
-
- ILOG("Registered channel %" PRIu64 " as the provider for the \"%s\" feature",
- channel_id,
- name);
-
- return true;
-}
-
-Object provider_call(char *method, Array args)
-{
- Feature *f = pmap_get(cstr_t)(registered_providers, method);
-
- if (!f || !channel_exists(f->channel_id)) {
- char buf[256];
- snprintf(buf,
- sizeof(buf),
- "Provider for method \"%s\" is not available",
- method);
- vim_report_error(cstr_as_string(buf));
- api_free_array(args);
- return NIL;
- }
-
- Error err = ERROR_INIT;
- Object result = NIL = channel_send_call(f->channel_id, method, args, &err);
-
- if (err.set) {
- vim_report_error(cstr_as_string(err.msg));
- api_free_object(result);
- return NIL;
- }
-
- return result;
-}
-
-void provider_init_feature_metadata(Dictionary *metadata)
-{
- Dictionary md = ARRAY_DICT_INIT;
-
- for (size_t i = 0; i < FEATURE_COUNT; i++) {
- Array methods = ARRAY_DICT_INIT;
- Feature *f = &features[i];
-
- size_t j;
- char *method;
- for (method = f->methods[j = 0]; method; method = f->methods[++j]) {
- ADD(methods, STRING_OBJ(cstr_to_string(method)));
- }
-
- PUT(md, f->name, ARRAY_OBJ(methods));
- }
-
- PUT(*metadata, "features", DICTIONARY_OBJ(md));
-}
-
-static Feature * find_feature(char *name)
-{
- for (size_t i = 0; i < FEATURE_COUNT; i++) {
- Feature *f = &features[i];
- if (!STRICMP(name, f->name)) {
- return f;
- }
- }
-
- return NULL;
-}
diff --git a/src/nvim/os/provider.h b/src/nvim/os/provider.h
deleted file mode 100644
index c6f12e02dd..0000000000
--- a/src/nvim/os/provider.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef NVIM_OS_PROVIDER_H
-#define NVIM_OS_PROVIDER_H
-
-#include "nvim/api/private/defs.h"
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "os/provider.h.generated.h"
-#endif
-
-#endif // NVIM_OS_PROVIDER_H
-