From 9689d0de4d6556b569e308cbf02169f8e7f0d1ac Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 10 Sep 2023 14:36:31 +1000 Subject: [PATCH 1/8] feat(#1079): add highlight NvimTreeCopiedText and NvimTreeCutText --- doc/nvim-tree-lua.txt | 4 ++ lua/nvim-tree/actions/fs/copy-paste.lua | 21 ++++++ lua/nvim-tree/colors.lua | 3 + lua/nvim-tree/renderer/builder.lua | 72 ++++++++++++------- .../renderer/components/diagnostics.lua | 12 ++-- lua/nvim-tree/renderer/components/git.lua | 14 ++-- .../renderer/components/modified.lua | 2 +- lua/nvim-tree/renderer/components/padding.lua | 4 +- lua/nvim-tree/renderer/init.lua | 6 +- 9 files changed, 97 insertions(+), 41 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 6645019e4e5..6c3dd214e23 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -2166,6 +2166,10 @@ Standard: > NvimTreeStatusLine StatusLine NvimTreeStatusLineNC StatusLineNC < +Clipboard: > + NvimTreeCopiedText + NvimTreeCutText +< Picker: > NvimTreeWindowPicker < diff --git a/lua/nvim-tree/actions/fs/copy-paste.lua b/lua/nvim-tree/actions/fs/copy-paste.lua index 1b26ef12678..e6ceb1db301 100644 --- a/lua/nvim-tree/actions/fs/copy-paste.lua +++ b/lua/nvim-tree/actions/fs/copy-paste.lua @@ -4,6 +4,7 @@ local utils = require "nvim-tree.utils" local core = require "nvim-tree.core" local events = require "nvim-tree.events" local notify = require "nvim-tree.notify" +local renderer = require "nvim-tree.renderer" local find_file = require("nvim-tree.actions.finders.find-file").fn @@ -150,14 +151,17 @@ function M.clear_clipboard() clipboard.move = {} clipboard.copy = {} notify.info "Clipboard has been emptied." + renderer.draw() end function M.copy(node) add_to_clipboard(node, clipboard.copy) + renderer.draw() end function M.cut(node) add_to_clipboard(node, clipboard.move) + renderer.draw() end local function do_paste(node, action_type, action_fn) @@ -267,6 +271,23 @@ function M.copy_absolute_path(node) return copy_to_clipboard(content) end +---clipboard text highlight group +---@param node table +---@return string|nil group +function M.get_highlight(node) + for _, n in ipairs(clipboard.move) do + if node == n then + return "NvimTreeCutText" + end + end + + for _, n in ipairs(clipboard.copy) do + if node == n then + return "NvimTreeCopiedText" + end + end +end + function M.setup(opts) M.config.filesystem_watchers = opts.filesystem_watchers M.config.actions = opts.actions diff --git a/lua/nvim-tree/colors.lua b/lua/nvim-tree/colors.lua index d06957106db..3337167895e 100644 --- a/lua/nvim-tree/colors.lua +++ b/lua/nvim-tree/colors.lua @@ -42,6 +42,9 @@ local function get_hl_groups() OpenedFile = { gui = "bold", fg = colors.green }, ModifiedFile = { fg = colors.green }, + CopiedText = { gui = "underline" }, + CutText = { gui = "strikethrough" }, + GitDirty = { fg = colors.dark_red }, GitDeleted = { fg = colors.dark_red }, GitStaged = { fg = colors.green }, diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index ba5b5478dce..b5350d9e4e5 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -114,7 +114,7 @@ end ---@class HighlightedString ---@field str string ----@field hl string|nil +---@field hl string[] ---@param highlighted_strings HighlightedString[] ---@return string @@ -126,7 +126,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 +136,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 +167,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 +182,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 +207,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 +215,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 +226,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 +237,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 @@ -290,6 +291,20 @@ function Builder:_get_highlight_override(node, unloaded_bufnr) return icon_hl, name_hl end +---@param node table +---@return string[] icon_hl +---@return string[] name_hl +function Builder:_get_highlight_extra(node) + local icon_hl = {} + local name_hl = {} + + -- clipboard + local clipboard_highlight = require "nvim-tree.actions.fs.copy-paste".get_highlight(node) + table.insert(name_hl, clipboard_highlight) + + return icon_hl, name_hl +end + ---@param indent_markers HighlightedString[] ---@param arrows HighlightedString[]|nil ---@param icon HighlightedString @@ -364,12 +379,21 @@ 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_override then + name.hl = { name_hl_override } + end + + -- extra highighting + local icon_hl_extra, name_hl_extra = self:_get_highlight_extra(node) + for _, hl in ipairs(icon_hl_extra) do + table.insert(icon.hl, hl) end - if name_hl then - name.hl = name_hl + for _, hl in ipairs(name_hl_extra) do + table.insert(name.hl, hl) end local line = self:_format_line(indent_markers, arrows, icon, name, git_icons, diagnostics_icon, modified_icon) @@ -429,7 +453,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 +461,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 diff --git a/lua/nvim-tree/renderer/components/diagnostics.lua b/lua/nvim-tree/renderer/components/diagnostics.lua index e62ebd22398..0c0e3150645 100644 --- a/lua/nvim-tree/renderer/components/diagnostics.lua +++ b/lua/nvim-tree/renderer/components/diagnostics.lua @@ -6,7 +6,7 @@ local ICON = {} ---diagnostics text highlight group if there is a status ---@param node table ----@return string|nil highlight +---@return string|nil group function M.get_highlight(node) if node and M.config.diagnostics.enable and M.config.renderer.highlight_diagnostics then if node.nodes then @@ -44,24 +44,24 @@ function M.setup(opts) ICON[vim.diagnostic.severity.ERROR] = { str = M.config.diagnostics.icons.error, - hl = "NvimTreeLspDiagnosticsError", + hl = { "NvimTreeLspDiagnosticsError" }, } ICON[vim.diagnostic.severity.WARN] = { str = M.config.diagnostics.icons.warning, - hl = "NvimTreeLspDiagnosticsWarning", + hl = { "NvimTreeLspDiagnosticsWarning" }, } ICON[vim.diagnostic.severity.INFO] = { str = M.config.diagnostics.icons.info, - hl = "NvimTreeLspDiagnosticsInfo", + hl = { "NvimTreeLspDiagnosticsInfo" }, } ICON[vim.diagnostic.severity.HINT] = { str = M.config.diagnostics.icons.hint, - hl = "NvimTreeLspDiagnosticsHint", + hl = { "NvimTreeLspDiagnosticsHint" }, } for _, i in ipairs(ICON) do - vim.fn.sign_define(i.hl, { text = i.str, texthl = i.hl }) + vim.fn.sign_define(i.hl[1], { text = i.str, texthl = i.hl[1] }) end end diff --git a/lua/nvim-tree/renderer/components/git.lua b/lua/nvim-tree/renderer/components/git.lua index fdfa8b81077..977031fd945 100644 --- a/lua/nvim-tree/renderer/components/git.lua +++ b/lua/nvim-tree/renderer/components/git.lua @@ -5,13 +5,13 @@ local M = {} local function build_icons_table(i) local icons = { - staged = { str = i.staged, hl = "NvimTreeGitStaged", ord = 1 }, - unstaged = { str = i.unstaged, hl = "NvimTreeGitDirty", ord = 2 }, - renamed = { str = i.renamed, hl = "NvimTreeGitRenamed", ord = 3 }, - deleted = { str = i.deleted, hl = "NvimTreeGitDeleted", ord = 4 }, - unmerged = { str = i.unmerged, hl = "NvimTreeGitMerge", ord = 5 }, - untracked = { str = i.untracked, hl = "NvimTreeGitNew", ord = 6 }, - ignored = { str = i.ignored, hl = "NvimTreeGitIgnored", ord = 7 }, + staged = { str = i.staged, hl = { "NvimTreeGitStaged" }, ord = 1 }, + unstaged = { str = i.unstaged, hl = { "NvimTreeGitDirty" }, ord = 2 }, + renamed = { str = i.renamed, hl = { "NvimTreeGitRenamed" }, ord = 3 }, + deleted = { str = i.deleted, hl = { "NvimTreeGitDeleted" }, ord = 4 }, + unmerged = { str = i.unmerged, hl = { "NvimTreeGitMerge" }, ord = 5 }, + untracked = { str = i.untracked, hl = { "NvimTreeGitNew" }, ord = 6 }, + ignored = { str = i.ignored, hl = { "NvimTreeGitIgnored" }, ord = 7 }, } return { ["M "] = { icons.staged }, diff --git a/lua/nvim-tree/renderer/components/modified.lua b/lua/nvim-tree/renderer/components/modified.lua index 1ae9870b405..f247d7b2046 100644 --- a/lua/nvim-tree/renderer/components/modified.lua +++ b/lua/nvim-tree/renderer/components/modified.lua @@ -12,7 +12,7 @@ function M.get_icon(node) return nil end - return { str = M.icon, hl = HIGHLIGHT } + return { str = M.icon, hl = { HIGHLIGHT } } end function M.setup_signs() diff --git a/lua/nvim-tree/renderer/components/padding.lua b/lua/nvim-tree/renderer/components/padding.lua index b20091f0c57..f3196f88908 100644 --- a/lua/nvim-tree/renderer/components/padding.lua +++ b/lua/nvim-tree/renderer/components/padding.lua @@ -78,7 +78,7 @@ function M.get_indent_markers(depth, idx, nodes_number, node, markers) str = str .. string.rep(" ", depth * indent_width) end - return { str = str, hl = "NvimTreeIndentMarker" } + return { str = str, hl = { "NvimTreeIndentMarker" } } end ---@param node table @@ -104,7 +104,7 @@ function M.get_arrows(node) str = " " end - return { str = str, hl = hl } + return { str = str, hl = { hl } } end function M.setup(opts) diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 8785e175ef3..72e04df017d 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -38,7 +38,11 @@ function M.render_hl(bufnr, hl) end vim.api.nvim_buf_clear_namespace(bufnr, namespace_id, 0, -1) for _, data in ipairs(hl or M.last_highlights) do - vim.api.nvim_buf_add_highlight(bufnr, namespace_id, data[1], data[2], data[3], data[4]) + if type(data[1]) == "table" then + for _, group in ipairs(data[1]) do + vim.api.nvim_buf_add_highlight(bufnr, namespace_id, group, data[2], data[3], data[4]) + end + end end end From c9ed71877398bd49ae06072f721401f8a3354df1 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 10 Sep 2023 14:36:56 +1000 Subject: [PATCH 2/8] feat(#1079): add highlight NvimTreeCopiedText and NvimTreeCutText --- lua/nvim-tree/renderer/builder.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index b5350d9e4e5..b8b9c6b1eef 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -299,7 +299,7 @@ function Builder:_get_highlight_extra(node) local name_hl = {} -- clipboard - local clipboard_highlight = require "nvim-tree.actions.fs.copy-paste".get_highlight(node) + local clipboard_highlight = require("nvim-tree.actions.fs.copy-paste").get_highlight(node) table.insert(name_hl, clipboard_highlight) return icon_hl, name_hl From 4e161cbf8044d559c78751ef1f209668650f377f Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 10 Sep 2023 14:57:59 +1000 Subject: [PATCH 3/8] feat(#1079): node may not be present in copy and cut --- lua/nvim-tree/actions/fs/copy-paste.lua | 36 ++++++++++++------------- lua/nvim-tree/utils.lua | 10 +++++-- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/lua/nvim-tree/actions/fs/copy-paste.lua b/lua/nvim-tree/actions/fs/copy-paste.lua index e6ceb1db301..fb8ce0f0116 100644 --- a/lua/nvim-tree/actions/fs/copy-paste.lua +++ b/lua/nvim-tree/actions/fs/copy-paste.lua @@ -13,7 +13,7 @@ local M = { } local clipboard = { - move = {}, + cut = {}, copy = {}, } @@ -131,36 +131,36 @@ local function do_single_paste(source, dest, action_type, action_fn) end end -local function add_to_clipboard(node, clip) +local function toggle(node, clip) if node.name == ".." then return end local notify_node = notify.render_path(node.absolute_path) - for idx, _node in ipairs(clip) do - if _node.absolute_path == node.absolute_path then - table.remove(clip, idx) - return notify.info(notify_node .. " removed from clipboard.") - end + if utils.array_remove(clip, node) then + return notify.info(notify_node .. " removed from clipboard.") end + table.insert(clip, node) notify.info(notify_node .. " added to clipboard.") end function M.clear_clipboard() - clipboard.move = {} + clipboard.cut = {} clipboard.copy = {} notify.info "Clipboard has been emptied." renderer.draw() end function M.copy(node) - add_to_clipboard(node, clipboard.copy) + utils.array_remove(clipboard.cut, node) + toggle(node, clipboard.copy) renderer.draw() end function M.cut(node) - add_to_clipboard(node, clipboard.move) + utils.array_remove(clipboard.copy, node) + toggle(node, clipboard.cut) renderer.draw() end @@ -217,8 +217,8 @@ local function do_cut(source, destination) end function M.paste(node) - if clipboard.move[1] ~= nil then - return do_paste(node, "move", do_cut) + if clipboard.cut[1] ~= nil then + return do_paste(node, "cut", do_cut) end return do_paste(node, "copy", do_copy) @@ -226,16 +226,16 @@ end function M.print_clipboard() local content = {} - if #clipboard.move > 0 then + if #clipboard.cut > 0 then table.insert(content, "Cut") - for _, item in pairs(clipboard.move) do - table.insert(content, " * " .. (notify.render_path(item.absolute_path))) + for _, node in pairs(clipboard.cut) do + table.insert(content, " * " .. (notify.render_path(node.absolute_path))) end end if #clipboard.copy > 0 then table.insert(content, "Copy") - for _, item in pairs(clipboard.copy) do - table.insert(content, " * " .. (notify.render_path(item.absolute_path))) + for _, node in pairs(clipboard.copy) do + table.insert(content, " * " .. (notify.render_path(node.absolute_path))) end end @@ -275,7 +275,7 @@ end ---@param node table ---@return string|nil group function M.get_highlight(node) - for _, n in ipairs(clipboard.move) do + for _, n in ipairs(clipboard.cut) do if node == n then return "NvimTreeCutText" end diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index 386472eaa85..9181d87296f 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -425,12 +425,18 @@ function M.array_shallow_clone(array) return to end --- remove item from array if it exists +--- Remove and return item from array if present. +--- @param array table +--- @param item any +--- @return any|nil removed function M.array_remove(array, item) + if not array then + return nil + end for i, v in ipairs(array) do if v == item then table.remove(array, i) - break + return v end end end From 4fc759ec8cdc7c8d9c13bbc84b6cd5f5af58b214 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 10 Sep 2023 16:56:22 +1000 Subject: [PATCH 4/8] feat(#1079): add renderer.highlight_clipboard --- doc/nvim-tree-lua.txt | 6 ++++++ lua/nvim-tree.lua | 1 + lua/nvim-tree/actions/fs/copy-paste.lua | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 6c3dd214e23..e3815d9670b 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -387,6 +387,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. highlight_diagnostics = false, highlight_opened_files = "none", highlight_modified = "none", + highlight_clipboard = true, indent_markers = { enable = false, inline_arrows = true, @@ -842,6 +843,11 @@ Value can be `"none"`, `"icon"`, `"name"` or `"all"` This can be used with or without the icons. Type: `string`, Default `"none"` +*nvim-tree.renderer.highlight_clipboard* +Enable highlight for clipboard items using the `NvimTreeCutText` and +`NvimTreeCopiedText` highlight groups. + Type: `boolean`, Default: `true` + *nvim-tree.renderer.indent_markers* Configuration options for tree indent markers. diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 6b9a0d23086..cc33b5cddfd 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -417,6 +417,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS highlight_diagnostics = false, highlight_opened_files = "none", highlight_modified = "none", + highlight_clipboard = true, indent_markers = { enable = false, inline_arrows = true, diff --git a/lua/nvim-tree/actions/fs/copy-paste.lua b/lua/nvim-tree/actions/fs/copy-paste.lua index fb8ce0f0116..1c81e749594 100644 --- a/lua/nvim-tree/actions/fs/copy-paste.lua +++ b/lua/nvim-tree/actions/fs/copy-paste.lua @@ -275,6 +275,10 @@ end ---@param node table ---@return string|nil group function M.get_highlight(node) + if not M.config.renderer.highlight_clipboard then + return nil + end + for _, n in ipairs(clipboard.cut) do if node == n then return "NvimTreeCutText" @@ -291,6 +295,7 @@ end function M.setup(opts) M.config.filesystem_watchers = opts.filesystem_watchers M.config.actions = opts.actions + M.config.renderer = opts.renderer end return M From 83e10bbba7d8ebbb1d8d4623c0b2ec93e68e11af Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 17 Sep 2023 14:26:02 +1000 Subject: [PATCH 5/8] feat(#1079): renderer.highlight_clipboard takes options, style cut/copy HL --- doc/nvim-tree-lua.txt | 11 +++--- lua/nvim-tree.lua | 2 +- lua/nvim-tree/actions/fs/copy-paste.lua | 9 ++--- lua/nvim-tree/colors.lua | 5 ++- lua/nvim-tree/renderer/builder.lua | 48 +++++++++++++++---------- lua/nvim-tree/renderer/init.lua | 1 + 6 files changed, 42 insertions(+), 34 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index e3815d9670b..3fbc5a2236b 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -844,9 +844,10 @@ This can be used with or without the icons. Type: `string`, Default `"none"` *nvim-tree.renderer.highlight_clipboard* -Enable highlight for clipboard items using the `NvimTreeCutText` and -`NvimTreeCopiedText` highlight groups. - Type: `boolean`, Default: `true` +Enable highlight for clipboard items using the `NvimTreeCutHL` and +`NvimTreeCopiedHL` groups. +Value can be `"none"`, `"icon"`, `"name"` or `"all"`. + Type: `string`, Default: `"name"` *nvim-tree.renderer.indent_markers* Configuration options for tree indent markers. @@ -2173,8 +2174,8 @@ Standard: > NvimTreeStatusLineNC StatusLineNC < Clipboard: > - NvimTreeCopiedText - NvimTreeCutText + NvimTreeCopiedHL SpellRare + NvimTreeCutHL SpellBad < Picker: > NvimTreeWindowPicker diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index cc33b5cddfd..cfb2c3a1ab0 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -417,7 +417,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS highlight_diagnostics = false, highlight_opened_files = "none", highlight_modified = "none", - highlight_clipboard = true, + highlight_clipboard = "name", indent_markers = { enable = false, inline_arrows = true, diff --git a/lua/nvim-tree/actions/fs/copy-paste.lua b/lua/nvim-tree/actions/fs/copy-paste.lua index 1c81e749594..4b81afe5d25 100644 --- a/lua/nvim-tree/actions/fs/copy-paste.lua +++ b/lua/nvim-tree/actions/fs/copy-paste.lua @@ -275,19 +275,15 @@ end ---@param node table ---@return string|nil group function M.get_highlight(node) - if not M.config.renderer.highlight_clipboard then - return nil - end - for _, n in ipairs(clipboard.cut) do if node == n then - return "NvimTreeCutText" + return "NvimTreeCutHL" end end for _, n in ipairs(clipboard.copy) do if node == n then - return "NvimTreeCopiedText" + return "NvimTreeCopiedHL" end end end @@ -295,7 +291,6 @@ end function M.setup(opts) M.config.filesystem_watchers = opts.filesystem_watchers M.config.actions = opts.actions - M.config.renderer = opts.renderer end return M diff --git a/lua/nvim-tree/colors.lua b/lua/nvim-tree/colors.lua index 3337167895e..62b676589dd 100644 --- a/lua/nvim-tree/colors.lua +++ b/lua/nvim-tree/colors.lua @@ -42,9 +42,6 @@ local function get_hl_groups() OpenedFile = { gui = "bold", fg = colors.green }, ModifiedFile = { fg = colors.green }, - CopiedText = { gui = "underline" }, - CutText = { gui = "strikethrough" }, - GitDirty = { fg = colors.dark_red }, GitDeleted = { fg = colors.dark_red }, GitStaged = { fg = colors.green }, @@ -109,6 +106,8 @@ local function get_links() StatusLine = "StatusLine", StatusLineNC = "StatusLineNC", SignColumn = "NvimTreeNormal", + CutHL = "SpellBad", + CopiedHL = "SpellRare", } end diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index b8b9c6b1eef..6860140a246 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -60,6 +60,11 @@ function Builder:configure_modified_highlighting(highlight_modified) return self end +function Builder:configure_clipboard_highlighting(highlight_clipboard) + self.highlight_clipboard = highlight_clipboard + return self +end + function Builder:configure_icon_padding(padding) self.icon_padding = padding or " " return self @@ -291,18 +296,29 @@ function Builder:_get_highlight_override(node, unloaded_bufnr) return icon_hl, name_hl end +---Append optional highlighting to icon or name +--- ---@param node table ----@return string[] icon_hl ----@return string[] name_hl -function Builder:_get_highlight_extra(node) - local icon_hl = {} - local name_hl = {} - - -- clipboard - local clipboard_highlight = require("nvim-tree.actions.fs.copy-paste").get_highlight(node) - table.insert(name_hl, clipboard_highlight) - - return icon_hl, name_hl +---@param enable_for string +---|"'none'" +---|"'icon'" +---|"'name'" +---|"'all'" +---@param get_highlight fun(node: table): string|nil +---@param icon_hl string[] icons to append to +---@param name_hl string[] names to append to +function Builder:_append_highlight(node, enable_for, get_highlight, icon_hl, name_hl) + if enable_for ~= "none" then + local hl = get_highlight(node) + if hl then + if self.highlight_clipboard == "all" or self.highlight_clipboard == "icon" then + table.insert(icon_hl, hl) + end + if self.highlight_clipboard == "all" or self.highlight_clipboard == "name" then + table.insert(name_hl, hl) + end + end + end end ---@param indent_markers HighlightedString[] @@ -359,6 +375,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) @@ -388,13 +406,7 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr) end -- extra highighting - local icon_hl_extra, name_hl_extra = self:_get_highlight_extra(node) - for _, hl in ipairs(icon_hl_extra) do - table.insert(icon.hl, hl) - end - for _, hl in ipairs(name_hl_extra) do - table.insert(name.hl, hl) - end + self:_append_highlight(node, self.highlight_clipboard, 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)) diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 72e04df017d..1817a2bb3af 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -71,6 +71,7 @@ function M.draw(unloaded_bufnr) :configure_picture_map(picture_map) :configure_opened_file_highlighting(M.config.highlight_opened_files) :configure_modified_highlighting(M.config.highlight_modified) + :configure_clipboard_highlighting(M.config.highlight_clipboard) :configure_icon_padding(M.config.icons.padding) :configure_git_icons_placement(M.config.icons.git_placement) :configure_diagnostics_icon_placement(M.config.icons.diagnostics_placement) From cbf2f63fa43338fdbffcd2a7e9dcff7179e83186 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 17 Sep 2023 14:35:26 +1000 Subject: [PATCH 6/8] feat(#1079): renderer.highlight_clipboard takes options, style cut/copy HL --- doc/nvim-tree-lua.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 3fbc5a2236b..08512936f80 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -387,7 +387,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. highlight_diagnostics = false, highlight_opened_files = "none", highlight_modified = "none", - highlight_clipboard = true, + highlight_clipboard = "name", indent_markers = { enable = false, inline_arrows = true, From 8ac129b04021d96a1dcb834155e500f5177849c7 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 17 Sep 2023 15:24:14 +1000 Subject: [PATCH 7/8] feat(#1079): use an enum for highlight position --- lua/nvim-tree/actions/fs/copy-paste.lua | 18 ++++++++++--- lua/nvim-tree/enum.lua | 20 ++++++++++++++ lua/nvim-tree/renderer/builder.lua | 35 +++++++++---------------- lua/nvim-tree/renderer/init.lua | 1 - 4 files changed, 46 insertions(+), 28 deletions(-) create mode 100644 lua/nvim-tree/enum.lua diff --git a/lua/nvim-tree/actions/fs/copy-paste.lua b/lua/nvim-tree/actions/fs/copy-paste.lua index 4b81afe5d25..7ccfd86a031 100644 --- a/lua/nvim-tree/actions/fs/copy-paste.lua +++ b/lua/nvim-tree/actions/fs/copy-paste.lua @@ -6,6 +6,8 @@ local events = require "nvim-tree.events" local notify = require "nvim-tree.notify" local renderer = require "nvim-tree.renderer" +local HL_POSITION = require("nvim-tree.enum").HL_POSITION + local find_file = require("nvim-tree.actions.finders.find-file").fn local M = { @@ -271,26 +273,34 @@ function M.copy_absolute_path(node) return copy_to_clipboard(content) end ----clipboard text highlight group +---Clipboard text highlight group and position. ---@param node table ----@return string|nil group +---@return HL_POSITION position none when clipboard empty +---@return string|nil group only when node present in clipboard function M.get_highlight(node) + if M.hl_pos == HL_POSITION.none then + return HL_POSITION.none, nil + end + for _, n in ipairs(clipboard.cut) do if node == n then - return "NvimTreeCutHL" + return M.hl_pos, "NvimTreeCutHL" end end for _, n in ipairs(clipboard.copy) do if node == n then - return "NvimTreeCopiedHL" + return M.hl_pos, "NvimTreeCopiedHL" end end + + return HL_POSITION.none, nil end function M.setup(opts) M.config.filesystem_watchers = opts.filesystem_watchers M.config.actions = opts.actions + M.hl_pos = HL_POSITION[opts.renderer.highlight_clipboard] end return M diff --git a/lua/nvim-tree/enum.lua b/lua/nvim-tree/enum.lua new file mode 100644 index 00000000000..e3791427e31 --- /dev/null +++ b/lua/nvim-tree/enum.lua @@ -0,0 +1,20 @@ +local M = {} + +---Setup options for "highlight_*" +---@enum HL_POSITION +M.HL_POSITION = { + none = 0, + icon = 1, + name = 2, + all = 4, +} + +---Setup options for "*_placement" +---@enum ICON_PLACEMENT +M.ICON_PLACEMENT = { + signcolumn = 0, + before = 1, + after = 2, +} + +return M diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 6860140a246..78ca4d929e5 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -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 @@ -60,11 +62,6 @@ function Builder:configure_modified_highlighting(highlight_modified) return self end -function Builder:configure_clipboard_highlighting(highlight_clipboard) - self.highlight_clipboard = highlight_clipboard - return self -end - function Builder:configure_icon_padding(padding) self.icon_padding = padding or " " return self @@ -297,26 +294,18 @@ function Builder:_get_highlight_override(node, unloaded_bufnr) end ---Append optional highlighting to icon or name ---- ---@param node table ----@param enable_for string ----|"'none'" ----|"'icon'" ----|"'name'" ----|"'all'" ----@param get_highlight fun(node: table): string|nil +---@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, enable_for, get_highlight, icon_hl, name_hl) - if enable_for ~= "none" then - local hl = get_highlight(node) - if hl then - if self.highlight_clipboard == "all" or self.highlight_clipboard == "icon" then - table.insert(icon_hl, hl) - end - if self.highlight_clipboard == "all" or self.highlight_clipboard == "name" then - table.insert(name_hl, hl) - end +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 @@ -406,7 +395,7 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr) end -- extra highighting - self:_append_highlight(node, self.highlight_clipboard, copy_paste.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)) diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 1817a2bb3af..72e04df017d 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -71,7 +71,6 @@ function M.draw(unloaded_bufnr) :configure_picture_map(picture_map) :configure_opened_file_highlighting(M.config.highlight_opened_files) :configure_modified_highlighting(M.config.highlight_modified) - :configure_clipboard_highlighting(M.config.highlight_clipboard) :configure_icon_padding(M.config.icons.padding) :configure_git_icons_placement(M.config.icons.git_placement) :configure_diagnostics_icon_placement(M.config.icons.diagnostics_placement) From 3808d38b8a04916b50f46942428e6e895cc548f2 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 17 Sep 2023 15:57:39 +1000 Subject: [PATCH 8/8] feat(#1079): diagnostics uses _append_highlight --- lua/nvim-tree/actions/fs/copy-paste.lua | 2 +- lua/nvim-tree/renderer/builder.lua | 9 +-- .../renderer/components/diagnostics.lua | 71 ++++++++++++------- 3 files changed, 48 insertions(+), 34 deletions(-) diff --git a/lua/nvim-tree/actions/fs/copy-paste.lua b/lua/nvim-tree/actions/fs/copy-paste.lua index 7ccfd86a031..de21d0edbf9 100644 --- a/lua/nvim-tree/actions/fs/copy-paste.lua +++ b/lua/nvim-tree/actions/fs/copy-paste.lua @@ -273,7 +273,7 @@ function M.copy_absolute_path(node) return copy_to_clipboard(content) end ----Clipboard text highlight group and position. +---Clipboard text highlight group and position when highlight_clipboard. ---@param node table ---@return HL_POSITION position none when clipboard empty ---@return string|nil group only when node present in clipboard diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 78ca4d929e5..ad39e7f3684 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -284,16 +284,10 @@ 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 +---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 @@ -395,6 +389,7 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr) 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) diff --git a/lua/nvim-tree/renderer/components/diagnostics.lua b/lua/nvim-tree/renderer/components/diagnostics.lua index 0c0e3150645..5475aa5c5fe 100644 --- a/lua/nvim-tree/renderer/components/diagnostics.lua +++ b/lua/nvim-tree/renderer/components/diagnostics.lua @@ -1,19 +1,32 @@ -local M = {} +local HL_POSITION = require("nvim-tree.enum").HL_POSITION -local HS_FILE = {} -local HS_FOLDER = {} -local ICON = {} +local M = { + HS_FILE = {}, + HS_FOLDER = {}, + ICON = {}, + hl_pos = HL_POSITION.none, +} ----diagnostics text highlight group if there is a status +---Diagnostics text highlight group when highlight_diagnostics. ---@param node table ----@return string|nil group +---@return HL_POSITION position none when no status +---@return string|nil group only when status function M.get_highlight(node) - if node and M.config.diagnostics.enable and M.config.renderer.highlight_diagnostics then - if node.nodes then - return HS_FOLDER[node.diag_status] - else - return HS_FILE[node.diag_status] - end + if not node or M.hl_pos == HL_POSITION.none then + return HL_POSITION.none, nil + end + + local group + if node.nodes then + group = M.HS_FOLDER[node.diag_status] + else + group = M.HS_FILE[node.diag_status] + end + + if group then + return M.hl_pos, group + else + return HL_POSITION.none, nil end end @@ -22,7 +35,7 @@ end ---@return HighlightedString|nil modified icon function M.get_icon(node) if node and M.config.diagnostics.enable and M.config.renderer.icons.show.diagnostics then - return ICON[node.diag_status] + return M.ICON[node.diag_status] end end @@ -32,35 +45,41 @@ function M.setup(opts) renderer = opts.renderer, } - HS_FILE[vim.diagnostic.severity.ERROR] = "NvimTreeLspDiagnosticsErrorText" - HS_FILE[vim.diagnostic.severity.WARN] = "NvimTreeLspDiagnosticsWarningText" - HS_FILE[vim.diagnostic.severity.INFO] = "NvimTreeLspDiagnosticsInfoText" - HS_FILE[vim.diagnostic.severity.HINT] = "NvimTreeLspDiagnosticsHintText" + if opts.diagnostics.enable and opts.renderer.highlight_diagnostics then + -- TODO add a HL_POSITION + -- M.hl_pos = HL_POSITION[opts.renderer.highlight_diagnostics] + M.hl_pos = HL_POSITION.name + end + + M.HS_FILE[vim.diagnostic.severity.ERROR] = "NvimTreeLspDiagnosticsErrorText" + M.HS_FILE[vim.diagnostic.severity.WARN] = "NvimTreeLspDiagnosticsWarningText" + M.HS_FILE[vim.diagnostic.severity.INFO] = "NvimTreeLspDiagnosticsInfoText" + M.HS_FILE[vim.diagnostic.severity.HINT] = "NvimTreeLspDiagnosticsHintText" - HS_FOLDER[vim.diagnostic.severity.ERROR] = "NvimTreeLspDiagnosticsErrorFolderText" - HS_FOLDER[vim.diagnostic.severity.WARN] = "NvimTreeLspDiagnosticsWarningFolderText" - HS_FOLDER[vim.diagnostic.severity.INFO] = "NvimTreeLspDiagnosticsInfoFolderText" - HS_FOLDER[vim.diagnostic.severity.HINT] = "NvimTreeLspDiagnosticsHintFolderText" + M.HS_FOLDER[vim.diagnostic.severity.ERROR] = "NvimTreeLspDiagnosticsErrorFolderText" + M.HS_FOLDER[vim.diagnostic.severity.WARN] = "NvimTreeLspDiagnosticsWarningFolderText" + M.HS_FOLDER[vim.diagnostic.severity.INFO] = "NvimTreeLspDiagnosticsInfoFolderText" + M.HS_FOLDER[vim.diagnostic.severity.HINT] = "NvimTreeLspDiagnosticsHintFolderText" - ICON[vim.diagnostic.severity.ERROR] = { + M.ICON[vim.diagnostic.severity.ERROR] = { str = M.config.diagnostics.icons.error, hl = { "NvimTreeLspDiagnosticsError" }, } - ICON[vim.diagnostic.severity.WARN] = { + M.ICON[vim.diagnostic.severity.WARN] = { str = M.config.diagnostics.icons.warning, hl = { "NvimTreeLspDiagnosticsWarning" }, } - ICON[vim.diagnostic.severity.INFO] = { + M.ICON[vim.diagnostic.severity.INFO] = { str = M.config.diagnostics.icons.info, hl = { "NvimTreeLspDiagnosticsInfo" }, } - ICON[vim.diagnostic.severity.HINT] = { + M.ICON[vim.diagnostic.severity.HINT] = { str = M.config.diagnostics.icons.hint, hl = { "NvimTreeLspDiagnosticsHint" }, } - for _, i in ipairs(ICON) do + for _, i in ipairs(M.ICON) do vim.fn.sign_define(i.hl[1], { text = i.str, texthl = i.hl[1] }) end end