summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJackson Moore <jacksonmoore@tuta.io>2026-09-04 13:41:50 +0200
committerJackson Moore <jacksonmoore@tuta.io>2026-09-04 13:41:50 +0200
commitc67ce4226f350671875d458a90604c6c4dec83db (patch)
tree8686a796f68c5092cda9cd77373f4b9cdf0089e5
parent15ed87626e8774ea2a54a82ff3bf9ac399ba4fc0 (diff)
Restore repeated primary feedback
-rw-r--r--lua/clever_f/sequence_coordinator.lua27
-rw-r--r--tests/run.lua31
2 files changed, 57 insertions, 1 deletions
diff --git a/lua/clever_f/sequence_coordinator.lua b/lua/clever_f/sequence_coordinator.lua
index c5ee808..3f0b510 100644
--- a/lua/clever_f/sequence_coordinator.lua
+++ b/lua/clever_f/sequence_coordinator.lua
@@ -331,6 +331,29 @@ function SequenceCoordinator:build_movement_plan(
return motion_plan
end
+function SequenceCoordinator:restore_repeated_feedback(resolution)
+ if type(resolution) ~= "table"
+ or not domain.TargetPlan.is(resolution.target_plan)
+ or not domain.ResolvedMotionPlan.is(resolution.motion_plan)
+ then
+ fail("feedback restoration requires a repeated primary resolution", 2)
+ end
+ local feedback = coordinator_records[self].feedback
+ if type(feedback.restore_primary) ~= "function" then
+ fail("FeedbackService must restore primary feedback", 2)
+ end
+ return feedback:restore_primary({
+ context = resolution.invocation.context,
+ anchor = resolution.invocation.position,
+ target_plan = resolution.target_plan,
+ motion_plan = resolution.motion_plan,
+ stored_descriptor = resolution.stored_descriptor,
+ endpoint_policy = resolution.motion_plan.endpoint_policy,
+ text_view = resolution.text_view,
+ window = resolution.timeout.window,
+ })
+end
+
function SequenceCoordinator:stored_primary_resolution(
invocation,
pressed_descriptor,
@@ -366,7 +389,7 @@ function SequenceCoordinator:stored_primary_resolution(
invocation,
search_scope
)
- return {
+ local resolution = {
kind = "repeat",
invocation = invocation,
pressed_descriptor = pressed_descriptor,
@@ -379,6 +402,8 @@ function SequenceCoordinator:stored_primary_resolution(
search_scope = search_scope,
effective_descriptor = effective_descriptor,
}
+ resolution.restored_feedback = self:restore_repeated_feedback(resolution)
+ return resolution
end
function SequenceCoordinator:primary(value)
diff --git a/tests/run.lua b/tests/run.lua
index eb82d0b..b577512 100644
--- a/tests/run.lua
+++ b/tests/run.lua
@@ -7508,6 +7508,37 @@ test("Primary repetition builds its effective contextual motion plan", function(
)
end)
+test("Primary repetition restores stored-descriptor feedback before movement", function()
+ local state, transitions = fresh_sequence_state()
+ local landing = domain.Position.new(1, 3)
+ transitions:BeginAcquisition("n", "t")
+ transitions:CommitAcquiredTarget("n", target("b"))
+ transitions:CommitCommandSuccess("n", landing, true)
+ local host = MemoryHost.new({
+ buffer_lines = { "ababa" },
+ cursor = landing,
+ configuration = { mark_char = true },
+ emit_movement_events = false,
+ })
+
+ local resolution = sequence_coordinator.new({ host = host }):primary("T")
+
+ truthy(resolution.restored_feedback ~= nil)
+ same(
+ domain.Descriptor.TILL_FORWARD,
+ resolution.restored_feedback.descriptor
+ )
+ same(resolution.target_plan, resolution.restored_feedback.target_plan)
+ same(
+ domain.Descriptor.TILL_BACKWARD,
+ resolution.motion_plan.descriptor
+ )
+ same(
+ resolution.restored_feedback.identity,
+ state.target_overlays[1].identity
+ )
+end)
+
for _, item in ipairs(tests) do
local ok, failure = xpcall(item.body, debug.traceback)
if not ok then