From 0809f1eb0c73648cae15806cf8a43ad35f445f7c Mon Sep 17 00:00:00 2001 From: Jackson Moore Date: Fri, 4 Sep 2026 11:34:56 +0200 Subject: Preserve colorscheme default labels --- lua/clever_f/capabilities.lua | 1 + lua/clever_f/feedback_service.lua | 69 ++++++++++++++++++++++++++++++++++++ lua/clever_f/testing/memory_host.lua | 17 +++++++++ tests/run.lua | 24 +++++++++++++ 4 files changed, 111 insertions(+) diff --git a/lua/clever_f/capabilities.lua b/lua/clever_f/capabilities.lua index 23da397..194de0b 100644 --- a/lua/clever_f/capabilities.lua +++ b/lua/clever_f/capabilities.lua @@ -11,6 +11,7 @@ M.read_methods = { macro_state = { "read_macro_state" }, fold_state = { "read_fold_state" }, time = { "read_time_ms" }, + highlight_groups = { "read_highlight_group" }, } M.effect_methods = { diff --git a/lua/clever_f/feedback_service.lua b/lua/clever_f/feedback_service.lua index 0b9c8cd..f7e1dd6 100644 --- a/lua/clever_f/feedback_service.lua +++ b/lua/clever_f/feedback_service.lua @@ -1,4 +1,11 @@ local M = {} +local FeedbackService = {} +FeedbackService.__index = FeedbackService +M.FeedbackService = FeedbackService + +M.DEFAULT_LABEL_GROUP = "CleverFDefaultLabel" + +local service_records = setmetatable({}, { __mode = "k" }) local DEFAULT_LABEL_DEFINITION = { guifg = "red", @@ -30,4 +37,66 @@ function M.default_label_definition() return copy(DEFAULT_LABEL_DEFINITION) end +local function fail(message, level) + error(message, (level or 1) + 1) +end + +local function normalize_options(options) + if type(options) ~= "table" then + fail("FeedbackService options must be a table", 3) + end + if options.host == nil then + return { host = options } + end + return options +end + +local function require_host(host) + if type(host) ~= "table" or type(host.read_highlight_group) ~= "function" then + fail("FeedbackService host must provide highlight groups", 3) + end + return host +end + +function FeedbackService.new(options) + if FeedbackService.is(options) then + return options + end + options = normalize_options(options) + local service = setmetatable({}, FeedbackService) + service_records[service] = { + host = require_host(options.host), + } + return service +end + +function FeedbackService.is(value) + return type(value) == "table" and service_records[value] ~= nil +end + +function FeedbackService:ensure_default_label() + local existing = service_records[self].host:read_highlight_group( + M.DEFAULT_LABEL_GROUP + ) + if existing ~= nil then + return { + group = M.DEFAULT_LABEL_GROUP, + definition = existing, + source = "colorscheme", + applied = false, + } + end + return nil +end + +function M.new(options) + return FeedbackService.new(options) +end + +setmetatable(M, { + __call = function(_, options) + return FeedbackService.new(options) + end, +}) + return M diff --git a/lua/clever_f/testing/memory_host.lua b/lua/clever_f/testing/memory_host.lua index 42dab71..459c9a8 100644 --- a/lua/clever_f/testing/memory_host.lua +++ b/lua/clever_f/testing/memory_host.lua @@ -163,6 +163,7 @@ function MemoryHost.new(options) _prompts = {}, _redraws = {}, _diagnostics = {}, + _highlight_groups = copy(options.highlight_groups or {}), _highlights = {}, _timers = {}, _event_registrations = {}, @@ -646,6 +647,22 @@ function MemoryHost:diagnostics() return copy(self._diagnostics) end +function MemoryHost:read_highlight_group(name) + if type(name) ~= "string" or name == "" then + error("highlight group name must be a nonempty string", 2) + end + local definition = self._highlight_groups[name] + self:_record("read_highlight_group", { + name = name, + defined = definition ~= nil, + }) + return copy(definition) +end + +function MemoryHost:highlight_groups() + return copy(self._highlight_groups) +end + function MemoryHost:create_highlight(specification) if type(specification) ~= "table" then error("highlight specification must be a table", 2) diff --git a/tests/run.lua b/tests/run.lua index 082b952..696026e 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -4233,6 +4233,30 @@ test("Default label fallback covers GUI and terminal rendering", function() truthy(fresh.cterm.bold) end) +test("Default label evaluation preserves a colorscheme definition", function() + local supplied = { + guifg = "blue", + gui = { italic = true }, + } + local host = MemoryHost.new({ + highlight_groups = { + CleverFDefaultLabel = supplied, + }, + }) + local feedback = feedback_service.new(host) + + local result = feedback:ensure_default_label() + same("colorscheme", result.source) + falsy(result.applied) + same("blue", result.definition.guifg) + truthy(result.definition.gui.italic) + same("blue", host:highlight_groups().CleverFDefaultLabel.guifg) + + local operations = host:operations() + same(1, #operations) + same("read_highlight_group", operations[1].operation) +end) + for _, item in ipairs(tests) do local ok, failure = xpcall(item.body, debug.traceback) if not ok then -- cgit v1.2.3