summaryrefslogtreecommitdiff
path: root/lua/clever_f/acquisition_service.lua
diff options
context:
space:
mode:
authorJackson Moore <jacksonmoore@tuta.io>2026-09-04 12:14:32 +0200
committerJackson Moore <jacksonmoore@tuta.io>2026-09-04 12:14:32 +0200
commit7406476fa093b9af888e82d3cf5c1cc3b320a06f (patch)
tree4ecc4ab06cdb046506c0706065ab71fa6b4044b0 /lua/clever_f/acquisition_service.lua
parentf4c2e8dfd3d0ededbd350bde046b5f2e5ab1c131 (diff)
Finalize acquisition resource scope
Diffstat (limited to 'lua/clever_f/acquisition_service.lua')
-rw-r--r--lua/clever_f/acquisition_service.lua56
1 files changed, 46 insertions, 10 deletions
diff --git a/lua/clever_f/acquisition_service.lua b/lua/clever_f/acquisition_service.lua
index a50e614..a19f8f8 100644
--- a/lua/clever_f/acquisition_service.lua
+++ b/lua/clever_f/acquisition_service.lua
@@ -695,10 +695,7 @@ local function direct_preview_settings(policy_service)
fail("AcquisitionService policy must sample direct preview settings", 3)
end
-function AcquisitionService:acquire(descriptor, context, position, count, macro_state)
- local request = self:request(descriptor, context, position, count, macro_state)
- local scope = self:start_temporary_scope(request)
- local record = service_records[self]
+local function acquire_in_scope(record, request, scope)
local acquisition = record.policy:sample_acquisition()
local interactive = not request.macro_state.executing
scope:set_cursor_presentation_lease(
@@ -711,11 +708,11 @@ function AcquisitionService:acquire(descriptor, context, position, count, macro_
request.position,
current_window(record)
))
- if not request.macro_state.executing then
+ if interactive then
record.host:redraw("screen")
end
end
- if acquisition.mark_direct and not request.macro_state.executing then
+ if acquisition.mark_direct and interactive then
local view = scope:set_text_view(text_topology.from_host(record.host))
local positions = record.direct_planner:plan(
view,
@@ -733,7 +730,7 @@ function AcquisitionService:acquire(descriptor, context, position, count, macro_
))
record.host:redraw("screen")
end
- if acquisition.show_prompt and not request.macro_state.executing then
+ if acquisition.show_prompt and interactive then
record.host:show_prompt(M.PROMPT)
scope:mark_prompt_shown()
end
@@ -742,7 +739,6 @@ function AcquisitionService:acquire(descriptor, context, position, count, macro_
scope:mark_input_completed()
if M.is_escape(packet) then
local outcome = scope:set_outcome(domain.ActionOutcome.escape(request.position))
- scope:release()
return AcquisitionResult.new(request, { outcome = outcome })
end
local target = scope:set_acquired_target(M.normalize_input_packet(packet))
@@ -765,7 +761,6 @@ function AcquisitionService:acquire(descriptor, context, position, count, macro_
local outcome = scope:set_outcome(
domain.ActionOutcome.empty(request.position)
)
- scope:release()
return AcquisitionResult.new(request, {
outcome = outcome,
previous_input_trigger = trigger,
@@ -836,7 +831,48 @@ function AcquisitionService:acquire(descriptor, context, position, count, macro_
missing_previous_input = scope.missing_previous_input,
})
scope:mark_acquisition_completed()
- scope:release()
+ return result
+end
+
+local function error_message(failure)
+ local message = tostring(failure)
+ if message == "" then
+ return "clever-f: Acquisition failed"
+ end
+ return message
+end
+
+function AcquisitionService:acquire(descriptor, context, position, count, macro_state)
+ local request = self:request(descriptor, context, position, count, macro_state)
+ local scope = self:start_temporary_scope(request)
+ local record = service_records[self]
+ local ok, result = xpcall(function()
+ return acquire_in_scope(record, request, scope)
+ end, function(failure)
+ return failure
+ end)
+
+ if not ok then
+ local diagnostic = error_message(result)
+ result = AcquisitionResult.new(request, {
+ outcome = domain.ActionOutcome.error(request.position, diagnostic),
+ })
+ end
+
+ local cleanup_ok, cleanup_error = pcall(function()
+ scope:release()
+ end)
+ if not cleanup_ok and ok then
+ local diagnostic = error_message(cleanup_error)
+ result = AcquisitionResult.new(request, {
+ outcome = domain.ActionOutcome.error(request.position, diagnostic),
+ })
+ ok = false
+ end
+
+ if not ok then
+ pcall(record.host.emit_diagnostic, record.host, "error", result.outcome.diagnostic)
+ end
return result
end