diff options
Diffstat (limited to 'lua/clever_f/acquisition_service.lua')
| -rw-r--r-- | lua/clever_f/acquisition_service.lua | 56 |
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 |
