diff options
| author | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 10:29:59 +0200 |
|---|---|---|
| committer | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 10:29:59 +0200 |
| commit | 2b62f5654d6b9d939266dda369c52ba0aaa59c07 (patch) | |
| tree | a8605574725c873ce70d396d34798f6fb7add8b4 | |
| parent | 3521acb1ddeff755e4af9c385ec0b202fa3c3333 (diff) | |
Preserve origins before any match
| -rw-r--r-- | lua/clever_f/destination_engine.lua | 18 | ||||
| -rw-r--r-- | tests/run.lua | 44 |
2 files changed, 55 insertions, 7 deletions
diff --git a/lua/clever_f/destination_engine.lua b/lua/clever_f/destination_engine.lua index 027dd2a..53cb654 100644 --- a/lua/clever_f/destination_engine.lua +++ b/lua/clever_f/destination_engine.lua @@ -147,6 +147,16 @@ local function till_equality_allowed(request, successful_steps) return request.first_move and successful_steps == 0 end +local function boundary_outcome(request, endpoint, successful_steps) + if successful_steps > 0 then + return domain.SearchOutcome.boundary_after_partial( + endpoint, + successful_steps + ) + end + return domain.SearchOutcome.boundary_before_any(request.origin) +end + function DestinationEngine:calculate(view, origin, plan, count, first_move) local request = calculation_inputs(view, origin, plan, count, first_move) local current_origin = request.origin @@ -168,13 +178,7 @@ function DestinationEngine:calculate(view, origin, plan, count, first_move) if successful_steps == request.count.value then return domain.SearchOutcome.complete(current_origin, successful_steps) end - if successful_steps > 0 then - return domain.SearchOutcome.boundary_after_partial( - current_origin, - successful_steps - ) - end - return domain.SearchOutcome.boundary_before_any(request.origin) + return boundary_outcome(request, current_origin, successful_steps) end function M.new() diff --git a/tests/run.lua b/tests/run.lua index eac53bf..7431de5 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -2839,6 +2839,50 @@ test("Partial outcomes retain the last intermediate destination", function() same(2, till_partial.successful_steps) end) +test("Boundary-before-any outcomes preserve the original position", function() + local engine = destination_engine.new() + local view = text_topology.new({ "", "abc" }, "utf-8") + local origin = domain.Position.new(1, 1) + local missing = motion_plan.build( + target_plan.build(target("z"), matching_policy()), + "f", + "buffer" + ) + local missing_outcome = engine:calculate(view, origin, missing, 4, true) + same(domain.SearchStatus.BOUNDARY_BEFORE_ANY, missing_outcome.status) + same(origin, missing_outcome.endpoint) + same(0, missing_outcome.successful_steps) + + local adjacent_view = text_topology.new({ "ab" }, "utf-8") + local adjacent_origin = domain.Position.new(1, 1) + local repeated_till = motion_plan.build( + target_plan.build(target("b"), matching_policy()), + "t" + ) + local adjacent_outcome = engine:calculate( + adjacent_view, + adjacent_origin, + repeated_till, + 1, + false + ) + same(domain.SearchStatus.BOUNDARY_BEFORE_ANY, adjacent_outcome.status) + same(adjacent_origin, adjacent_outcome.endpoint) + same(0, adjacent_outcome.successful_steps) + + local all_empty = text_topology.new({ "", "" }, "utf-8") + local empty_origin = domain.Position.new(2, 1) + local empty_outcome = engine:calculate( + all_empty, + empty_origin, + missing, + 1, + true + ) + same(domain.SearchStatus.BOUNDARY_BEFORE_ANY, empty_outcome.status) + same(empty_origin, empty_outcome.endpoint) +end) + for _, item in ipairs(tests) do local ok, failure = xpcall(item.body, debug.traceback) if not ok then |
