diff options
author | bfredl <bjorn.linse@gmail.com> | 2022-03-01 14:27:19 +0100 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2022-03-03 20:03:30 +0100 |
commit | f9faba88fdc46b2dd1a979a37ba61b000830ff3a (patch) | |
tree | 2780af6feccd0d488c32578f535257fa358b0813 /src/nvim/lua/executor.c | |
parent | 7211d8ef21cd93365c5f0582c5a0115e84c011ce (diff) | |
download | rneovim-f9faba88fdc46b2dd1a979a37ba61b000830ff3a.tar.gz rneovim-f9faba88fdc46b2dd1a979a37ba61b000830ff3a.tar.bz2 rneovim-f9faba88fdc46b2dd1a979a37ba61b000830ff3a.zip |
refactor(lua): reorganize builtin modules, phase 1
Diffstat (limited to 'src/nvim/lua/executor.c')
-rw-r--r-- | src/nvim/lua/executor.c | 175 |
1 files changed, 75 insertions, 100 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 7ac80f01f0..e233e0e6d0 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -53,6 +53,12 @@ typedef struct { String lua_err_str; } LuaError; +typedef struct { + char *name; + const uint8_t *data; + size_t size; +} ModuleDef; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "lua/executor.c.generated.h" # include "lua/vim_module.generated.h" @@ -519,60 +525,70 @@ static void nlua_common_vim_init(lua_State *lstate, bool is_thread) lua_pop(lstate, 3); } -static void nlua_common_package_init(lua_State *lstate) - FUNC_ATTR_NONNULL_ALL +static void nlua_preload_modules(lua_State *lstate) { - { - const char *code = (char *)&shared_module[0]; - if (luaL_loadbuffer(lstate, code, sizeof(shared_module) - 1, "@vim/shared.lua") - || nlua_pcall(lstate, 0, 0)) { - nlua_error(lstate, _("E5106: Error while creating shared module: %.*s\n")); - return; - } - } + lua_getglobal(lstate, "package"); // [package] + lua_getfield(lstate, -1, "preload"); // [package, preload] + for (size_t i = 0; i < ARRAY_SIZE(builtin_modules); i++) { + ModuleDef def = builtin_modules[i]; + lua_pushinteger(lstate, (long)i); // [package, preload, i] + lua_pushcclosure(lstate, nlua_module_preloader, 1); // [package, preload, cclosure] + lua_setfield(lstate, -2, def.name); // [package, preload] - { - const char *code = (char *)&lua_load_package_module[0]; - if (luaL_loadbuffer(lstate, code, sizeof(lua_load_package_module) - 1, "@vim/_load_package.lua") - || lua_pcall(lstate, 0, 0, 0)) { - nlua_error(lstate, _("E5106: Error while creating _load_package module: %.*s")); - return; + if (nlua_disable_preload && strequal(def.name, "vim")) { + break; } } - { - lua_getglobal(lstate, "package"); // [package] - lua_getfield(lstate, -1, "loaded"); // [package, loaded] + lua_pop(lstate, 2); // [] +} - const char *code = (char *)&inspect_module[0]; - if (luaL_loadbuffer(lstate, code, sizeof(inspect_module) - 1, "@vim/inspect.lua") - || nlua_pcall(lstate, 0, 1)) { - nlua_error(lstate, _("E5106: Error while creating inspect module: %.*s\n")); - return; - } +static int nlua_module_preloader(lua_State *lstate) +{ + size_t i = (size_t)lua_tointeger(lstate, lua_upvalueindex(1)); + ModuleDef def = builtin_modules[i]; + char name[256]; + name[0] = '@'; + size_t off = xstrlcpy(name+1, def.name, (sizeof name) - 2); + strchrsub(name+1, '.', '/'); + xstrlcpy(name+1+off, ".lua", (sizeof name)-2-off); - // [package, loaded, inspect] - lua_setfield(lstate, -2, "vim.inspect"); // [package, loaded] + if (luaL_loadbuffer(lstate, (const char *)def.data, def.size - 1, name)) { + return lua_error(lstate); } - { - const char *code = (char *)&lua_F_module[0]; - if (luaL_loadbuffer(lstate, code, sizeof(lua_F_module) - 1, "@vim/F.lua") - || nlua_pcall(lstate, 0, 1)) { - nlua_error(lstate, _("E5106: Error while creating vim.F module: %.*s\n")); - return; - } - // [package, loaded, module] - lua_setfield(lstate, -2, "vim.F"); // [package, loaded] + lua_call(lstate, 0, 1); // propagates error to caller + return 1; +} - lua_pop(lstate, 2); // [] +static bool nlua_common_package_init(lua_State *lstate) + FUNC_ATTR_NONNULL_ALL +{ + nlua_preload_modules(lstate); + + lua_getglobal(lstate, "require"); + lua_pushstring(lstate, "vim._load_package"); + if (nlua_pcall(lstate, 1, 0)) { + nlua_error(lstate, _("E5106: Error while creating _load_package module: %.*s\n")); + return false; + } + + // TODO(bfredl): ideally all initialization should be done as a single require + // call. + lua_getglobal(lstate, "require"); + lua_pushstring(lstate, "vim.shared"); + if (nlua_pcall(lstate, 1, 0)) { + nlua_error(lstate, _("E5106: Error while creating shared module: %.*s\n")); + return false; } + + return true; } /// Initialize lua interpreter state /// /// Called by lua interpreter itself to initialize state. -static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL +static bool nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { // print lua_pushcfunction(lstate, &nlua_print); @@ -638,59 +654,18 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL lua_setglobal(lstate, "vim"); - nlua_common_package_init(lstate); - - { - lua_getglobal(lstate, "package"); // [package] - lua_getfield(lstate, -1, "loaded"); // [package, loaded] - - char *code = (char *)&lua_filetype_module[0]; - if (luaL_loadbuffer(lstate, code, sizeof(lua_filetype_module) - 1, "@vim/filetype.lua") - || nlua_pcall(lstate, 0, 1)) { - nlua_error(lstate, _("E5106: Error while creating vim.filetype module: %.*s")); - return 1; - } - // [package, loaded, module] - lua_setfield(lstate, -2, "vim.filetype"); // [package, loaded] - - code = (char *)&lua_keymap_module[0]; - if (luaL_loadbuffer(lstate, code, sizeof(lua_keymap_module) - 1, "@vim/keymap.lua") - || nlua_pcall(lstate, 0, 1)) { - nlua_error(lstate, _("E5106: Error while creating vim.keymap module: %.*s")); - return 1; - } - // [package, loaded, module] - lua_setfield(lstate, -2, "vim.keymap"); // [package, loaded] - - lua_pop(lstate, 2); // [] - } - - { - const char *code = (char *)&vim_module[0]; - if (luaL_loadbuffer(lstate, code, sizeof(vim_module) - 1, "@vim.lua") - || nlua_pcall(lstate, 0, 0)) { - nlua_error(lstate, _("E5106: Error while creating vim module: %.*s\n")); - return 1; - } + if (!nlua_common_package_init(lstate)) { + return false; } - { - lua_getglobal(lstate, "package"); // [package] - lua_getfield(lstate, -1, "loaded"); // [package, loaded] - - const char *code = (char *)&lua_meta_module[0]; - if (luaL_loadbuffer(lstate, code, sizeof(lua_meta_module) - 1, "@vim/_meta.lua") - || nlua_pcall(lstate, 0, 1)) { - nlua_error(lstate, _("E5106: Error while creating vim._meta module: %.*s\n")); - return 1; - } - // [package, loaded, module] - lua_setfield(lstate, -2, "vim._meta"); // [package, loaded] - - lua_pop(lstate, 2); // [] + lua_getglobal(lstate, "require"); + lua_pushstring(lstate, "vim"); + if (nlua_pcall(lstate, 1, 0)) { + nlua_error(lstate, _("E5106: Error while creating vim module: %.*s\n")); + return false; } - return 0; + return true; } /// Initialize global lua interpreter @@ -707,11 +682,14 @@ void nlua_init(void) lua_State *lstate = luaL_newstate(); if (lstate == NULL) { - emsg(_("E970: Failed to initialize lua interpreter")); - preserve_exit(); + mch_errmsg(_("E970: Failed to initialize lua interpreter\n")); + os_exit(1); } luaL_openlibs(lstate); - nlua_state_init(lstate); + if (!nlua_state_init(lstate)) { + mch_errmsg(_("E970: Failed to initialize builtin lua modules\n")); + os_exit(1); + } luv_set_thread_cb(nlua_thread_acquire_vm, nlua_common_free_all_mem); @@ -747,23 +725,20 @@ static lua_State *nlua_thread_acquire_vm(void) nlua_state_add_stdlib(lstate, true); + lua_createtable(lstate, 0, 0); + lua_pushcfunction(lstate, nlua_thr_api_nvim__get_runtime); + lua_setfield(lstate, -2, "nvim__get_runtime"); + lua_setfield(lstate, -2, "api"); + lua_setglobal(lstate, "vim"); nlua_common_package_init(lstate); - lua_getglobal(lstate, "vim"); lua_getglobal(lstate, "package"); lua_getfield(lstate, -1, "loaded"); - lua_getfield(lstate, -1, "vim.inspect"); - lua_setfield(lstate, -4, "inspect"); - lua_pop(lstate, 3); - lua_getglobal(lstate, "vim"); - lua_createtable(lstate, 0, 0); - lua_pushcfunction(lstate, nlua_thr_api_nvim__get_runtime); - lua_setfield(lstate, -2, "nvim__get_runtime"); - lua_setfield(lstate, -2, "api"); - lua_pop(lstate, 1); + lua_setfield(lstate, -2, "vim"); + lua_pop(lstate, 2); return lstate; } |