local Util = require("lazy.core.util") local Loader = require("lazy.core.loader") local M = {} ---@alias LazyHandler fun(grouped:table) ---@type table> M._groups = nil ---@param plugins LazyPlugin[] ---@param rebuild? boolean function M.group(plugins, rebuild) if M._groups == nil or rebuild then M._groups = {} local types = vim.tbl_keys(M.handlers) --[[@as string[] ]] for _, key in ipairs(types) do M._groups[key] = {} for _, plugin in pairs(plugins) do if plugin[key] then ---@diagnostic disable-next-line: no-unknown for _, value in pairs(type(plugin[key]) == "table" and plugin[key] or { plugin[key] }) do M._groups[key][value] = M._groups[key][value] or {} table.insert(M._groups[key][value], plugin.name) end end end end end return M._groups end ---@type table M.handlers = {} function M.handlers.event(grouped) local group = vim.api.nvim_create_augroup("lazy_handler_event", { clear = true }) for event, plugins in pairs(grouped) do ---@cast event string if event == "VimEnter" and vim.v.vim_did_enter == 1 then Loader.load(plugins, { event = event }) else local _event, pattern = event:match("^(%w+)%s+(.*)$") vim.api.nvim_create_autocmd(_event or event, { group = group, once = true, pattern = pattern, callback = function() Util.track("event: " .. (_event == "User" and pattern or event)) Loader.load(plugins, { event = event }) Util.track() end, }) end end end function M.handlers.keys(grouped) for keys, plugins in pairs(grouped) do ---@cast keys string vim.keymap.set("n", keys, function() vim.keymap.del("n", keys) Util.track("keys: " .. keys) Loader.load(plugins, { keys = keys }) vim.api.nvim_input(keys) Util.track() end) end end function M.handlers.ft(grouped) local group = vim.api.nvim_create_augroup("lazy_handler_ft", { clear = true }) for ft, plugins in pairs(grouped) do ---@cast ft string vim.api.nvim_create_autocmd("FileType", { once = true, pattern = ft, group = group, callback = function() Util.track("filetype: " .. ft) Loader.load(plugins, { ft = ft }) Util.track() end, }) end end function M.handlers.cmd(grouped) for cmd, plugins in pairs(grouped) do ---@cast cmd string local function _load(complete) vim.api.nvim_del_user_command(cmd) if complete then Util.track("cmd-complete: " .. cmd) else Util.track("cmd: " .. cmd) end Loader.load(plugins, { cmd = cmd }) Util.track() end vim.api.nvim_create_user_command(cmd, function(event) _load() vim.cmd( ("%s %s%s%s %s"):format( event.mods or "", event.line1 == event.line2 and "" or event.line1 .. "," .. event.line2, cmd, event.bang and "!" or "", event.args or "" ) ) end, { bang = true, nargs = "*", complete = function() _load(true) -- HACK: trick Neovim to show the newly loaded command completion vim.api.nvim_input("") end, }) end end function M.handlers.module(grouped) ---@param modname string table.insert(package.loaders, 2, function(modname) local idx = modname:find(".", 1, true) or #modname + 1 while idx do local name = modname:sub(1, idx - 1) ---@diagnostic disable-next-line: redefined-local local plugins = grouped[name] if plugins then grouped[name] = nil local reason = { require = modname } if #Loader.loading == 0 then local f = 3 while not reason.source do local info = debug.getinfo(f, "S") if not info then break end if info.what ~= "C" then reason.source = info.source:sub(2) end f = f + 1 end end Loader.load(plugins, reason) end idx = modname:find(".", idx + 1, true) end end) end return M