diff options
| author | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 12:05:52 +0200 |
|---|---|---|
| committer | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 12:05:52 +0200 |
| commit | 7d08a49b62eed6c4afcd19897670fb10930faa46 (patch) | |
| tree | f258ec84a2093df71a226fba34a43d47d52beaea | |
| parent | b5a2d9934368ff15fb195abc1ef69b45226c5b06 (diff) | |
Report missing previous input
| -rw-r--r-- | lua/clever_f/acquisition_service.lua | 15 | ||||
| -rw-r--r-- | tests/run.lua | 28 |
2 files changed, 43 insertions, 0 deletions
diff --git a/lua/clever_f/acquisition_service.lua b/lua/clever_f/acquisition_service.lua index a81c501..52b3949 100644 --- a/lua/clever_f/acquisition_service.lua +++ b/lua/clever_f/acquisition_service.lua @@ -20,6 +20,7 @@ M.RepeatedDirection = { SAME = "same", } M.PROMPT = "clever-f: " +M.PREVIOUS_INPUT_NOT_FOUND = "Previous input not found." local request_records = setmetatable({}, { __mode = "k" }) local result_records = setmetatable({}, { __mode = "k" }) @@ -142,6 +143,7 @@ function AcquisitionResult.new(request, options) previous_input_trigger = options.previous_input_trigger, previous_target_source = options.previous_target_source, cached_target = options.cached_target, + missing_previous_input = options.missing_previous_input == true, completed = outcome ~= nil or target ~= nil, } return result @@ -187,6 +189,7 @@ function TemporaryResourceScope.new(request, feedback) previous_input_trigger = nil, previous_target_source = nil, cached_target = nil, + missing_previous_input = false, outcome = nil, } return scope @@ -238,6 +241,13 @@ function TemporaryResourceScope:set_cached_target(context, target) return set_scope_resource(self, "cached_target", target) end +function TemporaryResourceScope:set_missing_previous_input(missing) + if type(missing) ~= "boolean" then + fail("missing previous-input state must be a Boolean", 2) + end + return set_scope_resource(self, "missing_previous_input", missing) +end + function TemporaryResourceScope:set_outcome(outcome) if not domain.ActionOutcome.is(outcome) then fail("temporary resource scope outcome must be an ActionOutcome", 2) @@ -639,6 +649,10 @@ function AcquisitionService:acquire(descriptor, context, position, count, macro_ scope:set_cached_target(source, cached_target) if cached_target ~= nil then target = cached_target + else + target = nil + scope:set_missing_previous_input(true) + record.host:emit_diagnostic("error", M.PREVIOUS_INPUT_NOT_FOUND) end end scope:set_resolved_target(target) @@ -647,6 +661,7 @@ function AcquisitionService:acquire(descriptor, context, position, count, macro_ previous_input_trigger = trigger, previous_target_source = scope.previous_target_source, cached_target = scope.cached_target, + missing_previous_input = scope.missing_previous_input, }) end diff --git a/tests/run.lua b/tests/run.lua index c968d87..69f5087 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -5257,6 +5257,34 @@ test("Acquisition compares first codes with previous-input triggers", function() same(nil, acquisition_service.match_previous_input_trigger(122, { "xy" })) end) +test("Missing previous input preserves cursor and emits exact diagnostic", function() + fresh_sequence_state() + local origin = domain.Position.new(1, 2) + local host = MemoryHost.new({ + buffer_lines = { "abc" }, + cursor = origin, + configuration = { + mark_cursor = false, + hide_cursor_on_cmdline = false, + repeat_last_char_inputs = { "\r" }, + }, + input_packets = { { kind = "text", text = "\r" } }, + }) + local service = acquisition_service.new(host) + + local result = service:acquire("f", "n", origin, nil, nil) + truthy(result.missing_previous_input) + same(nil, result.target) + same(origin, host:read_cursor()) + same(1, #host:diagnostics()) + same("error", host:diagnostics()[1].level) + same("Previous input not found.", host:diagnostics()[1].text) + same( + acquisition_service.PREVIOUS_INPUT_NOT_FOUND, + host:diagnostics()[1].text + ) +end) + for _, item in ipairs(tests) do local ok, failure = xpcall(item.body, debug.traceback) if not ok then |
