summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/clever_f/destination_engine.lua18
-rw-r--r--tests/run.lua44
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