summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/clever_f/feedback_service.lua20
-rw-r--r--tests/run.lua36
2 files changed, 53 insertions, 3 deletions
diff --git a/lua/clever_f/feedback_service.lua b/lua/clever_f/feedback_service.lua
index 061ed1d..c5c9fc8 100644
--- a/lua/clever_f/feedback_service.lua
+++ b/lua/clever_f/feedback_service.lua
@@ -461,11 +461,15 @@ function FeedbackService:build_persistent(specification)
}
end
-local function remove_target_overlays(record, window)
- local resources = record.transitions:ClearTargetOverlays(window)
+local function release_target_overlays(record, resources)
for _, resource in ipairs(resources) do
record.host:remove_highlight(resource.identity)
end
+end
+
+local function remove_target_overlays(record, window)
+ local resources = record.transitions:ClearTargetOverlays(window)
+ release_target_overlays(record, resources)
return resources
end
@@ -489,10 +493,20 @@ function FeedbackService:cursor_moved_decision()
}
end
+local function release_finalizers(record, resources)
+ for _, resource in ipairs(resources) do
+ record.host:remove_event_registration(resource.identity)
+ end
+end
+
function FeedbackService:full_finalize(window)
local record = service_records[self]
window = window or record.host:read_window()
- return record.transitions:FullFinalization(window)
+ local cleanup = record.transitions:FullFinalization(window)
+ release_finalizers(record, cleanup.finalizers)
+ release_target_overlays(record, cleanup.target_overlays)
+ record.owned_finalizer = nil
+ return cleanup
end
function FeedbackService:handle_finalizer_event(name, payload)
diff --git a/tests/run.lua b/tests/run.lua
index 2a0786f..6244677 100644
--- a/tests/run.lua
+++ b/tests/run.lua
@@ -6261,6 +6261,42 @@ test("Insert and text events finalize feedback directly", function()
end
end)
+test("Full finalization removes owned registrations and window overlays", 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 current = feedback:request_persistent({
+ context = "n",
+ anchor = domain.Position.new(1, 1),
+ target_plan = shared_target,
+ motion_plan = movement,
+ window = "window-1",
+ })
+ local peer = host:create_highlight({
+ group = "CleverFChar",
+ window = "window-2",
+ positions = {},
+ priority = feedback_service.Priority.HIGH,
+ })
+ transitions:AddTargetOverlay(peer, "window-2", 1)
+
+ local cleanup = feedback:full_finalize("window-1")
+
+ same(1, #cleanup.finalizers)
+ same(current.finalizers.identity, cleanup.finalizers[1].identity)
+ falsy(host:event_registrations()[current.finalizers.identity].active)
+ same(nil, host:highlights()[current.identity])
+ truthy(host:highlights()[peer] ~= nil)
+ same(1, #state.target_overlays)
+ same(peer, state.target_overlays[1].identity)
+ same(0, #state.finalizers)
+end)
+
for _, item in ipairs(tests) do
local ok, failure = xpcall(item.body, debug.traceback)
if not ok then