summaryrefslogtreecommitdiff
path: root/lua/clever_f
diff options
context:
space:
mode:
authorJackson Moore <jacksonmoore@tuta.io>2026-09-04 12:15:32 +0200
committerJackson Moore <jacksonmoore@tuta.io>2026-09-04 12:15:32 +0200
commitba398cbb4cdb04ffadf2935a2bb536a1c5105400 (patch)
tree9c103a95eb940308771eab1133794d1d6cd2fd3d /lua/clever_f
parent7406476fa093b9af888e82d3cf5c1cc3b320a06f (diff)
Make temporary releases idempotent
Diffstat (limited to 'lua/clever_f')
-rw-r--r--lua/clever_f/acquisition_service.lua34
-rw-r--r--lua/clever_f/feedback_service.lua24
2 files changed, 49 insertions, 9 deletions
diff --git a/lua/clever_f/acquisition_service.lua b/lua/clever_f/acquisition_service.lua
index a19f8f8..5cbe6ab 100644
--- a/lua/clever_f/acquisition_service.lua
+++ b/lua/clever_f/acquisition_service.lua
@@ -321,23 +321,47 @@ function TemporaryResourceScope:release()
if record == nil then
fail("temporary resource scope is invalid", 2)
end
+ if not record.active then
+ return false
+ end
+ record.active = false
+
+ local first_error
+ local function release_operation(operation)
+ local ok, failure = pcall(operation)
+ if not ok and first_error == nil then
+ first_error = failure
+ end
+ end
+
if record.interactive
and record.prompt_shown
and record.input_completed
and record.acquisition_completed
then
- record.host:redraw("full")
+ release_operation(function()
+ record.host:redraw("full")
+ end)
end
if record.direct_marker ~= nil then
- record.feedback:remove_temporary_overlay(record.direct_marker)
+ release_operation(function()
+ record.feedback:remove_temporary_overlay(record.direct_marker)
+ end)
end
if record.cursor_marker ~= nil then
- record.feedback:remove_temporary_overlay(record.cursor_marker)
+ release_operation(function()
+ record.feedback:remove_temporary_overlay(record.cursor_marker)
+ end)
end
if record.cursor_presentation_lease ~= nil then
- record.cursor_presentation_lease:release()
+ release_operation(function()
+ record.cursor_presentation_lease:release()
+ end)
end
- record.active = false
+ if first_error ~= nil then
+ error(first_error, 0)
+ end
+ return true
end
local function require_policy(service, host)
diff --git a/lua/clever_f/feedback_service.lua b/lua/clever_f/feedback_service.lua
index 2b100a4..084b30a 100644
--- a/lua/clever_f/feedback_service.lua
+++ b/lua/clever_f/feedback_service.lua
@@ -23,6 +23,7 @@ local OVERLAY_PRIORITIES = {
local service_records = setmetatable({}, { __mode = "k" })
local cursor_lease_records = setmetatable({}, { __mode = "k" })
+local temporary_release_records = setmetatable({}, { __mode = "k" })
local FEATURE_GROUPS = {
"CleverFCursor",
@@ -186,8 +187,8 @@ function CursorPresentationLease:release()
if not record.active then
return false
end
- record.host:restore_cursor_presentation(record.identity)
record.active = false
+ record.host:restore_cursor_presentation(record.identity)
return true
end
@@ -242,12 +243,14 @@ function FeedbackService:create_direct_markers(positions, window)
priority = M.overlay_priority("CleverFDirect"),
})
record.transitions:AddTemporaryOverlay(identity, window, "CleverFDirect")
- return {
+ local resource = {
identity = identity,
window = window,
group = "CleverFDirect",
positions = positions,
}
+ temporary_release_records[resource] = false
+ return resource
end
function FeedbackService:create_cursor_marker(position, window)
@@ -264,21 +267,34 @@ function FeedbackService:create_cursor_marker(position, window)
priority = M.overlay_priority("CleverFCursor"),
})
record.transitions:AddTemporaryOverlay(identity, window, "CleverFCursor")
- return {
+ local resource = {
identity = identity,
window = window,
group = "CleverFCursor",
position = position,
}
+ temporary_release_records[resource] = false
+ return resource
end
function FeedbackService:remove_temporary_overlay(resource)
if type(resource) ~= "table" or resource.identity == nil then
fail("temporary overlay resource must identify its highlight", 2)
end
+ if temporary_release_records[resource] == true then
+ return false
+ end
+ temporary_release_records[resource] = true
local record = service_records[self]
- local removed = record.host:remove_highlight(resource.identity)
+ local ok, removed = pcall(
+ record.host.remove_highlight,
+ record.host,
+ resource.identity
+ )
record.transitions:RemoveTemporaryOverlay(resource.identity, resource.window)
+ if not ok then
+ error(removed, 0)
+ end
return removed
end