From 4adf0440cdf0bdc9db3dadf89ebda0c9622d2a01 Mon Sep 17 00:00:00 2001 From: Jackson Moore Date: Fri, 4 Sep 2026 12:36:55 +0200 Subject: Reuse owned feedback finalizers --- lua/clever_f/feedback_service.lua | 16 +++++++++++++++- tests/run.lua | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/lua/clever_f/feedback_service.lua b/lua/clever_f/feedback_service.lua index 492eda6..0af482a 100644 --- a/lua/clever_f/feedback_service.lua +++ b/lua/clever_f/feedback_service.lua @@ -102,6 +102,7 @@ local function require_host(host) or type(host.remove_highlight) ~= "function" or type(host.read_buffer) ~= "function" or type(host.register_events) ~= "function" + or type(host.remove_event_registration) ~= "function" or type(host.supports_cursor_presentation) ~= "function" or type(host.suppress_cursor_presentation) ~= "function" or type(host.restore_cursor_presentation) ~= "function" @@ -119,6 +120,7 @@ local function require_transitions(transitions, state) or type(transitions.AddTargetOverlay) ~= "function" or type(transitions.ClearTargetOverlays) ~= "function" or type(transitions.AddFinalizer) ~= "function" + or type(transitions.RemoveFinalizer) ~= "function" then fail("FeedbackService transitions must manage overlay resources", 3) end @@ -151,6 +153,7 @@ function FeedbackService.new(options) options.state ), persistent_requests = {}, + owned_finalizer = nil, } return service end @@ -461,6 +464,15 @@ end local function register_finalizers(service, record) local buffer = record.host:read_buffer() + local owned = record.owned_finalizer + if owned ~= nil and owned.buffer == buffer then + return owned + end + if owned ~= nil then + record.host:remove_event_registration(owned.identity) + record.transitions:RemoveFinalizer(owned.identity, owned.buffer) + end + local identity = record.host:register_events( M.FINALIZER_EVENTS, function(name, payload) @@ -469,10 +481,12 @@ local function register_finalizers(service, record) { buffer = buffer } ) record.transitions:AddFinalizer(identity, buffer) - return { + owned = { identity = identity, buffer = buffer, } + record.owned_finalizer = owned + return owned end function FeedbackService:request_persistent(specification) diff --git a/tests/run.lua b/tests/run.lua index 2da1855..062f9ec 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -6097,6 +6097,41 @@ test("Persistent creation registers current-buffer finalizers", function() truthy(registration.active) end) +test("Persistent feedback owns one finalizer set", function() + local state, transitions = fresh_sequence_state() + local host = MemoryHost.new({ buffer_lines = { "aba" } }) + local feedback = feedback_service.new({ + host = host, + transitions = transitions, + }) + local shared_target = target_plan.build(target("a"), matching_policy()) + local movement = motion_plan.build(shared_target, "f") + local function create() + return feedback:request_persistent({ + context = "n", + anchor = domain.Position.new(1, 1), + target_plan = shared_target, + motion_plan = movement, + window = "window-1", + }) + end + + local first = create() + local second = create() + same(first.finalizers.identity, second.finalizers.identity) + same(1, #state.finalizers) + + host:set_buffer("buffer-2") + local third = create() + falsy(first.finalizers.identity == third.finalizers.identity) + same(1, #state.finalizers) + same(third.finalizers.identity, state.finalizers[1].identity) + same("buffer-2", state.finalizers[1].buffer) + local registrations = host:event_registrations() + falsy(registrations[first.finalizers.identity].active) + truthy(registrations[third.finalizers.identity].active) +end) + for _, item in ipairs(tests) do local ok, failure = xpcall(item.body, debug.traceback) if not ok then -- cgit v1.2.3