summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJackson Moore <jacksonmoore@tuta.io>2026-09-04 14:18:34 +0200
committerJackson Moore <jacksonmoore@tuta.io>2026-09-04 14:18:34 +0200
commit5e2146af55a73b8d34596c2f28e6d7fc83a959ea (patch)
tree54588fbe9c823795dbc300a670268efe9cc65a4d
parentd1ba6bdac0924a5592e25e8bf80c595c1c05ce4c (diff)
Expose seven logical actions
-rw-r--r--lua/clever_f/composition_root.lua45
-rw-r--r--tests/run.lua31
2 files changed, 76 insertions, 0 deletions
diff --git a/lua/clever_f/composition_root.lua b/lua/clever_f/composition_root.lua
index ecd1047..83cfe96 100644
--- a/lua/clever_f/composition_root.lua
+++ b/lua/clever_f/composition_root.lua
@@ -10,6 +10,39 @@ local M = {}
local CompositionRoot = {}
CompositionRoot.__index = CompositionRoot
M.CompositionRoot = CompositionRoot
+M.ACTION_NAMES = {
+ "StartFindForward",
+ "StartFindBackward",
+ "StartTillForward",
+ "StartTillBackward",
+ "Reset",
+ "RepeatSameDirection",
+ "RepeatOppositeDirection",
+}
+
+local ACTION_INVOCATIONS = {
+ StartFindForward = function(facade)
+ return facade:primary("f")
+ end,
+ StartFindBackward = function(facade)
+ return facade:primary("F")
+ end,
+ StartTillForward = function(facade)
+ return facade:primary("t")
+ end,
+ StartTillBackward = function(facade)
+ return facade:primary("T")
+ end,
+ Reset = function(facade)
+ return facade:reset()
+ end,
+ RepeatSameDirection = function(facade)
+ return facade:repeat_same_direction()
+ end,
+ RepeatOppositeDirection = function(facade)
+ return facade:repeat_opposite_direction()
+ end,
+}
local root_records = setmetatable({}, { __mode = "k" })
@@ -80,6 +113,17 @@ function CompositionRoot.is(value)
return type(value) == "table" and root_records[value] ~= nil
end
+local function register_logical_actions(record)
+ local registrations = {}
+ for _, name in ipairs(M.ACTION_NAMES) do
+ local invoke = ACTION_INVOCATIONS[name]
+ registrations[name] = record.host:register_action(name, function(...)
+ return invoke(record.facade, ...)
+ end)
+ end
+ return registrations
+end
+
function CompositionRoot:activate()
local record = root_records[self]
if record.activation == nil then
@@ -97,6 +141,7 @@ function CompositionRoot:activate()
feedback = feedback_activation,
highlights = highlights,
colorscheme_registration = colorscheme_registration,
+ actions = register_logical_actions(record),
}
end
return record.activation
diff --git a/tests/run.lua b/tests/run.lua
index 17749c9..403000a 100644
--- a/tests/run.lua
+++ b/tests/run.lua
@@ -7156,6 +7156,37 @@ test("Core activation installs sampled eager window hooks", function()
same(nil, disabled.feedback.eager_registration)
end)
+test("Core activation exposes all seven logical actions", function()
+ fresh_sequence_state()
+ local host = MemoryHost.new({
+ buffer_lines = { "aba" },
+ input_packets = { { kind = "text", text = "b" } },
+ configuration = {
+ mark_cursor = false,
+ mark_char = false,
+ },
+ emit_movement_events = false,
+ })
+ local activation = composition_root.new({ host = host }):activate()
+
+ same(7, #composition_root.ACTION_NAMES)
+ local registered = {}
+ for _, operation in ipairs(host:operations()) do
+ if operation.operation == "register_action" then
+ registered[#registered + 1] = operation.name
+ end
+ end
+ list_same(composition_root.ACTION_NAMES, registered)
+ for _, name in ipairs(composition_root.ACTION_NAMES) do
+ same(name, activation.actions[name])
+ end
+
+ local outcome = host:invoke_action("StartFindForward")
+ same(domain.ActionKind.MOVEMENT, outcome.kind)
+ same(domain.Position.new(1, 2), outcome.position)
+ same(domain.ActionKind.NEUTRAL, host:invoke_action("Reset").kind)
+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