diff options
| -rw-r--r-- | lua/clever_f/acquisition_service.lua | 26 | ||||
| -rw-r--r-- | lua/clever_f/feedback_service.lua | 44 | ||||
| -rw-r--r-- | tests/run.lua | 37 |
3 files changed, 105 insertions, 2 deletions
diff --git a/lua/clever_f/acquisition_service.lua b/lua/clever_f/acquisition_service.lua index 77d08ec..ba796fd 100644 --- a/lua/clever_f/acquisition_service.lua +++ b/lua/clever_f/acquisition_service.lua @@ -155,6 +155,7 @@ function AcquisitionResult.new(request, options) cached_target = options.cached_target, missing_previous_input = options.missing_previous_input == true, acquisition_time_ms = options.acquisition_time_ms, + persistent_feedback_request = options.persistent_feedback_request, completed = outcome ~= nil or target ~= nil, } return result @@ -355,8 +356,11 @@ local function require_feedback(feedback, host, policy_service, transitions) policy = policy_service, transitions = transitions, }) - if type(feedback) ~= "table" or type(feedback.create_cursor_marker) ~= "function" then - fail("AcquisitionService feedback must create cursor markers", 3) + if type(feedback) ~= "table" + or type(feedback.create_cursor_marker) ~= "function" + or type(feedback.request_persistent) ~= "function" + then + fail("AcquisitionService feedback must manage acquisition markers", 3) end return feedback end @@ -760,11 +764,29 @@ function AcquisitionService:acquire(descriptor, context, position, count, macro_ search_scope ) ) + local persistent_feedback_request + if record.policy:sample_markers().mark_char + and feedback_service.persistent_context_eligible(request.context) + then + local window = scope.cursor_marker + and scope.cursor_marker.window + or scope.direct_marker + and scope.direct_marker.window + or current_window(record) + persistent_feedback_request = record.feedback:request_persistent({ + context = request.context, + anchor = request.position, + target_plan = target_plan, + motion_plan = motion_plan, + window = window, + }) + end return AcquisitionResult.new(request, { target = target, target_plan = target_plan, motion_plan = motion_plan, acquisition_time_ms = acquisition_time_ms, + persistent_feedback_request = persistent_feedback_request, previous_input_trigger = trigger, previous_target_source = scope.previous_target_source, cached_target = scope.cached_target, diff --git a/lua/clever_f/feedback_service.lua b/lua/clever_f/feedback_service.lua index b1a4233..2b100a4 100644 --- a/lua/clever_f/feedback_service.lua +++ b/lua/clever_f/feedback_service.lua @@ -133,6 +133,7 @@ function FeedbackService.new(options) options.transitions or options.state_transitions, options.state ), + persistent_requests = {}, } return service end @@ -281,6 +282,49 @@ function FeedbackService:remove_temporary_overlay(resource) return removed end +function M.persistent_context_eligible(context) + context = domain.ModeContext.from_full_mode(context) + return context.key == "n" + or context.visual_kind ~= nil + or context.select_kind ~= nil + or context.key == "cv" + or context.key == "cvr" +end + +function FeedbackService:request_persistent(specification) + if type(specification) ~= "table" then + fail("persistent feedback request must be a table", 2) + end + local context = domain.ModeContext.from_full_mode(specification.context) + if not M.persistent_context_eligible(context) then + fail("persistent feedback request requires an eligible context", 2) + end + if not domain.TargetPlan.is(specification.target_plan) then + fail("persistent feedback request requires a TargetPlan", 2) + end + if not domain.ResolvedMotionPlan.is(specification.motion_plan) then + fail("persistent feedback request requires a ResolvedMotionPlan", 2) + end + local request = { + context = context, + anchor = domain.Position.coerce(specification.anchor), + target_plan = specification.target_plan, + motion_plan = specification.motion_plan, + window = specification.window, + } + local requests = service_records[self].persistent_requests + requests[#requests + 1] = request + return request +end + +function FeedbackService:persistent_requests() + local result = {} + for index, request in ipairs(service_records[self].persistent_requests) do + result[index] = request + end + return result +end + function FeedbackService:evaluate_feature_links() local record = service_records[self] local rules = record.policy:evaluate_highlight_links() diff --git a/tests/run.lua b/tests/run.lua index 1249316..ed7cd33 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -5416,6 +5416,43 @@ test("Acquisition builds a fresh initiating motion plan", function() falsy(first.motion_plan == second.motion_plan) end) +test("Acquisition requests eligible persistent target feedback", function() + local _, transitions = fresh_sequence_state() + local host = MemoryHost.new({ + buffer_lines = { "aha" }, + configuration = { + mark_cursor = false, + mark_char = true, + }, + input_packets = { + { kind = "text", text = "h" }, + { kind = "text", text = "h" }, + }, + }) + local feedback = feedback_service.new({ + host = host, + transitions = transitions, + }) + local service = acquisition_service.new({ + host = host, + transitions = transitions, + feedback = feedback, + }) + local origin = domain.Position.new(1, 1) + + local normal = service:acquire("f", "n", origin, nil, nil) + truthy(normal.persistent_feedback_request ~= nil) + same(normal.target_plan, normal.persistent_feedback_request.target_plan) + same(normal.motion_plan, normal.persistent_feedback_request.motion_plan) + same("window-1", normal.persistent_feedback_request.window) + + local operator = service:acquire("f", "no", origin, nil, nil) + same(nil, operator.persistent_feedback_request) + same(1, #feedback:persistent_requests()) + truthy(feedback_service.persistent_context_eligible("n")) + falsy(feedback_service.persistent_context_eligible("no")) +end) + for _, item in ipairs(tests) do local ok, failure = xpcall(item.body, debug.traceback) if not ok then |
