refactor: moved handler to separate modules

This commit is contained in:
Folke Lemaitre 2022-12-05 14:45:50 +01:00
parent 1ae4e0ce9a
commit b8d8648d28
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040
7 changed files with 320 additions and 228 deletions

View file

@ -0,0 +1,45 @@
local Util = require("lazy.core.util")
local Loader = require("lazy.core.loader")
---@class LazyCmdHandler:LazyHandler
local M = {}
local function _load(plugin, cmd)
vim.api.nvim_del_user_command(cmd)
Util.track({ cmd = cmd })
Loader.load(plugin, { cmd = cmd })
Util.track()
end
---@param plugin LazyPlugin
---@param cmd string
function M:_add(plugin, cmd)
vim.api.nvim_create_user_command(cmd, function(event)
_load(plugin, cmd)
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(plugin, cmd)
-- HACK: trick Neovim to show the newly loaded command completion
vim.api.nvim_input("<space><bs><tab>")
end,
})
end
---@param _plugin LazyPlugin
---@param value string
function M:_del(_plugin, value)
pcall(vim.api.nvim_del_user_command, value)
end
return M

View file

@ -0,0 +1,97 @@
local Util = require("lazy.core.util")
local Config = require("lazy.core.config")
local Loader = require("lazy.core.loader")
---@class LazyEventHandler:LazyHandler
---@field events table<string,true>
---@field group number
local M = {}
M.trigger_events = {
BufRead = { "BufReadPre", "BufRead" },
BufReadPost = { "BufReadPre", "BufRead", "BufReadPost" },
}
function M:init()
self.group = vim.api.nvim_create_augroup("lazy_handler_" .. self.type, { clear = true })
self.events = {}
end
---@param event_spec string
function M:_add(_, event_spec)
if not self.events[event_spec] then
self:listen(event_spec)
end
end
---@param value string
function M:_value(value)
return value == "VeryLazy" and "User VeryLazy" or value
end
function M:listen(event_spec)
self.events[event_spec] = true
---@type string?, string?
local event, pattern = event_spec:match("^(%w+)%s+(.*)$")
event = event or event_spec
vim.api.nvim_create_autocmd(event, {
group = self.group,
once = true,
pattern = pattern,
callback = function()
if not self.active[event_spec] then
return
end
Util.track({ [self.type] = event_spec })
local groups = M.get_augroups(event, pattern)
-- load the plugins
Loader.load(self.active[event_spec], { [self.type] = event_spec })
self.events[event_spec] = nil
-- check if any plugin created an event handler for this event and fire the group
M.trigger(event, pattern, groups)
Util.track()
end,
})
end
-- Get all augroups for the events
---@param event string
---@param pattern? string
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
if autocmd.group then
groups[autocmd.group] = true
end
end
return groups
end
---@param event string|string[]
---@param pattern? string
---@param groups table<string,true>
function M.trigger(event, pattern, groups)
local events = M.trigger_events[event] or { event }
---@cast events string[]
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
Util.info({
"# Firing Events",
" - **group:** `" .. autocmd.group_name .. "`",
" - **event:** " .. autocmd.event,
pattern and "- **pattern:** ",
})
end
Util.try(function()
vim.api.nvim_exec_autocmds(autocmd.event, { group = autocmd.group, modeline = false })
end)
end
end
end
end
return M

View file

@ -0,0 +1,20 @@
local Event = require("lazy.core.handler.event")
local Loader = require("lazy.core.loader")
---@class LazyFiletypeHandler:LazyEventHandler
local M = {}
M.extends = Event
---@param value string
function M:_value(value)
return "FileType " .. value
end
---@param plugin LazyPlugin
---@param value string
function M:_add(plugin, value)
Loader.ftdetect(plugin)
Event._add(self, plugin, value)
end
return M

View file

@ -0,0 +1,123 @@
local Config = require("lazy.core.config")
---@class LazyPluginHandlers: table<LazyHandlerTypes, string|string[]>
---@field event? string|string[]
---@field cmd? string|string[]
---@field ft? string|string[]
---@field keys? string|string[]
---@class LazyHandler
---@field type LazyHandlerTypes
---@field extends? LazyHandler
---@field active table<string,table<string,string>>
local M = {}
---@enum LazyHandlerTypes
M.types = {
keys = "keys",
event = "event",
cmd = "cmd",
ft = "ft",
}
---@type table<string,LazyHandler>
M.handlers = {}
function M.setup()
for _, type in pairs(M.types) do
M.handlers[type] = M.new(type)
end
for _, plugin in pairs(Config.plugins) do
M.enable(plugin)
end
end
---@param plugin LazyPlugin
function M.disable(plugin)
for type, handler in pairs(M.handlers) do
if plugin[type] then
handler:del(plugin)
end
end
end
---@param plugin LazyPlugin
function M.enable(plugin)
if not plugin._.loaded then
for type, handler in pairs(M.handlers) do
if plugin[type] then
handler:add(plugin)
end
end
end
end
---@param type LazyHandlerTypes
function M.new(type)
---@type LazyHandler
local handler = require("lazy.core.handler." .. type)
local self = setmetatable({}, {
__index = function(_, k)
return handler[k] or (handler.extends and handler.extends[k]) or M[k]
end,
})
self.active = {}
self.type = type
self:init()
return self
end
---@protected
function M:init() end
---@param plugin LazyPlugin
---@param value string
---@protected
function M:_add(plugin, value) end
---@param plugin LazyPlugin
---@param value string
---@protected
function M:_del(plugin, value) end
---@param value string
function M:_value(value)
return value
end
---@param values? string|string[]
---@param fn fun(value:string)
function M:foreach(values, fn)
if type(values) == "string" then
fn(values)
elseif values ~= nil then
for _, value in ipairs(values) do
fn(value)
end
end
end
---@param plugin LazyPlugin
function M:add(plugin)
self:foreach(plugin[self.type], function(value)
value = self:_value(value)
if not (self.active[value] and self.active[value][plugin.name]) then
self.active[value] = self.active[value] or {}
self.active[value][plugin.name] = plugin.name
self:_add(plugin, value)
end
end)
end
---@param plugin LazyPlugin
function M:del(plugin)
self:foreach(plugin[self.type], function(value)
value = self:_value(value)
if self.active[value] and self.active[value][plugin.name] then
self.active[value][plugin.name] = nil
self:_del(plugin, value)
end
end)
end
return M

View file

@ -0,0 +1,25 @@
local Util = require("lazy.core.util")
local Loader = require("lazy.core.loader")
---@class LazyKeysHandler:LazyHandler
local M = {}
---@param plugin LazyPlugin
---@param keys string
function M:_add(plugin, keys)
vim.keymap.set("n", keys, function()
vim.keymap.del("n", keys)
Util.track({ keys = keys })
Loader.load(plugin, { keys = keys })
vim.api.nvim_input(keys)
Util.track()
end)
end
---@param _plugin LazyPlugin
---@param value string
function M:_del(_plugin, value)
pcall(vim.keymap.del, "n", value)
end
return M