diff --git a/README.md b/README.md index a0fb32b..e8d1edb 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,8 @@ - [ ] other package manager artifacts still present? compiled etc - [x] rename `run` to `build` - [ ] delete lazy keymaps when a plugin loads -- [ ] temp colorscheme -- [x] allow setting up plugins through config +- [x] temp colorscheme +- [x] allow setting up plugins through config **fooo** - [x] task timeout - [ ] log file - [ ] deal with re-sourcing init.lua. Check a global? @@ -38,10 +38,10 @@ - [ ] git tests - [x] max concurrency - [x] ui border -- [ ] make sure we can reload specs while keeping state +- [x] make sure we can reload specs while keeping state - [ ] show disabled plugins (strikethrough?) - [ ] Import specs from other plugin managers -- [ ] use uv file watcher (or stat) to check for config changes +- [x] use uv file watcher (or stat) to check for config changes - [ ] [packspec](https://github.com/nvim-lua/nvim-package-specification) - [ ] add support to specify `engines`, `os` and `cpu` like in `package.json` - [ ] semver merging. Should check if two or more semver ranges are compatible and calculate the union range diff --git a/lua/lazy/core/config.lua b/lua/lazy/core/config.lua index 2385f7b..cc27d0c 100644 --- a/lua/lazy/core/config.lua +++ b/lua/lazy/core/config.lua @@ -33,7 +33,7 @@ M.defaults = { -- install missing plugins on startup. This doesn't increase startup time. missing = true, -- try to load one of the colorschemes in this list when starting an install during startup - -- the first colorscheme that is found will be used + -- the first colorscheme that is found will be loaded colorscheme = { "habamax" }, }, ui = { @@ -100,6 +100,7 @@ function M.setup(spec, opts) callback = function() require("lazy.core.cache").autosave() require("lazy.view").setup() + require("lazy.manage.reloader").enable() end, }) diff --git a/lua/lazy/core/handler.lua b/lua/lazy/core/handler.lua index b862d02..043853b 100644 --- a/lua/lazy/core/handler.lua +++ b/lua/lazy/core/handler.lua @@ -63,7 +63,9 @@ function M.trigger(groups, events, pattern) end Util.info(lines) end - vim.api.nvim_exec_autocmds(autocmd.event, { group = autocmd.group, modeline = false }) + Util.try(function() + vim.api.nvim_exec_autocmds(autocmd.event, { group = autocmd.group, modeline = false }) + end) end end end diff --git a/lua/lazy/core/plugin.lua b/lua/lazy/core/plugin.lua index cb76ed9..b83cd5a 100644 --- a/lua/lazy/core/plugin.lua +++ b/lua/lazy/core/plugin.lua @@ -195,6 +195,8 @@ function M.spec() -- spec is a module local function _load(name) local modname = name and (Config.spec .. "." .. name) or Config.spec + -- unload the module so we get a clean slate + ---@diagnostic disable-next-line: no-unknown package.loaded[modname] = nil Util.try(function() spec:normalize(require(modname)) diff --git a/lua/lazy/manage/init.lua b/lua/lazy/manage/init.lua index ce8c169..8817c16 100644 --- a/lua/lazy/manage/init.lua +++ b/lua/lazy/manage/init.lua @@ -115,7 +115,6 @@ end ---@param opts? ManagerOpts function M.clean(opts) - Plugin.update_state() M.run({ pipeline = { "fs.clean" }, plugins = Config.to_clean, @@ -123,7 +122,7 @@ function M.clean(opts) end function M.clear() - Plugin.update_state() + Plugin.load() for _, plugin in pairs(Config.plugins) do plugin._.updated = nil plugin._.cloned = nil diff --git a/lua/lazy/manage/reloader.lua b/lua/lazy/manage/reloader.lua new file mode 100644 index 0000000..61d4407 --- /dev/null +++ b/lua/lazy/manage/reloader.lua @@ -0,0 +1,82 @@ +local Cache = require("lazy.core.cache") +local Config = require("lazy.core.config") +local Util = require("lazy.util") +local Plugin = require("lazy.core.plugin") + +local M = {} + +---@type table +M.files = {} + +---@type vim.loop.Timer +M.timer = nil +M.main = nil +M.root = nil + +function M.enable() + if M.timer then + M.timer:stop() + end + if type(Config.spec) == "string" then + M.timer = vim.loop.new_timer() + M.root = vim.fn.stdpath("config") .. "/lua/" .. Config.spec:gsub("%.", "/") + M.main = vim.loop.fs_stat(M.root .. ".lua") and (M.root .. ".lua") or (M.root .. "/init.lua") + M.check(true) + M.timer:start(2000, 2000, M.check) + end +end + +function M.disable() + if M.timer then + M.timer:stop() + M.timer = nil + end +end + +function M.check(start) + ---@type table + local checked = {} + ---@type {file:string, what:string}[] + local changes = {} + + -- spec is a module + local function check(_, modpath) + checked[modpath] = true + local hash = Cache.hash(modpath) + if hash then + if M.files[modpath] then + if not Cache.eq(M.files[modpath], hash) then + M.files[modpath] = hash + table.insert(changes, { file = modpath, what = "changed" }) + end + else + M.files[modpath] = hash + table.insert(changes, { file = modpath, what = "added" }) + end + end + end + + check(nil, M.main) + Util.lsmod(M.root, check) + + for file in pairs(M.files) do + if not checked[file] then + table.insert(changes, { file = file, what = "deleted" }) + M.files[file] = nil + end + end + + if not (start or #changes == 0) then + vim.schedule(function() + local lines = { "# Config Change Detected. Reloading...", "" } + for _, change in ipairs(changes) do + table.insert(lines, "- **" .. change.what .. "**: `" .. vim.fn.fnamemodify(change.file, ":p:~:.") .. "`") + end + Util.warn(lines) + Plugin.load() + vim.cmd([[do User LazyRender]]) + end) + end +end + +return M