mirror of https://github.com/folke/lazy.nvim.git
feat: cleanup keys/cmd handlers when loading a plugin
This commit is contained in:
parent
c98e722fa4
commit
3f517abfa4
24
README.md
24
README.md
|
@ -27,26 +27,28 @@
|
|||
- [ ] unsupported props or props from other managers
|
||||
- [ ] other packages still in site?
|
||||
- [ ] other package manager artifacts still present? compiled etc
|
||||
- [x] rename `run` to `build`
|
||||
- [ ] delete lazy keymaps when a plugin loads
|
||||
- [x] temp colorscheme
|
||||
- [x] allow setting up plugins through config **fooo**
|
||||
- [x] task timeout
|
||||
- [ ] status page showing running handlers and cache stats
|
||||
- [x] delete lazy keymaps when a plugin loads. Reset handlers for a plugin?
|
||||
- [ ] fix plugin details
|
||||
- [ ] show disabled plugins (strikethrough?)
|
||||
- [ ] log file
|
||||
- [ ] deal with re-sourcing init.lua. Check a global?
|
||||
- [x] incorrect when switching TN from opt to start
|
||||
- [ ] git tests
|
||||
- [x] max concurrency
|
||||
- [x] ui border
|
||||
- [x] make sure we can reload specs while keeping state
|
||||
- [ ] show disabled plugins (strikethrough?)
|
||||
- [ ] Import specs from other plugin managers
|
||||
- [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
|
||||
- default semver merging strategy: if no version matches all, then use highest version?
|
||||
- [ ] package meta index (package.lua cache for all packages)
|
||||
- [x] rename `run` to `build`
|
||||
- [x] temp colorscheme
|
||||
- [x] allow setting up plugins through config **fooo**
|
||||
- [x] task timeout
|
||||
- [x] incorrect when switching TN from opt to start
|
||||
- [x] max concurrency
|
||||
- [x] ui border
|
||||
- [x] make sure we can reload specs while keeping state
|
||||
- [x] use uv file watcher (or stat) to check for config changes
|
||||
- [x] support for Plugin.lock
|
||||
- [x] defaults for git log
|
||||
- [x] view keybindings for update/clean/...
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
local Util = require("lazy.core.util")
|
||||
local Loader = require("lazy.core.loader")
|
||||
local Config = require("lazy.core.config")
|
||||
|
||||
---@class LazyPluginHandlers
|
||||
|
@ -10,10 +9,31 @@ local Config = require("lazy.core.config")
|
|||
|
||||
local M = {}
|
||||
|
||||
---@enum LazyPluginHandlerTYpes
|
||||
M.types = {
|
||||
keys = "keys",
|
||||
event = "event",
|
||||
cmd = "cmd",
|
||||
ft = "ft",
|
||||
}
|
||||
|
||||
M.trigger_events = {
|
||||
BufRead = { "BufReadPre", "BufRead" },
|
||||
BufReadPost = { "BufReadPre", "BufRead", "BufReadPost" },
|
||||
}
|
||||
|
||||
---@alias LazyHandler fun(grouped:table<string, string[]>)
|
||||
|
||||
function M.setup()
|
||||
for key, handler in pairs(M.handlers) do
|
||||
M.cmd()
|
||||
M.event()
|
||||
M.ft()
|
||||
M.keys()
|
||||
end
|
||||
|
||||
---@param key string
|
||||
---@param fn fun(plugins:LazyPlugin[], value:string)
|
||||
function M.foreach_group(key, fn)
|
||||
---@type table<string, string[]>
|
||||
local group = {}
|
||||
for _, plugin in pairs(Config.plugins) do
|
||||
|
@ -25,14 +45,53 @@ function M.setup()
|
|||
end
|
||||
end
|
||||
end
|
||||
handler(group)
|
||||
for value, plugins in pairs(group) do
|
||||
fn(plugins, value)
|
||||
end
|
||||
end
|
||||
|
||||
---@param events string|string[]
|
||||
---@param key string
|
||||
---@param fn fun(plugin:LazyPlugin, value:string)
|
||||
function M.foreach_value(key, fn)
|
||||
for _, plugin in pairs(Config.plugins) do
|
||||
---@type string|string[]|nil
|
||||
local values = plugin[key]
|
||||
if values then
|
||||
if type(values) == "string" then
|
||||
fn(plugin, values)
|
||||
else
|
||||
for _, value in ipairs(values) do
|
||||
fn(plugin, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param plugin LazyPlugin
|
||||
function M.cleanup(plugin)
|
||||
if plugin.keys then
|
||||
local keys = type(plugin.keys) == "string" and { plugin.keys } or plugin.keys
|
||||
---@cast keys string[]
|
||||
for _, k in ipairs(keys) do
|
||||
pcall(vim.keymap.del, "n", k)
|
||||
end
|
||||
end
|
||||
|
||||
if plugin.cmd then
|
||||
local cmd = type(plugin.cmd) == "string" and { plugin.cmd } or plugin.cmd
|
||||
---@cast cmd string[]
|
||||
for _, c in ipairs(cmd) do
|
||||
pcall(vim.api.nvim_del_user_command, c)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Get all augroups for the events
|
||||
---@param event string
|
||||
---@param pattern? string
|
||||
function M.get_augroups(events, pattern)
|
||||
-- Check for all autocmd groups listening for the events
|
||||
function M.get_augroups(event, pattern)
|
||||
local events = M.trigger_events[event] or { event }
|
||||
---@type table<string,true>
|
||||
local groups = {}
|
||||
for _, autocmd in ipairs(vim.api.nvim_get_autocmds({ event = events, pattern = pattern })) do
|
||||
|
@ -43,25 +102,22 @@ function M.get_augroups(events, pattern)
|
|||
return groups
|
||||
end
|
||||
|
||||
---@param groups table<string,true>
|
||||
---@param events string|string[]
|
||||
---@param event string|string[]
|
||||
---@param pattern? string
|
||||
function M.trigger(groups, events, pattern)
|
||||
events = type(events) == "string" and { events } or events
|
||||
---@param groups table<string,true>
|
||||
function M.trigger(event, pattern, groups)
|
||||
local events = M.trigger_events[event] or { event }
|
||||
---@cast events string[]
|
||||
for _, event in ipairs(events) do
|
||||
for _, autocmd in ipairs(vim.api.nvim_get_autocmds({ event = event, pattern = pattern })) do
|
||||
if autocmd.event == event and autocmd.group and not groups[autocmd.group] then
|
||||
for _, e in ipairs(events) do
|
||||
for _, autocmd in ipairs(vim.api.nvim_get_autocmds({ event = e, pattern = pattern })) do
|
||||
if autocmd.event == e and autocmd.group and not groups[autocmd.group] then
|
||||
if Config.options.debug then
|
||||
local lines = {
|
||||
Util.info({
|
||||
"# Firing Events",
|
||||
" - **event:** " .. autocmd.event,
|
||||
" - **group:** `" .. autocmd.group_name .. "`",
|
||||
}
|
||||
if pattern then
|
||||
table.insert(lines, 2, "- **pattern:** " .. pattern)
|
||||
end
|
||||
Util.info(lines)
|
||||
" - **event:** " .. autocmd.event,
|
||||
pattern and "- **pattern:** ",
|
||||
})
|
||||
end
|
||||
Util.try(function()
|
||||
vim.api.nvim_exec_autocmds(autocmd.event, { group = autocmd.group, modeline = false })
|
||||
|
@ -71,17 +127,12 @@ function M.trigger(groups, events, pattern)
|
|||
end
|
||||
end
|
||||
|
||||
---@type table<string, LazyHandler>
|
||||
M.handlers = {}
|
||||
function M.handlers.event(grouped)
|
||||
function M.event()
|
||||
local Loader = require("lazy.core.loader")
|
||||
local group = vim.api.nvim_create_augroup("lazy_handler_event", { clear = true })
|
||||
for event_spec, plugins in pairs(grouped) do
|
||||
if event_spec == "VeryLazy" then
|
||||
event_spec = "User VeryLazy"
|
||||
end
|
||||
if event_spec == "VimEnter" and vim.v.vim_did_enter == 1 then
|
||||
Loader.load(plugins, { event = event_spec })
|
||||
else
|
||||
|
||||
M.foreach_group("event", function(plugins, event_spec)
|
||||
event_spec = event_spec == "VeryLazy" and "User VeryLazy" or event_spec
|
||||
local event, pattern = event_spec:match("^(%w+)%s+(.*)$")
|
||||
event = event or event_spec
|
||||
vim.api.nvim_create_autocmd(event, {
|
||||
|
@ -90,42 +141,34 @@ function M.handlers.event(grouped)
|
|||
pattern = pattern,
|
||||
callback = function()
|
||||
Util.track({ event = event_spec })
|
||||
local events = { event }
|
||||
if event == "BufRead" then
|
||||
events = { "BufReadPre", "BufRead" }
|
||||
elseif event == "BufReadPost" then
|
||||
events = { "BufReadPre", "BufRead", "BufReadPost" }
|
||||
end
|
||||
|
||||
local groups = M.get_augroups(events, pattern)
|
||||
|
||||
local groups = M.get_augroups(event, pattern)
|
||||
-- load the plugins
|
||||
Loader.load(plugins, { event = event_spec })
|
||||
|
||||
-- check if any plugin created an event handler for this event and fire the group
|
||||
M.trigger(groups, events, pattern)
|
||||
M.trigger(event, pattern, groups)
|
||||
Util.track()
|
||||
end,
|
||||
})
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function M.handlers.keys(grouped)
|
||||
for keys, plugins in pairs(grouped) do
|
||||
function M.keys()
|
||||
local Loader = require("lazy.core.loader")
|
||||
M.foreach_value("keys", function(plugin, keys)
|
||||
vim.keymap.set("n", keys, function()
|
||||
vim.keymap.del("n", keys)
|
||||
Util.track({ keys = keys })
|
||||
Loader.load(plugins, { keys = keys })
|
||||
Loader.load(plugin, { keys = keys })
|
||||
vim.api.nvim_input(keys)
|
||||
Util.track()
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function M.handlers.ft(grouped)
|
||||
function M.ft()
|
||||
local Loader = require("lazy.core.loader")
|
||||
local group = vim.api.nvim_create_augroup("lazy_handler_ft", { clear = true })
|
||||
for ft, plugins in pairs(grouped) do
|
||||
M.foreach_group("ft", function(plugins, ft)
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
once = true,
|
||||
pattern = ft,
|
||||
|
@ -134,23 +177,25 @@ function M.handlers.ft(grouped)
|
|||
Util.track({ ft = ft })
|
||||
local groups = M.get_augroups("FileType", ft)
|
||||
Loader.load(plugins, { ft = ft })
|
||||
M.trigger(groups, "FileType", ft)
|
||||
M.trigger("FileType", ft, groups)
|
||||
Util.track()
|
||||
end,
|
||||
})
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function M.handlers.cmd(grouped)
|
||||
for cmd, plugins in pairs(grouped) do
|
||||
local function _load()
|
||||
function M.cmd()
|
||||
local Loader = require("lazy.core.loader")
|
||||
local function _load(plugin, cmd)
|
||||
vim.api.nvim_del_user_command(cmd)
|
||||
Util.track({ cmd = cmd })
|
||||
Loader.load(plugins, { cmd = cmd })
|
||||
Loader.load(plugin, { cmd = cmd })
|
||||
Util.track()
|
||||
end
|
||||
|
||||
M.foreach_value("cmd", function(plugin, cmd)
|
||||
vim.api.nvim_create_user_command(cmd, function(event)
|
||||
_load()
|
||||
_load(plugin, cmd)
|
||||
vim.cmd(
|
||||
("%s %s%s%s %s"):format(
|
||||
event.mods or "",
|
||||
|
@ -164,12 +209,12 @@ function M.handlers.cmd(grouped)
|
|||
bang = true,
|
||||
nargs = "*",
|
||||
complete = function()
|
||||
_load()
|
||||
_load(plugin, cmd)
|
||||
-- HACK: trick Neovim to show the newly loaded command completion
|
||||
vim.api.nvim_input("<space><bs><tab>")
|
||||
end,
|
||||
})
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
local Util = require("lazy.core.util")
|
||||
local Config = require("lazy.core.config")
|
||||
local Handler = require("lazy.core.handler")
|
||||
|
||||
local M = {}
|
||||
|
||||
|
@ -27,7 +28,6 @@ function M.setup()
|
|||
|
||||
-- setup handlers
|
||||
Util.track("handlers")
|
||||
local Handler = require("lazy.core.handler")
|
||||
Handler.setup()
|
||||
Util.track()
|
||||
|
||||
|
@ -81,6 +81,7 @@ function M.load(plugins, reason)
|
|||
table.insert(M.loading, plugin)
|
||||
|
||||
Util.track({ plugin = plugin.name, start = reason.start })
|
||||
Handler.cleanup(plugin)
|
||||
|
||||
vim.opt.runtimepath:prepend(plugin.dir)
|
||||
if not M.init_done then
|
||||
|
|
|
@ -127,7 +127,7 @@ function Spec:merge(old, new)
|
|||
for k, v in pairs(new) do
|
||||
if k == "_" then
|
||||
elseif old[k] ~= nil and old[k] ~= v then
|
||||
if Handler.handlers[k] then
|
||||
if Handler.types[k] then
|
||||
local values = type(v) == "string" and { v } or v
|
||||
vim.list_extend(values, type(old[k]) == "string" and { old[k] } or old[k])
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
|
|
|
@ -161,7 +161,14 @@ end
|
|||
|
||||
---@param msg string|string[]
|
||||
function M.notify(msg, level)
|
||||
msg = type(msg) == "table" and table.concat(msg, "\n") or msg
|
||||
if type(msg) == "table" then
|
||||
msg = table.concat(
|
||||
vim.tbl_filter(function(line)
|
||||
return line or false
|
||||
end, msg),
|
||||
"\n"
|
||||
)
|
||||
end
|
||||
vim.notify(msg, level, {
|
||||
on_open = function(win)
|
||||
vim.wo[win].conceallevel = 3
|
||||
|
|
|
@ -382,7 +382,7 @@ function M:details(plugin)
|
|||
end
|
||||
end)
|
||||
|
||||
for handler in pairs(Handler.handlers) do
|
||||
for handler in pairs(Handler.types) do
|
||||
if plugin[handler] then
|
||||
table.insert(props, {
|
||||
handler,
|
||||
|
|
Loading…
Reference in New Issue