From fbee8a69a46f558d29ab84e96301425b0501c668 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 29 Jan 2024 12:42:19 +1100 Subject: [PATCH] fix(#2643): correctly apply linked highlight groups in tree window (#2653) * fix(#2643): correctly apply linked highlight groups in tree window * fix(#2643): recreate and apply combined highlight groups on colorscheme change --- lua/nvim-tree.lua | 5 ++-- lua/nvim-tree/appearance.lua | 25 +--------------- lua/nvim-tree/renderer/builder.lua | 30 ++++++++----------- .../renderer/components/full-name.lua | 7 ++--- lua/nvim-tree/renderer/init.lua | 15 ++++------ lua/nvim-tree/view.lua | 24 ++++++++++++--- 6 files changed, 45 insertions(+), 61 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 51beee21a38..1cfead102ab 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -162,11 +162,12 @@ local function setup_autocommands(opts) vim.api.nvim_create_autocmd(name, vim.tbl_extend("force", default_opts, custom_opts)) end - -- reset and draw highlights when colorscheme is changed + -- reset and draw (highlights) when colorscheme is changed create_nvim_tree_autocmd("ColorScheme", { callback = function() appearance.setup() - renderer.render_hl(view.get_bufnr()) + view.reset_winhl() + renderer.draw() end, }) diff --git a/lua/nvim-tree/appearance.lua b/lua/nvim-tree/appearance.lua index d744a92e310..671d9a25446 100644 --- a/lua/nvim-tree/appearance.lua +++ b/lua/nvim-tree/appearance.lua @@ -1,7 +1,4 @@ -local M = { - -- namespace for all tree window highlights - NS_ID = vim.api.nvim_create_namespace "nvim_tree", -} +local M = {} -- directly defined groups, please keep these to an absolute minimum local DEFAULT_DEFS = { @@ -125,21 +122,6 @@ local DEFAULT_LINKS = { NvimTreeDiagnosticHintFolderHL = "NvimTreeDiagnosticHintFileHL", } --- namespace standard links -local NS_LINKS = { - EndOfBuffer = "NvimTreeEndOfBuffer", - CursorLine = "NvimTreeCursorLine", - CursorLineNr = "NvimTreeCursorLineNr", - LineNr = "NvimTreeLineNr", - WinSeparator = "NvimTreeWinSeparator", - StatusLine = "NvimTreeStatusLine", - StatusLineNC = "NvimTreeStatuslineNC", - SignColumn = "NvimTreeSignColumn", - Normal = "NvimTreeNormal", - NormalNC = "NvimTreeNormalNC", - NormalFloat = "NvimTreeNormalFloat", -} - -- nvim-tree highlight groups to legacy local LEGACY_LINKS = { NvimTreeModifiedIcon = "NvimTreeModifiedFile", @@ -207,11 +189,6 @@ function M.setup() for from, to in pairs(DEFAULT_LINKS) do vim.api.nvim_command("hi def link " .. from .. " " .. to) end - - -- window standard; this doesn't appear to clear on ColorScheme however we err on the side of caution - for from, to in pairs(NS_LINKS) do - vim.api.nvim_set_hl(M.NS_ID, from, { link = to }) - end end return M diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 7cb6fe7ec71..99f4506cd50 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -1,4 +1,3 @@ -local appearance = require "nvim-tree.appearance" local core = require "nvim-tree.core" local live_filter = require "nvim-tree.live-filter" local notify = require "nvim-tree.notify" @@ -46,7 +45,7 @@ local M = { ---@field private root_cwd string absolute path ---@field private index number ---@field private depth number ----@field private combined_groups string[] combined group names +---@field private combined_groups table combined group names ---@field private markers boolean[] indent markers local Builder = {} @@ -246,22 +245,17 @@ function Builder:build_signs(node) end end ----Combined group name less than the 200 byte limit of highlight group names ----@private ----@param groups string[] highlight group names ----@return string name "NvimTreeCombinedHL" .. sha256 -function Builder:combined_group_name(groups) - return string.format("NvimTreeCombinedHL%s", vim.fn.sha256(table.concat(groups))) -end - ---Create a highlight group for groups with later groups overriding previous. +---Combined group name is less than the 200 byte limit of highlight group names ---@private ---@param groups string[] highlight group names +---@return string group_name "NvimTreeCombinedHL" .. sha256 function Builder:create_combined_group(groups) - local combined_name = self:combined_group_name(groups) + local combined_name = string.format("NvimTreeCombinedHL%s", vim.fn.sha256(table.concat(groups))) -- only create if necessary - if not vim.tbl_contains(self.combined_groups, combined_name) then + if not self.combined_groups[combined_name] then + self.combined_groups[combined_name] = true local combined_hl = {} -- build the highlight, overriding values @@ -270,11 +264,13 @@ function Builder:create_combined_group(groups) combined_hl = vim.tbl_extend("force", combined_hl, hl) end - -- highlight directly in the namespace - vim.api.nvim_set_hl(appearance.NS_ID, combined_name, combined_hl) + -- add highlights to the global namespace + vim.api.nvim_set_hl(0, combined_name, combined_hl) table.insert(self.combined_groups, combined_name) end + + return combined_name end ---Calculate highlight group for icon and name. A combined highlight group will be created @@ -301,16 +297,14 @@ function Builder:add_highlights(node) -- one or many icon groups if #icon_groups > 1 then - icon_hl_group = self:combined_group_name(icon_groups) - self:create_combined_group(icon_groups) + icon_hl_group = self:create_combined_group(icon_groups) else icon_hl_group = icon_groups[1] end -- one or many name groups if #name_groups > 1 then - name_hl_group = self:combined_group_name(name_groups) - self:create_combined_group(name_groups) + name_hl_group = self:create_combined_group(name_groups) else name_hl_group = name_groups[1] end diff --git a/lua/nvim-tree/renderer/components/full-name.lua b/lua/nvim-tree/renderer/components/full-name.lua index 03e67e09955..9dde3c88a7a 100644 --- a/lua/nvim-tree/renderer/components/full-name.lua +++ b/lua/nvim-tree/renderer/components/full-name.lua @@ -1,5 +1,3 @@ -local appearance = require "nvim-tree.appearance" - local M = {} local utils = require "nvim-tree.utils" @@ -68,12 +66,13 @@ local function show() style = "minimal", }) - local extmarks = vim.api.nvim_buf_get_extmarks(0, appearance.NS_ID, { line_nr - 1, 0 }, { line_nr - 1, -1 }, { details = 1 }) + local ns_id = vim.api.nvim_get_namespaces()["NvimTreeHighlights"] + local extmarks = vim.api.nvim_buf_get_extmarks(0, ns_id, { line_nr - 1, 0 }, { line_nr - 1, -1 }, { details = 1 }) vim.api.nvim_win_call(M.popup_win, function() vim.api.nvim_buf_set_lines(0, 0, -1, true, { line }) for _, extmark in ipairs(extmarks) do local hl = extmark[4] - vim.api.nvim_buf_add_highlight(0, appearance.NS_ID, hl.hl_group, 0, extmark[3], hl.end_col) + vim.api.nvim_buf_add_highlight(0, ns_id, hl.hl_group, 0, extmark[3], hl.end_col) end vim.cmd [[ setlocal nowrap cursorline noswapfile nobuflisted buftype=nofile bufhidden=hide ]] end) diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index ce918682743..daffc104166 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -1,4 +1,3 @@ -local appearance = require "nvim-tree.appearance" local core = require "nvim-tree.core" local log = require "nvim-tree.log" local view = require "nvim-tree.view" @@ -9,12 +8,12 @@ local icon_component = require "nvim-tree.renderer.components.icons" local full_name = require "nvim-tree.renderer.components.full-name" local Builder = require "nvim-tree.renderer.builder" -local M = { - last_hl_args = {}, -} +local M = {} local SIGN_GROUP = "NvimTreeRendererSigns" +local namespace_id = vim.api.nvim_create_namespace "NvimTreeHighlights" + ---@param bufnr number ---@param lines string[] ---@param hl_args AddHighlightArgs[] @@ -34,11 +33,11 @@ function M.render_hl(bufnr, hl) if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then return end - vim.api.nvim_buf_clear_namespace(bufnr, appearance.NS_ID, 0, -1) - for _, data in ipairs(hl or M.last_hl_args) do + vim.api.nvim_buf_clear_namespace(bufnr, namespace_id, 0, -1) + for _, data in ipairs(hl) do if type(data[1]) == "table" then for _, group in ipairs(data[1]) do - vim.api.nvim_buf_add_highlight(bufnr, appearance.NS_ID, group, data[2], data[3], data[4]) + vim.api.nvim_buf_add_highlight(bufnr, namespace_id, group, data[2], data[3], data[4]) end end end @@ -59,8 +58,6 @@ function M.draw() _draw(bufnr, builder.lines, builder.hl_args, builder.signs) - M.last_hl_args = builder.hl_args - if cursor and #builder.lines >= cursor[1] then vim.api.nvim_win_set_cursor(view.get_winnr(), cursor) end diff --git a/lua/nvim-tree/view.lua b/lua/nvim-tree/view.lua index 5e52701dc60..4923cd2992d 100644 --- a/lua/nvim-tree/view.lua +++ b/lua/nvim-tree/view.lua @@ -1,4 +1,3 @@ -local appearance = require "nvim-tree.appearance" local events = require "nvim-tree.events" local utils = require "nvim-tree.utils" local log = require "nvim-tree.log" @@ -39,6 +38,19 @@ M.View = { cursorlineopt = "both", colorcolumn = "0", wrap = false, + winhl = table.concat({ + "EndOfBuffer:NvimTreeEndOfBuffer", + "CursorLine:NvimTreeCursorLine", + "CursorLineNr:NvimTreeCursorLineNr", + "LineNr:NvimTreeLineNr", + "WinSeparator:NvimTreeWinSeparator", + "StatusLine:NvimTreeStatusLine", + "StatusLineNC:NvimTreeStatuslineNC", + "SignColumn:NvimTreeSignColumn", + "Normal:NvimTreeNormal", + "NormalNC:NvimTreeNormalNC", + "NormalFloat:NvimTreeNormalFloat", + }, ","), }, } @@ -135,9 +147,6 @@ local function set_window_options_and_buffer() vim.opt_local[k] = v end vim.opt.eventignore = eventignore - - -- use highlights from the nvim_tree namespace - vim.api.nvim_win_set_hl_ns(M.get_winnr(), appearance.NS_ID) end ---@return table @@ -530,6 +539,13 @@ function M.is_root_folder_visible(cwd) return cwd ~= "/" and not M.View.hide_root_folder end +-- used on ColorScheme event +function M.reset_winhl() + if M.get_winnr() and vim.api.nvim_win_is_valid(M.get_winnr()) then + vim.wo[M.get_winnr()].winhl = M.View.winopts.winhl + end +end + function M.setup(opts) local options = opts.view or {} M.View.centralize_selection = options.centralize_selection