Files
telescope.nvim/lua/telescope/actions/mt.lua

153 lines
3.6 KiB
Lua

local action_mt = {}
--- Checks all replacement combinations to determine which function to run.
--- If no replacement can be found, then it will run the original function
local run_replace_or_original = function(replacements, original_func, ...)
for _, replacement_map in ipairs(replacements or {}) do
for condition, replacement in pairs(replacement_map) do
if condition == true or condition(...) then
return replacement(...)
end
end
end
return original_func(...)
end
action_mt.create = function(mod)
local mt = {
__call = function(t, ...)
local values = {}
for _, action_name in ipairs(t) do
if t._static_pre[action_name] then
t._static_pre[action_name](...)
end
if t._pre[action_name] then
t._pre[action_name](...)
end
local result = {
run_replace_or_original(t._replacements[action_name], mod[action_name], ...),
}
for _, res in ipairs(result) do
table.insert(values, res)
end
if t._static_post[action_name] then
t._static_post[action_name](...)
end
if t._post[action_name] then
t._post[action_name](...)
end
end
return unpack(values)
end,
__add = function(lhs, rhs)
local new_actions = {}
for _, v in ipairs(lhs) do
table.insert(new_actions, v)
end
for _, v in ipairs(rhs) do
table.insert(new_actions, v)
end
return setmetatable(new_actions, getmetatable(lhs))
end,
_static_pre = {},
_pre = {},
_replacements = {},
_static_post = {},
_post = {},
}
mt.__index = mt
mt.clear = function()
mt._pre = {}
mt._replacements = {}
mt._post = {}
end
--- Replace the reference to the function with a new one temporarily
function mt:replace(v)
assert(#self == 1, "Cannot replace an already combined action")
return self:replace_map { [true] = v }
end
function mt:replace_if(condition, replacement)
assert(#self == 1, "Cannot replace an already combined action")
return self:replace_map { [condition] = replacement }
end
--- Replace table with
-- Example:
--
-- actions.select:replace_map {
-- [function() return filetype == 'lua' end] = actions.file_split,
-- [function() return filetype == 'other' end] = actions.file_split_edit,
-- }
function mt:replace_map(tbl)
assert(#self == 1, "Cannot replace an already combined action")
local action_name = self[1]
if not mt._replacements[action_name] then
mt._replacements[action_name] = {}
end
table.insert(mt._replacements[action_name], 1, tbl)
return self
end
function mt:enhance(opts)
assert(#self == 1, "Cannot enhance already combined actions")
local action_name = self[1]
if opts.pre then
mt._pre[action_name] = opts.pre
end
if opts.post then
mt._post[action_name] = opts.post
end
return self
end
return mt
end
action_mt.transform = function(k, mt, mod, v)
local res = setmetatable({ k }, mt)
if type(v) == "table" then
res._static_pre[k] = v.pre
res._static_post[k] = v.post
mod[k] = v.action
end
return res
end
action_mt.transform_mod = function(mod)
local mt = action_mt.create(mod)
-- Pass the metatable of the module if applicable.
-- This allows for custom errors, lookups, etc.
local redirect = setmetatable({}, getmetatable(mod) or {})
for k, v in pairs(mod) do
redirect[k] = action_mt.transform(k, mt, mod, v)
end
redirect._clear = mt.clear
return redirect
end
return action_mt