mirror of
https://github.com/zoriya/lz.n.git
synced 2026-06-06 03:56:27 +00:00
105 lines
3.4 KiB
Lua
105 lines
3.4 KiB
Lua
---@mod lz.n.handler.state Safe state management for handlers
|
|
---
|
|
---@brief [[
|
|
---This module is to be used by |lz.n.Handler| implementations.
|
|
---It provides an API for safely managing handler state,
|
|
---ensuring that `trigger_load` can be called in plugin hooks.
|
|
---@brief ]]
|
|
|
|
local state = {}
|
|
|
|
---@return lz.n.handler.State
|
|
function state.new()
|
|
---@type table<string, table<string, lz.n.Plugin>>
|
|
local pending = {}
|
|
|
|
local DEFAULT_KEY = "lz.n.handler.State.DEFAULT_KEY"
|
|
|
|
return {
|
|
---@overload fun(key: string, plugin: lz.n.Plugin)
|
|
---@overload fun(plugin: lz.n.Plugin)
|
|
insert = function(key, plugin)
|
|
if type(key) ~= "string" then
|
|
plugin = key
|
|
key = DEFAULT_KEY
|
|
end
|
|
pending[key] = pending[key] or {}
|
|
pending[key][plugin.name] = plugin
|
|
end,
|
|
|
|
del = function(plugin_name, callback)
|
|
vim.iter(pending)
|
|
:filter(function(_, plugins)
|
|
return plugins[plugin_name] ~= nil
|
|
end)
|
|
:each(
|
|
---@param key string
|
|
---@param plugins lz.n.Plugin[]
|
|
function(key, plugins)
|
|
if callback then
|
|
callback(key)
|
|
end
|
|
plugins[plugin_name] = nil
|
|
end
|
|
)
|
|
end,
|
|
|
|
has_pending_plugins = function(key)
|
|
key = key or DEFAULT_KEY
|
|
return pending[key] ~= nil and not vim.tbl_isempty(pending[key])
|
|
end,
|
|
|
|
lookup_plugin = function(plugin_name)
|
|
return vim
|
|
.iter(pending)
|
|
---@param plugins table<string, lz.n.Plugin>
|
|
:map(function(_, plugins)
|
|
return plugins[plugin_name]
|
|
end)
|
|
---@param plugin lz.n.Plugin?
|
|
:find(function(plugin)
|
|
return plugin ~= nil
|
|
end)
|
|
end,
|
|
|
|
---@overload fun(key: string, callback: fun(plugin: lz.n.Plugin)): string[]
|
|
---@overload fun(callback: fun(plugin: lz.n.Plugin)): string[]
|
|
each_pending = function(key, callback)
|
|
if type(key) ~= "string" then
|
|
callback = key
|
|
key = DEFAULT_KEY
|
|
end
|
|
local plugins = pending[key] or {}
|
|
vim
|
|
.iter(vim.deepcopy(plugins))
|
|
---@param plugin lz.n.Plugin
|
|
:each(function(_, plugin)
|
|
if pending[key][plugin.name] then
|
|
callback(plugin)
|
|
end
|
|
end)
|
|
return vim.tbl_keys(plugins)
|
|
end,
|
|
}
|
|
end
|
|
|
|
---@class lz.n.handler.State
|
|
---
|
|
---Insert a plugin (optionally, by key).
|
|
---@field insert fun(key: string, plugin: lz.n.Plugin) | fun(plugin: lz.n.Plugin)
|
|
---
|
|
---Remove a plugin by its name.
|
|
---@field del fun(plugin_name: string, callback?: fun(key: string))
|
|
---
|
|
---Check if there are pending plugins (optionally, by key)
|
|
---@field has_pending_plugins fun(key?: string):boolean
|
|
---
|
|
---Lookup a plugin by its name.
|
|
---@field lookup_plugin fun(plugin_name: string):(lz.n.Plugin | nil)
|
|
---
|
|
---Safely apply a callback to all pending plugins
|
|
---(optionally, by key).
|
|
---@field each_pending fun(key: string, callback: fun(plugin: lz.n.Plugin)): string[] | fun(callback: fun(plugin: lz.n.Plugin)): string[]
|
|
|
|
return state
|