diff options
| author | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 12:34:32 +0200 |
|---|---|---|
| committer | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 12:34:32 +0200 |
| commit | 97dd567a7847e6efb7974a000353ecf4c44e1519 (patch) | |
| tree | 02b31760abd828a0bfa1d641cc45a5d23b158589 | |
| parent | 44682cf3244b773c33037967bd028608eb7be6dd (diff) | |
Create persistent character overlay
| -rw-r--r-- | lua/clever_f/feedback_service.lua | 39 | ||||
| -rw-r--r-- | tests/run.lua | 29 |
2 files changed, 65 insertions, 3 deletions
diff --git a/lua/clever_f/feedback_service.lua b/lua/clever_f/feedback_service.lua index 9c16cca..a5b0dd0 100644 --- a/lua/clever_f/feedback_service.lua +++ b/lua/clever_f/feedback_service.lua @@ -104,8 +104,10 @@ local function require_transitions(transitions, state) if type(transitions) ~= "table" or type(transitions.AddTemporaryOverlay) ~= "function" or type(transitions.RemoveTemporaryOverlay) ~= "function" + or type(transitions.AddTargetOverlay) ~= "function" + or type(transitions.ClearTargetOverlays) ~= "function" then - fail("FeedbackService transitions must manage temporary overlays", 3) + fail("FeedbackService transitions must manage overlay resources", 3) end return transitions end @@ -426,9 +428,42 @@ function FeedbackService:build_persistent(specification) } end +local function remove_target_overlays(record, window) + local resources = record.transitions:ClearTargetOverlays(window) + for _, resource in ipairs(resources) do + record.host:remove_highlight(resource.identity) + end + return resources +end + +function FeedbackService:remove_character_overlays(window) + if window == nil then + fail("character overlay window must identify its host window", 2) + end + return remove_target_overlays(service_records[self], window) +end + function FeedbackService:request_persistent(specification) local request = self:build_persistent(specification) - local requests = service_records[self].persistent_requests + if request.window == nil then + fail("persistent feedback window must identify its host window", 2) + end + local record = service_records[self] + remove_target_overlays(record, request.window) + request.identity = record.host:create_highlight({ + group = "CleverFChar", + window = request.window, + positions = request.positions, + priority = M.overlay_priority("CleverFChar"), + target_plan = request.target_plan, + descriptor = request.descriptor, + endpoint_policy = request.endpoint_policy, + match_start_line = request.match_start_line, + }) + request.group = "CleverFChar" + request.priority = M.overlay_priority("CleverFChar") + record.transitions:AddTargetOverlay(request.identity, request.window) + local requests = record.persistent_requests requests[#requests + 1] = request return request end diff --git a/tests/run.lua b/tests/run.lua index a03556f..7cb848c 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -4953,7 +4953,7 @@ end) test("Interactive acquisition redraws after cursor marker creation", function() fresh_sequence_state() local host = MemoryHost.new({ - configuration = { mark_cursor = true }, + configuration = { mark_cursor = true, mark_char = false }, input_packets = { { kind = "text", text = "a" } }, }) local service = acquisition_service.new(host) @@ -4997,6 +4997,7 @@ test("Interactive acquisition creates enabled direct previews", function() configuration = { mark_cursor = false, mark_direct = true, + mark_char = false, ignore_case = false, smart_case = false, }, @@ -5956,6 +5957,32 @@ test("Persistent match starts stay on the anchor line", function() same(domain.Position.new(2, 3), persistent.positions[2]) end) +test("Persistent matches share one high-priority character overlay", function() + local state, transitions = fresh_sequence_state() + local host = MemoryHost.new({ buffer_lines = { "ababa" } }) + local feedback = feedback_service.new({ + host = host, + transitions = transitions, + }) + local shared_target = target_plan.build(target("a"), matching_policy()) + local movement = motion_plan.build(shared_target, "f") + local persistent = feedback:request_persistent({ + context = "n", + anchor = domain.Position.new(1, 1), + target_plan = shared_target, + motion_plan = movement, + window = "window-1", + }) + local highlight = host:highlights()[persistent.identity] + + same("CleverFChar", highlight.group) + same(feedback_service.Priority.HIGH, highlight.priority) + same(shared_target, highlight.target_plan) + same(3, #highlight.positions) + list_same({ persistent.identity }, state:target_overlay_identities()) + same(1, map_size(host:highlights())) +end) + for _, item in ipairs(tests) do local ok, failure = xpcall(item.body, debug.traceback) if not ok then |
