From 20141233347c9c552ec7d229b6ac0c18769e2713 Mon Sep 17 00:00:00 2001 From: Logan Swartzendruber Date: Sun, 1 Sep 2024 10:23:47 -0400 Subject: [PATCH 1/2] Add custom highlight groups and alias them to the previous highlights --- lua/hover.lua | 1 + lua/hover/actions.lua | 7 +++--- lua/hover/highlights.lua | 39 ++++++++++++++++++++++++++++++ lua/hover/providers/diagnostic.lua | 19 ++++++++------- lua/hover/util.lua | 26 ++++++++++++++------ 5 files changed, 72 insertions(+), 20 deletions(-) create mode 100644 lua/hover/highlights.lua diff --git a/lua/hover.lua b/lua/hover.lua index 9fc86da..dd964c4 100644 --- a/lua/hover.lua +++ b/lua/hover.lua @@ -33,6 +33,7 @@ end ---@param user_config Hover.Config function M.setup(user_config) require('hover.config').set(user_config) + require('hover.highlights').setup() end return M diff --git a/lua/hover/actions.lua b/lua/hover/actions.lua index 44390d4..ac40e52 100644 --- a/lua/hover/actions.lua +++ b/lua/hover/actions.lua @@ -4,6 +4,7 @@ local npcall = vim.F.npcall local has_winbar = vim.fn.has('nvim-0.8') == 1 local async = require('hover.async') +local highlights = require('hover.highlights').HIGHLIGHT_GROUPS local providers = require('hover.providers').providers local get_config = require('hover.config').get @@ -35,9 +36,9 @@ local function add_title(bufnr, winnr, active_provider_id) for _, p in ipairs(providers) do if is_enabled(p, bufnr) then - local hl = p.id == active_provider_id and 'TabLineSel' or 'TabLineFill' - title[#title+1] = string.format('%%#%s# %s ', hl, p.name) - title[#title+1] = '%#Normal# ' + local hl = p.id == active_provider_id and highlights.HoverActiveSource or highlights.HoverInactiveSource + title[#title + 1] = string.format('%%#%s# %s ', hl, p.name) + title[#title + 1] = '%#' .. highlights.HoverSourceLine .. '# ' winbar_length = winbar_length + #p.name + 2 -- + 2 for whitespace padding end end diff --git a/lua/hover/highlights.lua b/lua/hover/highlights.lua new file mode 100644 index 0000000..8295d37 --- /dev/null +++ b/lua/hover/highlights.lua @@ -0,0 +1,39 @@ +local M = {} + +---@enum HoverHighlightGroup +M.HIGHLIGHT_GROUPS = { + HoverWindow = 'HoverWindow', + HoverBorder = 'HoverBorder', + HoverActiveSource = 'HoverActiveSource', + HoverInactiveSource = 'HoverInactiveSource', + HoverSourceLine = 'HoverSourceLine', + HoverFloatingError = 'HoverFloatingError', + HoverFloatingWarn = 'HoverFloatingWarn', + HoverFloatingInfo = 'HoverFloatingInfo', + HoverFloatingHint = 'HoverFloatingHint', +} + +---@type table +M.HIGHLIGHT_GROUP_DEFAULTS = { + [M.HIGHLIGHT_GROUPS.HoverWindow] = 'NormalFloat', + [M.HIGHLIGHT_GROUPS.HoverBorder] = 'FloatBorder', + [M.HIGHLIGHT_GROUPS.HoverSourceLine] = 'TabLine', + [M.HIGHLIGHT_GROUPS.HoverActiveSource] = 'TabLineSel', + [M.HIGHLIGHT_GROUPS.HoverInactiveSource] = 'TabLineFill', + [M.HIGHLIGHT_GROUPS.HoverFloatingError] = 'DiagnosticFloatingError', + [M.HIGHLIGHT_GROUPS.HoverFloatingWarn] = 'DiagnosticFloatingWarn', + [M.HIGHLIGHT_GROUPS.HoverFloatingInfo] = 'DiagnosticFloatingInfo', + [M.HIGHLIGHT_GROUPS.HoverFloatingHint] = 'DiagnosticFloatingHint', +} + +function M.setup() + for highlight, value in pairs(M.HIGHLIGHT_GROUP_DEFAULTS) do + local existing = vim.api.nvim_get_hl(0, { name = highlight }) + + if vim.tbl_isempty(existing) then + vim.api.nvim_set_hl(0, highlight, { link = value }) + end + end +end + +return M diff --git a/lua/hover/providers/diagnostic.lua b/lua/hover/providers/diagnostic.lua index 2ffa7fa..7a2b2b6 100644 --- a/lua/hover/providers/diagnostic.lua +++ b/lua/hover/providers/diagnostic.lua @@ -1,13 +1,14 @@ +local highlights = require('hover.highlights').HIGHLIGHT_GROUPS local api, if_nil = vim.api, vim.F.if_nil -- Most of this is taken straight from vim.diagnostic.open_float, -- with some tweaks to remove some unnecessary parts local highlight_map = { - [vim.diagnostic.severity.ERROR] = 'DiagnosticFloatingError', - [vim.diagnostic.severity.WARN] = 'DiagnosticFloatingWarn', - [vim.diagnostic.severity.INFO] = 'DiagnosticFloatingInfo', - [vim.diagnostic.severity.HINT] = 'DiagnosticFloatingHint', + [vim.diagnostic.severity.ERROR] = highlights.HoverFloatingError, + [vim.diagnostic.severity.WARN] = highlights.HoverFloatingWarn, + [vim.diagnostic.severity.INFO] = highlights.HoverFloatingInfo, + [vim.diagnostic.severity.HINT] = highlights.HoverFloatingHint, } --- @return vim.diagnostic.Opts.Float @@ -146,18 +147,18 @@ local function execute(opts, done) end local lines = {} --- @type string[] - local highlights = {} --- @type table[] + local _highlights = {} --- @type table[] for i, diagnostic in ipairs(diagnostics) do if type(prefix_opt) == 'function' then --- @cast prefix_opt fun(...): string?, string? local prefix0, prefix_hl_group0 = prefix_opt(diagnostic, i, #diagnostics) - prefix, prefix_hl_group = prefix0 or '', prefix_hl_group0 or 'NormalFloat' + prefix, prefix_hl_group = prefix0 or '', prefix_hl_group0 or highlights.HoverWindow end if type(suffix_opt) == 'function' then --- @cast suffix_opt fun(...): string?, string? local suffix0, suffix_hl_group0 = suffix_opt(diagnostic, i, #diagnostics) - suffix, suffix_hl_group = suffix0 or '', suffix_hl_group0 or 'NormalFloat' + suffix, suffix_hl_group = suffix0 or '', suffix_hl_group0 or highlights.HoverWindow end --- @type string? local hiname = highlight_map[assert(diagnostic.severity)] @@ -170,7 +171,7 @@ local function execute(opts, done) local pre = j == 1 and prefix or string.rep(' ', #prefix) local suf = j == #message_lines and suffix or '' table.insert(lines, pre .. message_lines[j] .. suf) - table.insert(highlights, { + table.insert(_highlights, { hlname = hiname, prefix = { length = j == 1 and #prefix or 0, @@ -187,7 +188,7 @@ local function execute(opts, done) local float_bufnr = api.nvim_create_buf(false, true) api.nvim_buf_set_lines(float_bufnr, 0, -1, true, lines) - for i, hl in ipairs(highlights) do + for i, hl in ipairs(_highlights) do local line = lines[i] local prefix_len = hl.prefix and hl.prefix.length or 0 local suffix_len = hl.suffix and hl.suffix.length or 0 diff --git a/lua/hover/util.lua b/lua/hover/util.lua index d4428c9..731ddbe 100644 --- a/lua/hover/util.lua +++ b/lua/hover/util.lua @@ -1,3 +1,5 @@ +local highlights = require("hover.highlights").HIGHLIGHT_GROUPS +local highlight_defaults = require("hover.highlights").HIGHLIGHT_GROUP_DEFAULTS local api = vim.api local M = {} @@ -61,14 +63,14 @@ end ---@type ({[1]: string, [2]: string}|string)[] local default_border = { - { '' , 'NormalFloat' }, - { '' , 'NormalFloat' }, - { '' , 'NormalFloat' }, - { ' ', 'NormalFloat' }, - { '' , 'NormalFloat' }, - { '' , 'NormalFloat' }, - { '' , 'NormalFloat' }, - { ' ', 'NormalFloat' }, + { '', highlights.HoverBorder }, + { '', highlights.HoverBorder }, + { '', highlights.HoverBorder }, + { ' ', highlights.HoverBorder }, + { '', highlights.HoverBorder }, + { '', highlights.HoverBorder }, + { '', highlights.HoverBorder }, + { ' ', highlights.HoverBorder }, } --- @param width integer @@ -294,6 +296,14 @@ function M.open_floating_preview(contents, bufnr, syntax, opts) local float_option = make_floating_popup_options(width, height, opts) local hover_winid = api.nvim_open_win(floating_bufnr, false, float_option) + -- Set custom highlights for the window + local _winhl = {} + for hl, link in pairs(highlight_defaults) do + table.insert(_winhl, link .. ':' .. hl) + end + local winhl = table.concat(_winhl, ',') + vim.api.nvim_set_option_value('winhl', winhl, { win = hover_winid }) + if do_stylize then vim.wo[hover_winid].conceallevel = 2 vim.wo[hover_winid].concealcursor = 'n' From 75eb30c1c2cbe438cdef4d1f7ab7bfc68ea9c10d Mon Sep 17 00:00:00 2001 From: Logan Swartzendruber Date: Sun, 1 Sep 2024 10:34:06 -0400 Subject: [PATCH 2/2] Update README --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 50d9c71..6a103a4 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,21 @@ end) } ``` +## Appearance + +The appearance of the hover window can be customized with the following +highlight groups: + +* `HoverWindow` (defaults to: `NormalFloat`) +* `HoverBorder` (defaults to: `FloatBorder`) +* `HoverSourceLine` (defaults to: `TabLine`) +* `HoverActiveSource` (defaults to: `TabLineSel`) +* `HoverInactiveSource` (defaults to: `TabLineFill`) +* `HoverFloatingError` (defaults to: `DiagnosticFloatingError`) +* `HoverFloatingWarn` (defaults to: `DiagnosticFloatingWarn`) +* `HoverFloatingInfo` (defaults to: `DiagnosticFloatingInfo`) +* `HoverFloatingHint` (defaults to: `DiagnosticFloatingHint`) + ## Built in Providers ### LSP