refactor(handlers): lazy resolving of plugin handlers (#1126)

* refactor(handlers): lazy resolving of plugin handlers

* test: fixed tests
This commit is contained in:
Folke Lemaitre 2023-10-16 22:34:44 +02:00 committed by GitHub
parent b9c604e839
commit 2f169e74d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 126 additions and 120 deletions

View file

@ -55,7 +55,7 @@ M.defaults = {
icons = {
cmd = "",
config = "",
event = "",
event = " ",
ft = "",
init = "",
import = "",
@ -67,7 +67,7 @@ M.defaults = {
runtime = "",
require = "󰢱 ",
source = "",
start = "",
start = " ",
task = "",
list = {
"",

View file

@ -37,7 +37,7 @@ M.group = vim.api.nvim_create_augroup("lazy_handler_event", { clear = true })
---@param spec LazyEventSpec
---@return LazyEvent
function M:parse(spec)
function M:_parse(spec)
local ret = M.mappings[spec] --[[@as LazyEvent?]]
if ret then
return ret
@ -62,19 +62,6 @@ function M:parse(spec)
return ret
end
---@param plugin LazyPlugin
function M:values(plugin)
local Plugin = require("lazy.core.plugin")
---@type table<string,any>
local values = {}
---@diagnostic disable-next-line: no-unknown
for _, value in ipairs(Plugin.values(plugin, self.type, true)) do
local event = self:parse(value)
values[event.id] = event
end
return values
end
---@param event LazyEvent
function M:_add(event)
local done = false

View file

@ -13,7 +13,8 @@ function M:add(plugin)
end
end
function M:parse(value)
---@return LazyEvent
function M:_parse(value)
return {
id = value,
event = "FileType",

View file

@ -39,29 +39,20 @@ end
---@param plugin LazyPlugin
function M.disable(plugin)
if not plugin._.handlers_enabled then
return
end
plugin._.handlers_enabled = false
for type, handler in pairs(M.handlers) do
if plugin[type] then
handler:del(plugin)
end
for type in pairs(plugin._.handlers or {}) do
M.handlers[type]:del(plugin)
end
end
---@param plugin LazyPlugin
function M.enable(plugin)
if not plugin._.loaded then
if plugin._.handlers_enabled then
return
if not plugin._.handlers then
M.load(plugin)
end
for type, handler in pairs(M.handlers) do
if plugin[type] then
handler:add(plugin)
end
for type in pairs(plugin._.handlers or {}) do
M.handlers[type]:add(plugin)
end
plugin._.handlers_enabled = true
end
end
@ -86,21 +77,40 @@ function M:_add(_value) end
---@protected
function M:_del(_value) end
---@param value any
---@param _plugin LazyPlugin
---@return string|{id:string}
function M:_parse(value, _plugin)
assert(type(value) == "string", "Expected string, got " .. vim.inspect(value))
return value
end
---@param values any[]
---@param plugin LazyPlugin
function M:values(plugin)
local Plugin = require("lazy.core.plugin")
function M:_values(values, plugin)
---@type table<string,any>
local values = {}
---@diagnostic disable-next-line: no-unknown
for _, value in ipairs(Plugin.values(plugin, self.type, true)) do
values[value] = value
local ret = {}
for _, value in ipairs(values) do
local parsed = self:_parse(value, plugin)
ret[type(parsed) == "string" and parsed or parsed.id] = parsed
end
return ret
end
---@param plugin LazyPlugin
function M.load(plugin)
local Plugin = require("lazy.core.plugin")
plugin._.handlers = {}
for type, handler in pairs(M.handlers) do
if plugin[type] then
plugin._.handlers[type] = handler:_values(Plugin.values(plugin, type, true), plugin)
end
end
return values
end
---@param plugin LazyPlugin
function M:add(plugin)
for key, value in pairs(self:values(plugin)) do
for key, value in pairs(plugin._.handlers[self.type] or {}) do
if not self.active[key] then
self.active[key] = {}
self:_add(value)
@ -112,7 +122,10 @@ end
---@param plugin LazyPlugin
function M:del(plugin)
for key, value in pairs(self:values(plugin)) do
if not plugin._.handlers then
return
end
for key, value in pairs(plugin._.handlers[self.type] or {}) do
if self.active[key] and self.active[key][plugin.name] then
self.active[key][plugin.name] = nil
if vim.tbl_isempty(self.active[key]) then

View file

@ -19,10 +19,13 @@ local Util = require("lazy.core.util")
---@field rhs? string|fun() rhs
---@field mode? string
---@field id string
---@field name string
---@class LazyKeysHandler:LazyHandler
local M = {}
local skip = { mode = true, id = true, ft = true, rhs = true, lhs = true }
---@param value string|LazyKeysSpec
---@param mode? string
---@return LazyKeys
@ -37,12 +40,18 @@ function M.parse(value, mode)
ret[2] = nil
ret.mode = mode or "n"
ret.id = vim.api.nvim_replace_termcodes(ret.lhs, true, true, true)
if ret.mode ~= "n" then
ret.id = ret.id .. " (" .. ret.mode .. ")"
end
return ret
end
---@param keys LazyKeys
function M.to_string(keys)
return keys.lhs .. (keys.mode == "n" and "" or " (" .. keys.mode .. ")")
end
---@param lhs string
---@param mode? string
function M:have(lhs, mode)
@ -50,10 +59,8 @@ function M:have(lhs, mode)
return self.managed[keys.id] ~= nil
end
---@param plugin LazyPlugin
function M:values(plugin)
local Plugin = require("lazy.core.plugin")
return M.resolve(Plugin.values(plugin, "keys", true))
function M:_values(values)
return M.resolve(values)
end
---@param spec? (string|LazyKeysSpec)[]
@ -79,7 +86,6 @@ end
---@param keys LazyKeys
function M.opts(keys)
local skip = { mode = true, id = true, ft = true, rhs = true, lhs = true }
local opts = {} ---@type LazyKeysBase
---@diagnostic disable-next-line: no-unknown
for k, v in pairs(keys) do
@ -106,8 +112,9 @@ function M:_add(keys)
self.active[keys.id] = nil
if plugins then
Util.track({ keys = lhs })
Loader.load(plugins, { keys = lhs })
local name = M.to_string(keys)
Util.track({ keys = name })
Loader.load(plugins, { keys = name })
Util.track()
end

View file

@ -556,10 +556,6 @@ function M.load()
Config.plugins[name]._ = plugin._
Config.plugins[name]._.dep = dep
Config.plugins[name]._.super = super
-- FIXME: work-around for changes related to Plugin.values
for handler in pairs(Handler) do
Config.plugins[name][handler] = plugin[handler]
end
end
end
Util.track()
@ -607,29 +603,32 @@ function M.values(plugin, prop, is_list)
if not plugin[prop] then
return {}
end
plugin._.values = plugin._.values or {}
plugin._.cache = plugin._.cache or {}
local key = prop .. (is_list and "_list" or "")
if plugin._.values[key] == nil then
plugin[prop] = M._values(plugin, prop, is_list)
plugin._.values[key] = true
if plugin._.cache[key] == nil then
plugin._.cache[key] = M._values(plugin, plugin, prop, is_list)
end
return plugin[prop] or {}
return plugin._.cache[key]
end
-- Merges super values or runs the values function to override values or return new ones
-- Used for opts, cmd, event, ft and keys
---@param root LazyPlugin
---@param plugin LazyPlugin
---@param prop string
---@param is_list? boolean
function M._values(plugin, prop, is_list)
function M._values(root, plugin, prop, is_list)
if not plugin[prop] then
return {}
end
---@type table
local ret = plugin._.super and M._values(plugin._.super, prop, is_list) or {}
local ret = plugin._.super and M._values(root, plugin._.super, prop, is_list) or {}
local values = rawget(plugin, prop)
if not values then
return ret
elseif type(values) == "function" then
ret = values(plugin, ret) or ret
ret = values(root, ret) or ret
return type(ret) == "table" and ret or { ret }
end