summaryrefslogtreecommitdiffstats
path: root/src/if_lua.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-05-31 14:08:12 +0200
committerBram Moolenaar <Bram@vim.org>2020-05-31 14:08:12 +0200
commit788fbb47079e6df4d4815d27273faf8390395029 (patch)
tree4257162a0428962e3aad34a926ff40d08b0d632d /src/if_lua.c
parent5cd1cb9ff9d04979ff4cbc36ca8416d83364505d (diff)
patch 8.2.0858: not easy to require Lua modulesv8.2.0858
Problem: Not easy to require Lua modules. Solution: Improve use of Lua path. (Prabir Shrestha, closes #6098)
Diffstat (limited to 'src/if_lua.c')
-rw-r--r--src/if_lua.c104
1 files changed, 95 insertions, 9 deletions
diff --git a/src/if_lua.c b/src/if_lua.c
index 3ecedaf7d6..75231b4c27 100644
--- a/src/if_lua.c
+++ b/src/if_lua.c
@@ -2061,15 +2061,80 @@ luaV_setref(lua_State *L)
}
#define LUA_VIM_FN_CODE \
- "vim.fn = setmetatable({}, {"\
- " __index = function (t, key)"\
- " local function _fn(...)"\
- " return vim.call(key, ...)"\
- " end"\
- " t[key] = _fn"\
- " return _fn"\
- " end"\
- "})"
+ "vim.fn = setmetatable({}, {\n"\
+ " __index = function (t, key)\n"\
+ " local function _fn(...)\n"\
+ " return vim.call(key, ...)\n"\
+ " end\n"\
+ " t[key] = _fn\n"\
+ " return _fn\n"\
+ " end\n"\
+ " })"
+
+#define LUA_VIM_UPDATE_PACKAGE_PATHS \
+ "local last_vim_paths = {}\n"\
+ "vim._update_package_paths = function ()\n"\
+ " local cur_vim_paths = {}\n"\
+ " local function split(s, delimiter)\n"\
+ " result = {}\n"\
+ " for match in (s..delimiter):gmatch(\"(.-)\"..delimiter) do\n"\
+ " table.insert(result, match)\n"\
+ " end\n"\
+ " return result\n"\
+ " end\n"\
+ " local rtps = split(vim.eval('&runtimepath'), ',')\n"\
+ " local sep = package.config:sub(1, 1)\n"\
+ " for _, key in ipairs({'path', 'cpath'}) do\n"\
+ " local orig_str = package[key] .. ';'\n"\
+ " local pathtrails_ordered = {}\n"\
+ " -- Note: ignores trailing item without trailing `;`. Not using something\n"\
+ " -- simpler in order to preserve empty items (stand for default path).\n"\
+ " local orig = {}\n"\
+ " for s in orig_str:gmatch('[^;]*;') do\n"\
+ " s = s:sub(1, -2) -- Strip trailing semicolon\n"\
+ " orig[#orig + 1] = s\n"\
+ " end\n"\
+ " if key == 'path' then\n"\
+ " -- /?.lua and /?/init.lua\n"\
+ " pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}\n"\
+ " else\n"\
+ " local pathtrails = {}\n"\
+ " for _, s in ipairs(orig) do\n"\
+ " -- Find out path patterns. pathtrail should contain something like\n"\
+ " -- /?.so, \?.dll. This allows not to bother determining what correct\n"\
+ " -- suffixes are.\n"\
+ " local pathtrail = s:match('[/\\\\][^/\\\\]*%?.*$')\n"\
+ " if pathtrail and not pathtrails[pathtrail] then\n"\
+ " pathtrails[pathtrail] = true\n"\
+ " pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail\n"\
+ " end\n"\
+ " end\n"\
+ " end\n"\
+ " local new = {}\n"\
+ " for _, rtp in ipairs(rtps) do\n"\
+ " if not rtp:match(';') then\n"\
+ " for _, pathtrail in pairs(pathtrails_ordered) do\n"\
+ " local new_path = rtp .. sep .. 'lua' .. pathtrail\n"\
+ " -- Always keep paths from &runtimepath at the start:\n"\
+ " -- append them here disregarding orig possibly containing one of them.\n"\
+ " new[#new + 1] = new_path\n"\
+ " cur_vim_paths[new_path] = true\n"\
+ " end\n"\
+ " end\n"\
+ " end\n"\
+ " for _, orig_path in ipairs(orig) do\n"\
+ " -- Handle removing obsolete paths originating from &runtimepath: such\n"\
+ " -- paths either belong to cur_nvim_paths and were already added above or\n"\
+ " -- to last_nvim_paths and should not be added at all if corresponding\n"\
+ " -- entry was removed from &runtimepath list.\n"\
+ " if not (cur_vim_paths[orig_path] or last_vim_paths[orig_path]) then\n"\
+ " new[#new + 1] = orig_path\n"\
+ " end\n"\
+ " end\n"\
+ " package[key] = table.concat(new, ';')\n"\
+ " end\n"\
+ " last_vim_paths = cur_vim_paths\n"\
+ "end"
static int
luaopen_vim(lua_State *L)
@@ -2128,6 +2193,14 @@ luaopen_vim(lua_State *L)
lua_setglobal(L, LUAVIM_NAME);
// custom code
(void)luaL_dostring(L, LUA_VIM_FN_CODE);
+ (void)luaL_dostring(L, LUA_VIM_UPDATE_PACKAGE_PATHS);
+
+ lua_getglobal(L, "vim");
+ lua_getfield(L, -1, "_update_package_paths");
+
+ if (lua_pcall(L, 0, 0, 0))
+ luaV_emsg(L);
+
return 0;
}
@@ -2329,4 +2402,17 @@ set_ref_in_lua(int copyID)
return aborted;
}
+ void
+update_package_paths_in_lua()
+{
+ if (lua_isopen())
+ {
+ lua_getglobal(L, "vim");
+ lua_getfield(L, -1, "_update_package_paths");
+
+ if (lua_pcall(L, 0, 0, 0))
+ luaV_emsg(L);
+ }
+}
+
#endif