feat(#1079): add renderer.highlight_clipboard default name, defaults to undercurls (#2410)

* feat(#1079): add highlight NvimTreeCopiedText and NvimTreeCutText

* feat(#1079): add highlight NvimTreeCopiedText and NvimTreeCutText

* feat(#1079): node may not be present in copy and cut

* feat(#1079): add renderer.highlight_clipboard

* feat(#1079): renderer.highlight_clipboard takes options, style cut/copy HL

* feat(#1079): renderer.highlight_clipboard takes options, style cut/copy HL

* feat(#1079): use an enum for highlight position

* feat(#1079): diagnostics uses _append_highlight
This commit is contained in:
Alexander Courtis
2023-09-17 16:08:04 +10:00
committed by GitHub
parent f742b86852
commit a3aa3b47ea
12 changed files with 205 additions and 91 deletions

View File

@@ -7,6 +7,8 @@ local icons = require "nvim-tree.renderer.components.icons"
local modified = require "nvim-tree.renderer.components.modified"
local diagnostics = require "nvim-tree.renderer.components.diagnostics"
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local Builder = {}
Builder.__index = Builder
@@ -114,7 +116,7 @@ end
---@class HighlightedString
---@field str string
---@field hl string|nil
---@field hl string[]
---@param highlighted_strings HighlightedString[]
---@return string
@@ -126,7 +128,7 @@ function Builder:_unwrap_highlighted_strings(highlighted_strings)
local string = ""
for _, v in ipairs(highlighted_strings) do
if #v.str > 0 then
if v.hl then
if v.hl and type(v.hl) == "table" then
self:_insert_highlight(v.hl, #string, #string + #v.str)
end
string = string .. v.str
@@ -136,7 +138,8 @@ function Builder:_unwrap_highlighted_strings(highlighted_strings)
end
---@param node table
---@return HighlightedString icon, HighlightedString name
---@return HighlightedString icon
---@return HighlightedString name
function Builder:_build_folder(node)
local has_children = #node.nodes ~= 0 or node.has_children
local icon, icon_hl = icons.get_folder_icon(node, has_children)
@@ -166,11 +169,12 @@ function Builder:_build_folder(node)
foldername_hl = "NvimTreeEmptyFolderName"
end
return { str = icon, hl = icon_hl }, { str = foldername, hl = foldername_hl }
return { str = icon, hl = { icon_hl } }, { str = foldername, hl = { foldername_hl } }
end
---@param node table
---@return HighlightedString icon, HighlightedString name
---@return HighlightedString icon
---@return HighlightedString name
function Builder:_build_symlink(node)
local icon = icons.i.symlink
local arrow = icons.i.symlink_arrow
@@ -180,21 +184,19 @@ function Builder:_build_symlink(node)
symlink_formatted = symlink_formatted .. arrow .. link_to
end
local link_highlight = "NvimTreeSymlink"
local icon_hl = "NvimTreeSymlinkIcon"
return { str = icon, hl = icon_hl }, { str = symlink_formatted, hl = link_highlight }
return { str = icon, hl = { "NvimTreeSymlinkIcon" } }, { str = symlink_formatted, hl = { "NvimTreeSymlink" } }
end
---@param node table
---@return HighlightedString icon
function Builder:_build_file_icon(node)
local icon, hl_group = icons.get_file_icon(node.name, node.extension)
return { str = icon, hl = hl_group }
return { str = icon, hl = { hl_group } }
end
---@param node table
---@return HighlightedString icon, HighlightedString name
---@return HighlightedString icon
---@return HighlightedString name
function Builder:_build_file(node)
local icon = self:_build_file_icon(node)
@@ -207,7 +209,7 @@ function Builder:_build_file(node)
hl = "NvimTreeImageFile"
end
return icon, { str = node.name, hl = hl }
return icon, { str = node.name, hl = { hl } }
end
---@param node table
@@ -215,7 +217,7 @@ end
function Builder:_get_git_icons(node)
local git_icons = git.get_icons(node)
if git_icons and #git_icons > 0 and self.git_placement == "signcolumn" then
table.insert(self.signs, { sign = git_icons[1].hl, lnum = self.index + 1, priority = 1 })
table.insert(self.signs, { sign = git_icons[1].hl[1], lnum = self.index + 1, priority = 1 })
git_icons = nil
end
return git_icons
@@ -226,7 +228,7 @@ end
function Builder:_get_diagnostics_icon(node)
local diagnostics_icon = diagnostics.get_icon(node)
if diagnostics_icon and self.diagnostics_placement == "signcolumn" then
table.insert(self.signs, { sign = diagnostics_icon.hl, lnum = self.index + 1, priority = 2 })
table.insert(self.signs, { sign = diagnostics_icon.hl[1], lnum = self.index + 1, priority = 2 })
diagnostics_icon = nil
end
return diagnostics_icon
@@ -237,14 +239,15 @@ end
function Builder:_get_modified_icon(node)
local modified_icon = modified.get_icon(node)
if modified_icon and self.modified_placement == "signcolumn" then
table.insert(self.signs, { sign = modified_icon.hl, lnum = self.index + 1, priority = 3 })
table.insert(self.signs, { sign = modified_icon.hl[1], lnum = self.index + 1, priority = 3 })
modified_icon = nil
end
return modified_icon
end
---@param node table
---@return string icon_highlight, string name_highlight
---@return string|nil icon_hl
---@return string|nil name_hl
function Builder:_get_highlight_override(node, unloaded_bufnr)
-- highlights precedence:
-- original < git < opened_file < modified
@@ -281,15 +284,26 @@ function Builder:_get_highlight_override(node, unloaded_bufnr)
end
end
-- diagnostic status
local diagnostic_highlight = diagnostics.get_highlight(node)
if diagnostic_highlight then
name_hl = diagnostic_highlight
end
return icon_hl, name_hl
end
---Append optional highlighting to icon or name.
---@param node table
---@param get_hl fun(node: table): HL_POSITION, string
---@param icon_hl string[] icons to append to
---@param name_hl string[] names to append to
function Builder:_append_highlight(node, get_hl, icon_hl, name_hl)
local pos, hl = get_hl(node)
if pos ~= HL_POSITION.none and hl then
if pos == HL_POSITION.all or pos == HL_POSITION.icon then
table.insert(icon_hl, hl)
end
if pos == HL_POSITION.all or pos == HL_POSITION.name then
table.insert(name_hl, hl)
end
end
end
---@param indent_markers HighlightedString[]
---@param arrows HighlightedString[]|nil
---@param icon HighlightedString
@@ -344,6 +358,8 @@ function Builder:_format_line(indent_markers, arrows, icon, name, git_icons, dia
end
function Builder:_build_line(node, idx, num_children, unloaded_bufnr)
local copy_paste = require "nvim-tree.actions.fs.copy-paste"
-- various components
local indent_markers = pad.get_indent_markers(self.depth, idx, num_children, node, self.markers)
local arrows = pad.get_arrows(node)
@@ -364,14 +380,18 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr)
end
-- highlight override
local icon_hl, name_hl = self:_get_highlight_override(node, unloaded_bufnr)
if icon_hl then
icon.hl = icon_hl
local icon_hl_override, name_hl_override = self:_get_highlight_override(node, unloaded_bufnr)
if icon_hl_override then
icon.hl = { icon_hl_override }
end
if name_hl then
name.hl = name_hl
if name_hl_override then
name.hl = { name_hl_override }
end
-- extra highighting
self:_append_highlight(node, diagnostics.get_highlight, icon.hl, name.hl)
self:_append_highlight(node, copy_paste.get_highlight, icon.hl, name.hl)
local line = self:_format_line(indent_markers, arrows, icon, name, git_icons, diagnostics_icon, modified_icon)
self:_insert_line(self:_unwrap_highlighted_strings(line))
@@ -429,7 +449,7 @@ function Builder:build_header(show_header)
if show_header then
local root_name = format_root_name(self.root_cwd, self.root_folder_label)
self:_insert_line(root_name)
self:_insert_highlight("NvimTreeRootFolder", 0, string.len(root_name))
self:_insert_highlight({ "NvimTreeRootFolder" }, 0, string.len(root_name))
self.index = 1
end
@@ -437,8 +457,8 @@ function Builder:build_header(show_header)
local filter_line = self.filter_prefix .. "/" .. self.filter .. "/"
self:_insert_line(filter_line)
local prefix_length = string.len(self.filter_prefix)
self:_insert_highlight("NvimTreeLiveFilterPrefix", 0, prefix_length)
self:_insert_highlight("NvimTreeLiveFilterValue", prefix_length, string.len(filter_line))
self:_insert_highlight({ "NvimTreeLiveFilterPrefix" }, 0, prefix_length)
self:_insert_highlight({ "NvimTreeLiveFilterValue" }, prefix_length, string.len(filter_line))
self.index = self.index + 1
end