summaryrefslogtreecommitdiff
path: root/lua/lvim/utils/modules.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/lvim/utils/modules.lua')
-rw-r--r--lua/lvim/utils/modules.lua98
1 files changed, 98 insertions, 0 deletions
diff --git a/lua/lvim/utils/modules.lua b/lua/lvim/utils/modules.lua
new file mode 100644
index 00000000..d5674483
--- /dev/null
+++ b/lua/lvim/utils/modules.lua
@@ -0,0 +1,98 @@
+local M = {}
+
+local Log = require "lvim.core.log"
+-- revisit this
+-- function prequire(package)
+-- local status, lib = pcall(require, package)
+-- if status then
+-- return lib
+-- else
+-- vim.notify("Failed to require '" .. package .. "' from " .. debug.getinfo(2).source)
+-- return nil
+-- end
+-- end
+
+local function _assign(old, new, k)
+ local otype = type(old[k])
+ local ntype = type(new[k])
+ -- print("hi")
+ if (otype == "thread" or otype == "userdata") or (ntype == "thread" or ntype == "userdata") then
+ vim.notify(string.format("warning: old or new attr %s type be thread or userdata", k))
+ end
+ old[k] = new[k]
+end
+
+local function _replace(old, new, repeat_tbl)
+ if repeat_tbl[old] then
+ return
+ end
+ repeat_tbl[old] = true
+
+ local dellist = {}
+ for k, _ in pairs(old) do
+ if not new[k] then
+ table.insert(dellist, k)
+ end
+ end
+ for _, v in ipairs(dellist) do
+ old[v] = nil
+ end
+
+ for k, _ in pairs(new) do
+ if not old[k] then
+ old[k] = new[k]
+ else
+ if type(old[k]) ~= type(new[k]) then
+ Log:debug(
+ string.format("Reloader: mismatch between old [%s] and new [%s] type for [%s]", type(old[k]), type(new[k]), k)
+ )
+ _assign(old, new, k)
+ else
+ if type(old[k]) == "table" then
+ _replace(old[k], new[k], repeat_tbl)
+ else
+ _assign(old, new, k)
+ end
+ end
+ end
+ end
+end
+
+M.require_clean = function(m)
+ package.loaded[m] = nil
+ _G[m] = nil
+ local _, module = pcall(require, m)
+ return module
+end
+
+M.require_safe = function(mod)
+ local status_ok, module = pcall(require, mod)
+ if not status_ok then
+ local trace = debug.getinfo(2, "SL")
+ local shorter_src = trace.short_src
+ local lineinfo = shorter_src .. ":" .. (trace.currentline or trace.linedefined)
+ local msg = string.format("%s : skipped loading [%s]", lineinfo, mod)
+ Log:debug(msg)
+ end
+ return module
+end
+
+M.reload = function(mod)
+ if not package.loaded[mod] then
+ return M.require_safe(mod)
+ end
+
+ local old = package.loaded[mod]
+ package.loaded[mod] = nil
+ local new = M.require_safe(mod)
+
+ if type(old) == "table" and type(new) == "table" then
+ local repeat_tbl = {}
+ _replace(old, new, repeat_tbl)
+ end
+
+ package.loaded[mod] = old
+ return old
+end
+
+return M