From e5bcf01c759e7c833d8a5f1fcf665b6ea32a7c16 Mon Sep 17 00:00:00 2001 From: kylo252 <59826753+kylo252@users.noreply.github.com> Date: Tue, 4 Oct 2022 19:23:52 +0200 Subject: refactor: more deliberate reload (#3133) --- lua/lvim/utils/hooks.lua | 2 +- lua/lvim/utils/modules.lua | 98 ++++++++++++++++++++++++++++++++++++++++++++++ lua/lvim/utils/reload.lua | 80 ------------------------------------- 3 files changed, 99 insertions(+), 81 deletions(-) create mode 100644 lua/lvim/utils/modules.lua delete mode 100644 lua/lvim/utils/reload.lua (limited to 'lua/lvim/utils') diff --git a/lua/lvim/utils/hooks.lua b/lua/lvim/utils/hooks.lua index fd78ef19..4101c573 100644 --- a/lua/lvim/utils/hooks.lua +++ b/lua/lvim/utils/hooks.lua @@ -61,7 +61,7 @@ function M.run_post_update() vim.wait(1000, function() return false end) - local ret = require_clean("lvim.utils.git").switch_lvim_branch(compat_tag) + local ret = reload("lvim.utils.git").switch_lvim_branch(compat_tag) if ret then vim.notify("Reverted to the last known compatible version: " .. compat_tag, vim.log.levels.WARN) end 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 diff --git a/lua/lvim/utils/reload.lua b/lua/lvim/utils/reload.lua deleted file mode 100644 index 46392349..00000000 --- a/lua/lvim/utils/reload.lua +++ /dev/null @@ -1,80 +0,0 @@ -local M = {} - --- 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 - vim.notify(string.format("warning: attr %s old type no equal new type!!!", 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.reload = function(mod) - if not package.loaded[mod] then - local m = require(mod) - return m - end - -- vim.notify "begin reload!!!" - - local old = package.loaded[mod] - package.loaded[mod] = nil - local new = require(mod) - - if type(old) == "table" and type(new) == "table" then - -- vim.notify "pick object in new module to old module!!!" - local repeat_tbl = {} - _replace(old, new, repeat_tbl) - end - - package.loaded[mod] = old - -- vim.notify "finish reload!!!" - return old -end - -return M -- cgit v1.2.3