From 48a92907575df1dbd7242975a04e98169cb3a115 Mon Sep 17 00:00:00 2001 From: "Everton Jr." <69195288+evertonse@users.noreply.github.com> Date: Sun, 21 Jul 2024 03:00:34 -0300 Subject: [PATCH] feat: add renderer.highlight_hidden, renderer.icons.show.hidden and renderer.icons.hidden_placement for dotfile icons/highlights (#2840) * feat(hidden_decorator): Allow hidden (dotfiles) to be highlighted, both icon and name (this not related to git highlights). Better defaults squashed docs(hidden) docs(hidden) docs(hidden) * fix(typo): small typo on hl groups * feat(hidden_dotfile_highlight): make a file that has a dotfile parent be also a dotfile * docs: update docs on hidden highlight --------- Co-authored-by: Alexander Courtis --- .gitignore | 2 + doc/nvim-tree-lua.txt | 39 ++++++++++++++- lua/nvim-tree.lua | 6 +++ lua/nvim-tree/appearance/init.lua | 5 ++ lua/nvim-tree/explorer/node.lua | 13 +++++ lua/nvim-tree/node.lua | 1 + lua/nvim-tree/renderer/builder.lua | 2 + lua/nvim-tree/renderer/decorator/hidden.lua | 55 +++++++++++++++++++++ 8 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 lua/nvim-tree/renderer/decorator/hidden.lua diff --git a/.gitignore b/.gitignore index e4d0be68..faee0c43 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /luals-out/ /luals/ +# backup vim files +*~ diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 19fe4d60..8f03efab 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -428,6 +428,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. highlight_diagnostics = "none", highlight_opened_files = "none", highlight_modified = "none", + highlight_hidden = "none", highlight_bookmarks = "none", highlight_clipboard = "name", indent_markers = { @@ -454,6 +455,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. }, git_placement = "before", modified_placement = "after", + hidden_placement = "after", diagnostics_placement = "signcolumn", bookmarks_placement = "signcolumn", padding = " ", @@ -464,6 +466,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. folder_arrow = true, git = true, modified = true, + hidden = false, diagnostics = true, bookmarks = true, }, @@ -472,6 +475,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. symlink = "", bookmark = "󰆤", modified = "●", + hidden = "󰜌", folder = { arrow_closed = "", arrow_open = "", @@ -904,6 +908,13 @@ Requires |nvim-tree.modified.enable| Value can be `"none"`, `"icon"`, `"name"` or `"all"` Type: `string`, Default `"none"` +*nvim-tree.renderer.highlight_hidden* +Highlight icons and/or names for hidden files (dotfiles) using the +`NvimTreeHiddenFileHL` highlight group. +Requires |nvim-tree.hidden.enable| +Value can be `"none"`, `"icon"`, `"name"` or `"all"` + Type: `string`, Default `"none"` + *nvim-tree.renderer.highlight_bookmarks* Highlight bookmarked using the `NvimTreeBookmarkHL` group. Value can be `"none"`, `"icon"`, `"name"` or `"all"` @@ -942,7 +953,7 @@ Configuration options for tree indent markers. Configuration options for icons. Icon order and sign column precedence: - git < modified < bookmarked < diagnostics + git < hidden < modified < bookmarked < diagnostics *nvim-tree.renderer.icons.web_devicons* Configure optional plugin `"nvim-tree/nvim-web-devicons"` @@ -989,6 +1000,12 @@ Icon order and sign column precedence: or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled). Type: `string`, Default: `"after"` + *nvim-tree.renderer.icons.hidden_placement* + Place where the hidden (dotfile) icon will be rendered. + Can be `"after"` or `"before"` filename (after the file/folders icons) + or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled). + Type: `string`, Default: `"after"` + *nvim-tree.renderer.icons.bookmarks_placement* Place where the bookmarks icon will be rendered. Can be `"after"` or `"before"` filename (after the file/folders icons) @@ -1005,7 +1022,7 @@ Icon order and sign column precedence: *nvim-tree.renderer.icons.show* Configuration options for showing icon types. - Left to right order: file/folder, git, modified, diagnostics, bookmarked. + Left to right order: file/folder, git, modified, hidden, diagnostics, bookmarked. *nvim-tree.renderer.icons.show.file* Show an icon before the file name. @@ -1030,6 +1047,11 @@ Icon order and sign column precedence: Requires |modified.enable| `= true` Type: `boolean`, Default: `true` + *nvim-tree.renderer.icons.show.hidden* + Show a hidden icon, see |renderer.icons.hidden_placement| + Requires |hidden.enable| `= true` + Type: `boolean`, Default: `true` + *nvim-tree.renderer.icons.show.diagnostics* Show a diagnostics status icon, see |renderer.icons.diagnostics_placement| Requires |diagnostics.enable| `= true` @@ -1057,6 +1079,10 @@ Icon order and sign column precedence: Icon to display for modified files. Type: `string`, Default: `"●"` + *nvim-tree.renderer.icons.glyphs.hidden* + Icon to display for hidden files. + Type: `string`, Default: `"󰜌""` + *nvim-tree.renderer.icons.glyphs.folder* Glyphs for directories. Overridden by |nvim-tree.renderer.icons.web_devicons| if available. @@ -2433,6 +2459,11 @@ Modified: > NvimTreeModifiedIcon Type NvimTreeModifiedFileHL NvimTreeModifiedIcon NvimTreeModifiedFolderHL NvimTreeModifiedIcon + +Hidden: > + NvimTreeModifiedIcon Conceal + NvimTreeModifiedFileHL NvimTreeHiddenIcon + NvimTreeModifiedFolderHL NvimTreeHiddenFileHL < Opened: > NvimTreeOpenedHL Special @@ -2853,6 +2884,7 @@ highlight group is not, hard linking as follows: > |nvim-tree.renderer.highlight_clipboard| |nvim-tree.renderer.highlight_diagnostics| |nvim-tree.renderer.highlight_git| +|nvim-tree.renderer.highlight_hidden| |nvim-tree.renderer.highlight_modified| |nvim-tree.renderer.highlight_opened_files| |nvim-tree.renderer.icons| @@ -2863,8 +2895,10 @@ highlight group is not, hard linking as follows: > |nvim-tree.renderer.icons.glyphs.default| |nvim-tree.renderer.icons.glyphs.folder| |nvim-tree.renderer.icons.glyphs.git| +|nvim-tree.renderer.icons.glyphs.hidden| |nvim-tree.renderer.icons.glyphs.modified| |nvim-tree.renderer.icons.glyphs.symlink| +|nvim-tree.renderer.icons.hidden_placement| |nvim-tree.renderer.icons.modified_placement| |nvim-tree.renderer.icons.padding| |nvim-tree.renderer.icons.show| @@ -2874,6 +2908,7 @@ highlight group is not, hard linking as follows: > |nvim-tree.renderer.icons.show.folder| |nvim-tree.renderer.icons.show.folder_arrow| |nvim-tree.renderer.icons.show.git| +|nvim-tree.renderer.icons.show.hidden| |nvim-tree.renderer.icons.show.modified| |nvim-tree.renderer.icons.symlink_arrow| |nvim-tree.renderer.icons.web_devicons| diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 343196a0..f3260c47 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -392,6 +392,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS highlight_diagnostics = "none", highlight_opened_files = "none", highlight_modified = "none", + highlight_hidden = "none", highlight_bookmarks = "none", highlight_clipboard = "name", indent_markers = { @@ -418,6 +419,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS }, git_placement = "before", modified_placement = "after", + hidden_placement = "after", diagnostics_placement = "signcolumn", bookmarks_placement = "signcolumn", padding = " ", @@ -428,6 +430,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS folder_arrow = true, git = true, modified = true, + hidden = false, diagnostics = true, bookmarks = true, }, @@ -436,6 +439,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS symlink = "", bookmark = "󰆤", modified = "●", + hidden = "󰜌", folder = { arrow_closed = "", arrow_open = "", @@ -668,12 +672,14 @@ local ACCEPTED_STRINGS = { highlight_git = { "none", "icon", "name", "all" }, highlight_opened_files = { "none", "icon", "name", "all" }, highlight_modified = { "none", "icon", "name", "all" }, + highlight_hidden = { "none", "icon", "name", "all" }, highlight_bookmarks = { "none", "icon", "name", "all" }, highlight_diagnostics = { "none", "icon", "name", "all" }, highlight_clipboard = { "none", "icon", "name", "all" }, icons = { git_placement = { "before", "after", "signcolumn" }, modified_placement = { "before", "after", "signcolumn" }, + hidden_placement = { "before", "after", "signcolumn" }, diagnostics_placement = { "before", "after", "signcolumn" }, bookmarks_placement = { "before", "after", "signcolumn" }, }, diff --git a/lua/nvim-tree/appearance/init.lua b/lua/nvim-tree/appearance/init.lua index cc886d86..4b4f33ff 100644 --- a/lua/nvim-tree/appearance/init.lua +++ b/lua/nvim-tree/appearance/init.lua @@ -76,6 +76,11 @@ M.HIGHLIGHT_GROUPS = { { group = "NvimTreeModifiedFileHL", link = "NvimTreeModifiedIcon" }, { group = "NvimTreeModifiedFolderHL", link = "NvimTreeModifiedFileHL" }, + -- Hidden + { group = "NvimTreeHiddenIcon", link = "Conceal" }, + { group = "NvimTreeHiddenFileHL", link = "NvimTreeHiddenIcon" }, + { group = "NvimTreeHiddenFolderHL", link = "NvimTreeHiddenFileHL" }, + -- Opened { group = "NvimTreeOpenedHL", link = "Special" }, diff --git a/lua/nvim-tree/explorer/node.lua b/lua/nvim-tree/explorer/node.lua index 5657826f..16e149f7 100644 --- a/lua/nvim-tree/explorer/node.lua +++ b/lua/nvim-tree/explorer/node.lua @@ -128,6 +128,19 @@ function M.is_git_ignored(node) return node and node.git_status ~= nil and node.git_status.file == "!!" end +---@param node Node +---@return boolean +function M.is_dotfile(node) + if node == nil then + return false + end + if node.is_dot or (node.name and (node.name:sub(1, 1) == ".")) or M.is_dotfile(node.parent) then + node.is_dot = true + return true + end + return false +end + ---@param node Node function M.node_destroy(node) if not node then diff --git a/lua/nvim-tree/node.lua b/lua/nvim-tree/node.lua index d1b4da8f..f1344fe9 100644 --- a/lua/nvim-tree/node.lua +++ b/lua/nvim-tree/node.lua @@ -9,6 +9,7 @@ ---@field fs_stat uv.fs_stat.result|nil ---@field git_status GitStatus|nil ---@field hidden boolean +---@field is_dot boolean ---@field name string ---@field parent DirNode ---@field type string diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 52c6c7e5..594ba03a 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -10,6 +10,7 @@ local DecoratorCut = require "nvim-tree.renderer.decorator.cut" local DecoratorDiagnostics = require "nvim-tree.renderer.decorator.diagnostics" local DecoratorGit = require "nvim-tree.renderer.decorator.git" local DecoratorModified = require "nvim-tree.renderer.decorator.modified" +local DecoratorHidden = require "nvim-tree.renderer.decorator.hidden" local DecoratorOpened = require "nvim-tree.renderer.decorator.opened" local pad = require "nvim-tree.renderer.components.padding" @@ -442,6 +443,7 @@ function Builder.setup(opts) DecoratorDiagnostics:new(opts), DecoratorBookmarks:new(opts), DecoratorModified:new(opts), + DecoratorHidden:new(opts), DecoratorOpened:new(opts), DecoratorGit:new(opts), } diff --git a/lua/nvim-tree/renderer/decorator/hidden.lua b/lua/nvim-tree/renderer/decorator/hidden.lua new file mode 100644 index 00000000..a433968f --- /dev/null +++ b/lua/nvim-tree/renderer/decorator/hidden.lua @@ -0,0 +1,55 @@ +local HL_POSITION = require("nvim-tree.enum").HL_POSITION +local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT +local explorer_node = require "nvim-tree.explorer.node" +local Decorator = require "nvim-tree.renderer.decorator" + +---@class DecoratorHidden: Decorator +---@field icon HighlightedString|nil +local DecoratorHidden = Decorator:new() + +---@param opts table +---@return DecoratorHidden +function DecoratorHidden:new(opts) + local o = Decorator.new(self, { + enabled = true, + hl_pos = HL_POSITION[opts.renderer.highlight_hidden] or HL_POSITION.none, + icon_placement = ICON_PLACEMENT[opts.renderer.icons.hidden_placement] or ICON_PLACEMENT.none, + }) + ---@cast o DecoratorHidden + + if opts.renderer.icons.show.hidden then + o.icon = { + str = opts.renderer.icons.glyphs.hidden, + hl = { "NvimTreeHiddenIcon" }, + } + o:define_sign(o.icon) + end + + return o +end + +---Hidden icon: hidden.enable, renderer.icons.show.hidden and node starts with `.` (dotfile). +---@param node Node +---@return HighlightedString[]|nil icons +function DecoratorHidden:calculate_icons(node) + if self.enabled and explorer_node.is_dotfile(node) then + return { self.icon } + end +end + +---Hidden highlight: hidden.enable, renderer.highlight_hidden and node starts with `.` (dotfile). +---@param node Node +---@return string|nil group +function DecoratorHidden:calculate_highlight(node) + if not self.enabled or self.hl_pos == HL_POSITION.none or (not explorer_node.is_dotfile(node)) then + return nil + end + + if node.nodes then + return "NvimTreeHiddenFolderHL" + else + return "NvimTreeHiddenFileHL" + end +end + +return DecoratorHidden