summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/clever_f/motion_executor.lua10
-rw-r--r--tests/run.lua36
2 files changed, 45 insertions, 1 deletions
diff --git a/lua/clever_f/motion_executor.lua b/lua/clever_f/motion_executor.lua
index c22bed9..f7722e8 100644
--- a/lua/clever_f/motion_executor.lua
+++ b/lua/clever_f/motion_executor.lua
@@ -112,8 +112,9 @@ local function require_transitions(transitions, state)
transitions = transitions or state_transitions.new(state)
if type(transitions) ~= "table"
or type(transitions.CommitCommandSuccess) ~= "function"
+ or type(transitions.CommitVisualSuccess) ~= "function"
then
- fail("MotionExecutor transitions must commit command success", 3)
+ fail("MotionExecutor transitions must commit motion success", 3)
end
return transitions
end
@@ -249,6 +250,13 @@ function MotionExecutor:_execute_visual(request)
if outcome.successful_steps > 0 then
host:apply_selection(selection:with_focus(outcome.endpoint))
end
+ if not outcome.complete then
+ return domain.ActionOutcome.from_search(outcome, request.plan.descriptor)
+ end
+ executor_records[self].transitions:CommitVisualSuccess(
+ request.context,
+ outcome.endpoint
+ )
return domain.ActionOutcome.from_search(outcome, request.plan.descriptor)
end
diff --git a/tests/run.lua b/tests/run.lua
index 725fe98..743308d 100644
--- a/tests/run.lua
+++ b/tests/run.lua
@@ -3419,6 +3419,42 @@ test("Visual execution applies exact endpoints for every selection kind", functi
end
end)
+test("Complete Visual execution commits landing and first-move state", function()
+ local state, transitions = fresh_sequence_state()
+ local target_value = target("x")
+ transitions:BeginAcquisition("v", "f")
+ transitions:CommitAcquiredTarget("v", target_value)
+
+ local origin = domain.Position.new(1, 1)
+ local host = MemoryHost.new({
+ buffer_lines = { "abx" },
+ cursor = origin,
+ mode = "v",
+ selection = domain.Selection.active(
+ domain.SelectionKind.CHARACTER,
+ origin,
+ origin,
+ domain.SelectionOption.INCLUSIVE
+ ),
+ })
+ local plan = motion_plan.build(
+ target_plan.build(target_value, matching_policy()),
+ "f"
+ )
+ local outcome = motion_executor.new(host):execute(
+ text_topology.from_host(host),
+ "v",
+ plan,
+ 1,
+ true
+ )
+
+ same(domain.ActionKind.MOVEMENT, outcome.kind)
+ same(domain.Position.new(1, 3), state:get_previous_landing("v"))
+ falsy(state:get_first_move("v"))
+ same(target_value, state:get_previous_target("v"))
+end)
+
for _, item in ipairs(tests) do
local ok, failure = xpcall(item.body, debug.traceback)
if not ok then