From 83d452db377867729230a7fbf806c39fa2977a9b Mon Sep 17 00:00:00 2001 From: Joshua Wood Date: Fri, 24 May 2024 10:06:25 +1200 Subject: [PATCH] feat: further customise highlight colors (#31) * feat: further customise highlight colors * Fixes indentation, highlight casing. * refactor: drop string input add tests * docs: update docs * docs: clearer wording --------- Co-authored-by: tris203 --- README.md | 6 ++- lua/precognition/init.lua | 17 ++++-- tests/precognition/e2e_spec.lua | 93 +++++++++++++++++++++++++++++---- 3 files changed, 99 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 2531726..47a1034 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ return { config = { -- startVisible = true, -- showBlankVirtLine = true, - -- highlightColor = "Comment", + -- highlightColor = { link = "Comment"), -- hints = { -- Caret = { text = "^", prio = 2 }, -- Dollar = { text = "$", prio = 1 }, @@ -52,6 +52,10 @@ return { - `showBlankVirtLine = false` Setting this option will mean that if a Virtual Line would be blank it wont be rendered +- highlightColor can be set in two ways: + +1. As a table containing a link property pointing to an existing highlight group (see `:highlight` for valid options). +2. As a table specifying custom highlight values, such as foreground and background colors. ([more info]()) ## ā¯”Usage diff --git a/lua/precognition/init.lua b/lua/precognition/init.lua index a2e8656..fba6720 100644 --- a/lua/precognition/init.lua +++ b/lua/precognition/init.lua @@ -28,14 +28,14 @@ local M = {} ---@class Precognition.Config ---@field startVisible boolean ---@field showBlankVirtLine boolean ----@field highlightColor string +---@field highlightColor vim.api.keyset.highlight ---@field hints Precognition.HintConfig ---@field gutterHints Precognition.GutterHintConfig ---@class Precognition.PartialConfig ---@field startVisible? boolean ---@field showBlankVirtLine? boolean ----@field highlightColor? string +---@field highlightColor? vim.api.keyset.highlight ---@field hints? Precognition.HintConfig ---@field gutterHints? Precognition.GutterHintConfig @@ -72,7 +72,7 @@ local defaultHintConfig = { local default = { startVisible = true, showBlankVirtLine = true, - highlightColor = "Comment", + highlightColor = { link = "Comment" }, hints = defaultHintConfig, gutterHints = { --prio is not currentlt used for gutter hints @@ -143,7 +143,7 @@ local function build_virt_line(marks, line_len) if line:match("^%s+$") then return {} end - table.insert(virt_line, { line, config.highlightColor }) + table.insert(virt_line, { line, "PrecognitionHighlight" }) return virt_line end @@ -175,7 +175,7 @@ local function apply_gutter_hints(gutter_hints, bufnr) end vim.fn.sign_define(gutter_name_prefix .. hint, { text = config.gutterHints[hint].text, - texthl = config.highlightColor, + texthl = "PrecognitionHighlight", }) local ok, res = pcall(vim.fn.sign_place, 0, gutter_group, gutter_name_prefix .. hint, bufnr, { lnum = loc, @@ -352,9 +352,16 @@ end ---@param opts Precognition.PartialConfig function M.setup(opts) config = vim.tbl_deep_extend("force", default, opts or {}) + if opts.highlightColor then + config.highlightColor = opts.highlightColor + end ns = vim.api.nvim_create_namespace("precognition") au = vim.api.nvim_create_augroup("precognition", { clear = true }) + + local hl_name = "PrecognitionHighlight" + vim.api.nvim_set_hl(0, hl_name, config.highlightColor) + if config.startVisible then M.show() end diff --git a/tests/precognition/e2e_spec.lua b/tests/precognition/e2e_spec.lua index c579d45..dec6d34 100644 --- a/tests/precognition/e2e_spec.lua +++ b/tests/precognition/e2e_spec.lua @@ -16,6 +16,17 @@ local function get_gutter_extmarks(buffer) return gutter_extmarks end +local function hex2dec(hex) + hex = hex:gsub("#", "") + local r = tonumber("0x" .. hex:sub(1, 2)) + local g = tonumber("0x" .. hex:sub(3, 4)) + local b = tonumber("0x" .. hex:sub(5, 6)) + + local dec = (r * 256 ^ 2) + (g * 256) + b + + return dec +end + describe("e2e tests", function() before_each(function() precognition.setup({}) @@ -58,16 +69,17 @@ describe("e2e tests", function() for _, extmark in pairs(gutter_extmarks) do if extmark[4].sign_text == "G " then - eq("Comment", extmark[4].sign_hl_group) + eq("PrecognitionHighlight", extmark[4].sign_hl_group) + eq({ link = "Comment" }, vim.api.nvim_get_hl(0, { name = extmark[4].sign_hl_group })) eq(5, extmark[2]) elseif extmark[4].sign_text == "gg" then - eq("Comment", extmark[4].sign_hl_group) + eq("PrecognitionHighlight", extmark[4].sign_hl_group) eq(0, extmark[2]) elseif extmark[4].sign_text == "{ " then - eq("Comment", extmark[4].sign_hl_group) + eq("PrecognitionHighlight", extmark[4].sign_hl_group) eq(0, extmark[2]) elseif extmark[4].sign_text == "} " then - eq("Comment", extmark[4].sign_hl_group) + eq("PrecognitionHighlight", extmark[4].sign_hl_group) eq(2, extmark[2]) else assert(false, "unexpected sign text") @@ -76,7 +88,8 @@ describe("e2e tests", function() eq(vim.api.nvim_win_get_cursor(0)[1] - 1, extmarks[1]) eq("b e w $", extmarks[3].virt_lines[1][1][1]) - eq("Comment", extmarks[3].virt_lines[1][1][2]) + eq("PrecognitionHighlight", extmarks[3].virt_lines[1][1][2]) + eq({ link = "Comment" }, vim.api.nvim_get_hl(0, { name = extmarks[3].virt_lines[1][1][2] })) vim.api.nvim_win_set_cursor(0, { 1, 6 }) precognition.on_cursor_moved() @@ -134,7 +147,60 @@ describe("e2e tests", function() end) it("virtual line text color can be customised", function() - precognition.setup({ highlightColor = "Function" }) + precognition.setup({ highlightColor = { link = "Function" } }) + local buffer = vim.api.nvim_create_buf(true, false) + vim.api.nvim_set_current_buf(buffer) + vim.api.nvim_buf_set_lines( + buffer, + 0, + -1, + false, + { "Hello World this is a test", "line 2", "", "line 4", "", "line 6" } + ) + vim.api.nvim_win_set_cursor(0, { 1, 1 }) + + precognition.on_cursor_moved() + + local extmarks = vim.api.nvim_buf_get_extmark_by_id(buffer, precognition.ns, precognition.extmark, { + details = true, + }) + + local gutter_extmarks = get_gutter_extmarks(buffer) + + for _, extmark in pairs(gutter_extmarks) do + if extmark[4].sign_text == "G " then + eq("PrecognitionHighlight", extmark[4].sign_hl_group) + eq({ link = "Function" }, vim.api.nvim_get_hl(0, { name = extmark[4].sign_hl_group })) + eq(5, extmark[2]) + elseif extmark[4].sign_text == "gg" then + eq("PrecognitionHighlight", extmark[4].sign_hl_group) + eq({ link = "Function" }, vim.api.nvim_get_hl(0, { name = extmark[4].sign_hl_group })) + eq(0, extmark[2]) + elseif extmark[4].sign_text == "{ " then + eq("PrecognitionHighlight", extmark[4].sign_hl_group) + eq({ link = "Function" }, vim.api.nvim_get_hl(0, { name = extmark[4].sign_hl_group })) + eq(0, extmark[2]) + elseif extmark[4].sign_text == "} " then + eq("PrecognitionHighlight", extmark[4].sign_hl_group) + eq({ link = "Function" }, vim.api.nvim_get_hl(0, { name = extmark[4].sign_hl_group })) + eq(2, extmark[2]) + else + assert(false, "unexpected sign text") + end + end + + eq(vim.api.nvim_win_get_cursor(0)[1] - 1, extmarks[1]) + eq("b e w $", extmarks[3].virt_lines[1][1][1]) + eq("PrecognitionHighlight", extmarks[3].virt_lines[1][1][2]) + eq({ link = "Function" }, vim.api.nvim_get_hl(0, { name = extmarks[3].virt_lines[1][1][2] })) + end) + + it("virtual line can be customised without a link", function() + local background = "#00ff00" + local foreground = "#ff0000" + local customColor = { foreground = foreground, background = background } + local customMark = { fg = hex2dec(foreground), bg = hex2dec(background) } + precognition.setup({ highlightColor = customColor }) local buffer = vim.api.nvim_create_buf(true, false) vim.api.nvim_set_current_buf(buffer) vim.api.nvim_buf_set_lines( @@ -156,16 +222,20 @@ describe("e2e tests", function() for _, extmark in pairs(gutter_extmarks) do if extmark[4].sign_text == "G " then - eq("Function", extmark[4].sign_hl_group) + eq("PrecognitionHighlight", extmark[4].sign_hl_group) + eq(customMark, vim.api.nvim_get_hl(0, { name = extmark[4].sign_hl_group })) eq(5, extmark[2]) elseif extmark[4].sign_text == "gg" then - eq("Function", extmark[4].sign_hl_group) + eq("PrecognitionHighlight", extmark[4].sign_hl_group) + eq(customMark, vim.api.nvim_get_hl(0, { name = extmark[4].sign_hl_group })) eq(0, extmark[2]) elseif extmark[4].sign_text == "{ " then - eq("Function", extmark[4].sign_hl_group) + eq("PrecognitionHighlight", extmark[4].sign_hl_group) + eq(customMark, vim.api.nvim_get_hl(0, { name = extmark[4].sign_hl_group })) eq(0, extmark[2]) elseif extmark[4].sign_text == "} " then - eq("Function", extmark[4].sign_hl_group) + eq("PrecognitionHighlight", extmark[4].sign_hl_group) + eq(customMark, vim.api.nvim_get_hl(0, { name = extmark[4].sign_hl_group })) eq(2, extmark[2]) else assert(false, "unexpected sign text") @@ -174,6 +244,7 @@ describe("e2e tests", function() eq(vim.api.nvim_win_get_cursor(0)[1] - 1, extmarks[1]) eq("b e w $", extmarks[3].virt_lines[1][1][1]) - eq("Function", extmarks[3].virt_lines[1][1][2]) + eq("PrecognitionHighlight", extmarks[3].virt_lines[1][1][2]) + eq(customMark, vim.api.nvim_get_hl(0, { name = extmarks[3].virt_lines[1][1][2] })) end) end)