diff options
| author | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 13:38:52 +0200 |
|---|---|---|
| committer | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 13:38:52 +0200 |
| commit | 973ca221adfce140eb3ce7e537abfaef70c32e3e (patch) | |
| tree | 8347445e92f1f5ce4105f026a7ff66d34fee4c4a | |
| parent | ec0bc598ba3b623af5426bec280585ada78489e0 (diff) | |
Reacquire expired primary sequences
| -rw-r--r-- | lua/clever_f/sequence_coordinator.lua | 10 | ||||
| -rw-r--r-- | tests/run.lua | 37 |
2 files changed, 47 insertions, 0 deletions
diff --git a/lua/clever_f/sequence_coordinator.lua b/lua/clever_f/sequence_coordinator.lua index 9e6a9b6..837acf5 100644 --- a/lua/clever_f/sequence_coordinator.lua +++ b/lua/clever_f/sequence_coordinator.lua @@ -274,6 +274,16 @@ function SequenceCoordinator:primary(value) return self:resolve_acquisition(descriptor, invocation) end local timeout = self:evaluate_repeat_timeout(invocation) + if timeout.decision == repeat_resolver_factory.Decision.ACQUIRE then + local record = coordinator_records[self] + if timeout.cleanup ~= nil then + if type(record.feedback.release_transition_cleanup) ~= "function" then + fail("FeedbackService must release reset cleanup", 2) + end + record.feedback:release_transition_cleanup(timeout.cleanup) + end + return self:resolve_acquisition(descriptor, invocation) + end return { kind = "repeat", invocation = invocation, diff --git a/tests/run.lua b/tests/run.lua index 089f6dc..05a37f7 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -7338,6 +7338,43 @@ test("Repeated primary coordination evaluates timeout before reuse", function() truthy(time_read ~= nil) end) +test("Expired primary repetition resets resources and reacquires pressed key", function() + local state, transitions = fresh_sequence_state() + local landing = domain.Position.new(1, 3) + local old_target = target("a") + local host = MemoryHost.new({ + buffer_lines = { "ababa" }, + cursor = landing, + input_packets = { { kind = "text", text = "b" } }, + time_values_ms = { 120 }, + configuration = { + repeat_timeout_ms = 10, + mark_cursor = false, + mark_char = false, + }, + }) + transitions:BeginAcquisition("n", "f") + transitions:CommitAcquiredTarget("n", old_target, 100) + transitions:CommitCommandSuccess("n", landing, true) + local overlay = host:create_highlight({ + group = "CleverFChar", + window = "window-1", + positions = { landing }, + }) + transitions:AddTargetOverlay(overlay, "window-1", 1) + local timer = host:start_timer(50, function() end) + transitions:SetHighlightTimer(timer) + + local resolution = sequence_coordinator.new({ host = host }):primary("T") + + same("fresh", resolution.kind) + same(domain.Descriptor.TILL_BACKWARD, resolution.effective_descriptor) + same("b", resolution.target.value) + same(domain.Descriptor.TILL_BACKWARD, state:get_previous_descriptor("n")) + same(nil, host:highlights()[overlay]) + falsy(host:timers()[timer].active) +end) + for _, item in ipairs(tests) do local ok, failure = xpcall(item.body, debug.traceback) if not ok then |
