From c7b14ffb6d14969c9c41864e827f33f8e80fc24e Mon Sep 17 00:00:00 2001 From: Jackson Moore Date: Fri, 4 Sep 2026 18:44:32 +0200 Subject: Rename plugin to clever-tee --- lua/clever_tee/action_facade.lua | 134 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 lua/clever_tee/action_facade.lua (limited to 'lua/clever_tee/action_facade.lua') diff --git a/lua/clever_tee/action_facade.lua b/lua/clever_tee/action_facade.lua new file mode 100644 index 0000000..fe7a035 --- /dev/null +++ b/lua/clever_tee/action_facade.lua @@ -0,0 +1,134 @@ +local domain = require("clever_tee.domain") +local sequence_coordinator = require("clever_tee.sequence_coordinator") + +local M = {} +local ActionFacade = {} +ActionFacade.__index = ActionFacade +M.ActionFacade = ActionFacade + +local facade_records = setmetatable({}, { __mode = "k" }) + +local function fail(message, level) + error(message, (level or 1) + 1) +end + +function ActionFacade.new(options) + if ActionFacade.is(options) then + return options + end + local coordinator + if sequence_coordinator.SequenceCoordinator.is(options) then + coordinator = options + elseif type(options) == "table" then + coordinator = options.coordinator + or options.sequence_coordinator + or sequence_coordinator.new(options) + else + fail("ActionFacade options must be a table", 2) + end + if not sequence_coordinator.SequenceCoordinator.is(coordinator) then + fail("ActionFacade requires a SequenceCoordinator", 2) + end + + local facade = setmetatable({}, ActionFacade) + facade_records[facade] = { coordinator = coordinator } + return facade +end + +function ActionFacade.is(value) + return type(value) == "table" and facade_records[value] ~= nil +end + +function ActionFacade:coordinator() + return facade_records[self].coordinator +end + +function ActionFacade:primary(descriptor) + local outcome = self:coordinator():primary(descriptor) + if not domain.ActionOutcome.is(outcome) then + fail("SequenceCoordinator must return an ActionOutcome", 2) + end + return outcome +end + +function ActionFacade:invoke_descriptor(value) + local descriptor = sequence_coordinator.validate_primary_descriptor(value) + return self:primary(descriptor) +end + +ActionFacade.invoke_primary = ActionFacade.invoke_descriptor +ActionFacade.start = ActionFacade.invoke_descriptor +ActionFacade.FreeForm = ActionFacade.invoke_descriptor + +function ActionFacade:start_find_forward() + return self:primary("f") +end + +function ActionFacade:start_find_backward() + return self:primary("F") +end + +function ActionFacade:start_till_forward() + return self:primary("t") +end + +function ActionFacade:start_till_backward() + return self:primary("T") +end + +ActionFacade.StartFindForward = ActionFacade.start_find_forward +ActionFacade.StartFindBackward = ActionFacade.start_find_backward +ActionFacade.StartTillForward = ActionFacade.start_till_forward +ActionFacade.StartTillBackward = ActionFacade.start_till_backward + +function ActionFacade:reset() + local outcome = self:coordinator():reset() + if not domain.ActionOutcome.is(outcome) then + fail("SequenceCoordinator must return an ActionOutcome", 2) + end + return outcome +end + +ActionFacade.Reset = ActionFacade.reset + +function ActionFacade:diagnostic_full_reset() + local outcome = self:coordinator():diagnostic_full_reset() + if not domain.ActionOutcome.is(outcome) then + fail("SequenceCoordinator must return an ActionOutcome", 2) + end + return outcome +end + +ActionFacade.DiagnosticFullReset = ActionFacade.diagnostic_full_reset + +local function explicit_outcome(facade, method_name) + local coordinator = facade:coordinator() + local outcome = coordinator[method_name](coordinator) + if not domain.ActionOutcome.is(outcome) then + fail("SequenceCoordinator must return an ActionOutcome", 3) + end + return outcome +end + +function ActionFacade:repeat_same_direction() + return explicit_outcome(self, "repeat_same_direction") +end + +function ActionFacade:repeat_opposite_direction() + return explicit_outcome(self, "repeat_opposite_direction") +end + +ActionFacade.RepeatSameDirection = ActionFacade.repeat_same_direction +ActionFacade.RepeatOppositeDirection = ActionFacade.repeat_opposite_direction + +function M.new(options) + return ActionFacade.new(options) +end + +setmetatable(M, { + __call = function(_, options) + return ActionFacade.new(options) + end, +}) + +return M -- cgit v1.2.3