summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/clever_f/domain.lua35
-rw-r--r--lua/clever_f/repeat_resolver.lua18
-rw-r--r--tests/run.lua25
3 files changed, 78 insertions, 0 deletions
diff --git a/lua/clever_f/domain.lua b/lua/clever_f/domain.lua
index 6a40092..d7ba040 100644
--- a/lua/clever_f/domain.lua
+++ b/lua/clever_f/domain.lua
@@ -1169,6 +1169,41 @@ function DotPayload:to_table()
}
end
+local ExplicitRepeatRequest = {}
+M.ExplicitRepeatRequest = ExplicitRepeatRequest
+
+register_type("ExplicitRepeatRequest", ExplicitRepeatRequest, function(data)
+ return "explicit-repeat:" .. data.descriptor.value
+end, function(left, right)
+ return left.descriptor == right.descriptor and left.target == right.target
+end)
+
+function ExplicitRepeatRequest.new(descriptor, target)
+ if ExplicitRepeatRequest.is(descriptor) and target == nil then
+ return descriptor
+ end
+ descriptor = Descriptor.from_string(descriptor)
+ target = require_record(target, "TargetValue", "explicit repeat target")
+ return new_record("ExplicitRepeatRequest", {
+ descriptor = descriptor,
+ effective_descriptor = descriptor,
+ target = target,
+ neutral = false,
+ })
+end
+
+function ExplicitRepeatRequest.is(value)
+ return is_record(value, "ExplicitRepeatRequest")
+end
+
+function ExplicitRepeatRequest:to_table()
+ return {
+ descriptor = self.descriptor.value,
+ target = self.target:to_table(),
+ neutral = self.neutral,
+ }
+end
+
local ActionOutcome = {}
M.ActionOutcome = ActionOutcome
diff --git a/lua/clever_f/repeat_resolver.lua b/lua/clever_f/repeat_resolver.lua
index 5f6a160..8f40059 100644
--- a/lua/clever_f/repeat_resolver.lua
+++ b/lua/clever_f/repeat_resolver.lua
@@ -235,6 +235,24 @@ RepeatResolver.primary_direction = RepeatResolver.resolve_primary_direction
RepeatResolver.effective_primary_descriptor =
RepeatResolver.resolve_primary_direction
+function M.build_same_direction_request(stored_descriptor, stored_target)
+ return domain.ExplicitRepeatRequest.new(stored_descriptor, stored_target)
+end
+
+M.explicit_same_direction = M.build_same_direction_request
+
+function RepeatResolver:same_direction_request(context)
+ context = domain.ModeContext.from_full_mode(context)
+ local state = resolver_records[self].state
+ return M.build_same_direction_request(
+ state:get_previous_descriptor(context),
+ state:get_previous_target(context)
+ )
+end
+
+RepeatResolver.resolve_explicit_same = RepeatResolver.same_direction_request
+RepeatResolver.explicit_same = RepeatResolver.same_direction_request
+
function M.new(options)
return RepeatResolver.new(options)
end
diff --git a/tests/run.lua b/tests/run.lua
index 598ea2b..f60dbc6 100644
--- a/tests/run.lua
+++ b/tests/run.lua
@@ -4086,6 +4086,31 @@ test("Reverse-request algorithm matches every direction matrix pair", function()
end
end)
+test("Explicit same-direction requests use the stored descriptor", function()
+ local _, transitions = fresh_sequence_state()
+ local stored_target = target("h")
+ local resolver = repeat_resolver.new()
+
+ for _, stored in ipairs({ "f", "F", "t", "T" }) do
+ transitions:BeginAcquisition("nov", stored)
+ transitions:CommitAcquiredTarget("noV", stored_target)
+ local request = resolver:same_direction_request(
+ "no" .. string.char(0x16)
+ )
+ truthy(domain.ExplicitRepeatRequest.is(request))
+ same(domain.Descriptor.from_string(stored), request.descriptor)
+ same(request.descriptor, request.effective_descriptor)
+ same(stored_target, request.target)
+ falsy(request.neutral)
+ end
+
+ local request = repeat_resolver.build_same_direction_request("f", stored_target)
+ same("f", request:to_table().descriptor)
+ fails(function()
+ request.descriptor = domain.Descriptor.FIND_BACKWARD
+ end, "immutable")
+end)
+
for _, item in ipairs(tests) do
local ok, failure = xpcall(item.body, debug.traceback)
if not ok then