summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/clever_f/sequence_coordinator.lua65
-rw-r--r--tests/run.lua11
2 files changed, 76 insertions, 0 deletions
diff --git a/lua/clever_f/sequence_coordinator.lua b/lua/clever_f/sequence_coordinator.lua
new file mode 100644
index 0000000..0da3ef3
--- /dev/null
+++ b/lua/clever_f/sequence_coordinator.lua
@@ -0,0 +1,65 @@
+local domain = require("clever_f.domain")
+
+local M = {}
+local SequenceCoordinator = {}
+SequenceCoordinator.__index = SequenceCoordinator
+M.SequenceCoordinator = SequenceCoordinator
+
+local coordinator_records = setmetatable({}, { __mode = "k" })
+
+local function fail(message, level)
+ error(message, (level or 1) + 1)
+end
+
+local function descriptor_text(value)
+ if domain.Descriptor.is(value) then
+ return value.value
+ end
+ return tostring(value)
+end
+
+function M.validate_primary_descriptor(value)
+ local descriptor = domain.Descriptor.try_from_string(value)
+ if descriptor == nil then
+ fail("clever-f: Invalid mapping '" .. descriptor_text(value) .. "'", 2)
+ end
+ return descriptor
+end
+
+function SequenceCoordinator.new(options)
+ if SequenceCoordinator.is(options) then
+ return options
+ end
+ if type(options) ~= "table" then
+ fail("SequenceCoordinator options must be a table", 2)
+ end
+ local coordinator = setmetatable({}, SequenceCoordinator)
+ coordinator_records[coordinator] = {
+ host = options.host or options,
+ }
+ return coordinator
+end
+
+function SequenceCoordinator.is(value)
+ return type(value) == "table" and coordinator_records[value] ~= nil
+end
+
+function SequenceCoordinator:validate_primary_descriptor(value)
+ return M.validate_primary_descriptor(value)
+end
+
+function SequenceCoordinator:primary(value)
+ return self:validate_primary_descriptor(value)
+end
+
+function M.new(options)
+ return SequenceCoordinator.new(options)
+end
+
+setmetatable(M, {
+ __call = function(_, options)
+ return SequenceCoordinator.new(options)
+ end,
+})
+
+return M
diff --git a/tests/run.lua b/tests/run.lua
index b1555c2..aced20a 100644
--- a/tests/run.lua
+++ b/tests/run.lua
@@ -18,6 +18,7 @@ local repeat_resolver = require("clever_f.repeat_resolver")
local migemo_catalog = require("clever_f.migemo_catalog")
local motion_plan = require("clever_f.motion_plan")
local motion_executor = require("clever_f.motion_executor")
+local sequence_coordinator = require("clever_f.sequence_coordinator")
local sequence_state = require("clever_f.sequence_state")
local state_transitions = require("clever_f.state_transitions")
local text_topology = require("clever_f.text_topology")
@@ -7068,6 +7069,16 @@ test("Eager cleanup preserves history and finalizer registrations", function()
same(nil, state.highlight_timer)
end)
+test("Primary coordination accepts only the four motion descriptors", function()
+ local coordinator = sequence_coordinator.new({ host = MemoryHost.new() })
+ for _, value in ipairs({ "f", "F", "t", "T" }) do
+ same(domain.Descriptor.from_string(value), coordinator:primary(value))
+ end
+ fails(function()
+ coordinator:primary("x")
+ end, "clever-f: Invalid mapping 'x'")
+end)
+
for _, item in ipairs(tests) do
local ok, failure = xpcall(item.body, debug.traceback)
if not ok then