From ed9688ce68f0e6cded2e54e64057b58e040d26e4 Mon Sep 17 00:00:00 2001 From: Jackson Moore Date: Fri, 4 Sep 2026 11:13:31 +0200 Subject: Handle missing explicit descriptors --- lua/clever_f/domain.lua | 30 ++++++++++++++++++++++++++++-- lua/clever_f/repeat_resolver.lua | 6 ++++++ tests/run.lua | 21 +++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/lua/clever_f/domain.lua b/lua/clever_f/domain.lua index d7ba040..4d21d56 100644 --- a/lua/clever_f/domain.lua +++ b/lua/clever_f/domain.lua @@ -1173,11 +1173,18 @@ local ExplicitRepeatRequest = {} M.ExplicitRepeatRequest = ExplicitRepeatRequest register_type("ExplicitRepeatRequest", ExplicitRepeatRequest, function(data) + if data.neutral then + return "explicit-repeat:neutral" + end return "explicit-repeat:" .. data.descriptor.value end, function(left, right) - return left.descriptor == right.descriptor and left.target == right.target + return left.neutral == right.neutral + and left.descriptor == right.descriptor + and left.target == right.target end) +local neutral_explicit_repeat_request + function ExplicitRepeatRequest.new(descriptor, target) if ExplicitRepeatRequest.is(descriptor) and target == nil then return descriptor @@ -1192,15 +1199,34 @@ function ExplicitRepeatRequest.new(descriptor, target) }) end +function ExplicitRepeatRequest.neutral() + if neutral_explicit_repeat_request == nil then + neutral_explicit_repeat_request = new_record("ExplicitRepeatRequest", { + descriptor = nil, + effective_descriptor = nil, + target = nil, + neutral = true, + }) + end + return neutral_explicit_repeat_request +end + function ExplicitRepeatRequest.is(value) return is_record(value, "ExplicitRepeatRequest") end +function ExplicitRepeatRequest:is_neutral() + return self.neutral +end + function ExplicitRepeatRequest:to_table() + if self.neutral then + return { neutral = true } + end return { descriptor = self.descriptor.value, target = self.target:to_table(), - neutral = self.neutral, + neutral = false, } end diff --git a/lua/clever_f/repeat_resolver.lua b/lua/clever_f/repeat_resolver.lua index 057c7e6..2af60bf 100644 --- a/lua/clever_f/repeat_resolver.lua +++ b/lua/clever_f/repeat_resolver.lua @@ -236,6 +236,9 @@ RepeatResolver.effective_primary_descriptor = RepeatResolver.resolve_primary_direction function M.build_same_direction_request(stored_descriptor, stored_target) + if stored_descriptor == nil then + return domain.ExplicitRepeatRequest.neutral() + end return domain.ExplicitRepeatRequest.new(stored_descriptor, stored_target) end @@ -254,6 +257,9 @@ RepeatResolver.resolve_explicit_same = RepeatResolver.same_direction_request RepeatResolver.explicit_same = RepeatResolver.same_direction_request function M.build_opposite_direction_request(stored_descriptor, stored_target) + if stored_descriptor == nil then + return domain.ExplicitRepeatRequest.neutral() + end return domain.ExplicitRepeatRequest.new( domain.Descriptor.swap(stored_descriptor), stored_target diff --git a/tests/run.lua b/tests/run.lua index 4b6f1c7..d360332 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -4126,6 +4126,27 @@ test("Explicit opposite-direction requests swap the stored descriptor", function end end) +test("Missing explicit descriptors return a neutral request", function() + local _, transitions = fresh_sequence_state() + local resolver = repeat_resolver.new() + local same_request = resolver:same_direction_request("n") + local opposite_request = resolver:opposite_direction_request("n") + + same(same_request, opposite_request) + truthy(domain.ExplicitRepeatRequest.is(same_request)) + truthy(same_request.neutral) + truthy(same_request:is_neutral()) + same(nil, same_request.descriptor) + same(nil, same_request.target) + truthy(same_request:to_table().neutral) + + transitions:BeginAcquisition("n", "f") + transitions:CommitAcquiredTarget("n", target("a")) + transitions:PublicReset() + truthy(resolver:same_direction_request("n").neutral) + truthy(resolver:opposite_direction_request("n").neutral) +end) + for _, item in ipairs(tests) do local ok, failure = xpcall(item.body, debug.traceback) if not ok then -- cgit v1.2.3