From ff3dd126b9ea42e25c5e60e8db57c53653af9c7b Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sat, 9 Nov 2024 16:11:16 +1100 Subject: [PATCH 01/27] feat(#2948): add UserDecorator, proof of concept --- lua/nvim-tree.lua | 1 + lua/nvim-tree/renderer/builder.lua | 28 +++++++++++-------- .../renderer/decorator/bookmarks.lua | 18 ++++++------ lua/nvim-tree/renderer/decorator/copied.lua | 14 ++++++---- lua/nvim-tree/renderer/decorator/cut.lua | 14 ++++++---- .../renderer/decorator/diagnostics.lua | 18 ++++++------ lua/nvim-tree/renderer/decorator/git.lua | 26 +++++++++-------- lua/nvim-tree/renderer/decorator/hidden.lua | 18 ++++++------ lua/nvim-tree/renderer/decorator/init.lua | 8 +----- lua/nvim-tree/renderer/decorator/modified.lua | 18 ++++++------ lua/nvim-tree/renderer/decorator/opened.lua | 16 ++++++----- lua/nvim-tree/renderer/decorator/user.lua | 16 +++++++++++ 12 files changed, 114 insertions(+), 81 deletions(-) create mode 100644 lua/nvim-tree/renderer/decorator/user.lua diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 4d72d1859df..467a0996d46 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -276,6 +276,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS }, }, renderer = { + user_decorators = {}, add_trailing = false, group_empty = false, full_name = false, diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 303e02a39d3..614414c8908 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -13,12 +13,14 @@ 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 UserDecoratorExample = require("nvim-tree.renderer.decorator.example") local pad = require("nvim-tree.renderer.components.padding") ----@class (exact) HighlightedString ----@field str string ----@field hl string[] +----TODO move all these classes to API meta +----@class (exact) HighlightedString +----@field str string +----@field hl string[] ---@class (exact) AddHighlightArgs ---@field group string[] @@ -62,16 +64,20 @@ function Builder:new(args) self.virtual_lines = {} self.decorators = { -- priority order - DecoratorCut({ explorer = args.explorer }), - DecoratorCopied({ explorer = args.explorer }), - DecoratorDiagnostics({ explorer = args.explorer }), - DecoratorBookmarks({ explorer = args.explorer }), - DecoratorModified({ explorer = args.explorer }), - DecoratorHidden({ explorer = args.explorer }), - DecoratorOpened({ explorer = args.explorer }), - DecoratorGit({ explorer = args.explorer }) + DecoratorCut(self.explorer), + DecoratorCopied(self.explorer), + DecoratorDiagnostics(self.explorer), + DecoratorBookmarks(self.explorer), + DecoratorModified(self.explorer), + DecoratorHidden(self.explorer), + DecoratorOpened(self.explorer), + DecoratorGit(self.explorer), } self.hidden_display = Builder:setup_hidden_display_function(self.explorer.opts) + + for _, user_decorator in ipairs(args.explorer.opts.renderer.user_decorators) do + table.insert(self.decorators, user_decorator.class()) + end end ---Insert ranged highlight groups into self.highlights diff --git a/lua/nvim-tree/renderer/decorator/bookmarks.lua b/lua/nvim-tree/renderer/decorator/bookmarks.lua index c83290aa4ed..f741dda1b15 100644 --- a/lua/nvim-tree/renderer/decorator/bookmarks.lua +++ b/lua/nvim-tree/renderer/decorator/bookmarks.lua @@ -1,20 +1,22 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) DecoratorBookmarks: Decorator ----@field icon HighlightedString? +---@field private explorer Explorer +---@field private icon HighlightedString? local DecoratorBookmarks = Decorator:extend() ---@class DecoratorBookmarks ----@overload fun(explorer: DecoratorArgs): DecoratorBookmarks +---@overload fun(explorer: Explorer): DecoratorBookmarks ---@protected ----@param args DecoratorArgs -function DecoratorBookmarks:new(args) - Decorator.new(self, { - explorer = args.explorer, +---@param explorer Explorer +function DecoratorBookmarks:new(explorer) + self.explorer = explorer + + DecoratorBookmarks.super.new(self, { enabled = true, - hl_pos = args.explorer.opts.renderer.highlight_bookmarks or "none", - icon_placement = args.explorer.opts.renderer.icons.bookmarks_placement or "none", + hl_pos = self.explorer.opts.renderer.highlight_bookmarks or "none", + icon_placement = self.explorer.opts.renderer.icons.bookmarks_placement or "none", }) if self.explorer.opts.renderer.icons.show.bookmarks then diff --git a/lua/nvim-tree/renderer/decorator/copied.lua b/lua/nvim-tree/renderer/decorator/copied.lua index 4d54e1dc290..fd9af1a2d14 100644 --- a/lua/nvim-tree/renderer/decorator/copied.lua +++ b/lua/nvim-tree/renderer/decorator/copied.lua @@ -1,18 +1,20 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) DecoratorCopied: Decorator +---@field private explorer Explorer local DecoratorCopied = Decorator:extend() ---@class DecoratorCopied ----@overload fun(explorer: DecoratorArgs): DecoratorCopied +---@overload fun(explorer: Explorer): DecoratorCopied ---@protected ----@param args DecoratorArgs -function DecoratorCopied:new(args) - Decorator.new(self, { - explorer = args.explorer, +---@param explorer Explorer +function DecoratorCopied:new(explorer) + self.explorer = explorer + + DecoratorCopied.super.new(self, { enabled = true, - hl_pos = args.explorer.opts.renderer.highlight_clipboard or "none", + hl_pos = self.explorer.opts.renderer.highlight_clipboard or "none", icon_placement = "none", }) end diff --git a/lua/nvim-tree/renderer/decorator/cut.lua b/lua/nvim-tree/renderer/decorator/cut.lua index 92eb1b8355c..220fa7f9d4d 100644 --- a/lua/nvim-tree/renderer/decorator/cut.lua +++ b/lua/nvim-tree/renderer/decorator/cut.lua @@ -1,18 +1,20 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) DecoratorCut: Decorator +---@field private explorer Explorer local DecoratorCut = Decorator:extend() ---@class DecoratorCut ----@overload fun(explorer: DecoratorArgs): DecoratorCut +---@overload fun(explorer: Explorer): DecoratorCut ---@protected ----@param args DecoratorArgs -function DecoratorCut:new(args) - Decorator.new(self, { - explorer = args.explorer, +---@param explorer Explorer +function DecoratorCut:new(explorer) + self.explorer = explorer + + DecoratorCut.super.new(self, { enabled = true, - hl_pos = args.explorer.opts.renderer.highlight_clipboard or "none", + hl_pos = self.explorer.opts.renderer.highlight_clipboard or "none", icon_placement = "none", }) end diff --git a/lua/nvim-tree/renderer/decorator/diagnostics.lua b/lua/nvim-tree/renderer/decorator/diagnostics.lua index bcff66fafad..fb4b05e2912 100644 --- a/lua/nvim-tree/renderer/decorator/diagnostics.lua +++ b/lua/nvim-tree/renderer/decorator/diagnostics.lua @@ -31,20 +31,22 @@ local ICON_KEYS = { } ---@class (exact) DecoratorDiagnostics: Decorator ----@field icons HighlightedString[]? +---@field private explorer Explorer +---@field private icons HighlightedString[]? local DecoratorDiagnostics = Decorator:extend() ---@class DecoratorDiagnostics ----@overload fun(explorer: DecoratorArgs): DecoratorDiagnostics +---@overload fun(explorer: Explorer): DecoratorDiagnostics ---@protected ----@param args DecoratorArgs -function DecoratorDiagnostics:new(args) - Decorator.new(self, { - explorer = args.explorer, +---@param explorer Explorer +function DecoratorDiagnostics:new(explorer) + self.explorer = explorer + + DecoratorDiagnostics.super.new(self, { enabled = true, - hl_pos = args.explorer.opts.renderer.highlight_diagnostics or "none", - icon_placement = args.explorer.opts.renderer.icons.diagnostics_placement or "none", + hl_pos = self.explorer.opts.renderer.highlight_diagnostics or "none", + icon_placement = self.explorer.opts.renderer.icons.diagnostics_placement or "none", }) if not self.enabled then diff --git a/lua/nvim-tree/renderer/decorator/git.lua b/lua/nvim-tree/renderer/decorator/git.lua index 32e1aed07ef..a52de307c46 100644 --- a/lua/nvim-tree/renderer/decorator/git.lua +++ b/lua/nvim-tree/renderer/decorator/git.lua @@ -13,23 +13,25 @@ local DirectoryNode = require("nvim-tree.node.directory") ---@alias GitGlyphsByStatus table from opts ---@class (exact) DecoratorGit: Decorator ----@field file_hl_by_xy table? ----@field folder_hl_by_xy table? ----@field icons_by_status GitIconsByStatus? ----@field icons_by_xy GitIconsByXY? +---@field private explorer Explorer +---@field private file_hl_by_xy table? +---@field private folder_hl_by_xy table? +---@field private icons_by_status GitIconsByStatus? +---@field private icons_by_xy GitIconsByXY? local DecoratorGit = Decorator:extend() ---@class DecoratorGit ----@overload fun(explorer: DecoratorArgs): DecoratorGit +---@overload fun(explorer: Explorer): DecoratorGit ---@protected ----@param args DecoratorArgs -function DecoratorGit:new(args) - Decorator.new(self, { - explorer = args.explorer, - enabled = args.explorer.opts.git.enable, - hl_pos = args.explorer.opts.renderer.highlight_git or "none", - icon_placement = args.explorer.opts.renderer.icons.git_placement or "none", +---@param explorer Explorer +function DecoratorGit:new(explorer) + self.explorer = explorer + + DecoratorGit.super.new(self, { + enabled = self.explorer.opts.git.enable, + hl_pos = self.explorer.opts.renderer.highlight_git or "none", + icon_placement = self.explorer.opts.renderer.icons.git_placement or "none", }) if not self.enabled then diff --git a/lua/nvim-tree/renderer/decorator/hidden.lua b/lua/nvim-tree/renderer/decorator/hidden.lua index 291d9482774..f8f06e6cbb9 100644 --- a/lua/nvim-tree/renderer/decorator/hidden.lua +++ b/lua/nvim-tree/renderer/decorator/hidden.lua @@ -2,20 +2,22 @@ local Decorator = require("nvim-tree.renderer.decorator") local DirectoryNode = require("nvim-tree.node.directory") ---@class (exact) DecoratorHidden: Decorator ----@field icon HighlightedString? +---@field private explorer Explorer +---@field private icon HighlightedString? local DecoratorHidden = Decorator:extend() ---@class DecoratorHidden ----@overload fun(explorer: DecoratorArgs): DecoratorHidden +---@overload fun(explorer: Explorer): DecoratorHidden ---@protected ----@param args DecoratorArgs -function DecoratorHidden:new(args) - Decorator.new(self, { - explorer = args.explorer, +---@param explorer Explorer +function DecoratorHidden:new(explorer) + self.explorer = explorer + + DecoratorHidden.super.new(self, { enabled = true, - hl_pos = args.explorer.opts.renderer.highlight_hidden or "none", - icon_placement = args.explorer.opts.renderer.icons.hidden_placement or "none", + hl_pos = self.explorer.opts.renderer.highlight_hidden or "none", + icon_placement = self.explorer.opts.renderer.icons.hidden_placement or "none", }) if self.explorer.opts.renderer.icons.show.hidden then diff --git a/lua/nvim-tree/renderer/decorator/init.lua b/lua/nvim-tree/renderer/decorator/init.lua index f83b92dcae4..63085986f11 100644 --- a/lua/nvim-tree/renderer/decorator/init.lua +++ b/lua/nvim-tree/renderer/decorator/init.lua @@ -4,26 +4,20 @@ local Class = require("nvim-tree.classic") ---@alias DecoratorIconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" ---Abstract Decorator ----Uses the factory pattern to instantiate child instances. ---@class (exact) Decorator: Class ----@field protected explorer Explorer ---@field protected enabled boolean ---@field protected range DecoratorRange ---@field protected icon_placement DecoratorIconPlacement local Decorator = Class:extend() ---@class (exact) DecoratorArgs ----@field explorer Explorer - ----@class (exact) AbstractDecoratorArgs: DecoratorArgs ---@field enabled boolean ---@field hl_pos DecoratorRange ---@field icon_placement DecoratorIconPlacement ---@protected ----@param args AbstractDecoratorArgs +---@param args DecoratorArgs function Decorator:new(args) - self.explorer = args.explorer self.enabled = args.enabled self.range = args.hl_pos self.icon_placement = args.icon_placement diff --git a/lua/nvim-tree/renderer/decorator/modified.lua b/lua/nvim-tree/renderer/decorator/modified.lua index 68dc322bde1..30e044d2d66 100644 --- a/lua/nvim-tree/renderer/decorator/modified.lua +++ b/lua/nvim-tree/renderer/decorator/modified.lua @@ -4,20 +4,22 @@ local Decorator = require("nvim-tree.renderer.decorator") local DirectoryNode = require("nvim-tree.node.directory") ---@class (exact) DecoratorModified: Decorator ----@field icon HighlightedString? +---@field private explorer Explorer +---@field private icon HighlightedString? local DecoratorModified = Decorator:extend() ---@class DecoratorModified ----@overload fun(explorer: DecoratorArgs): DecoratorModified +---@overload fun(explorer: Explorer): DecoratorModified ---@protected ----@param args DecoratorArgs -function DecoratorModified:new(args) - Decorator.new(self, { - explorer = args.explorer, +---@param explorer Explorer +function DecoratorModified:new(explorer) + self.explorer = explorer + + DecoratorModified.super.new(self, { enabled = true, - hl_pos = args.explorer.opts.renderer.highlight_modified or "none", - icon_placement = args.explorer.opts.renderer.icons.modified_placement or "none", + hl_pos = self.explorer.opts.renderer.highlight_modified or "none", + icon_placement = self.explorer.opts.renderer.icons.modified_placement or "none", }) if not self.enabled then diff --git a/lua/nvim-tree/renderer/decorator/opened.lua b/lua/nvim-tree/renderer/decorator/opened.lua index 4f47e09727d..c58cc419984 100644 --- a/lua/nvim-tree/renderer/decorator/opened.lua +++ b/lua/nvim-tree/renderer/decorator/opened.lua @@ -3,19 +3,21 @@ local buffers = require("nvim-tree.buffers") local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) DecoratorOpened: Decorator ----@field icon HighlightedString|nil +---@field private explorer Explorer +---@field private icon HighlightedString|nil local DecoratorOpened = Decorator:extend() ---@class DecoratorOpened ----@overload fun(explorer: DecoratorArgs): DecoratorOpened +---@overload fun(explorer: Explorer): DecoratorOpened ---@protected ----@param args DecoratorArgs -function DecoratorOpened:new(args) - Decorator.new(self, { - explorer = args.explorer, +---@param explorer Explorer +function DecoratorOpened:new(explorer) + self.explorer = explorer + + DecoratorOpened.super.new(self, { enabled = true, - hl_pos = args.explorer.opts.renderer.highlight_opened_files or "none", + hl_pos = self.explorer.opts.renderer.highlight_opened_files or "none", icon_placement = "none", }) end diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua new file mode 100644 index 00000000000..28bbf131a48 --- /dev/null +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -0,0 +1,16 @@ +local Decorator = require("nvim-tree.renderer.decorator") + +---Marker parent for user decorators +---@class (exact) UserDecorator: Decorator +local UserDecorator = Decorator:extend() + +---@class UserDecorator +---@overload fun(args: DecoratorArgs): UserDecorator + +---@protected +---@param args DecoratorArgs +function UserDecorator:new(args) + UserDecorator.super.new(self, args) +end + +return UserDecorator From 5c3bf8fb61eb1ac014b19878fc6f8c7b4638a958 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Fri, 22 Nov 2024 10:14:11 +1100 Subject: [PATCH 02/27] feat(#2948): add UserDecorator, proof of concept --- lua/nvim-tree/renderer/builder.lua | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 614414c8908..8389a6192a6 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -13,14 +13,13 @@ 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 UserDecoratorExample = require("nvim-tree.renderer.decorator.example") local pad = require("nvim-tree.renderer.components.padding") -----TODO move all these classes to API meta -----@class (exact) HighlightedString -----@field str string -----@field hl string[] +---TODO move all these classes to API meta +---@class (exact) HighlightedString +---@field str string +---@field hl string[] ---@class (exact) AddHighlightArgs ---@field group string[] From 099de587eb2c8fc637a62d1829722e0f2825fbc2 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Fri, 22 Nov 2024 10:15:52 +1100 Subject: [PATCH 03/27] feat(#2948): add UserDecorator, proof of concept --- doc/nvim-tree-lua.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 060227f8220..2a670c59d31 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -417,6 +417,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. >lua }, }, renderer = { + user_decorators = {}, add_trailing = false, group_empty = false, full_name = false, From 24eb27ebbaefa1d99d5863b5cc3391f3e2edaa99 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Fri, 22 Nov 2024 12:18:47 +1100 Subject: [PATCH 04/27] feat(#2948): add UserDecorator --- .../renderer/decorator/bookmarks.lua | 15 ++-- lua/nvim-tree/renderer/decorator/copied.lua | 15 ++-- lua/nvim-tree/renderer/decorator/cut.lua | 15 ++-- .../renderer/decorator/diagnostics.lua | 15 ++-- lua/nvim-tree/renderer/decorator/git.lua | 19 +++-- lua/nvim-tree/renderer/decorator/hidden.lua | 15 ++-- lua/nvim-tree/renderer/decorator/init.lua | 56 ++++++------- lua/nvim-tree/renderer/decorator/meta.lua | 13 +++ lua/nvim-tree/renderer/decorator/modified.lua | 15 ++-- lua/nvim-tree/renderer/decorator/opened.lua | 15 ++-- lua/nvim-tree/renderer/decorator/user.lua | 80 +++++++++++++++++-- 11 files changed, 186 insertions(+), 87 deletions(-) create mode 100644 lua/nvim-tree/renderer/decorator/meta.lua diff --git a/lua/nvim-tree/renderer/decorator/bookmarks.lua b/lua/nvim-tree/renderer/decorator/bookmarks.lua index f741dda1b15..6724f5a9bea 100644 --- a/lua/nvim-tree/renderer/decorator/bookmarks.lua +++ b/lua/nvim-tree/renderer/decorator/bookmarks.lua @@ -13,11 +13,14 @@ local DecoratorBookmarks = Decorator:extend() function DecoratorBookmarks:new(explorer) self.explorer = explorer - DecoratorBookmarks.super.new(self, { - enabled = true, - hl_pos = self.explorer.opts.renderer.highlight_bookmarks or "none", - icon_placement = self.explorer.opts.renderer.icons.bookmarks_placement or "none", - }) + ---@type DecoratorArgs + local args = { + enabled = true, + highlight_range = self.explorer.opts.renderer.highlight_bookmarks or "none", + icon_placement = self.explorer.opts.renderer.icons.bookmarks_placement or "none", + } + + DecoratorBookmarks.super.new(self, args) if self.explorer.opts.renderer.icons.show.bookmarks then self.icon = { @@ -41,7 +44,7 @@ end ---@param node Node ---@return string|nil group function DecoratorBookmarks:calculate_highlight(node) - if self.range ~= "none" and self.explorer.marks:get(node) then + if self.highlight_range ~= "none" and self.explorer.marks:get(node) then return "NvimTreeBookmarkHL" end end diff --git a/lua/nvim-tree/renderer/decorator/copied.lua b/lua/nvim-tree/renderer/decorator/copied.lua index fd9af1a2d14..16d28624917 100644 --- a/lua/nvim-tree/renderer/decorator/copied.lua +++ b/lua/nvim-tree/renderer/decorator/copied.lua @@ -12,18 +12,21 @@ local DecoratorCopied = Decorator:extend() function DecoratorCopied:new(explorer) self.explorer = explorer - DecoratorCopied.super.new(self, { - enabled = true, - hl_pos = self.explorer.opts.renderer.highlight_clipboard or "none", - icon_placement = "none", - }) + ---@type DecoratorArgs + local args = { + enabled = true, + highlight_range = self.explorer.opts.renderer.highlight_clipboard or "none", + icon_placement = "none", + } + + DecoratorCopied.super.new(self, args) end ---Copied highlight: renderer.highlight_clipboard and node is copied ---@param node Node ---@return string|nil group function DecoratorCopied:calculate_highlight(node) - if self.range ~= "none" and self.explorer.clipboard:is_copied(node) then + if self.highlight_range ~= "none" and self.explorer.clipboard:is_copied(node) then return "NvimTreeCopiedHL" end end diff --git a/lua/nvim-tree/renderer/decorator/cut.lua b/lua/nvim-tree/renderer/decorator/cut.lua index 220fa7f9d4d..7fdeaae7599 100644 --- a/lua/nvim-tree/renderer/decorator/cut.lua +++ b/lua/nvim-tree/renderer/decorator/cut.lua @@ -12,18 +12,21 @@ local DecoratorCut = Decorator:extend() function DecoratorCut:new(explorer) self.explorer = explorer - DecoratorCut.super.new(self, { - enabled = true, - hl_pos = self.explorer.opts.renderer.highlight_clipboard or "none", - icon_placement = "none", - }) + ---@type DecoratorArgs + local args = { + enabled = true, + highlight_range = self.explorer.opts.renderer.highlight_clipboard or "none", + icon_placement = "none", + } + + DecoratorCut.super.new(self, args) end ---Cut highlight: renderer.highlight_clipboard and node is cut ---@param node Node ---@return string|nil group function DecoratorCut:calculate_highlight(node) - if self.range ~= "none" and self.explorer.clipboard:is_cut(node) then + if self.highlight_range ~= "none" and self.explorer.clipboard:is_cut(node) then return "NvimTreeCutHL" end end diff --git a/lua/nvim-tree/renderer/decorator/diagnostics.lua b/lua/nvim-tree/renderer/decorator/diagnostics.lua index fb4b05e2912..055ae1de1d4 100644 --- a/lua/nvim-tree/renderer/decorator/diagnostics.lua +++ b/lua/nvim-tree/renderer/decorator/diagnostics.lua @@ -43,11 +43,14 @@ local DecoratorDiagnostics = Decorator:extend() function DecoratorDiagnostics:new(explorer) self.explorer = explorer - DecoratorDiagnostics.super.new(self, { - enabled = true, - hl_pos = self.explorer.opts.renderer.highlight_diagnostics or "none", - icon_placement = self.explorer.opts.renderer.icons.diagnostics_placement or "none", - }) + ---@type DecoratorArgs + local args = { + enabled = true, + highlight_range = self.explorer.opts.renderer.highlight_diagnostics or "none", + icon_placement = self.explorer.opts.renderer.icons.diagnostics_placement or "none", + } + + DecoratorDiagnostics.super.new(self, args) if not self.enabled then return @@ -83,7 +86,7 @@ end ---@param node Node ---@return string|nil group function DecoratorDiagnostics:calculate_highlight(node) - if not node or not self.enabled or self.range == "none" then + if not node or not self.enabled or self.highlight_range == "none" then return nil end diff --git a/lua/nvim-tree/renderer/decorator/git.lua b/lua/nvim-tree/renderer/decorator/git.lua index a52de307c46..d56ad8a9fa2 100644 --- a/lua/nvim-tree/renderer/decorator/git.lua +++ b/lua/nvim-tree/renderer/decorator/git.lua @@ -28,17 +28,20 @@ local DecoratorGit = Decorator:extend() function DecoratorGit:new(explorer) self.explorer = explorer - DecoratorGit.super.new(self, { - enabled = self.explorer.opts.git.enable, - hl_pos = self.explorer.opts.renderer.highlight_git or "none", - icon_placement = self.explorer.opts.renderer.icons.git_placement or "none", - }) + ---@type DecoratorArgs + local args = { + enabled = self.explorer.opts.git.enable, + highlight_range = self.explorer.opts.renderer.highlight_git or "none", + icon_placement = self.explorer.opts.renderer.icons.git_placement or "none", + } + + DecoratorGit.super.new(self, args) if not self.enabled then return end - if self.range ~= "none" then + if self.highlight_range ~= "none" then self:build_file_folder_hl_by_xy() end @@ -161,7 +164,7 @@ function DecoratorGit:calculate_icons(node) for _, s in pairs(git_xy) do local icons = self.icons_by_xy[s] if not icons then - if self.range == "none" then + if self.highlight_range == "none" then notify.warn(string.format("Unrecognized git state '%s'", git_xy)) end return nil @@ -207,7 +210,7 @@ end ---@param node Node ---@return string|nil group function DecoratorGit:calculate_highlight(node) - if not node or not self.enabled or self.range == "none" then + if not node or not self.enabled or self.highlight_range == "none" then return nil end diff --git a/lua/nvim-tree/renderer/decorator/hidden.lua b/lua/nvim-tree/renderer/decorator/hidden.lua index f8f06e6cbb9..3bfff8550f5 100644 --- a/lua/nvim-tree/renderer/decorator/hidden.lua +++ b/lua/nvim-tree/renderer/decorator/hidden.lua @@ -14,11 +14,14 @@ local DecoratorHidden = Decorator:extend() function DecoratorHidden:new(explorer) self.explorer = explorer - DecoratorHidden.super.new(self, { - enabled = true, - hl_pos = self.explorer.opts.renderer.highlight_hidden or "none", - icon_placement = self.explorer.opts.renderer.icons.hidden_placement or "none", - }) + ---@type DecoratorArgs + local args = { + enabled = true, + highlight_range = self.explorer.opts.renderer.highlight_hidden or "none", + icon_placement = self.explorer.opts.renderer.icons.hidden_placement or "none", + } + + DecoratorHidden.super.new(self, args) if self.explorer.opts.renderer.icons.show.hidden then self.icon = { @@ -42,7 +45,7 @@ end ---@param node Node ---@return string|nil group function DecoratorHidden:calculate_highlight(node) - if not self.enabled or self.range == "none" or not node:is_dotfile() then + if not self.enabled or self.highlight_range == "none" or not node:is_dotfile() then return nil end diff --git a/lua/nvim-tree/renderer/decorator/init.lua b/lua/nvim-tree/renderer/decorator/init.lua index 63085986f11..d6a7656f842 100644 --- a/lua/nvim-tree/renderer/decorator/init.lua +++ b/lua/nvim-tree/renderer/decorator/init.lua @@ -1,42 +1,38 @@ local Class = require("nvim-tree.classic") ----@alias DecoratorRange "none" | "icon" | "name" | "all" ----@alias DecoratorIconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" - ---Abstract Decorator ---@class (exact) Decorator: Class ---@field protected enabled boolean ----@field protected range DecoratorRange +---@field protected highlight_range DecoratorHighlightRange ---@field protected icon_placement DecoratorIconPlacement local Decorator = Class:extend() ----@class (exact) DecoratorArgs ----@field enabled boolean ----@field hl_pos DecoratorRange ----@field icon_placement DecoratorIconPlacement - ---@protected ---@param args DecoratorArgs function Decorator:new(args) - self.enabled = args.enabled - self.range = args.hl_pos - self.icon_placement = args.icon_placement + if args then + self.enabled = args.enabled + self.highlight_range = args.highlight_range + self.icon_placement = args.icon_placement + else + self.enabled = false + end end ---Maybe highlight groups ---@param node Node ----@return string|nil icon highlight group ----@return string|nil name highlight group +---@return string? icon highlight group +---@return string? name highlight group function Decorator:groups_icon_name(node) local icon_hl, name_hl - if self.enabled and self.range ~= "none" then + if self.enabled and self.highlight_range ~= "none" then local hl = self:calculate_highlight(node) - if self.range == "all" or self.range == "icon" then + if self.highlight_range == "all" or self.highlight_range == "icon" then icon_hl = hl end - if self.range == "all" or self.range == "name" then + if self.highlight_range == "all" or self.highlight_range == "name" then name_hl = hl end end @@ -46,7 +42,7 @@ end ---Maybe icon sign ---@param node Node ----@return string|nil name +---@return string? name function Decorator:sign_name(node) if not self.enabled or self.icon_placement ~= "signcolumn" then return @@ -60,7 +56,7 @@ end ---Icons when "before" ---@param node Node ----@return HighlightedString[]|nil icons +---@return HighlightedString[]? icons function Decorator:icons_before(node) if not self.enabled or self.icon_placement ~= "before" then return @@ -71,7 +67,7 @@ end ---Icons when "after" ---@param node Node ----@return HighlightedString[]|nil icons +---@return HighlightedString[]? icons function Decorator:icons_after(node) if not self.enabled or self.icon_placement ~= "after" then return @@ -82,7 +78,7 @@ end ---Icons when "right_align" ---@param node Node ----@return HighlightedString[]|nil icons +---@return HighlightedString[]? icons function Decorator:icons_right_align(node) if not self.enabled or self.icon_placement ~= "right_align" then return @@ -93,23 +89,23 @@ end ---Maybe icons, optionally implemented ---@protected ----@param _ Node ----@return HighlightedString[]|nil icons -function Decorator:calculate_icons(_) - return nil +---@param node Node +---@return HighlightedString[]? icons +function Decorator:calculate_icons(node) + self:nop(node) end ---Maybe highlight group, optionally implemented ---@protected ----@param _ Node ----@return string|nil group -function Decorator:calculate_highlight(_) - return nil +---@param node Node +---@return string? group +function Decorator:calculate_highlight(node) + self:nop(node) end ---Define a sign ---@protected ----@param icon HighlightedString|nil +---@param icon HighlightedString? function Decorator:define_sign(icon) if icon and #icon.hl > 0 then local name = icon.hl[1] diff --git a/lua/nvim-tree/renderer/decorator/meta.lua b/lua/nvim-tree/renderer/decorator/meta.lua new file mode 100644 index 00000000000..6f4fead3e78 --- /dev/null +++ b/lua/nvim-tree/renderer/decorator/meta.lua @@ -0,0 +1,13 @@ +---@meta + +---Highlight group range as per nvim-tree.renderer.highlight_* +---@alias DecoratorHighlightRange "none" | "icon" | "name" | "all" + +---Icon position as per renderer.icons.*_placement +---@alias DecoratorIconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" + +---Decorator Constructor Arguments +---@class (exact) DecoratorArgs +---@field enabled boolean +---@field highlight_range DecoratorHighlightRange +---@field icon_placement DecoratorIconPlacement diff --git a/lua/nvim-tree/renderer/decorator/modified.lua b/lua/nvim-tree/renderer/decorator/modified.lua index 30e044d2d66..0c4c1bdc26a 100644 --- a/lua/nvim-tree/renderer/decorator/modified.lua +++ b/lua/nvim-tree/renderer/decorator/modified.lua @@ -16,11 +16,14 @@ local DecoratorModified = Decorator:extend() function DecoratorModified:new(explorer) self.explorer = explorer - DecoratorModified.super.new(self, { - enabled = true, - hl_pos = self.explorer.opts.renderer.highlight_modified or "none", - icon_placement = self.explorer.opts.renderer.icons.modified_placement or "none", - }) + ---@type DecoratorArgs + local args = { + enabled = true, + highlight_range = self.explorer.opts.renderer.highlight_modified or "none", + icon_placement = self.explorer.opts.renderer.icons.modified_placement or "none", + } + + DecoratorModified.super.new(self, args) if not self.enabled then return @@ -48,7 +51,7 @@ end ---@param node Node ---@return string|nil group function DecoratorModified:calculate_highlight(node) - if not self.enabled or self.range == "none" or not buffers.is_modified(node) then + if not self.enabled or self.highlight_range == "none" or not buffers.is_modified(node) then return nil end diff --git a/lua/nvim-tree/renderer/decorator/opened.lua b/lua/nvim-tree/renderer/decorator/opened.lua index c58cc419984..843d456d1ff 100644 --- a/lua/nvim-tree/renderer/decorator/opened.lua +++ b/lua/nvim-tree/renderer/decorator/opened.lua @@ -15,18 +15,21 @@ local DecoratorOpened = Decorator:extend() function DecoratorOpened:new(explorer) self.explorer = explorer - DecoratorOpened.super.new(self, { - enabled = true, - hl_pos = self.explorer.opts.renderer.highlight_opened_files or "none", - icon_placement = "none", - }) + ---@type DecoratorArgs + local args = { + enabled = true, + highlight_range = self.explorer.opts.renderer.highlight_opened_files or "none", + icon_placement = "none", + } + + DecoratorOpened.super.new(self, args) end ---Opened highlight: renderer.highlight_opened_files and node has an open buffer ---@param node Node ---@return string|nil group function DecoratorOpened:calculate_highlight(node) - if self.range ~= "none" and buffers.is_opened(node) then + if self.highlight_range ~= "none" and buffers.is_opened(node) then return "NvimTreeOpenedHL" end end diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index 28bbf131a48..c20d180e28c 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -1,16 +1,82 @@ local Decorator = require("nvim-tree.renderer.decorator") ----Marker parent for user decorators +---Abstract user decorator, extend to define your own. +---Icon and highlight are optional. +---Constructor will be called once per tree render, with no arguments: +--- Must call super passing DecoratorArgs: MyDecorator.super.new(self, args) +--- Must call define_sign, when using "signcolumn" +---See example at end. + ---@class (exact) UserDecorator: Decorator local UserDecorator = Decorator:extend() ----@class UserDecorator ----@overload fun(args: DecoratorArgs): UserDecorator +---Override this method to provide icons and the highlight groups to apply to them +---@param node Node +---@return HighlightedString[]? icons +function UserDecorator:calculate_icons(node) + self:nop(node) +end ----@protected ----@param args DecoratorArgs -function UserDecorator:new(args) - UserDecorator.super.new(self, args) +---Override this method to provide one highlight group to apply to DecoratorRange +---@param node Node +---@return string? group +function UserDecorator:calculate_highlight(node) + self:nop(node) end return UserDecorator + + +--- +---Example user decorator +--[[ + +local UserDecorator = require("nvim-tree.renderer.decorator.user") + +---@class (exact) MyDecorator: UserDecorator +---@field private my_icon HighlightedString +local MyDecorator = UserDecorator:extend() + +---Constructor +function MyDecorator:new() + + ---@type DecoratorArgs + local args = { + enabled = true, + highlight_range = "all", + icon_placement = "signcolumn", + } + + MyDecorator.super.new(self, args) + + -- create your icon once, for convenience + self.my_icon = { str = "I", hl = { "MyIcon" } } + + -- Define the icon sign only once + -- Only needed if you are using icon_placement = "signcolumn" + self:define_sign(self.my_icon) +end + +---Just one icon for DecoratorIconPlacement +---@param node Node +---@return HighlightedString[]|nil icons +function MyDecorator:calculate_icons(node) + if node.name == "example" then + return { self.my_icon } + else + return nil + end +end + +---Exactly one highlight group for DecoratorHighlightRange +---@param node Node +---@return string|nil group +function MyDecorator:calculate_highlight(node) + if node.name == "example" then + return "ExampleHighlight" + else + return nil + end +end + +--]] From f2a926d608d3ca9da30cdfe3d3d9ba5bddc57683 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Fri, 22 Nov 2024 12:38:17 +1100 Subject: [PATCH 05/27] feat(#2948): add UserDecorator --- lua/nvim-tree/renderer/builder.lua | 5 ----- lua/nvim-tree/renderer/decorator/meta.lua | 5 +++++ lua/nvim-tree/renderer/decorator/user.lua | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 8389a6192a6..2d54e12a8af 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -16,11 +16,6 @@ local DecoratorOpened = require("nvim-tree.renderer.decorator.opened") local pad = require("nvim-tree.renderer.components.padding") ----TODO move all these classes to API meta ----@class (exact) HighlightedString ----@field str string ----@field hl string[] - ---@class (exact) AddHighlightArgs ---@field group string[] ---@field line number diff --git a/lua/nvim-tree/renderer/decorator/meta.lua b/lua/nvim-tree/renderer/decorator/meta.lua index 6f4fead3e78..20930d4c898 100644 --- a/lua/nvim-tree/renderer/decorator/meta.lua +++ b/lua/nvim-tree/renderer/decorator/meta.lua @@ -11,3 +11,8 @@ ---@field enabled boolean ---@field highlight_range DecoratorHighlightRange ---@field icon_placement DecoratorIconPlacement + +---A string for rendering, with optional highlight groups to apply to it +---@class (exact) HighlightedString +---@field str string +---@field hl string[] diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index c20d180e28c..b36e69047db 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -2,7 +2,7 @@ local Decorator = require("nvim-tree.renderer.decorator") ---Abstract user decorator, extend to define your own. ---Icon and highlight are optional. ----Constructor will be called once per tree render, with no arguments: +---Mandatory constructor will be called once per tree render, with no arguments: --- Must call super passing DecoratorArgs: MyDecorator.super.new(self, args) --- Must call define_sign, when using "signcolumn" ---See example at end. @@ -10,7 +10,7 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) UserDecorator: Decorator local UserDecorator = Decorator:extend() ----Override this method to provide icons and the highlight groups to apply to them +---Override this method to provide icons and the highlight groups to apply to DecoratorIconPlacement ---@param node Node ---@return HighlightedString[]? icons function UserDecorator:calculate_icons(node) From ad368d91870134883c78c7032c7f09238a7518db Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Fri, 22 Nov 2024 14:00:56 +1100 Subject: [PATCH 06/27] feat(#2948): add UserDecorator --- lua/nvim-tree/renderer/builder.lua | 2 +- .../renderer/decorator/bookmarks.lua | 4 ++-- lua/nvim-tree/renderer/decorator/copied.lua | 2 +- lua/nvim-tree/renderer/decorator/cut.lua | 2 +- .../renderer/decorator/diagnostics.lua | 16 +++++++------- lua/nvim-tree/renderer/decorator/git.lua | 6 +++--- lua/nvim-tree/renderer/decorator/hidden.lua | 4 ++-- lua/nvim-tree/renderer/decorator/init.lua | 18 ++++++++-------- lua/nvim-tree/renderer/decorator/modified.lua | 4 ++-- lua/nvim-tree/renderer/decorator/opened.lua | 2 +- lua/nvim-tree/renderer/decorator/user.lua | 21 +++++++++++-------- 11 files changed, 42 insertions(+), 39 deletions(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 2d54e12a8af..e23c82507ee 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -214,7 +214,7 @@ function Builder:add_highlights(node) local d, icon, name for i = #self.decorators, 1, -1 do d = self.decorators[i] - icon, name = d:groups_icon_name(node) + icon, name = d:highlight_group_icon_name(node) table.insert(icon_groups, icon) table.insert(name_groups, name) end diff --git a/lua/nvim-tree/renderer/decorator/bookmarks.lua b/lua/nvim-tree/renderer/decorator/bookmarks.lua index 6724f5a9bea..b4baac890b8 100644 --- a/lua/nvim-tree/renderer/decorator/bookmarks.lua +++ b/lua/nvim-tree/renderer/decorator/bookmarks.lua @@ -34,7 +34,7 @@ end ---Bookmark icon: renderer.icons.show.bookmarks and node is marked ---@param node Node ---@return HighlightedString[]|nil icons -function DecoratorBookmarks:calculate_icons(node) +function DecoratorBookmarks:icons(node) if self.explorer.marks:get(node) then return { self.icon } end @@ -43,7 +43,7 @@ end ---Bookmark highlight: renderer.highlight_bookmarks and node is marked ---@param node Node ---@return string|nil group -function DecoratorBookmarks:calculate_highlight(node) +function DecoratorBookmarks:highlight_group(node) if self.highlight_range ~= "none" and self.explorer.marks:get(node) then return "NvimTreeBookmarkHL" end diff --git a/lua/nvim-tree/renderer/decorator/copied.lua b/lua/nvim-tree/renderer/decorator/copied.lua index 16d28624917..105da0a8a2c 100644 --- a/lua/nvim-tree/renderer/decorator/copied.lua +++ b/lua/nvim-tree/renderer/decorator/copied.lua @@ -25,7 +25,7 @@ end ---Copied highlight: renderer.highlight_clipboard and node is copied ---@param node Node ---@return string|nil group -function DecoratorCopied:calculate_highlight(node) +function DecoratorCopied:highlight_group(node) if self.highlight_range ~= "none" and self.explorer.clipboard:is_copied(node) then return "NvimTreeCopiedHL" end diff --git a/lua/nvim-tree/renderer/decorator/cut.lua b/lua/nvim-tree/renderer/decorator/cut.lua index 7fdeaae7599..35c9af1356f 100644 --- a/lua/nvim-tree/renderer/decorator/cut.lua +++ b/lua/nvim-tree/renderer/decorator/cut.lua @@ -25,7 +25,7 @@ end ---Cut highlight: renderer.highlight_clipboard and node is cut ---@param node Node ---@return string|nil group -function DecoratorCut:calculate_highlight(node) +function DecoratorCut:highlight_group(node) if self.highlight_range ~= "none" and self.explorer.clipboard:is_cut(node) then return "NvimTreeCutHL" end diff --git a/lua/nvim-tree/renderer/decorator/diagnostics.lua b/lua/nvim-tree/renderer/decorator/diagnostics.lua index 055ae1de1d4..0b2e7f9abc2 100644 --- a/lua/nvim-tree/renderer/decorator/diagnostics.lua +++ b/lua/nvim-tree/renderer/decorator/diagnostics.lua @@ -32,7 +32,7 @@ local ICON_KEYS = { ---@class (exact) DecoratorDiagnostics: Decorator ---@field private explorer Explorer ----@field private icons HighlightedString[]? +---@field private diag_icons HighlightedString[]? local DecoratorDiagnostics = Decorator:extend() ---@class DecoratorDiagnostics @@ -57,13 +57,13 @@ function DecoratorDiagnostics:new(explorer) end if self.explorer.opts.renderer.icons.show.diagnostics then - self.icons = {} + self.diag_icons = {} for name, sev in pairs(ICON_KEYS) do - self.icons[sev] = { + self.diag_icons[sev] = { str = self.explorer.opts.diagnostics.icons[name], hl = { HG_ICON[sev] }, } - self:define_sign(self.icons[sev]) + self:define_sign(self.diag_icons[sev]) end end end @@ -71,13 +71,13 @@ end ---Diagnostic icon: diagnostics.enable, renderer.icons.show.diagnostics and node has status ---@param node Node ---@return HighlightedString[]|nil icons -function DecoratorDiagnostics:calculate_icons(node) - if node and self.enabled and self.icons then +function DecoratorDiagnostics:icons(node) + if node and self.enabled and self.diag_icons then local diag_status = diagnostics.get_diag_status(node) local diag_value = diag_status and diag_status.value if diag_value then - return { self.icons[diag_value] } + return { self.diag_icons[diag_value] } end end end @@ -85,7 +85,7 @@ end ---Diagnostic highlight: diagnostics.enable, renderer.highlight_diagnostics and node has status ---@param node Node ---@return string|nil group -function DecoratorDiagnostics:calculate_highlight(node) +function DecoratorDiagnostics:highlight_group(node) if not node or not self.enabled or self.highlight_range == "none" then return nil end diff --git a/lua/nvim-tree/renderer/decorator/git.lua b/lua/nvim-tree/renderer/decorator/git.lua index d56ad8a9fa2..1ed0df7cf25 100644 --- a/lua/nvim-tree/renderer/decorator/git.lua +++ b/lua/nvim-tree/renderer/decorator/git.lua @@ -148,7 +148,7 @@ end ---Git icons: git.enable, renderer.icons.show.git and node has status ---@param node Node ---@return HighlightedString[]|nil modified icon -function DecoratorGit:calculate_icons(node) +function DecoratorGit:icons(node) if not node or not self.enabled or not self.icons_by_xy then return nil end @@ -200,7 +200,7 @@ function DecoratorGit:sign_name(node) return end - local icons = self:calculate_icons(node) + local icons = self:icons(node) if icons and #icons > 0 then return icons[1].hl[1] end @@ -209,7 +209,7 @@ end ---Git highlight: git.enable, renderer.highlight_git and node has status ---@param node Node ---@return string|nil group -function DecoratorGit:calculate_highlight(node) +function DecoratorGit:highlight_group(node) if not node or not self.enabled or self.highlight_range == "none" then return nil end diff --git a/lua/nvim-tree/renderer/decorator/hidden.lua b/lua/nvim-tree/renderer/decorator/hidden.lua index 3bfff8550f5..26d16b36f5c 100644 --- a/lua/nvim-tree/renderer/decorator/hidden.lua +++ b/lua/nvim-tree/renderer/decorator/hidden.lua @@ -35,7 +35,7 @@ end ---Hidden icon: renderer.icons.show.hidden and node starts with `.` (dotfile). ---@param node Node ---@return HighlightedString[]|nil icons -function DecoratorHidden:calculate_icons(node) +function DecoratorHidden:icons(node) if self.enabled and node:is_dotfile() then return { self.icon } end @@ -44,7 +44,7 @@ end ---Hidden highlight: renderer.highlight_hidden and node starts with `.` (dotfile). ---@param node Node ---@return string|nil group -function DecoratorHidden:calculate_highlight(node) +function DecoratorHidden:highlight_group(node) if not self.enabled or self.highlight_range == "none" or not node:is_dotfile() then return nil end diff --git a/lua/nvim-tree/renderer/decorator/init.lua b/lua/nvim-tree/renderer/decorator/init.lua index d6a7656f842..9abb8948ed4 100644 --- a/lua/nvim-tree/renderer/decorator/init.lua +++ b/lua/nvim-tree/renderer/decorator/init.lua @@ -19,15 +19,15 @@ function Decorator:new(args) end end ----Maybe highlight groups +---Maybe highlight groups for icon and name ---@param node Node ---@return string? icon highlight group ---@return string? name highlight group -function Decorator:groups_icon_name(node) +function Decorator:highlight_group_icon_name(node) local icon_hl, name_hl if self.enabled and self.highlight_range ~= "none" then - local hl = self:calculate_highlight(node) + local hl = self:highlight_group(node) if self.highlight_range == "all" or self.highlight_range == "icon" then icon_hl = hl @@ -48,7 +48,7 @@ function Decorator:sign_name(node) return end - local icons = self:calculate_icons(node) + local icons = self:icons(node) if icons and #icons > 0 then return icons[1].hl[1] end @@ -62,7 +62,7 @@ function Decorator:icons_before(node) return end - return self:calculate_icons(node) + return self:icons(node) end ---Icons when "after" @@ -73,7 +73,7 @@ function Decorator:icons_after(node) return end - return self:calculate_icons(node) + return self:icons(node) end ---Icons when "right_align" @@ -84,14 +84,14 @@ function Decorator:icons_right_align(node) return end - return self:calculate_icons(node) + return self:icons(node) end ---Maybe icons, optionally implemented ---@protected ---@param node Node ---@return HighlightedString[]? icons -function Decorator:calculate_icons(node) +function Decorator:icons(node) self:nop(node) end @@ -99,7 +99,7 @@ end ---@protected ---@param node Node ---@return string? group -function Decorator:calculate_highlight(node) +function Decorator:highlight_group(node) self:nop(node) end diff --git a/lua/nvim-tree/renderer/decorator/modified.lua b/lua/nvim-tree/renderer/decorator/modified.lua index 0c4c1bdc26a..80ecec9c13c 100644 --- a/lua/nvim-tree/renderer/decorator/modified.lua +++ b/lua/nvim-tree/renderer/decorator/modified.lua @@ -41,7 +41,7 @@ end ---Modified icon: modified.enable, renderer.icons.show.modified and node is modified ---@param node Node ---@return HighlightedString[]|nil icons -function DecoratorModified:calculate_icons(node) +function DecoratorModified:icons(node) if self.enabled and buffers.is_modified(node) then return { self.icon } end @@ -50,7 +50,7 @@ end ---Modified highlight: modified.enable, renderer.highlight_modified and node is modified ---@param node Node ---@return string|nil group -function DecoratorModified:calculate_highlight(node) +function DecoratorModified:highlight_group(node) if not self.enabled or self.highlight_range == "none" or not buffers.is_modified(node) then return nil end diff --git a/lua/nvim-tree/renderer/decorator/opened.lua b/lua/nvim-tree/renderer/decorator/opened.lua index 843d456d1ff..dbec8f7d4ea 100644 --- a/lua/nvim-tree/renderer/decorator/opened.lua +++ b/lua/nvim-tree/renderer/decorator/opened.lua @@ -28,7 +28,7 @@ end ---Opened highlight: renderer.highlight_opened_files and node has an open buffer ---@param node Node ---@return string|nil group -function DecoratorOpened:calculate_highlight(node) +function DecoratorOpened:highlight_group(node) if self.highlight_range ~= "none" and buffers.is_opened(node) then return "NvimTreeOpenedHL" end diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index b36e69047db..4370b0957a3 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -1,10 +1,13 @@ local Decorator = require("nvim-tree.renderer.decorator") ----Abstract user decorator, extend to define your own. ----Icon and highlight are optional. ----Mandatory constructor will be called once per tree render, with no arguments: ---- Must call super passing DecoratorArgs: MyDecorator.super.new(self, args) ---- Must call define_sign, when using "signcolumn" +---Define a Decorator to optionally set: +--- Additional icons +--- Highlight group +--- Node icon +---Mandator constructor MyDecorator:new() will be called once per tree render, with no arguments. +---Must call: +--- super passing DecoratorArgs MyDecorator.super.new(self, args) +--- define_sign when using "signcolumn" ---See example at end. ---@class (exact) UserDecorator: Decorator @@ -13,14 +16,14 @@ local UserDecorator = Decorator:extend() ---Override this method to provide icons and the highlight groups to apply to DecoratorIconPlacement ---@param node Node ---@return HighlightedString[]? icons -function UserDecorator:calculate_icons(node) +function UserDecorator:icons(node) self:nop(node) end ---Override this method to provide one highlight group to apply to DecoratorRange ---@param node Node ---@return string? group -function UserDecorator:calculate_highlight(node) +function UserDecorator:highlight_group(node) self:nop(node) end @@ -60,7 +63,7 @@ end ---Just one icon for DecoratorIconPlacement ---@param node Node ---@return HighlightedString[]|nil icons -function MyDecorator:calculate_icons(node) +function MyDecorator:icons(node) if node.name == "example" then return { self.my_icon } else @@ -71,7 +74,7 @@ end ---Exactly one highlight group for DecoratorHighlightRange ---@param node Node ---@return string|nil group -function MyDecorator:calculate_highlight(node) +function MyDecorator:highlight_group(node) if node.name == "example" then return "ExampleHighlight" else From dd6b015f86ccc6585d26226a045e442669af35fd Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Fri, 22 Nov 2024 15:16:13 +1100 Subject: [PATCH 07/27] feat(#2948): add Decorator node icon override --- lua/nvim-tree/renderer/builder.lua | 56 ++++++++++++----------- lua/nvim-tree/renderer/decorator/init.lua | 7 +++ lua/nvim-tree/renderer/decorator/user.lua | 18 ++++++++ 3 files changed, 54 insertions(+), 27 deletions(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index e23c82507ee..f3a89204f4e 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -197,43 +197,50 @@ function Builder:create_combined_group(groups) return combined_name end ----Calculate highlight group for icon and name. A combined highlight group will be created ----when there is more than one highlight. +---Calculate decorated icon and name for a node. +---A combined highlight group will be created when there is more than one highlight. ---A highlight group is always calculated and upserted for the case of highlights changing. ---@private ---@param node Node ----@return string|nil icon_hl_group ----@return string|nil name_hl_group -function Builder:add_highlights(node) - -- result - local icon_hl_group, name_hl_group +---@return HighlightedString icon +---@return HighlightedString name +function Builder:icon_name_decorated(node) - -- calculate all groups + -- base case + local icon = node:highlighted_icon() + local name = node:highlighted_name() + + -- calculate node icon and all decorated highlight groups local icon_groups = {} local name_groups = {} - local d, icon, name + local decorator, hl_icon, hl_name for i = #self.decorators, 1, -1 do - d = self.decorators[i] - icon, name = d:highlight_group_icon_name(node) - table.insert(icon_groups, icon) - table.insert(name_groups, name) + decorator = self.decorators[i] + + -- maybe overridde icon + icon = decorator:icon_node(node) or icon + + hl_icon, hl_name = decorator:highlight_group_icon_name(node) + + table.insert(icon_groups, hl_icon) + table.insert(name_groups, hl_name) end - -- one or many icon groups + -- add one or many icon groups if #icon_groups > 1 then - icon_hl_group = self:create_combined_group(icon_groups) + table.insert(icon.hl, self:create_combined_group(icon_groups)) else - icon_hl_group = icon_groups[1] + table.insert(icon.hl, icon_groups[1]) end - -- one or many name groups + -- add one or many name groups if #name_groups > 1 then - name_hl_group = self:create_combined_group(name_groups) + table.insert(name.hl, self:create_combined_group(name_groups)) else - name_hl_group = name_groups[1] + table.insert(name.hl, name_groups[1]) end - return icon_hl_group, name_hl_group + return icon, name end ---Insert node line into self.lines, calling Builder:build_lines for each directory @@ -246,13 +253,8 @@ function Builder:build_line(node, idx, num_children) local indent_markers = pad.get_indent_markers(self.depth, idx, num_children, node, self.markers) local arrows = pad.get_arrows(node) - -- main components - local icon, name = node:highlighted_icon(), node:highlighted_name() - - -- highighting - local icon_hl_group, name_hl_group = self:add_highlights(node) - table.insert(icon.hl, icon_hl_group) - table.insert(name.hl, name_hl_group) + -- decorated node icon and name + local icon, name = self:icon_name_decorated(node) local line = self:format_line(indent_markers, arrows, icon, name, node) table.insert(self.lines, self:unwrap_highlighted_strings(line)) diff --git a/lua/nvim-tree/renderer/decorator/init.lua b/lua/nvim-tree/renderer/decorator/init.lua index 9abb8948ed4..e4a1c098727 100644 --- a/lua/nvim-tree/renderer/decorator/init.lua +++ b/lua/nvim-tree/renderer/decorator/init.lua @@ -87,6 +87,13 @@ function Decorator:icons_right_align(node) return self:icons(node) end +---Maybe icon override, optionally implemented +---@param node Node +---@return HighlightedString? icon_node +function Decorator:icon_node(node) + return self:nop(node) +end + ---Maybe icons, optionally implemented ---@protected ---@param node Node diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index 4370b0957a3..c1c1adb4808 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -13,6 +13,13 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) UserDecorator: Decorator local UserDecorator = Decorator:extend() +---Override this method to set the node's icon +---@param node Node +---@return HighlightedString? icon_node +function UserDecorator:icon_node(node) + return self:nop(node) +end + ---Override this method to provide icons and the highlight groups to apply to DecoratorIconPlacement ---@param node Node ---@return HighlightedString[]? icons @@ -60,6 +67,17 @@ function MyDecorator:new() self:define_sign(self.my_icon) end +---Overridden node icon +---@param node Node +---@return HighlightedString? icon_node +function MyDecorator:icon_node(node) + if node.name == "example" then + return self.my_icon + else + return nil + end +end + ---Just one icon for DecoratorIconPlacement ---@param node Node ---@return HighlightedString[]|nil icons From 1f1ad9373f3545a2041a0e78abbf29249baa80c4 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sat, 23 Nov 2024 18:06:14 +1100 Subject: [PATCH 08/27] feat(#2948): add nvim_tree.api.* node classes --- lua/nvim-tree/explorer/init.lua | 2 +- lua/nvim-tree/meta.lua | 59 +++++++++++++++++++++++ lua/nvim-tree/node/directory-link.lua | 4 +- lua/nvim-tree/node/directory.lua | 11 +++-- lua/nvim-tree/node/file-link.lua | 4 +- lua/nvim-tree/node/file.lua | 4 +- lua/nvim-tree/node/init.lua | 17 +++---- lua/nvim-tree/node/link.lua | 2 +- lua/nvim-tree/node/root.lua | 8 +++ lua/nvim-tree/renderer/decorator/meta.lua | 18 ------- 10 files changed, 89 insertions(+), 40 deletions(-) create mode 100644 lua/nvim-tree/meta.lua delete mode 100644 lua/nvim-tree/renderer/decorator/meta.lua diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index 0c637b2a3d3..0fdd46a1d1c 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -530,7 +530,7 @@ function Explorer:place_cursor_on_node() end ---Api.tree.get_nodes ----@return Node +---@return nvim_tree.api.Node function Explorer:get_nodes() return self:clone() end diff --git a/lua/nvim-tree/meta.lua b/lua/nvim-tree/meta.lua new file mode 100644 index 00000000000..d66e725530b --- /dev/null +++ b/lua/nvim-tree/meta.lua @@ -0,0 +1,59 @@ +---@meta + +-- +-- Nodes +-- + +---@class (exact) nvim_tree.api.Node: Class +---@field type "file" | "directory" | "link" uv.fs_stat.result.type +---@field absolute_path string +---@field executable boolean +---@field fs_stat uv.fs_stat.result? +---@field git_status GitNodeStatus? +---@field hidden boolean +---@field name string +---@field parent nvim_tree.api.DirectoryNode? +---@field diag_severity lsp.DiagnosticSeverity? + +---@class (exact) nvim_tree.api.FileNode: nvim_tree.api.Node +---@field extension string + +---@class (exact) nvim_tree.api.DirectoryNode: nvim_tree.api.Node +---@field has_children boolean +---@field nodes nvim_tree.api.Node[] +---@field open boolean + +---@class (exact) nvim_tree.api.RootNode: nvim_tree.api.DirectoryNode + +---@class (exact) nvim_tree.api.LinkNode: Class +---@field link_to string +---@field fs_stat_target uv.fs_stat.result + +---@class (exact) nvim_tree.api.FileLinkNode: nvim_tree.api.FileNode, nvim_tree.api.LinkNode + +---@class (exact) nvim_tree.api.DirectoryLinkNode: nvim_tree.api.DirectoryNode, nvim_tree.api.LinkNode + +-- +-- Decorators +-- + +---Highlight group range as per nvim-tree.renderer.highlight_* +---@alias DecoratorHighlightRange "none" | "icon" | "name" | "all" + +---Icon position as per renderer.icons.*_placement +---@alias DecoratorIconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" + +---Decorator Constructor Arguments +---@class (exact) DecoratorArgs +---@field enabled boolean +---@field highlight_range DecoratorHighlightRange +---@field icon_placement DecoratorIconPlacement + +-- +-- Types +-- + +---A string for rendering, with optional highlight groups to apply to it +---@class (exact) HighlightedString +---@field str string +---@field hl string[] diff --git a/lua/nvim-tree/node/directory-link.lua b/lua/nvim-tree/node/directory-link.lua index 82383088b91..81f5dc9a998 100644 --- a/lua/nvim-tree/node/directory-link.lua +++ b/lua/nvim-tree/node/directory-link.lua @@ -73,9 +73,9 @@ function DirectoryLinkNode:highlighted_name() end ---Create a sanitized partial copy of a node, populating children recursively. ----@return DirectoryLinkNode cloned +---@return nvim_tree.api.DirectoryLinkNode cloned function DirectoryLinkNode:clone() - local clone = DirectoryNode.clone(self) --[[@as DirectoryLinkNode]] + local clone = DirectoryNode.clone(self) --[[@as nvim_tree.api.DirectoryLinkNode]] clone.link_to = self.link_to clone.fs_stat_target = self.fs_stat_target diff --git a/lua/nvim-tree/node/directory.lua b/lua/nvim-tree/node/directory.lua index 899de184044..866792d7788 100644 --- a/lua/nvim-tree/node/directory.lua +++ b/lua/nvim-tree/node/directory.lua @@ -271,18 +271,19 @@ function DirectoryNode:highlighted_name() end ---Create a sanitized partial copy of a node, populating children recursively. ----@return DirectoryNode cloned +---@return nvim_tree.api.DirectoryNode cloned function DirectoryNode:clone() - local clone = Node.clone(self) --[[@as DirectoryNode]] + local clone = Node.clone(self) --[[@as nvim_tree.api.DirectoryNode]] clone.has_children = self.has_children - clone.group_next = nil clone.nodes = {} clone.open = self.open - clone.hidden_stats = nil + local clone_child for _, child in ipairs(self.nodes) do - table.insert(clone.nodes, child:clone()) + clone_child = child:clone() + clone_child.parent = clone + table.insert(clone.nodes, clone_child) end return clone diff --git a/lua/nvim-tree/node/file-link.lua b/lua/nvim-tree/node/file-link.lua index 3c5571a29a2..9b68d5e9d3d 100644 --- a/lua/nvim-tree/node/file-link.lua +++ b/lua/nvim-tree/node/file-link.lua @@ -58,9 +58,9 @@ function FileLinkNode:highlighted_name() end ---Create a sanitized partial copy of a node ----@return FileLinkNode cloned +---@return nvim_tree.api.FileLinkNode cloned function FileLinkNode:clone() - local clone = FileNode.clone(self) --[[@as FileLinkNode]] + local clone = FileNode.clone(self) --[[@as nvim_tree.api.FileLinkNode]] clone.link_to = self.link_to clone.fs_stat_target = self.fs_stat_target diff --git a/lua/nvim-tree/node/file.lua b/lua/nvim-tree/node/file.lua index a74a213a8eb..6c3567f7cbc 100644 --- a/lua/nvim-tree/node/file.lua +++ b/lua/nvim-tree/node/file.lua @@ -94,9 +94,9 @@ function FileNode:highlighted_name() end ---Create a sanitized partial copy of a node ----@return FileNode cloned +---@return nvim_tree.api.FileNode cloned function FileNode:clone() - local clone = Node.clone(self) --[[@as FileNode]] + local clone = Node.clone(self) --[[@as nvim_tree.api.FileNode]] clone.extension = self.extension diff --git a/lua/nvim-tree/node/init.lua b/lua/nvim-tree/node/init.lua index f6ecf24d036..2a9eda56896 100644 --- a/lua/nvim-tree/node/init.lua +++ b/lua/nvim-tree/node/init.lua @@ -2,6 +2,7 @@ local Class = require("nvim-tree.classic") ---Abstract Node class. ---@class (exact) Node: Class +---@field uid_node number vim.loop.hrtime() at construction time ---@field type "file" | "directory" | "link" uv.fs_stat.result.type ---@field explorer Explorer ---@field absolute_path string @@ -11,6 +12,7 @@ local Class = require("nvim-tree.classic") ---@field hidden boolean ---@field name string ---@field parent DirectoryNode? +---TODO split this into diag_severity and diag_severity_cache_version ---@field diag_status DiagStatus? ---@field private is_dot boolean cached is_dotfile local Node = Class:extend() @@ -25,6 +27,7 @@ local Node = Class:extend() ---@protected ---@param args NodeArgs function Node:new(args) + self.uid_node = vim.loop.hrtime() self.explorer = args.explorer self.absolute_path = args.absolute_path self.executable = false @@ -112,21 +115,18 @@ end ---Highlighted name for the node ---Empty for base Node ----@return HighlightedString icon +---@return HighlightedString name function Node:highlighted_name() return self:highlighted_name_empty() end ---Create a sanitized partial copy of a node, populating children recursively. ----@return Node cloned +---@return nvim_tree.api.Node cloned function Node:clone() - ---@type Explorer - local explorer_placeholder = nil - - ---@type Node + ---@type nvim_tree.api.Node local clone = { + uid_node = self.uid_node, type = self.type, - explorer = explorer_placeholder, absolute_path = self.absolute_path, executable = self.executable, fs_stat = self.fs_stat, @@ -134,8 +134,7 @@ function Node:clone() hidden = self.hidden, name = self.name, parent = nil, - diag_status = nil, - is_dot = self.is_dot, + diag_severity = self.diag_status and self.diag_status.value or nil, } return clone diff --git a/lua/nvim-tree/node/link.lua b/lua/nvim-tree/node/link.lua index ff2d8e4df5b..c3bc164b912 100644 --- a/lua/nvim-tree/node/link.lua +++ b/lua/nvim-tree/node/link.lua @@ -2,7 +2,7 @@ local Class = require("nvim-tree.classic") ---@class (exact) LinkNode: Class ---@field link_to string ----@field protected fs_stat_target uv.fs_stat.result +---@field fs_stat_target uv.fs_stat.result local LinkNode = Class:extend() ---@class (exact) LinkNodeArgs: NodeArgs diff --git a/lua/nvim-tree/node/root.lua b/lua/nvim-tree/node/root.lua index ec3c44c4a82..683c08b8ef8 100644 --- a/lua/nvim-tree/node/root.lua +++ b/lua/nvim-tree/node/root.lua @@ -22,4 +22,12 @@ function RootNode:destroy() DirectoryNode.destroy(self) end +---Create a sanitized partial copy of a node, populating children recursively. +---@return nvim_tree.api.RootNode cloned +function RootNode:clone() + local clone = DirectoryNode.clone(self) --[[@as nvim_tree.api.RootNode]] + + return clone +end + return RootNode diff --git a/lua/nvim-tree/renderer/decorator/meta.lua b/lua/nvim-tree/renderer/decorator/meta.lua deleted file mode 100644 index 20930d4c898..00000000000 --- a/lua/nvim-tree/renderer/decorator/meta.lua +++ /dev/null @@ -1,18 +0,0 @@ ----@meta - ----Highlight group range as per nvim-tree.renderer.highlight_* ----@alias DecoratorHighlightRange "none" | "icon" | "name" | "all" - ----Icon position as per renderer.icons.*_placement ----@alias DecoratorIconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" - ----Decorator Constructor Arguments ----@class (exact) DecoratorArgs ----@field enabled boolean ----@field highlight_range DecoratorHighlightRange ----@field icon_placement DecoratorIconPlacement - ----A string for rendering, with optional highlight groups to apply to it ----@class (exact) HighlightedString ----@field str string ----@field hl string[] From 45a14f6c3839783e653ace532e50922f02f0a64e Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 24 Nov 2024 12:04:10 +1100 Subject: [PATCH 09/27] feat(#2948): extract _meta following nvim pattern --- lua/nvim-tree/{meta.lua => _meta/api.lua} | 35 ++++---- lua/nvim-tree/_meta/api_decorator.lua | 88 +++++++++++++++++++ .../renderer/decorator/bookmarks.lua | 4 +- lua/nvim-tree/renderer/decorator/copied.lua | 2 +- lua/nvim-tree/renderer/decorator/cut.lua | 2 +- .../renderer/decorator/diagnostics.lua | 4 +- lua/nvim-tree/renderer/decorator/git.lua | 6 +- lua/nvim-tree/renderer/decorator/hidden.lua | 4 +- lua/nvim-tree/renderer/decorator/init.lua | 7 +- lua/nvim-tree/renderer/decorator/modified.lua | 4 +- lua/nvim-tree/renderer/decorator/opened.lua | 2 +- lua/nvim-tree/renderer/decorator/user.lua | 75 +--------------- 12 files changed, 130 insertions(+), 103 deletions(-) rename lua/nvim-tree/{meta.lua => _meta/api.lua} (69%) create mode 100644 lua/nvim-tree/_meta/api_decorator.lua diff --git a/lua/nvim-tree/meta.lua b/lua/nvim-tree/_meta/api.lua similarity index 69% rename from lua/nvim-tree/meta.lua rename to lua/nvim-tree/_meta/api.lua index d66e725530b..d5903603133 100644 --- a/lua/nvim-tree/meta.lua +++ b/lua/nvim-tree/_meta/api.lua @@ -1,9 +1,14 @@ ---@meta +error('Cannot require a meta file') + +-- TODO describe class +-- TODO describe user decorator -- -- Nodes -- +---Base Node, Abstract ---@class (exact) nvim_tree.api.Node: Class ---@field type "file" | "directory" | "link" uv.fs_stat.result.type ---@field absolute_path string @@ -15,45 +20,41 @@ ---@field parent nvim_tree.api.DirectoryNode? ---@field diag_severity lsp.DiagnosticSeverity? +---File ---@class (exact) nvim_tree.api.FileNode: nvim_tree.api.Node ---@field extension string +---Directory ---@class (exact) nvim_tree.api.DirectoryNode: nvim_tree.api.Node ---@field has_children boolean ---@field nodes nvim_tree.api.Node[] ---@field open boolean +---Root Directory ---@class (exact) nvim_tree.api.RootNode: nvim_tree.api.DirectoryNode +---Link mixin ---@class (exact) nvim_tree.api.LinkNode: Class ---@field link_to string ---@field fs_stat_target uv.fs_stat.result +---File Link ---@class (exact) nvim_tree.api.FileLinkNode: nvim_tree.api.FileNode, nvim_tree.api.LinkNode +---DirectoryLink ---@class (exact) nvim_tree.api.DirectoryLinkNode: nvim_tree.api.DirectoryNode, nvim_tree.api.LinkNode -- --- Decorators +-- Various Types -- ----Highlight group range as per nvim-tree.renderer.highlight_* ----@alias DecoratorHighlightRange "none" | "icon" | "name" | "all" - ----Icon position as per renderer.icons.*_placement ----@alias DecoratorIconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" - ----Decorator Constructor Arguments ----@class (exact) DecoratorArgs ----@field enabled boolean ----@field highlight_range DecoratorHighlightRange ----@field icon_placement DecoratorIconPlacement +---A string for rendering, with optional highlight groups to apply to it +---@class (exact) nvim_tree.api.HighlightedString +---@field str string +---@field hl string[] -- --- Types +-- Internal Aliases -- +---@alias HighlightedString nvim_tree.api.HighlightedString ----A string for rendering, with optional highlight groups to apply to it ----@class (exact) HighlightedString ----@field str string ----@field hl string[] diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua new file mode 100644 index 00000000000..288979d325b --- /dev/null +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -0,0 +1,88 @@ +---@meta +error('Cannot require a meta file') + +---Highlight group range as per nvim-tree.renderer.highlight_* +---@alias nvim_tree.api.decorator.HighlightRange "none" | "icon" | "name" | "all" + +---Icon position as per renderer.icons.*_placement +---@alias nvim_tree.api.decorator.IconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" + +---UserDecorator Constructor Arguments +---@class (exact) nvim_tree.api.decorator.UserDecoratorArgs +---@field enabled boolean +---@field highlight_range nvim_tree.api.decorator.HighlightRange +---@field icon_placement nvim_tree.api.decorator.IconPlacement + + +-- +-- Example UserDecorator +-- + +local UserDecorator = require("nvim-tree.renderer.decorator.user") + +---@class (exact) MyDecorator: UserDecorator +---@field private my_icon nvim_tree.api.HighlightedString +local MyDecorator = UserDecorator:extend() + +---Constructor +function MyDecorator:new() + + ---@type nvim_tree.api.decorator.UserDecoratorArgs + local args = { + enabled = true, + highlight_range = "all", + icon_placement = "signcolumn", + } + + -- construct super with args + MyDecorator.super.new(self, args) + + -- create your icon once, for convenience + self.my_icon = { str = "I", hl = { "MyIcon" } } + + -- Define the icon sign only once + -- Only needed if you are using icon_placement = "signcolumn" + self:define_sign(self.my_icon) +end + +---Overridde node icon +---@param node nvim_tree.api.Node +---@return nvim_tree.api.HighlightedString? icon_node +function MyDecorator:icon_node(node) + if node.name == "example" then + return self.my_icon + else + return nil + end +end + +---Return one icon for DecoratorIconPlacement +---@param node nvim_tree.api.Node +---@return nvim_tree.api.HighlightedString[]? icons +function MyDecorator:icons(node) + if node.name == "example" then + return { self.my_icon } + else + return nil + end +end + +---Exactly one highlight group for DecoratorHighlightRange +---@param node nvim_tree.api.Node +---@return string? highlight_group +function MyDecorator:highlight_group(node) + if node.name == "example" then + return "MyHighlight" + else + return nil + end +end + +return MyDecorator + +-- +-- Internal Aliases +-- +---@alias DecoratorHighlightRange nvim_tree.api.decorator.HighlightRange +---@alias DecoratorIconPlacement nvim_tree.api.decorator.IconPlacement + diff --git a/lua/nvim-tree/renderer/decorator/bookmarks.lua b/lua/nvim-tree/renderer/decorator/bookmarks.lua index b4baac890b8..4d074e55794 100644 --- a/lua/nvim-tree/renderer/decorator/bookmarks.lua +++ b/lua/nvim-tree/renderer/decorator/bookmarks.lua @@ -33,7 +33,7 @@ end ---Bookmark icon: renderer.icons.show.bookmarks and node is marked ---@param node Node ----@return HighlightedString[]|nil icons +---@return HighlightedString[]? icons function DecoratorBookmarks:icons(node) if self.explorer.marks:get(node) then return { self.icon } @@ -42,7 +42,7 @@ end ---Bookmark highlight: renderer.highlight_bookmarks and node is marked ---@param node Node ----@return string|nil group +---@return string? highlight_group function DecoratorBookmarks:highlight_group(node) if self.highlight_range ~= "none" and self.explorer.marks:get(node) then return "NvimTreeBookmarkHL" diff --git a/lua/nvim-tree/renderer/decorator/copied.lua b/lua/nvim-tree/renderer/decorator/copied.lua index 105da0a8a2c..85ded7b7453 100644 --- a/lua/nvim-tree/renderer/decorator/copied.lua +++ b/lua/nvim-tree/renderer/decorator/copied.lua @@ -24,7 +24,7 @@ end ---Copied highlight: renderer.highlight_clipboard and node is copied ---@param node Node ----@return string|nil group +---@return string? highlight_group function DecoratorCopied:highlight_group(node) if self.highlight_range ~= "none" and self.explorer.clipboard:is_copied(node) then return "NvimTreeCopiedHL" diff --git a/lua/nvim-tree/renderer/decorator/cut.lua b/lua/nvim-tree/renderer/decorator/cut.lua index 35c9af1356f..4546a990a7d 100644 --- a/lua/nvim-tree/renderer/decorator/cut.lua +++ b/lua/nvim-tree/renderer/decorator/cut.lua @@ -24,7 +24,7 @@ end ---Cut highlight: renderer.highlight_clipboard and node is cut ---@param node Node ----@return string|nil group +---@return string? highlight_group function DecoratorCut:highlight_group(node) if self.highlight_range ~= "none" and self.explorer.clipboard:is_cut(node) then return "NvimTreeCutHL" diff --git a/lua/nvim-tree/renderer/decorator/diagnostics.lua b/lua/nvim-tree/renderer/decorator/diagnostics.lua index 0b2e7f9abc2..d61996bffef 100644 --- a/lua/nvim-tree/renderer/decorator/diagnostics.lua +++ b/lua/nvim-tree/renderer/decorator/diagnostics.lua @@ -70,7 +70,7 @@ end ---Diagnostic icon: diagnostics.enable, renderer.icons.show.diagnostics and node has status ---@param node Node ----@return HighlightedString[]|nil icons +---@return HighlightedString[]? icons function DecoratorDiagnostics:icons(node) if node and self.enabled and self.diag_icons then local diag_status = diagnostics.get_diag_status(node) @@ -84,7 +84,7 @@ end ---Diagnostic highlight: diagnostics.enable, renderer.highlight_diagnostics and node has status ---@param node Node ----@return string|nil group +---@return string? highlight_group function DecoratorDiagnostics:highlight_group(node) if not node or not self.enabled or self.highlight_range == "none" then return nil diff --git a/lua/nvim-tree/renderer/decorator/git.lua b/lua/nvim-tree/renderer/decorator/git.lua index 1ed0df7cf25..a4e6cd7945c 100644 --- a/lua/nvim-tree/renderer/decorator/git.lua +++ b/lua/nvim-tree/renderer/decorator/git.lua @@ -3,7 +3,7 @@ local notify = require("nvim-tree.notify") local Decorator = require("nvim-tree.renderer.decorator") local DirectoryNode = require("nvim-tree.node.directory") ----@class (exact) GitHighlightedString: HighlightedString +---@class (exact) GitHighlightedString: nvim_tree.api.HighlightedString ---@field ord number decreasing priority ---@alias GitStatusStrings "deleted" | "ignored" | "renamed" | "staged" | "unmerged" | "unstaged" | "untracked" @@ -147,7 +147,7 @@ end ---Git icons: git.enable, renderer.icons.show.git and node has status ---@param node Node ----@return HighlightedString[]|nil modified icon +---@return HighlightedString[]? icons function DecoratorGit:icons(node) if not node or not self.enabled or not self.icons_by_xy then return nil @@ -208,7 +208,7 @@ end ---Git highlight: git.enable, renderer.highlight_git and node has status ---@param node Node ----@return string|nil group +---@return string? highlight_group function DecoratorGit:highlight_group(node) if not node or not self.enabled or self.highlight_range == "none" then return nil diff --git a/lua/nvim-tree/renderer/decorator/hidden.lua b/lua/nvim-tree/renderer/decorator/hidden.lua index 26d16b36f5c..0c4c8fe1507 100644 --- a/lua/nvim-tree/renderer/decorator/hidden.lua +++ b/lua/nvim-tree/renderer/decorator/hidden.lua @@ -34,7 +34,7 @@ end ---Hidden icon: renderer.icons.show.hidden and node starts with `.` (dotfile). ---@param node Node ----@return HighlightedString[]|nil icons +---@return HighlightedString[]? icons function DecoratorHidden:icons(node) if self.enabled and node:is_dotfile() then return { self.icon } @@ -43,7 +43,7 @@ end ---Hidden highlight: renderer.highlight_hidden and node starts with `.` (dotfile). ---@param node Node ----@return string|nil group +---@return string? highlight_group function DecoratorHidden:highlight_group(node) if not self.enabled or self.highlight_range == "none" or not node:is_dotfile() then return nil diff --git a/lua/nvim-tree/renderer/decorator/init.lua b/lua/nvim-tree/renderer/decorator/init.lua index e4a1c098727..adfd01dc96d 100644 --- a/lua/nvim-tree/renderer/decorator/init.lua +++ b/lua/nvim-tree/renderer/decorator/init.lua @@ -7,6 +7,11 @@ local Class = require("nvim-tree.classic") ---@field protected icon_placement DecoratorIconPlacement local Decorator = Class:extend() +---@class (exact) DecoratorArgs +---@field enabled boolean +---@field highlight_range DecoratorHighlightRange +---@field icon_placement DecoratorIconPlacement + ---@protected ---@param args DecoratorArgs function Decorator:new(args) @@ -105,7 +110,7 @@ end ---Maybe highlight group, optionally implemented ---@protected ---@param node Node ----@return string? group +---@return string? highlight_group function Decorator:highlight_group(node) self:nop(node) end diff --git a/lua/nvim-tree/renderer/decorator/modified.lua b/lua/nvim-tree/renderer/decorator/modified.lua index 80ecec9c13c..da55f19adf7 100644 --- a/lua/nvim-tree/renderer/decorator/modified.lua +++ b/lua/nvim-tree/renderer/decorator/modified.lua @@ -40,7 +40,7 @@ end ---Modified icon: modified.enable, renderer.icons.show.modified and node is modified ---@param node Node ----@return HighlightedString[]|nil icons +---@return HighlightedString[]? icons function DecoratorModified:icons(node) if self.enabled and buffers.is_modified(node) then return { self.icon } @@ -49,7 +49,7 @@ end ---Modified highlight: modified.enable, renderer.highlight_modified and node is modified ---@param node Node ----@return string|nil group +---@return string? highlight_group function DecoratorModified:highlight_group(node) if not self.enabled or self.highlight_range == "none" or not buffers.is_modified(node) then return nil diff --git a/lua/nvim-tree/renderer/decorator/opened.lua b/lua/nvim-tree/renderer/decorator/opened.lua index dbec8f7d4ea..7a02c6d4c99 100644 --- a/lua/nvim-tree/renderer/decorator/opened.lua +++ b/lua/nvim-tree/renderer/decorator/opened.lua @@ -27,7 +27,7 @@ end ---Opened highlight: renderer.highlight_opened_files and node has an open buffer ---@param node Node ----@return string|nil group +---@return string? highlight_group function DecoratorOpened:highlight_group(node) if self.highlight_range ~= "none" and buffers.is_opened(node) then return "NvimTreeOpenedHL" diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index c1c1adb4808..21e66236cc5 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -8,96 +8,29 @@ local Decorator = require("nvim-tree.renderer.decorator") ---Must call: --- super passing DecoratorArgs MyDecorator.super.new(self, args) --- define_sign when using "signcolumn" ----See example at end. ---@class (exact) UserDecorator: Decorator local UserDecorator = Decorator:extend() ---Override this method to set the node's icon ----@param node Node +---@param node nvim_tree.api.Node ---@return HighlightedString? icon_node function UserDecorator:icon_node(node) return self:nop(node) end ---Override this method to provide icons and the highlight groups to apply to DecoratorIconPlacement ----@param node Node +---@param node nvim_tree.api.Node ---@return HighlightedString[]? icons function UserDecorator:icons(node) self:nop(node) end ---Override this method to provide one highlight group to apply to DecoratorRange ----@param node Node ----@return string? group +---@param node nvim_tree.api.Node +---@return string? highlight_group function UserDecorator:highlight_group(node) self:nop(node) end return UserDecorator - - ---- ----Example user decorator ---[[ - -local UserDecorator = require("nvim-tree.renderer.decorator.user") - ----@class (exact) MyDecorator: UserDecorator ----@field private my_icon HighlightedString -local MyDecorator = UserDecorator:extend() - ----Constructor -function MyDecorator:new() - - ---@type DecoratorArgs - local args = { - enabled = true, - highlight_range = "all", - icon_placement = "signcolumn", - } - - MyDecorator.super.new(self, args) - - -- create your icon once, for convenience - self.my_icon = { str = "I", hl = { "MyIcon" } } - - -- Define the icon sign only once - -- Only needed if you are using icon_placement = "signcolumn" - self:define_sign(self.my_icon) -end - ----Overridden node icon ----@param node Node ----@return HighlightedString? icon_node -function MyDecorator:icon_node(node) - if node.name == "example" then - return self.my_icon - else - return nil - end -end - ----Just one icon for DecoratorIconPlacement ----@param node Node ----@return HighlightedString[]|nil icons -function MyDecorator:icons(node) - if node.name == "example" then - return { self.my_icon } - else - return nil - end -end - ----Exactly one highlight group for DecoratorHighlightRange ----@param node Node ----@return string|nil group -function MyDecorator:highlight_group(node) - if node.name == "example" then - return "ExampleHighlight" - else - return nil - end -end - ---]] From 919a0a3333766ff32f766f329a03175112fb1221 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 24 Nov 2024 13:36:22 +1100 Subject: [PATCH 10/27] feat(#2948): extract _meta following nvim pattern --- Makefile | 2 +- lua/nvim-tree/_meta/aliases.lua | 19 ++++++ lua/nvim-tree/_meta/api.lua | 15 +---- lua/nvim-tree/_meta/api_decorator.lua | 76 +++++++++++++++++------ lua/nvim-tree/api.lua | 3 + lua/nvim-tree/renderer/builder.lua | 1 - lua/nvim-tree/renderer/decorator/user.lua | 12 ---- 7 files changed, 84 insertions(+), 44 deletions(-) create mode 100644 lua/nvim-tree/_meta/aliases.lua diff --git a/Makefile b/Makefile index 8df41f7c588..b5e829d8ddc 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ check: luals # subtasks # luacheck: - luacheck -q lua + luacheck --codes --quiet lua --exclude-files "**/_meta/**" # --diagnosis-as-error does not function for workspace, hence we post-process the output style-check: diff --git a/lua/nvim-tree/_meta/aliases.lua b/lua/nvim-tree/_meta/aliases.lua new file mode 100644 index 00000000000..8154d9371a1 --- /dev/null +++ b/lua/nvim-tree/_meta/aliases.lua @@ -0,0 +1,19 @@ +---@meta +error("Cannot require a meta file") + +-- +--Internal convenience aliases for api types +-- + +-- +--api.lua +-- + +---@alias HighlightedString nvim_tree.api.HighlightedString + +-- +--api_decorator.lua +-- + +---@alias DecoratorHighlightRange nvim_tree.api.decorator.HighlightRange +---@alias DecoratorIconPlacement nvim_tree.api.decorator.IconPlacement diff --git a/lua/nvim-tree/_meta/api.lua b/lua/nvim-tree/_meta/api.lua index d5903603133..d6847940781 100644 --- a/lua/nvim-tree/_meta/api.lua +++ b/lua/nvim-tree/_meta/api.lua @@ -1,15 +1,12 @@ ---@meta -error('Cannot require a meta file') - --- TODO describe class --- TODO describe user decorator +error("Cannot require a meta file") -- -- Nodes -- ---Base Node, Abstract ----@class (exact) nvim_tree.api.Node: Class +---@class (exact) nvim_tree.api.Node ---@field type "file" | "directory" | "link" uv.fs_stat.result.type ---@field absolute_path string ---@field executable boolean @@ -34,7 +31,7 @@ error('Cannot require a meta file') ---@class (exact) nvim_tree.api.RootNode: nvim_tree.api.DirectoryNode ---Link mixin ----@class (exact) nvim_tree.api.LinkNode: Class +---@class (exact) nvim_tree.api.LinkNode ---@field link_to string ---@field fs_stat_target uv.fs_stat.result @@ -52,9 +49,3 @@ error('Cannot require a meta file') ---@class (exact) nvim_tree.api.HighlightedString ---@field str string ---@field hl string[] - --- --- Internal Aliases --- ----@alias HighlightedString nvim_tree.api.HighlightedString - diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua index 288979d325b..5c4fed680df 100644 --- a/lua/nvim-tree/_meta/api_decorator.lua +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -1,33 +1,80 @@ ---@meta error('Cannot require a meta file') +local nvim_tree = { api = { decorator = { BaseDecorator = {} } } } + ---Highlight group range as per nvim-tree.renderer.highlight_* ---@alias nvim_tree.api.decorator.HighlightRange "none" | "icon" | "name" | "all" ---Icon position as per renderer.icons.*_placement ---@alias nvim_tree.api.decorator.IconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" ----UserDecorator Constructor Arguments ----@class (exact) nvim_tree.api.decorator.UserDecoratorArgs +-- +-- BaseDecorator Class, see example implementation below +-- + +---User defined decorator to optionally add: +--- Additional icons +--- Name highlight group +--- Node icon override +---Class must be created via nvim_tree.api.decorator.BaseDecorator:extend() +---Mandatory constructor :new() will be called once per tree render, with no arguments. +---Constructor must call: +--- .super.new(self, args) passing nvim_tree.api.decorator.BaseDecoratorArgs +--- :define_sign(...) when using "signcolumn" range +---@class (exact) nvim_tree.api.decorator.BaseDecorator +---@field protected enabled boolean +---@field protected highlight_range nvim_tree.api.decorator.HighlightRange +---@field protected icon_placement nvim_tree.api.decorator.IconPlacement + +---Constructor Arguments +---@class (exact) nvim_tree.api.decorator.BaseDecoratorArgs ---@field enabled boolean ---@field highlight_range nvim_tree.api.decorator.HighlightRange ---@field icon_placement nvim_tree.api.decorator.IconPlacement +---Use to instantiate your decorator class +function nvim_tree.api.decorator.BaseDecorator:extend() end + +---Super constructor must be called from your constructor +---BaseDecorator.super.new(self, args) +---@protected +---@param self nvim_tree.api.decorator.BaseDecorator your instance +---@param args nvim_tree.api.decorator.BaseDecoratorArgs +function nvim_tree.api.decorator.BaseDecorator.new(self, args) end + +---Must implement a constructor and call super +function nvim_tree.api.decorator.BaseDecorator:new() end + +---Implement this method to set the node's icon +---@param node nvim_tree.api.Node +---@return HighlightedString? icon_node +function nvim_tree.api.decorator.BaseDecorator:icon_node(node) end + +---Implement this method to provide icons and the highlight groups to apply to IconPlacement +---@param node nvim_tree.api.Node +---@return HighlightedString[]? icons +function nvim_tree.api.decorator.BaseDecorator:icons(node) end + +---Implement this method to provide one highlight group to apply to HighlightRange +---@param node nvim_tree.api.Node +---@return string? highlight_group +function nvim_tree.api.decorator.BaseDecorator:highlight_group(node) end + -- --- Example UserDecorator +-- Example Decorator -- -local UserDecorator = require("nvim-tree.renderer.decorator.user") +local BaseDecorator = require("nvim-tree.api").decorator.BaseDecorator ----@class (exact) MyDecorator: UserDecorator +---@class (exact) MyDecorator: nvim_tree.api.decorator.BaseDecorator ---@field private my_icon nvim_tree.api.HighlightedString -local MyDecorator = UserDecorator:extend() +local MyDecorator = BaseDecorator:extend() ----Constructor +---Mandatory constructor :new() will be called once per tree render, with no arguments. function MyDecorator:new() - - ---@type nvim_tree.api.decorator.UserDecoratorArgs + ----@type nvim_tree.api.decorator.BaseDecoratorArgs local args = { enabled = true, highlight_range = "all", @@ -35,7 +82,7 @@ function MyDecorator:new() } -- construct super with args - MyDecorator.super.new(self, args) + BaseDecorator.new(self, args) -- create your icon once, for convenience self.my_icon = { str = "I", hl = { "MyIcon" } } @@ -45,7 +92,7 @@ function MyDecorator:new() self:define_sign(self.my_icon) end ----Overridde node icon +---Override node icon ---@param node nvim_tree.api.Node ---@return nvim_tree.api.HighlightedString? icon_node function MyDecorator:icon_node(node) @@ -79,10 +126,3 @@ function MyDecorator:highlight_group(node) end return MyDecorator - --- --- Internal Aliases --- ----@alias DecoratorHighlightRange nvim_tree.api.decorator.HighlightRange ----@alias DecoratorIconPlacement nvim_tree.api.decorator.IconPlacement - diff --git a/lua/nvim-tree/api.lua b/lua/nvim-tree/api.lua index fb1596a273f..6a50a260b53 100644 --- a/lua/nvim-tree/api.lua +++ b/lua/nvim-tree/api.lua @@ -39,6 +39,7 @@ local Api = { }, commands = {}, diagnostics = {}, + decorator = {}, } ---Print error when setup not called. @@ -311,4 +312,6 @@ Api.commands.get = wrap(function() return require("nvim-tree.commands").get() end) +Api.decorator.BaseDecorator = require("nvim-tree.renderer.decorator.user") --[[@as nvim_tree.api.decorator.BaseDecorator ]] + return Api diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index f3a89204f4e..398d53d1825 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -205,7 +205,6 @@ end ---@return HighlightedString icon ---@return HighlightedString name function Builder:icon_name_decorated(node) - -- base case local icon = node:highlighted_icon() local name = node:highlighted_name() diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index 21e66236cc5..536725ed4b5 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -1,32 +1,20 @@ local Decorator = require("nvim-tree.renderer.decorator") ----Define a Decorator to optionally set: ---- Additional icons ---- Highlight group ---- Node icon ----Mandator constructor MyDecorator:new() will be called once per tree render, with no arguments. ----Must call: ---- super passing DecoratorArgs MyDecorator.super.new(self, args) ---- define_sign when using "signcolumn" - ---@class (exact) UserDecorator: Decorator local UserDecorator = Decorator:extend() ----Override this method to set the node's icon ---@param node nvim_tree.api.Node ---@return HighlightedString? icon_node function UserDecorator:icon_node(node) return self:nop(node) end ----Override this method to provide icons and the highlight groups to apply to DecoratorIconPlacement ---@param node nvim_tree.api.Node ---@return HighlightedString[]? icons function UserDecorator:icons(node) self:nop(node) end ----Override this method to provide one highlight group to apply to DecoratorRange ---@param node nvim_tree.api.Node ---@return string? highlight_group function UserDecorator:highlight_group(node) From 129c349eeef302ab31dd73afdbaf2bc3fae9d6d0 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 24 Nov 2024 15:19:05 +1100 Subject: [PATCH 11/27] feat(#2948): add decorator registry and order --- doc/nvim-tree-lua.txt | 1 - lua/nvim-tree.lua | 1 - lua/nvim-tree/api.lua | 5 ++ lua/nvim-tree/renderer/builder.lua | 33 +++------ .../renderer/decorator/bookmarks.lua | 13 ++-- lua/nvim-tree/renderer/decorator/copied.lua | 13 ++-- lua/nvim-tree/renderer/decorator/cut.lua | 13 ++-- .../renderer/decorator/diagnostics.lua | 13 ++-- lua/nvim-tree/renderer/decorator/git.lua | 13 ++-- lua/nvim-tree/renderer/decorator/hidden.lua | 13 ++-- lua/nvim-tree/renderer/decorator/init.lua | 6 +- lua/nvim-tree/renderer/decorator/modified.lua | 13 ++-- lua/nvim-tree/renderer/decorator/opened.lua | 13 ++-- lua/nvim-tree/renderer/decorator/registry.lua | 71 +++++++++++++++++++ lua/nvim-tree/renderer/decorator/user.lua | 25 ++----- 15 files changed, 152 insertions(+), 94 deletions(-) create mode 100644 lua/nvim-tree/renderer/decorator/registry.lua diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 2a670c59d31..060227f8220 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -417,7 +417,6 @@ Following is the default configuration. See |nvim-tree-opts| for details. >lua }, }, renderer = { - user_decorators = {}, add_trailing = false, group_empty = false, full_name = false, diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 8c05be4fa47..212d4c14bab 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -276,7 +276,6 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS }, }, renderer = { - user_decorators = {}, add_trailing = false, group_empty = false, full_name = false, diff --git a/lua/nvim-tree/api.lua b/lua/nvim-tree/api.lua index 6a50a260b53..9e3fdc989c7 100644 --- a/lua/nvim-tree/api.lua +++ b/lua/nvim-tree/api.lua @@ -7,6 +7,7 @@ local events = require("nvim-tree.events") local help = require("nvim-tree.help") local keymap = require("nvim-tree.keymap") local notify = require("nvim-tree.notify") +local decorator_registry = require("nvim-tree.renderer.decorator.registry") local DirectoryNode = require("nvim-tree.node.directory") local FileLinkNode = require("nvim-tree.node.file-link") @@ -312,6 +313,10 @@ Api.commands.get = wrap(function() return require("nvim-tree.commands").get() end) +-- TODO provide a registration convenience to hide classic +-- TODO add doc Api.decorator.BaseDecorator = require("nvim-tree.renderer.decorator.user") --[[@as nvim_tree.api.decorator.BaseDecorator ]] +Api.decorator.register = decorator_registry.register +Api.decorator.unregister = decorator_registry.unregister return Api diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 398d53d1825..e1da5314745 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -1,18 +1,11 @@ +local decorator_registry = require("nvim-tree.renderer.decorator.registry") local notify = require("nvim-tree.notify") local utils = require("nvim-tree.utils") local view = require("nvim-tree.view") local Class = require("nvim-tree.classic") local DirectoryNode = require("nvim-tree.node.directory") - -local DecoratorBookmarks = require("nvim-tree.renderer.decorator.bookmarks") -local DecoratorCopied = require("nvim-tree.renderer.decorator.copied") -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 DecoratorUser = require("nvim-tree.renderer.decorator.user") local pad = require("nvim-tree.renderer.components.padding") @@ -56,21 +49,17 @@ function Builder:new(args) self.signs = {} self.extmarks = {} self.virtual_lines = {} - self.decorators = { - -- priority order - DecoratorCut(self.explorer), - DecoratorCopied(self.explorer), - DecoratorDiagnostics(self.explorer), - DecoratorBookmarks(self.explorer), - DecoratorModified(self.explorer), - DecoratorHidden(self.explorer), - DecoratorOpened(self.explorer), - DecoratorGit(self.explorer), - } self.hidden_display = Builder:setup_hidden_display_function(self.explorer.opts) - for _, user_decorator in ipairs(args.explorer.opts.renderer.user_decorators) do - table.insert(self.decorators, user_decorator.class()) + -- lowest priority is registered first + self.decorators = {} + local decorator_args = { explorer = self.explorer } + for _, d in ipairs(decorator_registry.registered) do + if d:is(DecoratorUser) then + table.insert(self.decorators, 1, d()) + else + table.insert(self.decorators, 1, d(decorator_args)) + end end end diff --git a/lua/nvim-tree/renderer/decorator/bookmarks.lua b/lua/nvim-tree/renderer/decorator/bookmarks.lua index 4d074e55794..f963ddbf21a 100644 --- a/lua/nvim-tree/renderer/decorator/bookmarks.lua +++ b/lua/nvim-tree/renderer/decorator/bookmarks.lua @@ -4,23 +4,24 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@field private explorer Explorer ---@field private icon HighlightedString? local DecoratorBookmarks = Decorator:extend() +DecoratorBookmarks.name = "Bookmarks" ---@class DecoratorBookmarks ---@overload fun(explorer: Explorer): DecoratorBookmarks ---@protected ----@param explorer Explorer -function DecoratorBookmarks:new(explorer) - self.explorer = explorer +---@param args DecoratorArgs +function DecoratorBookmarks:new(args) + self.explorer = args.explorer - ---@type DecoratorArgs - local args = { + ---@type AbstractDecoratorArgs + local a = { enabled = true, highlight_range = self.explorer.opts.renderer.highlight_bookmarks or "none", icon_placement = self.explorer.opts.renderer.icons.bookmarks_placement or "none", } - DecoratorBookmarks.super.new(self, args) + DecoratorBookmarks.super.new(self, a) if self.explorer.opts.renderer.icons.show.bookmarks then self.icon = { diff --git a/lua/nvim-tree/renderer/decorator/copied.lua b/lua/nvim-tree/renderer/decorator/copied.lua index 85ded7b7453..4f9210e8128 100644 --- a/lua/nvim-tree/renderer/decorator/copied.lua +++ b/lua/nvim-tree/renderer/decorator/copied.lua @@ -3,23 +3,24 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) DecoratorCopied: Decorator ---@field private explorer Explorer local DecoratorCopied = Decorator:extend() +DecoratorCopied.name = "Copied" ---@class DecoratorCopied ---@overload fun(explorer: Explorer): DecoratorCopied ---@protected ----@param explorer Explorer -function DecoratorCopied:new(explorer) - self.explorer = explorer +---@param args DecoratorArgs +function DecoratorCopied:new(args) + self.explorer = args.explorer - ---@type DecoratorArgs - local args = { + ---@type AbstractDecoratorArgs + local a = { enabled = true, highlight_range = self.explorer.opts.renderer.highlight_clipboard or "none", icon_placement = "none", } - DecoratorCopied.super.new(self, args) + DecoratorCopied.super.new(self, a) end ---Copied highlight: renderer.highlight_clipboard and node is copied diff --git a/lua/nvim-tree/renderer/decorator/cut.lua b/lua/nvim-tree/renderer/decorator/cut.lua index 4546a990a7d..3441b627359 100644 --- a/lua/nvim-tree/renderer/decorator/cut.lua +++ b/lua/nvim-tree/renderer/decorator/cut.lua @@ -3,23 +3,24 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) DecoratorCut: Decorator ---@field private explorer Explorer local DecoratorCut = Decorator:extend() +DecoratorCut.name = "Cut" ---@class DecoratorCut ---@overload fun(explorer: Explorer): DecoratorCut ---@protected ----@param explorer Explorer -function DecoratorCut:new(explorer) - self.explorer = explorer +---@param args DecoratorArgs +function DecoratorCut:new(args) + self.explorer = args.explorer - ---@type DecoratorArgs - local args = { + ---@type AbstractDecoratorArgs + local a = { enabled = true, highlight_range = self.explorer.opts.renderer.highlight_clipboard or "none", icon_placement = "none", } - DecoratorCut.super.new(self, args) + DecoratorCut.super.new(self, a) end ---Cut highlight: renderer.highlight_clipboard and node is cut diff --git a/lua/nvim-tree/renderer/decorator/diagnostics.lua b/lua/nvim-tree/renderer/decorator/diagnostics.lua index d61996bffef..ba3c3bf5f03 100644 --- a/lua/nvim-tree/renderer/decorator/diagnostics.lua +++ b/lua/nvim-tree/renderer/decorator/diagnostics.lua @@ -34,23 +34,24 @@ local ICON_KEYS = { ---@field private explorer Explorer ---@field private diag_icons HighlightedString[]? local DecoratorDiagnostics = Decorator:extend() +DecoratorDiagnostics.name = "Diagnostics" ---@class DecoratorDiagnostics ---@overload fun(explorer: Explorer): DecoratorDiagnostics ---@protected ----@param explorer Explorer -function DecoratorDiagnostics:new(explorer) - self.explorer = explorer +---@param args DecoratorArgs +function DecoratorDiagnostics:new(args) + self.explorer = args.explorer - ---@type DecoratorArgs - local args = { + ---@type AbstractDecoratorArgs + local a = { enabled = true, highlight_range = self.explorer.opts.renderer.highlight_diagnostics or "none", icon_placement = self.explorer.opts.renderer.icons.diagnostics_placement or "none", } - DecoratorDiagnostics.super.new(self, args) + DecoratorDiagnostics.super.new(self, a) if not self.enabled then return diff --git a/lua/nvim-tree/renderer/decorator/git.lua b/lua/nvim-tree/renderer/decorator/git.lua index a4e6cd7945c..6a24a1b68d0 100644 --- a/lua/nvim-tree/renderer/decorator/git.lua +++ b/lua/nvim-tree/renderer/decorator/git.lua @@ -19,23 +19,24 @@ local DirectoryNode = require("nvim-tree.node.directory") ---@field private icons_by_status GitIconsByStatus? ---@field private icons_by_xy GitIconsByXY? local DecoratorGit = Decorator:extend() +DecoratorGit.name = "Git" ---@class DecoratorGit ---@overload fun(explorer: Explorer): DecoratorGit ---@protected ----@param explorer Explorer -function DecoratorGit:new(explorer) - self.explorer = explorer +---@param args DecoratorArgs +function DecoratorGit:new(args) + self.explorer = args.explorer - ---@type DecoratorArgs - local args = { + ---@type AbstractDecoratorArgs + local a = { enabled = self.explorer.opts.git.enable, highlight_range = self.explorer.opts.renderer.highlight_git or "none", icon_placement = self.explorer.opts.renderer.icons.git_placement or "none", } - DecoratorGit.super.new(self, args) + DecoratorGit.super.new(self, a) if not self.enabled then return diff --git a/lua/nvim-tree/renderer/decorator/hidden.lua b/lua/nvim-tree/renderer/decorator/hidden.lua index 0c4c8fe1507..98d25c6d524 100644 --- a/lua/nvim-tree/renderer/decorator/hidden.lua +++ b/lua/nvim-tree/renderer/decorator/hidden.lua @@ -5,23 +5,24 @@ local DirectoryNode = require("nvim-tree.node.directory") ---@field private explorer Explorer ---@field private icon HighlightedString? local DecoratorHidden = Decorator:extend() +DecoratorHidden.name = "Hidden" ---@class DecoratorHidden ---@overload fun(explorer: Explorer): DecoratorHidden ---@protected ----@param explorer Explorer -function DecoratorHidden:new(explorer) - self.explorer = explorer +---@param args DecoratorArgs +function DecoratorHidden:new(args) + self.explorer = args.explorer - ---@type DecoratorArgs - local args = { + ---@type AbstractDecoratorArgs + local a = { enabled = true, highlight_range = self.explorer.opts.renderer.highlight_hidden or "none", icon_placement = self.explorer.opts.renderer.icons.hidden_placement or "none", } - DecoratorHidden.super.new(self, args) + DecoratorHidden.super.new(self, a) if self.explorer.opts.renderer.icons.show.hidden then self.icon = { diff --git a/lua/nvim-tree/renderer/decorator/init.lua b/lua/nvim-tree/renderer/decorator/init.lua index adfd01dc96d..70093017575 100644 --- a/lua/nvim-tree/renderer/decorator/init.lua +++ b/lua/nvim-tree/renderer/decorator/init.lua @@ -2,18 +2,22 @@ local Class = require("nvim-tree.classic") ---Abstract Decorator ---@class (exact) Decorator: Class +---@field name string for registry ---@field protected enabled boolean ---@field protected highlight_range DecoratorHighlightRange ---@field protected icon_placement DecoratorIconPlacement local Decorator = Class:extend() ---@class (exact) DecoratorArgs +---@field explorer Explorer +--- +---@class (exact) AbstractDecoratorArgs ---@field enabled boolean ---@field highlight_range DecoratorHighlightRange ---@field icon_placement DecoratorIconPlacement ---@protected ----@param args DecoratorArgs +---@param args AbstractDecoratorArgs function Decorator:new(args) if args then self.enabled = args.enabled diff --git a/lua/nvim-tree/renderer/decorator/modified.lua b/lua/nvim-tree/renderer/decorator/modified.lua index da55f19adf7..667cf45217d 100644 --- a/lua/nvim-tree/renderer/decorator/modified.lua +++ b/lua/nvim-tree/renderer/decorator/modified.lua @@ -7,23 +7,24 @@ local DirectoryNode = require("nvim-tree.node.directory") ---@field private explorer Explorer ---@field private icon HighlightedString? local DecoratorModified = Decorator:extend() +DecoratorModified.name = "Modified" ---@class DecoratorModified ---@overload fun(explorer: Explorer): DecoratorModified ---@protected ----@param explorer Explorer -function DecoratorModified:new(explorer) - self.explorer = explorer +---@param args DecoratorArgs +function DecoratorModified:new(args) + self.explorer = args.explorer - ---@type DecoratorArgs - local args = { + ---@type AbstractDecoratorArgs + local a = { enabled = true, highlight_range = self.explorer.opts.renderer.highlight_modified or "none", icon_placement = self.explorer.opts.renderer.icons.modified_placement or "none", } - DecoratorModified.super.new(self, args) + DecoratorModified.super.new(self, a) if not self.enabled then return diff --git a/lua/nvim-tree/renderer/decorator/opened.lua b/lua/nvim-tree/renderer/decorator/opened.lua index 7a02c6d4c99..04e2f989b28 100644 --- a/lua/nvim-tree/renderer/decorator/opened.lua +++ b/lua/nvim-tree/renderer/decorator/opened.lua @@ -6,23 +6,24 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@field private explorer Explorer ---@field private icon HighlightedString|nil local DecoratorOpened = Decorator:extend() +DecoratorOpened.name = "Opened" ---@class DecoratorOpened ---@overload fun(explorer: Explorer): DecoratorOpened ---@protected ----@param explorer Explorer -function DecoratorOpened:new(explorer) - self.explorer = explorer +---@param args DecoratorArgs +function DecoratorOpened:new(args) + self.explorer = args.explorer - ---@type DecoratorArgs - local args = { + ---@type AbstractDecoratorArgs + local a = { enabled = true, highlight_range = self.explorer.opts.renderer.highlight_opened_files or "none", icon_placement = "none", } - DecoratorOpened.super.new(self, args) + DecoratorOpened.super.new(self, a) end ---Opened highlight: renderer.highlight_opened_files and node has an open buffer diff --git a/lua/nvim-tree/renderer/decorator/registry.lua b/lua/nvim-tree/renderer/decorator/registry.lua new file mode 100644 index 00000000000..5c94a31b4ac --- /dev/null +++ b/lua/nvim-tree/renderer/decorator/registry.lua @@ -0,0 +1,71 @@ +local notify = require("nvim-tree.notify") +local utils = require("nvim-tree.utils") + +local DecoratorBookmarks = require("nvim-tree.renderer.decorator.bookmarks") +local DecoratorCopied = require("nvim-tree.renderer.decorator.copied") +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 DecoratorUser = require("nvim-tree.renderer.decorator.user") + +-- Globally registered decorators including user +-- Lowest priority first + +---@alias DecoratorName nvim_tree.api.decorator.BaseDecorator | "Cut" | "Copied" | "Diagnostics" | "Bookmarks" | "Modified" | "Hidden" | "Opened" | "Git" + +local M = { + ---@type Decorator[] + registered = { + DecoratorGit, + DecoratorOpened, + DecoratorHidden, + DecoratorModified, + DecoratorBookmarks, + DecoratorDiagnostics, + DecoratorCopied, + DecoratorCut, + } +} + +---@class RegisterOpts +---@field decorator nvim_tree.api.decorator.BaseDecorator +---@field below DecoratorName? + +---@param opts RegisterOpts +function M.register(opts) + if not opts or not opts.decorator then + return + end + + if vim.tbl_contains(M.registered, opts.decorator) then + notify.error("decorator already registered") + return + end + + for i, d in ipairs(M.registered) do + if d:is(DecoratorUser) and d == opts.below or d.name == opts.below then + table.insert(M.registered, i, opts.decorator) + return + end + end + + -- default to highest at the top + table.insert(M.registered, opts.decorator) +end + +---@class UnRegisterOpts +---@field decorator nvim_tree.api.decorator.BaseDecorator + +---@param opts UnRegisterOpts +function M.unregister(opts) + if not opts or not opts.decorator then + return + end + + utils.array_remove(M.registered, opts.decorator) +end + +return M diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index 536725ed4b5..5dcbb7b82fc 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -1,24 +1,7 @@ local Decorator = require("nvim-tree.renderer.decorator") ----@class (exact) UserDecorator: Decorator -local UserDecorator = Decorator:extend() +---Exposed as nvim_tree.api.decorator.BaseDecorator +---@class (exact) DecoratorUser: Decorator +local DecoratorUser = Decorator:extend() ----@param node nvim_tree.api.Node ----@return HighlightedString? icon_node -function UserDecorator:icon_node(node) - return self:nop(node) -end - ----@param node nvim_tree.api.Node ----@return HighlightedString[]? icons -function UserDecorator:icons(node) - self:nop(node) -end - ----@param node nvim_tree.api.Node ----@return string? highlight_group -function UserDecorator:highlight_group(node) - self:nop(node) -end - -return UserDecorator +return DecoratorUser From 8e1e2aa6f86df356ffb823874b95c19fe98d6f64 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 24 Nov 2024 15:19:34 +1100 Subject: [PATCH 12/27] feat(#2948): add decorator registry and order --- lua/nvim-tree/_meta/api_decorator.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua index 5c4fed680df..819d276aa8f 100644 --- a/lua/nvim-tree/_meta/api_decorator.lua +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -1,5 +1,5 @@ ---@meta -error('Cannot require a meta file') +error("Cannot require a meta file") local nvim_tree = { api = { decorator = { BaseDecorator = {} } } } @@ -61,7 +61,6 @@ function nvim_tree.api.decorator.BaseDecorator:icons(node) end ---@return string? highlight_group function nvim_tree.api.decorator.BaseDecorator:highlight_group(node) end - -- -- Example Decorator -- From 294a96e020db323073133faa6f85c1398512d200 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 24 Nov 2024 17:03:59 +1100 Subject: [PATCH 13/27] feat(#2948): tidy --- lua/nvim-tree/renderer/decorator/bookmarks.lua | 2 +- lua/nvim-tree/renderer/decorator/copied.lua | 2 +- lua/nvim-tree/renderer/decorator/cut.lua | 2 +- lua/nvim-tree/renderer/decorator/diagnostics.lua | 2 +- lua/nvim-tree/renderer/decorator/git.lua | 2 +- lua/nvim-tree/renderer/decorator/hidden.lua | 2 +- lua/nvim-tree/renderer/decorator/modified.lua | 2 +- lua/nvim-tree/renderer/decorator/opened.lua | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lua/nvim-tree/renderer/decorator/bookmarks.lua b/lua/nvim-tree/renderer/decorator/bookmarks.lua index f963ddbf21a..ab8f41d9d20 100644 --- a/lua/nvim-tree/renderer/decorator/bookmarks.lua +++ b/lua/nvim-tree/renderer/decorator/bookmarks.lua @@ -7,7 +7,7 @@ local DecoratorBookmarks = Decorator:extend() DecoratorBookmarks.name = "Bookmarks" ---@class DecoratorBookmarks ----@overload fun(explorer: Explorer): DecoratorBookmarks +---@overload fun(args: DecoratorArgs): DecoratorBookmarks ---@protected ---@param args DecoratorArgs diff --git a/lua/nvim-tree/renderer/decorator/copied.lua b/lua/nvim-tree/renderer/decorator/copied.lua index 4f9210e8128..8c6ad15995f 100644 --- a/lua/nvim-tree/renderer/decorator/copied.lua +++ b/lua/nvim-tree/renderer/decorator/copied.lua @@ -6,7 +6,7 @@ local DecoratorCopied = Decorator:extend() DecoratorCopied.name = "Copied" ---@class DecoratorCopied ----@overload fun(explorer: Explorer): DecoratorCopied +---@overload fun(args: DecoratorArgs): DecoratorCopied ---@protected ---@param args DecoratorArgs diff --git a/lua/nvim-tree/renderer/decorator/cut.lua b/lua/nvim-tree/renderer/decorator/cut.lua index 3441b627359..0f2af987fb1 100644 --- a/lua/nvim-tree/renderer/decorator/cut.lua +++ b/lua/nvim-tree/renderer/decorator/cut.lua @@ -6,7 +6,7 @@ local DecoratorCut = Decorator:extend() DecoratorCut.name = "Cut" ---@class DecoratorCut ----@overload fun(explorer: Explorer): DecoratorCut +---@overload fun(args: DecoratorArgs): DecoratorCut ---@protected ---@param args DecoratorArgs diff --git a/lua/nvim-tree/renderer/decorator/diagnostics.lua b/lua/nvim-tree/renderer/decorator/diagnostics.lua index ba3c3bf5f03..6fbf087d7e1 100644 --- a/lua/nvim-tree/renderer/decorator/diagnostics.lua +++ b/lua/nvim-tree/renderer/decorator/diagnostics.lua @@ -37,7 +37,7 @@ local DecoratorDiagnostics = Decorator:extend() DecoratorDiagnostics.name = "Diagnostics" ---@class DecoratorDiagnostics ----@overload fun(explorer: Explorer): DecoratorDiagnostics +---@overload fun(args: DecoratorArgs): DecoratorDiagnostics ---@protected ---@param args DecoratorArgs diff --git a/lua/nvim-tree/renderer/decorator/git.lua b/lua/nvim-tree/renderer/decorator/git.lua index 6a24a1b68d0..47f22536f1f 100644 --- a/lua/nvim-tree/renderer/decorator/git.lua +++ b/lua/nvim-tree/renderer/decorator/git.lua @@ -22,7 +22,7 @@ local DecoratorGit = Decorator:extend() DecoratorGit.name = "Git" ---@class DecoratorGit ----@overload fun(explorer: Explorer): DecoratorGit +---@overload fun(args: DecoratorArgs): DecoratorGit ---@protected ---@param args DecoratorArgs diff --git a/lua/nvim-tree/renderer/decorator/hidden.lua b/lua/nvim-tree/renderer/decorator/hidden.lua index 98d25c6d524..c83a20151f7 100644 --- a/lua/nvim-tree/renderer/decorator/hidden.lua +++ b/lua/nvim-tree/renderer/decorator/hidden.lua @@ -8,7 +8,7 @@ local DecoratorHidden = Decorator:extend() DecoratorHidden.name = "Hidden" ---@class DecoratorHidden ----@overload fun(explorer: Explorer): DecoratorHidden +---@overload fun(args: DecoratorArgs): DecoratorHidden ---@protected ---@param args DecoratorArgs diff --git a/lua/nvim-tree/renderer/decorator/modified.lua b/lua/nvim-tree/renderer/decorator/modified.lua index 667cf45217d..e761fff7ac0 100644 --- a/lua/nvim-tree/renderer/decorator/modified.lua +++ b/lua/nvim-tree/renderer/decorator/modified.lua @@ -10,7 +10,7 @@ local DecoratorModified = Decorator:extend() DecoratorModified.name = "Modified" ---@class DecoratorModified ----@overload fun(explorer: Explorer): DecoratorModified +---@overload fun(args: DecoratorArgs): DecoratorModified ---@protected ---@param args DecoratorArgs diff --git a/lua/nvim-tree/renderer/decorator/opened.lua b/lua/nvim-tree/renderer/decorator/opened.lua index 04e2f989b28..56996d8368d 100644 --- a/lua/nvim-tree/renderer/decorator/opened.lua +++ b/lua/nvim-tree/renderer/decorator/opened.lua @@ -9,7 +9,7 @@ local DecoratorOpened = Decorator:extend() DecoratorOpened.name = "Opened" ---@class DecoratorOpened ----@overload fun(explorer: Explorer): DecoratorOpened +---@overload fun(args: DecoratorArgs): DecoratorOpened ---@protected ---@param args DecoratorArgs From 93cf3f9f427d5aa826824b8de88ecf1dc3e20329 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 24 Nov 2024 17:49:35 +1100 Subject: [PATCH 14/27] feat(#2948): document API --- lua/nvim-tree/_meta/api_decorator.lua | 64 +++++++++---------- lua/nvim-tree/api.lua | 27 ++++++-- lua/nvim-tree/renderer/decorator/registry.lua | 15 +---- lua/nvim-tree/renderer/decorator/user.lua | 6 ++ 4 files changed, 58 insertions(+), 54 deletions(-) diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua index 819d276aa8f..253e3da1b23 100644 --- a/lua/nvim-tree/_meta/api_decorator.lua +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -3,60 +3,56 @@ error("Cannot require a meta file") local nvim_tree = { api = { decorator = { BaseDecorator = {} } } } +---Create a custom decorator, extending nvim_tree.api.decorator.BaseDecorator +---It may: +--- Add icons +--- Set name highlight group +--- Override node icon +---Class must be created via nvim_tree.api.decorator.create() +---Mandatory constructor :new() will be called once per tree render, with no arguments. +---Constructor must call: +--- :init +--- :define_sign when using "signcolumn" range + ---Highlight group range as per nvim-tree.renderer.highlight_* ---@alias nvim_tree.api.decorator.HighlightRange "none" | "icon" | "name" | "all" ---Icon position as per renderer.icons.*_placement ---@alias nvim_tree.api.decorator.IconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" --- --- BaseDecorator Class, see example implementation below --- +---Names of predefined decorators or your decorator classes +---@alias nvim_tree.api.decorator.Name "Cut" | "Copied" | "Diagnostics" | "Bookmarks" | "Modified" | "Hidden" | "Opened" | "Git" | nvim_tree.api.decorator.BaseDecorator ----User defined decorator to optionally add: ---- Additional icons ---- Name highlight group ---- Node icon override ----Class must be created via nvim_tree.api.decorator.BaseDecorator:extend() ----Mandatory constructor :new() will be called once per tree render, with no arguments. ----Constructor must call: ---- .super.new(self, args) passing nvim_tree.api.decorator.BaseDecoratorArgs ---- :define_sign(...) when using "signcolumn" range +---BaseDecorator Class, your decorator will extend this ---@class (exact) nvim_tree.api.decorator.BaseDecorator ---@field protected enabled boolean ---@field protected highlight_range nvim_tree.api.decorator.HighlightRange ---@field protected icon_placement nvim_tree.api.decorator.IconPlacement ----Constructor Arguments ----@class (exact) nvim_tree.api.decorator.BaseDecoratorArgs +---No-args constructor must be implemented +function nvim_tree.api.decorator.BaseDecorator:new() end + +---Must be called from your constructor +---@class (exact) nvim_tree.api.decorator.InitArgs ---@field enabled boolean ---@field highlight_range nvim_tree.api.decorator.HighlightRange ---@field icon_placement nvim_tree.api.decorator.IconPlacement - ----Use to instantiate your decorator class -function nvim_tree.api.decorator.BaseDecorator:extend() end - ----Super constructor must be called from your constructor ----BaseDecorator.super.new(self, args) +--- ---@protected ----@param self nvim_tree.api.decorator.BaseDecorator your instance ----@param args nvim_tree.api.decorator.BaseDecoratorArgs -function nvim_tree.api.decorator.BaseDecorator.new(self, args) end +---@param args nvim_tree.api.decorator.InitArgs +function nvim_tree.api.decorator.BaseDecorator:init(args) end ----Must implement a constructor and call super -function nvim_tree.api.decorator.BaseDecorator:new() end - ----Implement this method to set the node's icon +---Optionally implement this method to set the node's icon ---@param node nvim_tree.api.Node ---@return HighlightedString? icon_node function nvim_tree.api.decorator.BaseDecorator:icon_node(node) end ----Implement this method to provide icons and the highlight groups to apply to IconPlacement +---Optionally implement this method to provide icons and the highlight groups for your icon_placement ---@param node nvim_tree.api.Node ---@return HighlightedString[]? icons function nvim_tree.api.decorator.BaseDecorator:icons(node) end ----Implement this method to provide one highlight group to apply to HighlightRange +---Optionally implement this method to provide one highlight group to apply to your highlight_range ---@param node nvim_tree.api.Node ---@return string? highlight_group function nvim_tree.api.decorator.BaseDecorator:highlight_group(node) end @@ -65,23 +61,21 @@ function nvim_tree.api.decorator.BaseDecorator:highlight_group(node) end -- Example Decorator -- -local BaseDecorator = require("nvim-tree.api").decorator.BaseDecorator - ---@class (exact) MyDecorator: nvim_tree.api.decorator.BaseDecorator ---@field private my_icon nvim_tree.api.HighlightedString -local MyDecorator = BaseDecorator:extend() +local MyDecorator = require("nvim-tree.api").decorator.create() ---Mandatory constructor :new() will be called once per tree render, with no arguments. function MyDecorator:new() - ----@type nvim_tree.api.decorator.BaseDecoratorArgs + ---@type nvim_tree.api.decorator.InitArgs local args = { enabled = true, highlight_range = "all", icon_placement = "signcolumn", } - -- construct super with args - BaseDecorator.new(self, args) + -- init + self:init(args) -- create your icon once, for convenience self.my_icon = { str = "I", hl = { "MyIcon" } } diff --git a/lua/nvim-tree/api.lua b/lua/nvim-tree/api.lua index 9e3fdc989c7..64d778339bd 100644 --- a/lua/nvim-tree/api.lua +++ b/lua/nvim-tree/api.lua @@ -12,6 +12,7 @@ local decorator_registry = require("nvim-tree.renderer.decorator.registry") local DirectoryNode = require("nvim-tree.node.directory") local FileLinkNode = require("nvim-tree.node.file-link") local RootNode = require("nvim-tree.node.root") +local DecoratorUser = require("nvim-tree.renderer.decorator.user") local Api = { tree = {}, @@ -313,10 +314,26 @@ Api.commands.get = wrap(function() return require("nvim-tree.commands").get() end) --- TODO provide a registration convenience to hide classic --- TODO add doc -Api.decorator.BaseDecorator = require("nvim-tree.renderer.decorator.user") --[[@as nvim_tree.api.decorator.BaseDecorator ]] -Api.decorator.register = decorator_registry.register -Api.decorator.unregister = decorator_registry.unregister +---Create a new decorator class +--- +---@return nvim_tree.api.decorator.BaseDecorator +Api.decorator.create = function() return DecoratorUser:extend() end + +---Register a decorator class +--- +---@class RegisterOpts +---@field decorator nvim_tree.api.decorator.BaseDecorator +---@field below nvim_tree.api.decorator.Name? +--- +---@param opts RegisterOpts +Api.decorator.register = function(opts) decorator_registry.register(opts) end + +---Unregister a decorator class +--- +---@class UnRegisterOpts +---@field decorator nvim_tree.api.decorator.BaseDecorator +--- +---@param opts UnRegisterOpts +Api.decorator.unregister = function(opts) decorator_registry.unregister(opts) end return Api diff --git a/lua/nvim-tree/renderer/decorator/registry.lua b/lua/nvim-tree/renderer/decorator/registry.lua index 5c94a31b4ac..dec70621235 100644 --- a/lua/nvim-tree/renderer/decorator/registry.lua +++ b/lua/nvim-tree/renderer/decorator/registry.lua @@ -1,4 +1,3 @@ -local notify = require("nvim-tree.notify") local utils = require("nvim-tree.utils") local DecoratorBookmarks = require("nvim-tree.renderer.decorator.bookmarks") @@ -11,12 +10,8 @@ local DecoratorHidden = require("nvim-tree.renderer.decorator.hidden") local DecoratorOpened = require("nvim-tree.renderer.decorator.opened") local DecoratorUser = require("nvim-tree.renderer.decorator.user") --- Globally registered decorators including user --- Lowest priority first - ----@alias DecoratorName nvim_tree.api.decorator.BaseDecorator | "Cut" | "Copied" | "Diagnostics" | "Bookmarks" | "Modified" | "Hidden" | "Opened" | "Git" - local M = { + -- Globally registered decorators including user. Lowest priority first. ---@type Decorator[] registered = { DecoratorGit, @@ -30,10 +25,6 @@ local M = { } } ----@class RegisterOpts ----@field decorator nvim_tree.api.decorator.BaseDecorator ----@field below DecoratorName? - ---@param opts RegisterOpts function M.register(opts) if not opts or not opts.decorator then @@ -41,7 +32,6 @@ function M.register(opts) end if vim.tbl_contains(M.registered, opts.decorator) then - notify.error("decorator already registered") return end @@ -56,9 +46,6 @@ function M.register(opts) table.insert(M.registered, opts.decorator) end ----@class UnRegisterOpts ----@field decorator nvim_tree.api.decorator.BaseDecorator - ---@param opts UnRegisterOpts function M.unregister(opts) if not opts or not opts.decorator then diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index 5dcbb7b82fc..61915d44b09 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -4,4 +4,10 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) DecoratorUser: Decorator local DecoratorUser = Decorator:extend() +---User calls this instead of new +---@param args nvim_tree.api.decorator.InitArgs +function DecoratorUser:init(args) + DecoratorUser.super.new(self, args) +end + return DecoratorUser From 8b5f3428842437fc82283c5805e5ff0f6212654d Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 25 Nov 2024 09:37:39 +1100 Subject: [PATCH 15/27] feat(#2948): document API --- lua/nvim-tree/_meta/api_decorator.lua | 9 ++++++++- lua/nvim-tree/renderer/builder.lua | 6 ++++-- lua/nvim-tree/renderer/decorator/init.lua | 5 +++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua index 253e3da1b23..1e26b602657 100644 --- a/lua/nvim-tree/_meta/api_decorator.lua +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -3,7 +3,7 @@ error("Cannot require a meta file") local nvim_tree = { api = { decorator = { BaseDecorator = {} } } } ----Create a custom decorator, extending nvim_tree.api.decorator.BaseDecorator +---Custom decorator extends nvim_tree.api.decorator.BaseDecorator ---It may: --- Add icons --- Set name highlight group @@ -24,15 +24,18 @@ local nvim_tree = { api = { decorator = { BaseDecorator = {} } } } ---@alias nvim_tree.api.decorator.Name "Cut" | "Copied" | "Diagnostics" | "Bookmarks" | "Modified" | "Hidden" | "Opened" | "Git" | nvim_tree.api.decorator.BaseDecorator ---BaseDecorator Class, your decorator will extend this +--- ---@class (exact) nvim_tree.api.decorator.BaseDecorator ---@field protected enabled boolean ---@field protected highlight_range nvim_tree.api.decorator.HighlightRange ---@field protected icon_placement nvim_tree.api.decorator.IconPlacement ---No-args constructor must be implemented +--- function nvim_tree.api.decorator.BaseDecorator:new() end ---Must be called from your constructor +--- ---@class (exact) nvim_tree.api.decorator.InitArgs ---@field enabled boolean ---@field highlight_range nvim_tree.api.decorator.HighlightRange @@ -43,20 +46,24 @@ function nvim_tree.api.decorator.BaseDecorator:new() end function nvim_tree.api.decorator.BaseDecorator:init(args) end ---Optionally implement this method to set the node's icon +--- ---@param node nvim_tree.api.Node ---@return HighlightedString? icon_node function nvim_tree.api.decorator.BaseDecorator:icon_node(node) end ---Optionally implement this method to provide icons and the highlight groups for your icon_placement +--- ---@param node nvim_tree.api.Node ---@return HighlightedString[]? icons function nvim_tree.api.decorator.BaseDecorator:icons(node) end ---Optionally implement this method to provide one highlight group to apply to your highlight_range +--- ---@param node nvim_tree.api.Node ---@return string? highlight_group function nvim_tree.api.decorator.BaseDecorator:highlight_group(node) end + -- -- Example Decorator -- diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index e1da5314745..306c2ebfb46 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -49,11 +49,13 @@ function Builder:new(args) self.signs = {} self.extmarks = {} self.virtual_lines = {} + self.decorators = {} self.hidden_display = Builder:setup_hidden_display_function(self.explorer.opts) - -- lowest priority is registered first - self.decorators = {} + ---@type DecoratorArgs local decorator_args = { explorer = self.explorer } + + -- lowest priority is registered first for _, d in ipairs(decorator_registry.registered) do if d:is(DecoratorUser) then table.insert(self.decorators, 1, d()) diff --git a/lua/nvim-tree/renderer/decorator/init.lua b/lua/nvim-tree/renderer/decorator/init.lua index 70093017575..12f441b3e0b 100644 --- a/lua/nvim-tree/renderer/decorator/init.lua +++ b/lua/nvim-tree/renderer/decorator/init.lua @@ -10,12 +10,13 @@ local Decorator = Class:extend() ---@class (exact) DecoratorArgs ---@field explorer Explorer ---- + +---Abstract constructor ---@class (exact) AbstractDecoratorArgs ---@field enabled boolean ---@field highlight_range DecoratorHighlightRange ---@field icon_placement DecoratorIconPlacement - +--- ---@protected ---@param args AbstractDecoratorArgs function Decorator:new(args) From 3ab398066fa1773ef3bc17a1fa7dd93400ea2e97 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 25 Nov 2024 09:57:17 +1100 Subject: [PATCH 16/27] feat(#2948): document API --- lua/nvim-tree/_meta/api_decorator.lua | 36 +++++++++++------------ lua/nvim-tree/api.lua | 6 ++-- lua/nvim-tree/renderer/decorator/user.lua | 4 +-- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua index 1e26b602657..b111999e072 100644 --- a/lua/nvim-tree/_meta/api_decorator.lua +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -1,9 +1,9 @@ ---@meta error("Cannot require a meta file") -local nvim_tree = { api = { decorator = { BaseDecorator = {} } } } +local nvim_tree = { api = { decorator = { AbstractDecorator = {} } } } ----Custom decorator extends nvim_tree.api.decorator.BaseDecorator +---Custom decorator extends nvim_tree.api.decorator.AbstractDecorator ---It may: --- Add icons --- Set name highlight group @@ -21,60 +21,60 @@ local nvim_tree = { api = { decorator = { BaseDecorator = {} } } } ---@alias nvim_tree.api.decorator.IconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" ---Names of predefined decorators or your decorator classes ----@alias nvim_tree.api.decorator.Name "Cut" | "Copied" | "Diagnostics" | "Bookmarks" | "Modified" | "Hidden" | "Opened" | "Git" | nvim_tree.api.decorator.BaseDecorator +---@alias nvim_tree.api.decorator.Name "Cut" | "Copied" | "Diagnostics" | "Bookmarks" | "Modified" | "Hidden" | "Opened" | "Git" | nvim_tree.api.decorator.AbstractDecorator ----BaseDecorator Class, your decorator will extend this +---Abstract decorator class, your decorator will extend this --- ----@class (exact) nvim_tree.api.decorator.BaseDecorator +---@class (exact) nvim_tree.api.decorator.AbstractDecorator ---@field protected enabled boolean ---@field protected highlight_range nvim_tree.api.decorator.HighlightRange ---@field protected icon_placement nvim_tree.api.decorator.IconPlacement ----No-args constructor must be implemented +---Abstract no-args constructor must be implemented --- -function nvim_tree.api.decorator.BaseDecorator:new() end +function nvim_tree.api.decorator.AbstractDecorator:new() end ---Must be called from your constructor --- ----@class (exact) nvim_tree.api.decorator.InitArgs +---@class (exact) nvim_tree.api.decorator.AbstractDecoratorInitArgs ---@field enabled boolean ---@field highlight_range nvim_tree.api.decorator.HighlightRange ---@field icon_placement nvim_tree.api.decorator.IconPlacement --- ---@protected ----@param args nvim_tree.api.decorator.InitArgs -function nvim_tree.api.decorator.BaseDecorator:init(args) end +---@param args nvim_tree.api.decorator.AbstractDecoratorInitArgs +function nvim_tree.api.decorator.AbstractDecorator:init(args) end ----Optionally implement this method to set the node's icon +---Abstract: optionally implement to set the node's icon --- ---@param node nvim_tree.api.Node ---@return HighlightedString? icon_node -function nvim_tree.api.decorator.BaseDecorator:icon_node(node) end +function nvim_tree.api.decorator.AbstractDecorator:icon_node(node) end ----Optionally implement this method to provide icons and the highlight groups for your icon_placement +---Abstract: optionally implement to provide icons and the highlight groups for your icon_placement --- ---@param node nvim_tree.api.Node ---@return HighlightedString[]? icons -function nvim_tree.api.decorator.BaseDecorator:icons(node) end +function nvim_tree.api.decorator.AbstractDecorator:icons(node) end ----Optionally implement this method to provide one highlight group to apply to your highlight_range +---Abstract: optionally implement to provide one highlight group to apply to your highlight_range --- ---@param node nvim_tree.api.Node ---@return string? highlight_group -function nvim_tree.api.decorator.BaseDecorator:highlight_group(node) end +function nvim_tree.api.decorator.AbstractDecorator:highlight_group(node) end -- -- Example Decorator -- ----@class (exact) MyDecorator: nvim_tree.api.decorator.BaseDecorator +---@class (exact) MyDecorator: nvim_tree.api.decorator.AbstractDecorator ---@field private my_icon nvim_tree.api.HighlightedString local MyDecorator = require("nvim-tree.api").decorator.create() ---Mandatory constructor :new() will be called once per tree render, with no arguments. function MyDecorator:new() - ---@type nvim_tree.api.decorator.InitArgs + ---@type nvim_tree.api.decorator.AbstractDecoratorInitArgs local args = { enabled = true, highlight_range = "all", diff --git a/lua/nvim-tree/api.lua b/lua/nvim-tree/api.lua index 64d778339bd..3b3eb667e8d 100644 --- a/lua/nvim-tree/api.lua +++ b/lua/nvim-tree/api.lua @@ -316,13 +316,13 @@ end) ---Create a new decorator class --- ----@return nvim_tree.api.decorator.BaseDecorator +---@return nvim_tree.api.decorator.AbstractDecorator Api.decorator.create = function() return DecoratorUser:extend() end ---Register a decorator class --- ---@class RegisterOpts ----@field decorator nvim_tree.api.decorator.BaseDecorator +---@field decorator nvim_tree.api.decorator.AbstractDecorator ---@field below nvim_tree.api.decorator.Name? --- ---@param opts RegisterOpts @@ -331,7 +331,7 @@ Api.decorator.register = function(opts) decorator_registry.register(opts) end ---Unregister a decorator class --- ---@class UnRegisterOpts ----@field decorator nvim_tree.api.decorator.BaseDecorator +---@field decorator nvim_tree.api.decorator.AbstractDecorator --- ---@param opts UnRegisterOpts Api.decorator.unregister = function(opts) decorator_registry.unregister(opts) end diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index 61915d44b09..98e7cbadc42 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -1,11 +1,11 @@ local Decorator = require("nvim-tree.renderer.decorator") ----Exposed as nvim_tree.api.decorator.BaseDecorator +---Exposed as nvim_tree.api.decorator.AbstractDecorator ---@class (exact) DecoratorUser: Decorator local DecoratorUser = Decorator:extend() ---User calls this instead of new ----@param args nvim_tree.api.decorator.InitArgs +---@param args nvim_tree.api.decorator.AbstractDecoratorInitArgs function DecoratorUser:init(args) DecoratorUser.super.new(self, args) end From 6148f69dd826af38deecb35a32f86b0b63580010 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 25 Nov 2024 12:28:03 +1100 Subject: [PATCH 17/27] feat(#2948): pass api nodes to user decorators --- lua/nvim-tree/_meta/api_decorator.lua | 4 ++- lua/nvim-tree/node/directory-link.lua | 5 +-- lua/nvim-tree/node/directory.lua | 7 ++-- lua/nvim-tree/node/file-link.lua | 5 +-- lua/nvim-tree/node/file.lua | 5 +-- lua/nvim-tree/node/init.lua | 7 +++- lua/nvim-tree/node/root.lua | 5 +-- lua/nvim-tree/renderer/builder.lua | 51 ++++++++++++++++++--------- 8 files changed, 60 insertions(+), 29 deletions(-) diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua index b111999e072..b14dfd256c8 100644 --- a/lua/nvim-tree/_meta/api_decorator.lua +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -13,6 +13,7 @@ local nvim_tree = { api = { decorator = { AbstractDecorator = {} } } } ---Constructor must call: --- :init --- :define_sign when using "signcolumn" range +---Decorator must be registered via api.decorator.register ---Highlight group range as per nvim-tree.renderer.highlight_* ---@alias nvim_tree.api.decorator.HighlightRange "none" | "icon" | "name" | "all" @@ -125,4 +126,5 @@ function MyDecorator:highlight_group(node) end end -return MyDecorator +---Register the decorator, below Cut in priority +require("nvim-tree.api").decorator.register({ decorator = MyDecorator, below = "Cut" }) diff --git a/lua/nvim-tree/node/directory-link.lua b/lua/nvim-tree/node/directory-link.lua index 81f5dc9a998..9666ca4d7c2 100644 --- a/lua/nvim-tree/node/directory-link.lua +++ b/lua/nvim-tree/node/directory-link.lua @@ -73,9 +73,10 @@ function DirectoryLinkNode:highlighted_name() end ---Create a sanitized partial copy of a node, populating children recursively. +---@param api_nodes table? optional map of uids to api node to populate ---@return nvim_tree.api.DirectoryLinkNode cloned -function DirectoryLinkNode:clone() - local clone = DirectoryNode.clone(self) --[[@as nvim_tree.api.DirectoryLinkNode]] +function DirectoryLinkNode:clone(api_nodes) + local clone = DirectoryNode.clone(self, api_nodes) --[[@as nvim_tree.api.DirectoryLinkNode]] clone.link_to = self.link_to clone.fs_stat_target = self.fs_stat_target diff --git a/lua/nvim-tree/node/directory.lua b/lua/nvim-tree/node/directory.lua index 866792d7788..0965e4ab9fc 100644 --- a/lua/nvim-tree/node/directory.lua +++ b/lua/nvim-tree/node/directory.lua @@ -271,9 +271,10 @@ function DirectoryNode:highlighted_name() end ---Create a sanitized partial copy of a node, populating children recursively. +---@param api_nodes table? optional map of uids to api node to populate ---@return nvim_tree.api.DirectoryNode cloned -function DirectoryNode:clone() - local clone = Node.clone(self) --[[@as nvim_tree.api.DirectoryNode]] +function DirectoryNode:clone(api_nodes) + local clone = Node.clone(self, api_nodes) --[[@as nvim_tree.api.DirectoryNode]] clone.has_children = self.has_children clone.nodes = {} @@ -281,7 +282,7 @@ function DirectoryNode:clone() local clone_child for _, child in ipairs(self.nodes) do - clone_child = child:clone() + clone_child = child:clone(api_nodes) clone_child.parent = clone table.insert(clone.nodes, clone_child) end diff --git a/lua/nvim-tree/node/file-link.lua b/lua/nvim-tree/node/file-link.lua index 9b68d5e9d3d..b13c88f0d6b 100644 --- a/lua/nvim-tree/node/file-link.lua +++ b/lua/nvim-tree/node/file-link.lua @@ -58,9 +58,10 @@ function FileLinkNode:highlighted_name() end ---Create a sanitized partial copy of a node +---@param api_nodes table? optional map of uids to api node to populate ---@return nvim_tree.api.FileLinkNode cloned -function FileLinkNode:clone() - local clone = FileNode.clone(self) --[[@as nvim_tree.api.FileLinkNode]] +function FileLinkNode:clone(api_nodes) + local clone = FileNode.clone(self, api_nodes) --[[@as nvim_tree.api.FileLinkNode]] clone.link_to = self.link_to clone.fs_stat_target = self.fs_stat_target diff --git a/lua/nvim-tree/node/file.lua b/lua/nvim-tree/node/file.lua index 6c3567f7cbc..6e160409c29 100644 --- a/lua/nvim-tree/node/file.lua +++ b/lua/nvim-tree/node/file.lua @@ -94,9 +94,10 @@ function FileNode:highlighted_name() end ---Create a sanitized partial copy of a node +---@param api_nodes table? optional map of uids to api node to populate ---@return nvim_tree.api.FileNode cloned -function FileNode:clone() - local clone = Node.clone(self) --[[@as nvim_tree.api.FileNode]] +function FileNode:clone(api_nodes) + local clone = Node.clone(self, api_nodes) --[[@as nvim_tree.api.FileNode]] clone.extension = self.extension diff --git a/lua/nvim-tree/node/init.lua b/lua/nvim-tree/node/init.lua index 2a9eda56896..f8898d12691 100644 --- a/lua/nvim-tree/node/init.lua +++ b/lua/nvim-tree/node/init.lua @@ -121,8 +121,9 @@ function Node:highlighted_name() end ---Create a sanitized partial copy of a node, populating children recursively. +---@param api_nodes table? optional map of uids to api node to populate ---@return nvim_tree.api.Node cloned -function Node:clone() +function Node:clone(api_nodes) ---@type nvim_tree.api.Node local clone = { uid_node = self.uid_node, @@ -137,6 +138,10 @@ function Node:clone() diag_severity = self.diag_status and self.diag_status.value or nil, } + if api_nodes then + api_nodes[self.uid_node] = clone + end + return clone end diff --git a/lua/nvim-tree/node/root.lua b/lua/nvim-tree/node/root.lua index 683c08b8ef8..f991dec847d 100644 --- a/lua/nvim-tree/node/root.lua +++ b/lua/nvim-tree/node/root.lua @@ -23,9 +23,10 @@ function RootNode:destroy() end ---Create a sanitized partial copy of a node, populating children recursively. +---@param api_nodes table? optional map of uids to api node to populate ---@return nvim_tree.api.RootNode cloned -function RootNode:clone() - local clone = DirectoryNode.clone(self) --[[@as nvim_tree.api.RootNode]] +function RootNode:clone(api_nodes) + local clone = DirectoryNode.clone(self, api_nodes) --[[@as nvim_tree.api.RootNode]] return clone end diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 306c2ebfb46..1b0a3bc0d63 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -28,6 +28,7 @@ local pad = require("nvim-tree.renderer.components.padding") ---@field private markers boolean[] indent markers ---@field private decorators Decorator[] ---@field private hidden_display fun(node: Node): string|nil +---@field private api_nodes table? optional map of uids to api node for user decorators local Builder = Class:extend() ---@class Builder @@ -51,20 +52,33 @@ function Builder:new(args) self.virtual_lines = {} self.decorators = {} self.hidden_display = Builder:setup_hidden_display_function(self.explorer.opts) + self.api_nodes = nil ---@type DecoratorArgs local decorator_args = { explorer = self.explorer } - -- lowest priority is registered first + -- instantiate all the decorators for _, d in ipairs(decorator_registry.registered) do if d:is(DecoratorUser) then - table.insert(self.decorators, 1, d()) + self:build_api_nodes() + table.insert(self.decorators, d()) else - table.insert(self.decorators, 1, d(decorator_args)) + table.insert(self.decorators, d(decorator_args)) end end end +---Create and populate api_nodes if not present +---@private +function Builder:build_api_nodes() + if self.api_nodes then + return + end + + self.api_nodes = {} + self.explorer:clone(self.api_nodes) +end + ---Insert ranged highlight groups into self.highlights ---@private ---@param groups string[] @@ -122,22 +136,25 @@ function Builder:format_line(indent_markers, arrows, icon, name, node) end end + -- use the api node for user decorators + local api_node = self.api_nodes and self.api_nodes[node.uid_node] --[[@as Node]] + local line = { indent_markers, arrows } add_to_end(line, { icon }) - for i = #self.decorators, 1, -1 do - add_to_end(line, self.decorators[i]:icons_before(node)) + for _, d in ipairs(self.decorators) do + add_to_end(line, d:icons_before(d:is(DecoratorUser) and api_node or node)) end add_to_end(line, { name }) - for i = #self.decorators, 1, -1 do - add_to_end(line, self.decorators[i]:icons_after(node)) + for _, d in ipairs(self.decorators) do + add_to_end(line, d:icons_after(d:is(DecoratorUser) and api_node or node)) end local rights = {} - for i = #self.decorators, 1, -1 do - add_to_end(rights, self.decorators[i]:icons_right_align(node)) + for _, d in ipairs(self.decorators) do + add_to_end(rights, d:icons_right_align(d:is(DecoratorUser) and api_node or node)) end if #rights > 0 then self.extmarks[self.index] = rights @@ -149,10 +166,14 @@ end ---@private ---@param node Node function Builder:build_signs(node) + -- use the api node for user decorators + local api_node = self.api_nodes and self.api_nodes[node.uid_node] --[[@as Node]] + -- first in priority order - local sign_name - for _, d in ipairs(self.decorators) do - sign_name = d:sign_name(node) + local d, sign_name + for i = #self.decorators, 1, -1 do + d = self.decorators[i] + sign_name = d:sign_name(d:is(DecoratorUser) and api_node or node) if sign_name then self.signs[self.index] = sign_name break @@ -203,10 +224,8 @@ function Builder:icon_name_decorated(node) -- calculate node icon and all decorated highlight groups local icon_groups = {} local name_groups = {} - local decorator, hl_icon, hl_name - for i = #self.decorators, 1, -1 do - decorator = self.decorators[i] - + local hl_icon, hl_name + for _, decorator in ipairs(self.decorators) do -- maybe overridde icon icon = decorator:icon_node(node) or icon From ba296e67e40d37c9aeab3bab22f9ea719755888b Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 25 Nov 2024 14:50:09 +1100 Subject: [PATCH 18/27] feat(#2948): document API --- lua/nvim-tree/_meta/api_decorator.lua | 40 +++++++++++++++------------ 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua index b14dfd256c8..02a88d351ed 100644 --- a/lua/nvim-tree/_meta/api_decorator.lua +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -3,10 +3,10 @@ error("Cannot require a meta file") local nvim_tree = { api = { decorator = { AbstractDecorator = {} } } } ----Custom decorator extends nvim_tree.api.decorator.AbstractDecorator +---Custom decorator ---It may: --- Add icons ---- Set name highlight group +--- Set highlight group for the name or icons --- Override node icon ---Class must be created via nvim_tree.api.decorator.create() ---Mandatory constructor :new() will be called once per tree render, with no arguments. @@ -24,46 +24,52 @@ local nvim_tree = { api = { decorator = { AbstractDecorator = {} } } } ---Names of predefined decorators or your decorator classes ---@alias nvim_tree.api.decorator.Name "Cut" | "Copied" | "Diagnostics" | "Bookmarks" | "Modified" | "Hidden" | "Opened" | "Git" | nvim_tree.api.decorator.AbstractDecorator ----Abstract decorator class, your decorator will extend this +---Abstract decorator class, your decorator will extend this. --- ---@class (exact) nvim_tree.api.decorator.AbstractDecorator ---@field protected enabled boolean ---@field protected highlight_range nvim_tree.api.decorator.HighlightRange ---@field protected icon_placement nvim_tree.api.decorator.IconPlacement ----Abstract no-args constructor must be implemented +---Abstract: no-args constructor must be implemented. --- function nvim_tree.api.decorator.AbstractDecorator:new() end ----Must be called from your constructor ---- ----@class (exact) nvim_tree.api.decorator.AbstractDecoratorInitArgs ----@field enabled boolean ----@field highlight_range nvim_tree.api.decorator.HighlightRange ----@field icon_placement nvim_tree.api.decorator.IconPlacement ---- ----@protected ----@param args nvim_tree.api.decorator.AbstractDecoratorInitArgs -function nvim_tree.api.decorator.AbstractDecorator:init(args) end - ---Abstract: optionally implement to set the node's icon --- ---@param node nvim_tree.api.Node ---@return HighlightedString? icon_node function nvim_tree.api.decorator.AbstractDecorator:icon_node(node) end ----Abstract: optionally implement to provide icons and the highlight groups for your icon_placement +---Abstract: optionally implement to provide icons and the highlight groups for your icon_placement. --- ---@param node nvim_tree.api.Node ---@return HighlightedString[]? icons function nvim_tree.api.decorator.AbstractDecorator:icons(node) end ----Abstract: optionally implement to provide one highlight group to apply to your highlight_range +---Abstract: optionally implement to provide one highlight group to apply to your highlight_range. --- ---@param node nvim_tree.api.Node ---@return string? highlight_group function nvim_tree.api.decorator.AbstractDecorator:highlight_group(node) end +---Must be called from your constructor. +--- +---@class (exact) nvim_tree.api.decorator.AbstractDecoratorInitArgs +---@field enabled boolean +---@field highlight_range nvim_tree.api.decorator.HighlightRange +---@field icon_placement nvim_tree.api.decorator.IconPlacement +--- +---@protected +---@param args nvim_tree.api.decorator.AbstractDecoratorInitArgs +function nvim_tree.api.decorator.AbstractDecorator:init(args) end + +---Define a sign. This should be called in the constructor. +--- +---@protected +---@param icon HighlightedString? +function nvim_tree.api.decorator.AbstractDecorator:define_sign(icon) end + -- -- Example Decorator From cb351ae1deaa6128367f5973430350be66c69474 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 1 Dec 2024 13:49:00 +1100 Subject: [PATCH 19/27] feat(#2948): use renderer.decorators to define order and register --- doc/nvim-tree-lua.txt | 22 ++++- lua/nvim-tree.lua | 1 + lua/nvim-tree/_meta/api_decorator.lua | 39 ++++----- lua/nvim-tree/api.lua | 25 +----- lua/nvim-tree/renderer/builder.lua | 84 ++++++++++++------- .../renderer/decorator/bookmarks.lua | 1 - lua/nvim-tree/renderer/decorator/copied.lua | 1 - lua/nvim-tree/renderer/decorator/cut.lua | 1 - .../renderer/decorator/diagnostics.lua | 1 - lua/nvim-tree/renderer/decorator/git.lua | 1 - lua/nvim-tree/renderer/decorator/hidden.lua | 1 - lua/nvim-tree/renderer/decorator/init.lua | 1 - lua/nvim-tree/renderer/decorator/modified.lua | 1 - lua/nvim-tree/renderer/decorator/opened.lua | 1 - lua/nvim-tree/renderer/decorator/registry.lua | 58 ------------- lua/nvim-tree/renderer/decorator/user.lua | 4 +- 16 files changed, 97 insertions(+), 145 deletions(-) delete mode 100644 lua/nvim-tree/renderer/decorator/registry.lua diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 060227f8220..1ce871427de 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -425,6 +425,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. >lua special_files = { "Cargo.toml", "Makefile", "README.md", "readme.md" }, hidden_display = "none", symlink_destination = true, + decorators = { "Git", "Opened", "Hidden", "Modified", "Bookmarks", "Diagnostics", "Copied", "Cut", }, highlight_git = "none", highlight_diagnostics = "none", highlight_opened_files = "none", @@ -842,7 +843,7 @@ Use nvim-tree in a floating window. ============================================================================== 5.3 OPTS: RENDERER *nvim-tree-opts-renderer* -Highlight precedence, additive: +Highlight precedence, additive, change via |nvim-tree.renderer.decorators| git < opened < modified < bookmarked < diagnostics < copied < cut *nvim-tree.renderer.add_trailing* @@ -927,6 +928,22 @@ Show a summary of hidden files below the tree using `NvimTreeHiddenDisplay Whether to show the destination of the symlink. Type: `boolean`, Default: `true` +*nvim-tree.renderer.decorators* +Highlighting and icons for the nodes, in increasing order of precedence. +Uses strings to specify builtin decorators otherwise specify your +`nvim_tree.api.decorator.DecoratorUser` class. + Type: `nvim_tree.api.decorator.Name[]`, Default: >lua + { + "Git", + "Opened", + "Hidden", + "Modified", + "Bookmarks", + "Diagnostics", + "Copied", + "Cut", + } +< *nvim-tree.renderer.highlight_git* Enable highlight for git attributes using `NvimTreeGit*HL` highlight groups. Requires |nvim-tree.git.enable| @@ -996,7 +1013,7 @@ Configuration options for tree indent markers. *nvim-tree.renderer.icons* Configuration options for icons. -Icon order and sign column precedence: +Icon order and sign column precedence, change via |nvim-tree.renderer.decorators| git < hidden < modified < bookmarked < diagnostics `renderer.icons.*_placement` options may be: @@ -2943,6 +2960,7 @@ highlight group is not, hard linking as follows: > |nvim-tree.prefer_startup_root| |nvim-tree.reload_on_bufenter| |nvim-tree.renderer.add_trailing| +|nvim-tree.renderer.decorators| |nvim-tree.renderer.full_name| |nvim-tree.renderer.group_empty| |nvim-tree.renderer.hidden_display| diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 212d4c14bab..c26b52e163f 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -284,6 +284,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS special_files = { "Cargo.toml", "Makefile", "README.md", "readme.md" }, hidden_display = "none", symlink_destination = true, + decorators = { "Git", "Opened", "Hidden", "Modified", "Bookmarks", "Diagnostics", "Copied", "Cut", }, highlight_git = "none", highlight_diagnostics = "none", highlight_opened_files = "none", diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua index 02a88d351ed..1c6ee014a18 100644 --- a/lua/nvim-tree/_meta/api_decorator.lua +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -1,19 +1,19 @@ ---@meta error("Cannot require a meta file") -local nvim_tree = { api = { decorator = { AbstractDecorator = {} } } } +local nvim_tree = { api = { decorator = { DecoratorUser = {} } } } ---Custom decorator ---It may: --- Add icons --- Set highlight group for the name or icons --- Override node icon ----Class must be created via nvim_tree.api.decorator.create() +---Register it via :help nvim-tree.renderer.decorators +---Create class via require("nvim-tree.api").decorator.DecoratorUser:extend() ---Mandatory constructor :new() will be called once per tree render, with no arguments. ---Constructor must call: --- :init --- :define_sign when using "signcolumn" range ----Decorator must be registered via api.decorator.register ---Highlight group range as per nvim-tree.renderer.highlight_* ---@alias nvim_tree.api.decorator.HighlightRange "none" | "icon" | "name" | "all" @@ -21,67 +21,67 @@ local nvim_tree = { api = { decorator = { AbstractDecorator = {} } } } ---Icon position as per renderer.icons.*_placement ---@alias nvim_tree.api.decorator.IconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" ----Names of predefined decorators or your decorator classes ----@alias nvim_tree.api.decorator.Name "Cut" | "Copied" | "Diagnostics" | "Bookmarks" | "Modified" | "Hidden" | "Opened" | "Git" | nvim_tree.api.decorator.AbstractDecorator +---Names of builtin decorators or your decorator classes. Builtins are ordered lowest to highest priority. +---@alias nvim_tree.api.decorator.Name "Git" | "Opened" | "Hidden" | "Modified" | "Bookmarks" | "Diagnostics" | "Copied" | "Cut" | nvim_tree.api.decorator.DecoratorUser ----Abstract decorator class, your decorator will extend this. +---Your decorator will extend this class via require("nvim-tree.api").decorator.DecoratorUser:extend() --- ----@class (exact) nvim_tree.api.decorator.AbstractDecorator +---@class (exact) nvim_tree.api.decorator.DecoratorUser ---@field protected enabled boolean ---@field protected highlight_range nvim_tree.api.decorator.HighlightRange ---@field protected icon_placement nvim_tree.api.decorator.IconPlacement ---Abstract: no-args constructor must be implemented. --- -function nvim_tree.api.decorator.AbstractDecorator:new() end +function nvim_tree.api.decorator.DecoratorUser:new() end ---Abstract: optionally implement to set the node's icon --- ---@param node nvim_tree.api.Node ---@return HighlightedString? icon_node -function nvim_tree.api.decorator.AbstractDecorator:icon_node(node) end +function nvim_tree.api.decorator.DecoratorUser:icon_node(node) end ---Abstract: optionally implement to provide icons and the highlight groups for your icon_placement. --- ---@param node nvim_tree.api.Node ---@return HighlightedString[]? icons -function nvim_tree.api.decorator.AbstractDecorator:icons(node) end +function nvim_tree.api.decorator.DecoratorUser:icons(node) end ---Abstract: optionally implement to provide one highlight group to apply to your highlight_range. --- ---@param node nvim_tree.api.Node ---@return string? highlight_group -function nvim_tree.api.decorator.AbstractDecorator:highlight_group(node) end +function nvim_tree.api.decorator.DecoratorUser:highlight_group(node) end ---Must be called from your constructor. --- ----@class (exact) nvim_tree.api.decorator.AbstractDecoratorInitArgs +---@class (exact) nvim_tree.api.decorator.InitArgs ---@field enabled boolean ---@field highlight_range nvim_tree.api.decorator.HighlightRange ---@field icon_placement nvim_tree.api.decorator.IconPlacement --- ---@protected ----@param args nvim_tree.api.decorator.AbstractDecoratorInitArgs -function nvim_tree.api.decorator.AbstractDecorator:init(args) end +---@param args nvim_tree.api.decorator.InitArgs +function nvim_tree.api.decorator.DecoratorUser:init(args) end ---Define a sign. This should be called in the constructor. --- ---@protected ---@param icon HighlightedString? -function nvim_tree.api.decorator.AbstractDecorator:define_sign(icon) end +function nvim_tree.api.decorator.DecoratorUser:define_sign(icon) end -- -- Example Decorator -- ----@class (exact) MyDecorator: nvim_tree.api.decorator.AbstractDecorator +---@class (exact) MyDecorator: nvim_tree.api.decorator.DecoratorUser ---@field private my_icon nvim_tree.api.HighlightedString -local MyDecorator = require("nvim-tree.api").decorator.create() +local MyDecorator = require("nvim-tree.api").decorator.DecoratorUser:extend() ---Mandatory constructor :new() will be called once per tree render, with no arguments. function MyDecorator:new() - ---@type nvim_tree.api.decorator.AbstractDecoratorInitArgs + ---@type nvim_tree.api.decorator.InitArgs local args = { enabled = true, highlight_range = "all", @@ -131,6 +131,3 @@ function MyDecorator:highlight_group(node) return nil end end - ----Register the decorator, below Cut in priority -require("nvim-tree.api").decorator.register({ decorator = MyDecorator, below = "Cut" }) diff --git a/lua/nvim-tree/api.lua b/lua/nvim-tree/api.lua index 3b3eb667e8d..880f115911a 100644 --- a/lua/nvim-tree/api.lua +++ b/lua/nvim-tree/api.lua @@ -7,7 +7,6 @@ local events = require("nvim-tree.events") local help = require("nvim-tree.help") local keymap = require("nvim-tree.keymap") local notify = require("nvim-tree.notify") -local decorator_registry = require("nvim-tree.renderer.decorator.registry") local DirectoryNode = require("nvim-tree.node.directory") local FileLinkNode = require("nvim-tree.node.file-link") @@ -314,26 +313,8 @@ Api.commands.get = wrap(function() return require("nvim-tree.commands").get() end) ----Create a new decorator class ---- ----@return nvim_tree.api.decorator.AbstractDecorator -Api.decorator.create = function() return DecoratorUser:extend() end - ----Register a decorator class ---- ----@class RegisterOpts ----@field decorator nvim_tree.api.decorator.AbstractDecorator ----@field below nvim_tree.api.decorator.Name? ---- ----@param opts RegisterOpts -Api.decorator.register = function(opts) decorator_registry.register(opts) end - ----Unregister a decorator class ---- ----@class UnRegisterOpts ----@field decorator nvim_tree.api.decorator.AbstractDecorator ---- ----@param opts UnRegisterOpts -Api.decorator.unregister = function(opts) decorator_registry.unregister(opts) end +---User provided decorator. Extend this class via :extend() +---@type nvim_tree.api.decorator.DecoratorUser +Api.decorator.DecoratorUser = DecoratorUser --[[@as nvim_tree.api.decorator.DecoratorUser]] return Api diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 1b0a3bc0d63..b22093f4035 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -1,14 +1,36 @@ -local decorator_registry = require("nvim-tree.renderer.decorator.registry") local notify = require("nvim-tree.notify") local utils = require("nvim-tree.utils") local view = require("nvim-tree.view") local Class = require("nvim-tree.classic") + local DirectoryNode = require("nvim-tree.node.directory") + +local DecoratorBookmarks = require("nvim-tree.renderer.decorator.bookmarks") +local DecoratorCopied = require("nvim-tree.renderer.decorator.copied") +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 DecoratorHidden = require("nvim-tree.renderer.decorator.hidden") +local DecoratorModified = require("nvim-tree.renderer.decorator.modified") +local DecoratorOpened = require("nvim-tree.renderer.decorator.opened") local DecoratorUser = require("nvim-tree.renderer.decorator.user") local pad = require("nvim-tree.renderer.components.padding") +-- Builtin Decorators +---@type table +local BUILTIN_DECORATORS = { + Git = DecoratorGit, + Opened = DecoratorOpened, + Hidden = DecoratorHidden, + Modified = DecoratorModified, + Bookmarks = DecoratorBookmarks, + Diagnostics = DecoratorDiagnostics, + Copied = DecoratorCopied, + Cut = DecoratorCut, +} + ---@class (exact) AddHighlightArgs ---@field group string[] ---@field line number @@ -52,31 +74,28 @@ function Builder:new(args) self.virtual_lines = {} self.decorators = {} self.hidden_display = Builder:setup_hidden_display_function(self.explorer.opts) - self.api_nodes = nil - - ---@type DecoratorArgs - local decorator_args = { explorer = self.explorer } - - -- instantiate all the decorators - for _, d in ipairs(decorator_registry.registered) do - if d:is(DecoratorUser) then - self:build_api_nodes() - table.insert(self.decorators, d()) - else - table.insert(self.decorators, d(decorator_args)) - end - end -end ----Create and populate api_nodes if not present ----@private -function Builder:build_api_nodes() - if self.api_nodes then - return - end + -- instantiate all the builtin and user decorator instances + local builtin, user + for _, d in ipairs(self.explorer.opts.renderer.decorators) do + ---@type Decorator + builtin = BUILTIN_DECORATORS[d] - self.api_nodes = {} - self.explorer:clone(self.api_nodes) + ---@type DecoratorUser + user = d.as and d:as(DecoratorUser) + + if builtin then + table.insert(self.decorators, builtin({ explorer = self.explorer })) + elseif user then + table.insert(self.decorators, user()) + + -- clone user nodes once + if not self.api_nodes then + self.api_nodes = {} + self.explorer:clone(self.api_nodes) + end + end + end end ---Insert ranged highlight groups into self.highlights @@ -143,18 +162,18 @@ function Builder:format_line(indent_markers, arrows, icon, name, node) add_to_end(line, { icon }) for _, d in ipairs(self.decorators) do - add_to_end(line, d:icons_before(d:is(DecoratorUser) and api_node or node)) + add_to_end(line, d:icons_before(not d:is(DecoratorUser) and node or api_node)) end add_to_end(line, { name }) for _, d in ipairs(self.decorators) do - add_to_end(line, d:icons_after(d:is(DecoratorUser) and api_node or node)) + add_to_end(line, d:icons_after(not d:is(DecoratorUser) and node or api_node)) end local rights = {} for _, d in ipairs(self.decorators) do - add_to_end(rights, d:icons_right_align(d:is(DecoratorUser) and api_node or node)) + add_to_end(rights, d:icons_right_align(not d:is(DecoratorUser) and node or api_node)) end if #rights > 0 then self.extmarks[self.index] = rights @@ -173,7 +192,7 @@ function Builder:build_signs(node) local d, sign_name for i = #self.decorators, 1, -1 do d = self.decorators[i] - sign_name = d:sign_name(d:is(DecoratorUser) and api_node or node) + sign_name = d:sign_name(not d:is(DecoratorUser) and node or api_node) if sign_name then self.signs[self.index] = sign_name break @@ -217,6 +236,9 @@ end ---@return HighlightedString icon ---@return HighlightedString name function Builder:icon_name_decorated(node) + -- use the api node for user decorators + local api_node = self.api_nodes and self.api_nodes[node.uid_node] --[[@as Node]] + -- base case local icon = node:highlighted_icon() local name = node:highlighted_name() @@ -225,11 +247,11 @@ function Builder:icon_name_decorated(node) local icon_groups = {} local name_groups = {} local hl_icon, hl_name - for _, decorator in ipairs(self.decorators) do + for _, d in ipairs(self.decorators) do -- maybe overridde icon - icon = decorator:icon_node(node) or icon + icon = d:icon_node((not d:is(DecoratorUser) and node or api_node)) or icon - hl_icon, hl_name = decorator:highlight_group_icon_name(node) + hl_icon, hl_name = d:highlight_group_icon_name((not d:is(DecoratorUser) and node or api_node)) table.insert(icon_groups, hl_icon) table.insert(name_groups, hl_name) diff --git a/lua/nvim-tree/renderer/decorator/bookmarks.lua b/lua/nvim-tree/renderer/decorator/bookmarks.lua index ab8f41d9d20..1c07e87d6e8 100644 --- a/lua/nvim-tree/renderer/decorator/bookmarks.lua +++ b/lua/nvim-tree/renderer/decorator/bookmarks.lua @@ -4,7 +4,6 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@field private explorer Explorer ---@field private icon HighlightedString? local DecoratorBookmarks = Decorator:extend() -DecoratorBookmarks.name = "Bookmarks" ---@class DecoratorBookmarks ---@overload fun(args: DecoratorArgs): DecoratorBookmarks diff --git a/lua/nvim-tree/renderer/decorator/copied.lua b/lua/nvim-tree/renderer/decorator/copied.lua index 8c6ad15995f..4422638535d 100644 --- a/lua/nvim-tree/renderer/decorator/copied.lua +++ b/lua/nvim-tree/renderer/decorator/copied.lua @@ -3,7 +3,6 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) DecoratorCopied: Decorator ---@field private explorer Explorer local DecoratorCopied = Decorator:extend() -DecoratorCopied.name = "Copied" ---@class DecoratorCopied ---@overload fun(args: DecoratorArgs): DecoratorCopied diff --git a/lua/nvim-tree/renderer/decorator/cut.lua b/lua/nvim-tree/renderer/decorator/cut.lua index 0f2af987fb1..6d29991231d 100644 --- a/lua/nvim-tree/renderer/decorator/cut.lua +++ b/lua/nvim-tree/renderer/decorator/cut.lua @@ -3,7 +3,6 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) DecoratorCut: Decorator ---@field private explorer Explorer local DecoratorCut = Decorator:extend() -DecoratorCut.name = "Cut" ---@class DecoratorCut ---@overload fun(args: DecoratorArgs): DecoratorCut diff --git a/lua/nvim-tree/renderer/decorator/diagnostics.lua b/lua/nvim-tree/renderer/decorator/diagnostics.lua index 6fbf087d7e1..6c72a2aa0e7 100644 --- a/lua/nvim-tree/renderer/decorator/diagnostics.lua +++ b/lua/nvim-tree/renderer/decorator/diagnostics.lua @@ -34,7 +34,6 @@ local ICON_KEYS = { ---@field private explorer Explorer ---@field private diag_icons HighlightedString[]? local DecoratorDiagnostics = Decorator:extend() -DecoratorDiagnostics.name = "Diagnostics" ---@class DecoratorDiagnostics ---@overload fun(args: DecoratorArgs): DecoratorDiagnostics diff --git a/lua/nvim-tree/renderer/decorator/git.lua b/lua/nvim-tree/renderer/decorator/git.lua index 47f22536f1f..b4bc2499c17 100644 --- a/lua/nvim-tree/renderer/decorator/git.lua +++ b/lua/nvim-tree/renderer/decorator/git.lua @@ -19,7 +19,6 @@ local DirectoryNode = require("nvim-tree.node.directory") ---@field private icons_by_status GitIconsByStatus? ---@field private icons_by_xy GitIconsByXY? local DecoratorGit = Decorator:extend() -DecoratorGit.name = "Git" ---@class DecoratorGit ---@overload fun(args: DecoratorArgs): DecoratorGit diff --git a/lua/nvim-tree/renderer/decorator/hidden.lua b/lua/nvim-tree/renderer/decorator/hidden.lua index c83a20151f7..bf7aab23303 100644 --- a/lua/nvim-tree/renderer/decorator/hidden.lua +++ b/lua/nvim-tree/renderer/decorator/hidden.lua @@ -5,7 +5,6 @@ local DirectoryNode = require("nvim-tree.node.directory") ---@field private explorer Explorer ---@field private icon HighlightedString? local DecoratorHidden = Decorator:extend() -DecoratorHidden.name = "Hidden" ---@class DecoratorHidden ---@overload fun(args: DecoratorArgs): DecoratorHidden diff --git a/lua/nvim-tree/renderer/decorator/init.lua b/lua/nvim-tree/renderer/decorator/init.lua index 12f441b3e0b..9c6a6bc1874 100644 --- a/lua/nvim-tree/renderer/decorator/init.lua +++ b/lua/nvim-tree/renderer/decorator/init.lua @@ -2,7 +2,6 @@ local Class = require("nvim-tree.classic") ---Abstract Decorator ---@class (exact) Decorator: Class ----@field name string for registry ---@field protected enabled boolean ---@field protected highlight_range DecoratorHighlightRange ---@field protected icon_placement DecoratorIconPlacement diff --git a/lua/nvim-tree/renderer/decorator/modified.lua b/lua/nvim-tree/renderer/decorator/modified.lua index e761fff7ac0..e2cad99aca8 100644 --- a/lua/nvim-tree/renderer/decorator/modified.lua +++ b/lua/nvim-tree/renderer/decorator/modified.lua @@ -7,7 +7,6 @@ local DirectoryNode = require("nvim-tree.node.directory") ---@field private explorer Explorer ---@field private icon HighlightedString? local DecoratorModified = Decorator:extend() -DecoratorModified.name = "Modified" ---@class DecoratorModified ---@overload fun(args: DecoratorArgs): DecoratorModified diff --git a/lua/nvim-tree/renderer/decorator/opened.lua b/lua/nvim-tree/renderer/decorator/opened.lua index 56996d8368d..da500c083b2 100644 --- a/lua/nvim-tree/renderer/decorator/opened.lua +++ b/lua/nvim-tree/renderer/decorator/opened.lua @@ -6,7 +6,6 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@field private explorer Explorer ---@field private icon HighlightedString|nil local DecoratorOpened = Decorator:extend() -DecoratorOpened.name = "Opened" ---@class DecoratorOpened ---@overload fun(args: DecoratorArgs): DecoratorOpened diff --git a/lua/nvim-tree/renderer/decorator/registry.lua b/lua/nvim-tree/renderer/decorator/registry.lua deleted file mode 100644 index dec70621235..00000000000 --- a/lua/nvim-tree/renderer/decorator/registry.lua +++ /dev/null @@ -1,58 +0,0 @@ -local utils = require("nvim-tree.utils") - -local DecoratorBookmarks = require("nvim-tree.renderer.decorator.bookmarks") -local DecoratorCopied = require("nvim-tree.renderer.decorator.copied") -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 DecoratorUser = require("nvim-tree.renderer.decorator.user") - -local M = { - -- Globally registered decorators including user. Lowest priority first. - ---@type Decorator[] - registered = { - DecoratorGit, - DecoratorOpened, - DecoratorHidden, - DecoratorModified, - DecoratorBookmarks, - DecoratorDiagnostics, - DecoratorCopied, - DecoratorCut, - } -} - ----@param opts RegisterOpts -function M.register(opts) - if not opts or not opts.decorator then - return - end - - if vim.tbl_contains(M.registered, opts.decorator) then - return - end - - for i, d in ipairs(M.registered) do - if d:is(DecoratorUser) and d == opts.below or d.name == opts.below then - table.insert(M.registered, i, opts.decorator) - return - end - end - - -- default to highest at the top - table.insert(M.registered, opts.decorator) -end - ----@param opts UnRegisterOpts -function M.unregister(opts) - if not opts or not opts.decorator then - return - end - - utils.array_remove(M.registered, opts.decorator) -end - -return M diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index 98e7cbadc42..b0037e7a5be 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -1,11 +1,11 @@ local Decorator = require("nvim-tree.renderer.decorator") ----Exposed as nvim_tree.api.decorator.AbstractDecorator +---Exposed as nvim_tree.api.decorator.DecoratorUser ---@class (exact) DecoratorUser: Decorator local DecoratorUser = Decorator:extend() ---User calls this instead of new ----@param args nvim_tree.api.decorator.AbstractDecoratorInitArgs +---@param args nvim_tree.api.decorator.InitArgs function DecoratorUser:init(args) DecoratorUser.super.new(self, args) end From 4bf4a85b9fc7221619691e918efdbd8c0aa605cb Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 1 Dec 2024 15:17:25 +1100 Subject: [PATCH 20/27] feat(#2948): tidy decorator args and complete documentation --- doc/nvim-tree-lua.txt | 122 ++++++++++++++---- lua/nvim-tree/_meta/aliases.lua | 19 --- lua/nvim-tree/_meta/api_decorator.lua | 98 +------------- lua/nvim-tree/api.lua | 2 +- lua/nvim-tree/renderer/builder.lua | 2 + .../renderer/decorator/bookmarks.lua | 13 +- lua/nvim-tree/renderer/decorator/copied.lua | 13 +- lua/nvim-tree/renderer/decorator/cut.lua | 13 +- .../renderer/decorator/diagnostics.lua | 21 +-- lua/nvim-tree/renderer/decorator/git.lua | 17 +-- lua/nvim-tree/renderer/decorator/hidden.lua | 17 +-- lua/nvim-tree/renderer/decorator/init.lua | 62 ++++----- lua/nvim-tree/renderer/decorator/modified.lua | 21 +-- lua/nvim-tree/renderer/decorator/opened.lua | 13 +- lua/nvim-tree/renderer/decorator/user.lua | 6 - 15 files changed, 172 insertions(+), 267 deletions(-) delete mode 100644 lua/nvim-tree/_meta/aliases.lua diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 1ce871427de..f16dbda65a4 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -52,14 +52,15 @@ CONTENTS *nvim-tree* 8.2 Highlight: Overhaul |nvim-tree-highlight-overhaul| 9. Events |nvim-tree-events| 10. Prompts |nvim-tree-prompts| - 11. OS Specific Restrictions |nvim-tree-os-specific| - 12. Netrw |nvim-tree-netrw| - 13. Legacy |nvim-tree-legacy| - 13.1 Legacy: Opts |nvim-tree-legacy-opts| - 13.2 Legacy: Highlight |nvim-tree-legacy-highlight| - 14. Index |nvim-tree-index| - 14.1 Index: Opts |nvim-tree-index-opts| - 14.2 Index: API |nvim-tree-index-api| + 11. Decorators |nvim-tree-decorators| + 12. OS Specific Restrictions |nvim-tree-os-specific| + 13. Netrw |nvim-tree-netrw| + 14. Legacy |nvim-tree-legacy| + 14.1 Legacy: Opts |nvim-tree-legacy-opts| + 14.2 Legacy: Highlight |nvim-tree-legacy-highlight| + 15. Index |nvim-tree-index| + 15.1 Index: Opts |nvim-tree-index-opts| + 15.2 Index: API |nvim-tree-index-api| ============================================================================== 1. INTRODUCTION *nvim-tree-introduction* @@ -843,9 +844,6 @@ Use nvim-tree in a floating window. ============================================================================== 5.3 OPTS: RENDERER *nvim-tree-opts-renderer* -Highlight precedence, additive, change via |nvim-tree.renderer.decorators| - git < opened < modified < bookmarked < diagnostics < copied < cut - *nvim-tree.renderer.add_trailing* Appends a trailing slash to folder names. Type: `boolean`, Default: `false` @@ -1013,9 +1011,6 @@ Configuration options for tree indent markers. *nvim-tree.renderer.icons* Configuration options for icons. -Icon order and sign column precedence, change via |nvim-tree.renderer.decorators| - git < hidden < modified < bookmarked < diagnostics - `renderer.icons.*_placement` options may be: - `"before"` : before file/folder, after the file/folders icons - `"after"` : after file/folder @@ -2772,7 +2767,90 @@ configurations for different types of prompts. send all bookmarked to trash during |nvim-tree-api.marks.bulk.trash()| ============================================================================== - 11. OS SPECIFIC RESTRICTIONS *nvim-tree-os-specific* + 11. DECORATORS *nvim-tree-decorators* + +Highlighting and icons for nodes are is provided by Decorators. You may provide +your own in addition to the builtin decorators. + +Decorators may: +- Add icons +- Set highlight group for the name or icons +- Override node icon + +Create your decorator class via `api.decorator.DecoratorUser:extend()` and add it +to |nvim-tree.renderer.decorators| + +e.g. default decorators with an user decorator being overridden only by Cut: >lua + { + "Git", + "Opened", + "Hidden", + "Modified", + "Bookmarks", + "Diagnostics", + "Copied", + MyDecorator, + "Cut", + } +< +See `api_decorator.lua` for decorator class definition and full documentation. + +Example decorator: >lua + + ---Create your decorator class + ---@class (exact) MyDecorator: nvim_tree.api.decorator.DecoratorUser + ---@field private my_icon nvim_tree.api.HighlightedString + local MyDecorator = require("nvim-tree.api").decorator.DecoratorUser:extend() + + ---Mandatory constructor :new() will be called once per tree render, with no arguments. + function MyDecorator:new() + self.enabled = true + self.highlight_range = "all" + self.icon_placement = "signcolumn" + + -- create your icon once, for convenience + self.my_icon = { str = "I", hl = { "MyIcon" } } + + -- Define the icon sign only once + -- Only needed if you are using icon_placement = "signcolumn" + self:define_sign(self.my_icon) + end + + ---Override node icon + ---@param node nvim_tree.api.Node + ---@return nvim_tree.api.HighlightedString? icon_node + function MyDecorator:icon_node(node) + if node.name == "example" then + return self.my_icon + else + return nil + end + end + + ---Return one icon for DecoratorIconPlacement + ---@param node nvim_tree.api.Node + ---@return nvim_tree.api.HighlightedString[]? icons + function MyDecorator:icons(node) + if node.name == "example" then + return { self.my_icon } + else + return nil + end + end + + ---Exactly one highlight group for DecoratorHighlightRange + ---@param node nvim_tree.api.Node + ---@return string? highlight_group + function MyDecorator:highlight_group(node) + if node.name == "example" then + return "MyHighlight" + else + return nil + end + end +< +============================================================================== + 12. OS SPECIFIC RESTRICTIONS *nvim-tree-os-specific* Windows WSL and PowerShell - Trash is synchronized @@ -2784,7 +2862,7 @@ Windows WSL and PowerShell issues or disable this feature. ============================================================================== - 12. NETRW *nvim-tree-netrw* + 13. NETRW *nvim-tree-netrw* |netrw| is a standard neovim plugin that is enabled by default. It provides, amongst other functionality, a file/directory browser. @@ -2805,14 +2883,14 @@ keep using |netrw| without its browser features please ensure: |nvim-tree.hijack_netrw| ` = true` ============================================================================== - 13. LEGACY *nvim-tree-legacy* + 14. LEGACY *nvim-tree-legacy* Breaking refactors have been made however the legacy versions will be silently migrated and used. There are no plans to remove this migration. ============================================================================== - 13.1 LEGACY: OPTS *nvim-tree-legacy-opts* + 14.1 LEGACY: OPTS *nvim-tree-legacy-opts* Legacy options are translated to the current, making type and value changes as needed. @@ -2830,7 +2908,7 @@ needed. `renderer.icons.webdev_colors` |nvim-tree.renderer.icons.web_devicons.file.color| ============================================================================== - 13.2 LEGACY: HIGHLIGHT *nvim-tree-legacy-highlight* + 14.2 LEGACY: HIGHLIGHT *nvim-tree-legacy-highlight* Legacy highlight group are still obeyed when they are defined and the current highlight group is not, hard linking as follows: > @@ -2879,10 +2957,10 @@ highlight group is not, hard linking as follows: > NvimTreeLspDiagnosticsHintFolderText NvimTreeDiagnosticHintFolderHL < ============================================================================== - 14 INDEX *nvim-tree-index* + 15 INDEX *nvim-tree-index* ============================================================================== - 14.1 INDEX: OPTS *nvim-tree-index-opts* + 15.1 INDEX: OPTS *nvim-tree-index-opts* |nvim-tree.actions.change_dir| |nvim-tree.actions.change_dir.enable| @@ -3051,7 +3129,7 @@ highlight group is not, hard linking as follows: > |nvim-tree.view.width.padding| ============================================================================== - 14.2 INDEX: API *nvim-tree-index-api* + 15.2 INDEX: API *nvim-tree-index-api* |nvim-tree-api.commands.get()| |nvim-tree-api.config.mappings.default_on_attach()| diff --git a/lua/nvim-tree/_meta/aliases.lua b/lua/nvim-tree/_meta/aliases.lua deleted file mode 100644 index 8154d9371a1..00000000000 --- a/lua/nvim-tree/_meta/aliases.lua +++ /dev/null @@ -1,19 +0,0 @@ ----@meta -error("Cannot require a meta file") - --- ---Internal convenience aliases for api types --- - --- ---api.lua --- - ----@alias HighlightedString nvim_tree.api.HighlightedString - --- ---api_decorator.lua --- - ----@alias DecoratorHighlightRange nvim_tree.api.decorator.HighlightRange ----@alias DecoratorIconPlacement nvim_tree.api.decorator.IconPlacement diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua index 1c6ee014a18..949f11bfa48 100644 --- a/lua/nvim-tree/_meta/api_decorator.lua +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -1,19 +1,7 @@ ---@meta error("Cannot require a meta file") -local nvim_tree = { api = { decorator = { DecoratorUser = {} } } } - ----Custom decorator ----It may: ---- Add icons ---- Set highlight group for the name or icons ---- Override node icon ----Register it via :help nvim-tree.renderer.decorators ----Create class via require("nvim-tree.api").decorator.DecoratorUser:extend() ----Mandatory constructor :new() will be called once per tree render, with no arguments. ----Constructor must call: ---- :init ---- :define_sign when using "signcolumn" range +local nvim_tree = {} ---Highlight group range as per nvim-tree.renderer.highlight_* ---@alias nvim_tree.api.decorator.HighlightRange "none" | "icon" | "name" | "all" @@ -24,27 +12,28 @@ local nvim_tree = { api = { decorator = { DecoratorUser = {} } } } ---Names of builtin decorators or your decorator classes. Builtins are ordered lowest to highest priority. ---@alias nvim_tree.api.decorator.Name "Git" | "Opened" | "Hidden" | "Modified" | "Bookmarks" | "Diagnostics" | "Copied" | "Cut" | nvim_tree.api.decorator.DecoratorUser ----Your decorator will extend this class via require("nvim-tree.api").decorator.DecoratorUser:extend() +---Custom decorator, see :help nvim-tree-decorators --- ---@class (exact) nvim_tree.api.decorator.DecoratorUser ---@field protected enabled boolean ---@field protected highlight_range nvim_tree.api.decorator.HighlightRange ---@field protected icon_placement nvim_tree.api.decorator.IconPlacement ----Abstract: no-args constructor must be implemented. +---Abstract: no-args constructor must be implemented and will be called once per tree render. +---Must set all fields. --- function nvim_tree.api.decorator.DecoratorUser:new() end ---Abstract: optionally implement to set the node's icon --- ---@param node nvim_tree.api.Node ----@return HighlightedString? icon_node +---@return nvim_tree.api.HighlightedString? icon_node function nvim_tree.api.decorator.DecoratorUser:icon_node(node) end ---Abstract: optionally implement to provide icons and the highlight groups for your icon_placement. --- ---@param node nvim_tree.api.Node ----@return HighlightedString[]? icons +---@return nvim_tree.api.HighlightedString[]? icons function nvim_tree.api.decorator.DecoratorUser:icons(node) end ---Abstract: optionally implement to provide one highlight group to apply to your highlight_range. @@ -53,81 +42,8 @@ function nvim_tree.api.decorator.DecoratorUser:icons(node) end ---@return string? highlight_group function nvim_tree.api.decorator.DecoratorUser:highlight_group(node) end ----Must be called from your constructor. ---- ----@class (exact) nvim_tree.api.decorator.InitArgs ----@field enabled boolean ----@field highlight_range nvim_tree.api.decorator.HighlightRange ----@field icon_placement nvim_tree.api.decorator.IconPlacement ---- ----@protected ----@param args nvim_tree.api.decorator.InitArgs -function nvim_tree.api.decorator.DecoratorUser:init(args) end - ---Define a sign. This should be called in the constructor. --- ---@protected ----@param icon HighlightedString? +---@param icon nvim_tree.api.HighlightedString? function nvim_tree.api.decorator.DecoratorUser:define_sign(icon) end - - --- --- Example Decorator --- - ----@class (exact) MyDecorator: nvim_tree.api.decorator.DecoratorUser ----@field private my_icon nvim_tree.api.HighlightedString -local MyDecorator = require("nvim-tree.api").decorator.DecoratorUser:extend() - ----Mandatory constructor :new() will be called once per tree render, with no arguments. -function MyDecorator:new() - ---@type nvim_tree.api.decorator.InitArgs - local args = { - enabled = true, - highlight_range = "all", - icon_placement = "signcolumn", - } - - -- init - self:init(args) - - -- create your icon once, for convenience - self.my_icon = { str = "I", hl = { "MyIcon" } } - - -- Define the icon sign only once - -- Only needed if you are using icon_placement = "signcolumn" - self:define_sign(self.my_icon) -end - ----Override node icon ----@param node nvim_tree.api.Node ----@return nvim_tree.api.HighlightedString? icon_node -function MyDecorator:icon_node(node) - if node.name == "example" then - return self.my_icon - else - return nil - end -end - ----Return one icon for DecoratorIconPlacement ----@param node nvim_tree.api.Node ----@return nvim_tree.api.HighlightedString[]? icons -function MyDecorator:icons(node) - if node.name == "example" then - return { self.my_icon } - else - return nil - end -end - ----Exactly one highlight group for DecoratorHighlightRange ----@param node nvim_tree.api.Node ----@return string? highlight_group -function MyDecorator:highlight_group(node) - if node.name == "example" then - return "MyHighlight" - else - return nil - end -end diff --git a/lua/nvim-tree/api.lua b/lua/nvim-tree/api.lua index 880f115911a..3da5437fe1a 100644 --- a/lua/nvim-tree/api.lua +++ b/lua/nvim-tree/api.lua @@ -313,7 +313,7 @@ Api.commands.get = wrap(function() return require("nvim-tree.commands").get() end) ----User provided decorator. Extend this class via :extend() +---Create a decorator class by calling :extend() ---@type nvim_tree.api.decorator.DecoratorUser Api.decorator.DecoratorUser = DecoratorUser --[[@as nvim_tree.api.decorator.DecoratorUser]] diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index b22093f4035..833df5767ce 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -18,6 +18,8 @@ local DecoratorUser = require("nvim-tree.renderer.decorator.user") local pad = require("nvim-tree.renderer.components.padding") +---@alias HighlightedString nvim_tree.api.HighlightedString + -- Builtin Decorators ---@type table local BUILTIN_DECORATORS = { diff --git a/lua/nvim-tree/renderer/decorator/bookmarks.lua b/lua/nvim-tree/renderer/decorator/bookmarks.lua index 1c07e87d6e8..b50073d4464 100644 --- a/lua/nvim-tree/renderer/decorator/bookmarks.lua +++ b/lua/nvim-tree/renderer/decorator/bookmarks.lua @@ -11,16 +11,11 @@ local DecoratorBookmarks = Decorator:extend() ---@protected ---@param args DecoratorArgs function DecoratorBookmarks:new(args) - self.explorer = args.explorer + self.explorer = args.explorer - ---@type AbstractDecoratorArgs - local a = { - enabled = true, - highlight_range = self.explorer.opts.renderer.highlight_bookmarks or "none", - icon_placement = self.explorer.opts.renderer.icons.bookmarks_placement or "none", - } - - DecoratorBookmarks.super.new(self, a) + self.enabled = true + self.highlight_range = self.explorer.opts.renderer.highlight_bookmarks or "none" + self.icon_placement = self.explorer.opts.renderer.icons.bookmarks_placement or "none" if self.explorer.opts.renderer.icons.show.bookmarks then self.icon = { diff --git a/lua/nvim-tree/renderer/decorator/copied.lua b/lua/nvim-tree/renderer/decorator/copied.lua index 4422638535d..5289a7617e8 100644 --- a/lua/nvim-tree/renderer/decorator/copied.lua +++ b/lua/nvim-tree/renderer/decorator/copied.lua @@ -10,16 +10,11 @@ local DecoratorCopied = Decorator:extend() ---@protected ---@param args DecoratorArgs function DecoratorCopied:new(args) - self.explorer = args.explorer + self.explorer = args.explorer - ---@type AbstractDecoratorArgs - local a = { - enabled = true, - highlight_range = self.explorer.opts.renderer.highlight_clipboard or "none", - icon_placement = "none", - } - - DecoratorCopied.super.new(self, a) + self.enabled = true + self.highlight_range = self.explorer.opts.renderer.highlight_clipboard or "none" + self.icon_placement = "none" end ---Copied highlight: renderer.highlight_clipboard and node is copied diff --git a/lua/nvim-tree/renderer/decorator/cut.lua b/lua/nvim-tree/renderer/decorator/cut.lua index 6d29991231d..64b9b96a099 100644 --- a/lua/nvim-tree/renderer/decorator/cut.lua +++ b/lua/nvim-tree/renderer/decorator/cut.lua @@ -10,16 +10,11 @@ local DecoratorCut = Decorator:extend() ---@protected ---@param args DecoratorArgs function DecoratorCut:new(args) - self.explorer = args.explorer + self.explorer = args.explorer - ---@type AbstractDecoratorArgs - local a = { - enabled = true, - highlight_range = self.explorer.opts.renderer.highlight_clipboard or "none", - icon_placement = "none", - } - - DecoratorCut.super.new(self, a) + self.enabled = true + self.highlight_range = self.explorer.opts.renderer.highlight_clipboard or "none" + self.icon_placement = "none" end ---Cut highlight: renderer.highlight_clipboard and node is cut diff --git a/lua/nvim-tree/renderer/decorator/diagnostics.lua b/lua/nvim-tree/renderer/decorator/diagnostics.lua index 6c72a2aa0e7..9802ba05e46 100644 --- a/lua/nvim-tree/renderer/decorator/diagnostics.lua +++ b/lua/nvim-tree/renderer/decorator/diagnostics.lua @@ -41,20 +41,11 @@ local DecoratorDiagnostics = Decorator:extend() ---@protected ---@param args DecoratorArgs function DecoratorDiagnostics:new(args) - self.explorer = args.explorer + self.explorer = args.explorer - ---@type AbstractDecoratorArgs - local a = { - enabled = true, - highlight_range = self.explorer.opts.renderer.highlight_diagnostics or "none", - icon_placement = self.explorer.opts.renderer.icons.diagnostics_placement or "none", - } - - DecoratorDiagnostics.super.new(self, a) - - if not self.enabled then - return - end + self.enabled = true + self.highlight_range = self.explorer.opts.renderer.highlight_diagnostics or "none" + self.icon_placement = self.explorer.opts.renderer.icons.diagnostics_placement or "none" if self.explorer.opts.renderer.icons.show.diagnostics then self.diag_icons = {} @@ -72,7 +63,7 @@ end ---@param node Node ---@return HighlightedString[]? icons function DecoratorDiagnostics:icons(node) - if node and self.enabled and self.diag_icons then + if node and self.diag_icons then local diag_status = diagnostics.get_diag_status(node) local diag_value = diag_status and diag_status.value @@ -86,7 +77,7 @@ end ---@param node Node ---@return string? highlight_group function DecoratorDiagnostics:highlight_group(node) - if not node or not self.enabled or self.highlight_range == "none" then + if self.highlight_range == "none" then return nil end diff --git a/lua/nvim-tree/renderer/decorator/git.lua b/lua/nvim-tree/renderer/decorator/git.lua index b4bc2499c17..6d5b9ec3db2 100644 --- a/lua/nvim-tree/renderer/decorator/git.lua +++ b/lua/nvim-tree/renderer/decorator/git.lua @@ -26,16 +26,11 @@ local DecoratorGit = Decorator:extend() ---@protected ---@param args DecoratorArgs function DecoratorGit:new(args) - self.explorer = args.explorer + self.explorer = args.explorer - ---@type AbstractDecoratorArgs - local a = { - enabled = self.explorer.opts.git.enable, - highlight_range = self.explorer.opts.renderer.highlight_git or "none", - icon_placement = self.explorer.opts.renderer.icons.git_placement or "none", - } - - DecoratorGit.super.new(self, a) + self.enabled = self.explorer.opts.git.enable + self.highlight_range = self.explorer.opts.renderer.highlight_git or "none" + self.icon_placement = self.explorer.opts.renderer.icons.git_placement or "none" if not self.enabled then return @@ -149,7 +144,7 @@ end ---@param node Node ---@return HighlightedString[]? icons function DecoratorGit:icons(node) - if not node or not self.enabled or not self.icons_by_xy then + if not self.icons_by_xy then return nil end @@ -210,7 +205,7 @@ end ---@param node Node ---@return string? highlight_group function DecoratorGit:highlight_group(node) - if not node or not self.enabled or self.highlight_range == "none" then + if self.highlight_range == "none" then return nil end diff --git a/lua/nvim-tree/renderer/decorator/hidden.lua b/lua/nvim-tree/renderer/decorator/hidden.lua index bf7aab23303..d35a022d148 100644 --- a/lua/nvim-tree/renderer/decorator/hidden.lua +++ b/lua/nvim-tree/renderer/decorator/hidden.lua @@ -12,16 +12,11 @@ local DecoratorHidden = Decorator:extend() ---@protected ---@param args DecoratorArgs function DecoratorHidden:new(args) - self.explorer = args.explorer + self.explorer = args.explorer - ---@type AbstractDecoratorArgs - local a = { - enabled = true, - highlight_range = self.explorer.opts.renderer.highlight_hidden or "none", - icon_placement = self.explorer.opts.renderer.icons.hidden_placement or "none", - } - - DecoratorHidden.super.new(self, a) + self.enabled = true + self.highlight_range = self.explorer.opts.renderer.highlight_hidden or "none" + self.icon_placement = self.explorer.opts.renderer.icons.hidden_placement or "none" if self.explorer.opts.renderer.icons.show.hidden then self.icon = { @@ -36,7 +31,7 @@ end ---@param node Node ---@return HighlightedString[]? icons function DecoratorHidden:icons(node) - if self.enabled and node:is_dotfile() then + if node:is_dotfile() then return { self.icon } end end @@ -45,7 +40,7 @@ end ---@param node Node ---@return string? highlight_group function DecoratorHidden:highlight_group(node) - if not self.enabled or self.highlight_range == "none" or not node:is_dotfile() then + if self.highlight_range == "none" or not node:is_dotfile() then return nil end diff --git a/lua/nvim-tree/renderer/decorator/init.lua b/lua/nvim-tree/renderer/decorator/init.lua index 9c6a6bc1874..97ea697f668 100644 --- a/lua/nvim-tree/renderer/decorator/init.lua +++ b/lua/nvim-tree/renderer/decorator/init.lua @@ -3,29 +3,34 @@ local Class = require("nvim-tree.classic") ---Abstract Decorator ---@class (exact) Decorator: Class ---@field protected enabled boolean ----@field protected highlight_range DecoratorHighlightRange ----@field protected icon_placement DecoratorIconPlacement +---@field protected highlight_range nvim_tree.api.decorator.HighlightRange +---@field protected icon_placement nvim_tree.api.decorator.IconPlacement local Decorator = Class:extend() ---@class (exact) DecoratorArgs ---@field explorer Explorer ----Abstract constructor ----@class (exact) AbstractDecoratorArgs ----@field enabled boolean ----@field highlight_range DecoratorHighlightRange ----@field icon_placement DecoratorIconPlacement ---- +---Abstract icon override, optionally implemented +---@param node Node +---@return HighlightedString? icon_node +function Decorator:icon_node(node) + return self:nop(node) +end + +---Abstract icons, optionally implemented ---@protected ----@param args AbstractDecoratorArgs -function Decorator:new(args) - if args then - self.enabled = args.enabled - self.highlight_range = args.highlight_range - self.icon_placement = args.icon_placement - else - self.enabled = false - end +---@param node Node +---@return HighlightedString[]? icons +function Decorator:icons(node) + self:nop(node) +end + +---Abstract highlight group, optionally implemented +---@protected +---@param node Node +---@return string? highlight_group +function Decorator:highlight_group(node) + self:nop(node) end ---Maybe highlight groups for icon and name @@ -96,29 +101,6 @@ function Decorator:icons_right_align(node) return self:icons(node) end ----Maybe icon override, optionally implemented ----@param node Node ----@return HighlightedString? icon_node -function Decorator:icon_node(node) - return self:nop(node) -end - ----Maybe icons, optionally implemented ----@protected ----@param node Node ----@return HighlightedString[]? icons -function Decorator:icons(node) - self:nop(node) -end - ----Maybe highlight group, optionally implemented ----@protected ----@param node Node ----@return string? highlight_group -function Decorator:highlight_group(node) - self:nop(node) -end - ---Define a sign ---@protected ---@param icon HighlightedString? diff --git a/lua/nvim-tree/renderer/decorator/modified.lua b/lua/nvim-tree/renderer/decorator/modified.lua index e2cad99aca8..bece8c6ee00 100644 --- a/lua/nvim-tree/renderer/decorator/modified.lua +++ b/lua/nvim-tree/renderer/decorator/modified.lua @@ -14,20 +14,11 @@ local DecoratorModified = Decorator:extend() ---@protected ---@param args DecoratorArgs function DecoratorModified:new(args) - self.explorer = args.explorer + self.explorer = args.explorer - ---@type AbstractDecoratorArgs - local a = { - enabled = true, - highlight_range = self.explorer.opts.renderer.highlight_modified or "none", - icon_placement = self.explorer.opts.renderer.icons.modified_placement or "none", - } - - DecoratorModified.super.new(self, a) - - if not self.enabled then - return - end + self.enabled = true + self.highlight_range = self.explorer.opts.renderer.highlight_modified or "none" + self.icon_placement = self.explorer.opts.renderer.icons.modified_placement or "none" if self.explorer.opts.renderer.icons.show.modified then self.icon = { @@ -42,7 +33,7 @@ end ---@param node Node ---@return HighlightedString[]? icons function DecoratorModified:icons(node) - if self.enabled and buffers.is_modified(node) then + if buffers.is_modified(node) then return { self.icon } end end @@ -51,7 +42,7 @@ end ---@param node Node ---@return string? highlight_group function DecoratorModified:highlight_group(node) - if not self.enabled or self.highlight_range == "none" or not buffers.is_modified(node) then + if self.highlight_range == "none" or not buffers.is_modified(node) then return nil end diff --git a/lua/nvim-tree/renderer/decorator/opened.lua b/lua/nvim-tree/renderer/decorator/opened.lua index da500c083b2..31c7a551293 100644 --- a/lua/nvim-tree/renderer/decorator/opened.lua +++ b/lua/nvim-tree/renderer/decorator/opened.lua @@ -13,16 +13,11 @@ local DecoratorOpened = Decorator:extend() ---@protected ---@param args DecoratorArgs function DecoratorOpened:new(args) - self.explorer = args.explorer + self.explorer = args.explorer - ---@type AbstractDecoratorArgs - local a = { - enabled = true, - highlight_range = self.explorer.opts.renderer.highlight_opened_files or "none", - icon_placement = "none", - } - - DecoratorOpened.super.new(self, a) + self.enabled = true + self.highlight_range = self.explorer.opts.renderer.highlight_opened_files or "none" + self.icon_placement = "none" end ---Opened highlight: renderer.highlight_opened_files and node has an open buffer diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index b0037e7a5be..8e554986436 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -4,10 +4,4 @@ local Decorator = require("nvim-tree.renderer.decorator") ---@class (exact) DecoratorUser: Decorator local DecoratorUser = Decorator:extend() ----User calls this instead of new ----@param args nvim_tree.api.decorator.InitArgs -function DecoratorUser:init(args) - DecoratorUser.super.new(self, args) -end - return DecoratorUser From 3b60fa7dfa2544abcd6a88babd5b99e746e067a5 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 1 Dec 2024 15:40:14 +1100 Subject: [PATCH 21/27] feat(#2948): decorator classes specified by prefix rather than suffix --- doc/nvim-tree-lua.txt | 8 +-- lua/nvim-tree.lua | 2 +- lua/nvim-tree/_meta/api_decorator.lua | 14 +++--- lua/nvim-tree/api.lua | 6 +-- lua/nvim-tree/renderer/builder.lua | 50 +++++++++---------- .../renderer/decorator/bookmarks.lua | 16 +++--- lua/nvim-tree/renderer/decorator/copied.lua | 14 +++--- lua/nvim-tree/renderer/decorator/cut.lua | 14 +++--- .../renderer/decorator/diagnostics.lua | 16 +++--- lua/nvim-tree/renderer/decorator/git.lua | 24 ++++----- lua/nvim-tree/renderer/decorator/hidden.lua | 16 +++--- lua/nvim-tree/renderer/decorator/modified.lua | 16 +++--- lua/nvim-tree/renderer/decorator/opened.lua | 14 +++--- lua/nvim-tree/renderer/decorator/user.lua | 8 +-- 14 files changed, 109 insertions(+), 109 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index f16dbda65a4..5252cae796e 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -929,7 +929,7 @@ Whether to show the destination of the symlink. *nvim-tree.renderer.decorators* Highlighting and icons for the nodes, in increasing order of precedence. Uses strings to specify builtin decorators otherwise specify your -`nvim_tree.api.decorator.DecoratorUser` class. +`nvim_tree.api.decorator.UserDecorator` class. Type: `nvim_tree.api.decorator.Name[]`, Default: >lua { "Git", @@ -2777,7 +2777,7 @@ Decorators may: - Set highlight group for the name or icons - Override node icon -Create your decorator class via `api.decorator.DecoratorUser:extend()` and add it +Create your decorator class via `api.decorator.UserDecorator:extend()` and add it to |nvim-tree.renderer.decorators| e.g. default decorators with an user decorator being overridden only by Cut: >lua @@ -2798,9 +2798,9 @@ See `api_decorator.lua` for decorator class definition and full documentation. Example decorator: >lua ---Create your decorator class - ---@class (exact) MyDecorator: nvim_tree.api.decorator.DecoratorUser + ---@class (exact) MyDecorator: nvim_tree.api.decorator.UserDecorator ---@field private my_icon nvim_tree.api.HighlightedString - local MyDecorator = require("nvim-tree.api").decorator.DecoratorUser:extend() + local MyDecorator = require("nvim-tree.api").decorator.UserDecorator:extend() ---Mandatory constructor :new() will be called once per tree render, with no arguments. function MyDecorator:new() diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index c26b52e163f..6ee2fd26800 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -284,7 +284,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS special_files = { "Cargo.toml", "Makefile", "README.md", "readme.md" }, hidden_display = "none", symlink_destination = true, - decorators = { "Git", "Opened", "Hidden", "Modified", "Bookmarks", "Diagnostics", "Copied", "Cut", }, + decorators = { "Git", "Open", "Hidden", "Modified", "Bookmark", "Diagnostics", "Copied", "Cut", }, highlight_git = "none", highlight_diagnostics = "none", highlight_opened_files = "none", diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua index 949f11bfa48..f0862ac160a 100644 --- a/lua/nvim-tree/_meta/api_decorator.lua +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -10,11 +10,11 @@ local nvim_tree = {} ---@alias nvim_tree.api.decorator.IconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" ---Names of builtin decorators or your decorator classes. Builtins are ordered lowest to highest priority. ----@alias nvim_tree.api.decorator.Name "Git" | "Opened" | "Hidden" | "Modified" | "Bookmarks" | "Diagnostics" | "Copied" | "Cut" | nvim_tree.api.decorator.DecoratorUser +---@alias nvim_tree.api.decorator.Name "Git" | "Opened" | "Hidden" | "Modified" | "Bookmarks" | "Diagnostics" | "Copied" | "Cut" | nvim_tree.api.decorator.UserDecorator ---Custom decorator, see :help nvim-tree-decorators --- ----@class (exact) nvim_tree.api.decorator.DecoratorUser +---@class (exact) nvim_tree.api.decorator.UserDecorator ---@field protected enabled boolean ---@field protected highlight_range nvim_tree.api.decorator.HighlightRange ---@field protected icon_placement nvim_tree.api.decorator.IconPlacement @@ -22,28 +22,28 @@ local nvim_tree = {} ---Abstract: no-args constructor must be implemented and will be called once per tree render. ---Must set all fields. --- -function nvim_tree.api.decorator.DecoratorUser:new() end +function nvim_tree.api.decorator.UserDecorator:new() end ---Abstract: optionally implement to set the node's icon --- ---@param node nvim_tree.api.Node ---@return nvim_tree.api.HighlightedString? icon_node -function nvim_tree.api.decorator.DecoratorUser:icon_node(node) end +function nvim_tree.api.decorator.UserDecorator:icon_node(node) end ---Abstract: optionally implement to provide icons and the highlight groups for your icon_placement. --- ---@param node nvim_tree.api.Node ---@return nvim_tree.api.HighlightedString[]? icons -function nvim_tree.api.decorator.DecoratorUser:icons(node) end +function nvim_tree.api.decorator.UserDecorator:icons(node) end ---Abstract: optionally implement to provide one highlight group to apply to your highlight_range. --- ---@param node nvim_tree.api.Node ---@return string? highlight_group -function nvim_tree.api.decorator.DecoratorUser:highlight_group(node) end +function nvim_tree.api.decorator.UserDecorator:highlight_group(node) end ---Define a sign. This should be called in the constructor. --- ---@protected ---@param icon nvim_tree.api.HighlightedString? -function nvim_tree.api.decorator.DecoratorUser:define_sign(icon) end +function nvim_tree.api.decorator.UserDecorator:define_sign(icon) end diff --git a/lua/nvim-tree/api.lua b/lua/nvim-tree/api.lua index 3da5437fe1a..fe7545d9b64 100644 --- a/lua/nvim-tree/api.lua +++ b/lua/nvim-tree/api.lua @@ -11,7 +11,7 @@ local notify = require("nvim-tree.notify") local DirectoryNode = require("nvim-tree.node.directory") local FileLinkNode = require("nvim-tree.node.file-link") local RootNode = require("nvim-tree.node.root") -local DecoratorUser = require("nvim-tree.renderer.decorator.user") +local UserDecorator = require("nvim-tree.renderer.decorator.user") local Api = { tree = {}, @@ -314,7 +314,7 @@ Api.commands.get = wrap(function() end) ---Create a decorator class by calling :extend() ----@type nvim_tree.api.decorator.DecoratorUser -Api.decorator.DecoratorUser = DecoratorUser --[[@as nvim_tree.api.decorator.DecoratorUser]] +---@type nvim_tree.api.decorator.UserDecorator +Api.decorator.UserDecorator = UserDecorator --[[@as nvim_tree.api.decorator.UserDecorator]] return Api diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 833df5767ce..c94af0e2a5a 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -6,15 +6,15 @@ local Class = require("nvim-tree.classic") local DirectoryNode = require("nvim-tree.node.directory") -local DecoratorBookmarks = require("nvim-tree.renderer.decorator.bookmarks") -local DecoratorCopied = require("nvim-tree.renderer.decorator.copied") -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 DecoratorHidden = require("nvim-tree.renderer.decorator.hidden") -local DecoratorModified = require("nvim-tree.renderer.decorator.modified") -local DecoratorOpened = require("nvim-tree.renderer.decorator.opened") -local DecoratorUser = require("nvim-tree.renderer.decorator.user") +local BookmarkDecorator = require("nvim-tree.renderer.decorator.bookmarks") +local CopiedDecorator = require("nvim-tree.renderer.decorator.copied") +local CutDecorator = require("nvim-tree.renderer.decorator.cut") +local DiagnosticsDecorator = require("nvim-tree.renderer.decorator.diagnostics") +local GitDecorator = require("nvim-tree.renderer.decorator.git") +local HiddenDecorator = require("nvim-tree.renderer.decorator.hidden") +local ModifiedDecorator = require("nvim-tree.renderer.decorator.modified") +local OpenDecorator = require("nvim-tree.renderer.decorator.opened") +local UserDecorator = require("nvim-tree.renderer.decorator.user") local pad = require("nvim-tree.renderer.components.padding") @@ -23,14 +23,14 @@ local pad = require("nvim-tree.renderer.components.padding") -- Builtin Decorators ---@type table local BUILTIN_DECORATORS = { - Git = DecoratorGit, - Opened = DecoratorOpened, - Hidden = DecoratorHidden, - Modified = DecoratorModified, - Bookmarks = DecoratorBookmarks, - Diagnostics = DecoratorDiagnostics, - Copied = DecoratorCopied, - Cut = DecoratorCut, + Git = GitDecorator, + Open = OpenDecorator, + Hidden = HiddenDecorator, + Modified = ModifiedDecorator, + Bookmark = BookmarkDecorator, + Diagnostics = DiagnosticsDecorator, + Copied = CopiedDecorator, + Cut = CutDecorator, } ---@class (exact) AddHighlightArgs @@ -83,8 +83,8 @@ function Builder:new(args) ---@type Decorator builtin = BUILTIN_DECORATORS[d] - ---@type DecoratorUser - user = d.as and d:as(DecoratorUser) + ---@type UserDecorator + user = d.as and d:as(UserDecorator) if builtin then table.insert(self.decorators, builtin({ explorer = self.explorer })) @@ -164,18 +164,18 @@ function Builder:format_line(indent_markers, arrows, icon, name, node) add_to_end(line, { icon }) for _, d in ipairs(self.decorators) do - add_to_end(line, d:icons_before(not d:is(DecoratorUser) and node or api_node)) + add_to_end(line, d:icons_before(not d:is(UserDecorator) and node or api_node)) end add_to_end(line, { name }) for _, d in ipairs(self.decorators) do - add_to_end(line, d:icons_after(not d:is(DecoratorUser) and node or api_node)) + add_to_end(line, d:icons_after(not d:is(UserDecorator) and node or api_node)) end local rights = {} for _, d in ipairs(self.decorators) do - add_to_end(rights, d:icons_right_align(not d:is(DecoratorUser) and node or api_node)) + add_to_end(rights, d:icons_right_align(not d:is(UserDecorator) and node or api_node)) end if #rights > 0 then self.extmarks[self.index] = rights @@ -194,7 +194,7 @@ function Builder:build_signs(node) local d, sign_name for i = #self.decorators, 1, -1 do d = self.decorators[i] - sign_name = d:sign_name(not d:is(DecoratorUser) and node or api_node) + sign_name = d:sign_name(not d:is(UserDecorator) and node or api_node) if sign_name then self.signs[self.index] = sign_name break @@ -251,9 +251,9 @@ function Builder:icon_name_decorated(node) local hl_icon, hl_name for _, d in ipairs(self.decorators) do -- maybe overridde icon - icon = d:icon_node((not d:is(DecoratorUser) and node or api_node)) or icon + icon = d:icon_node((not d:is(UserDecorator) and node or api_node)) or icon - hl_icon, hl_name = d:highlight_group_icon_name((not d:is(DecoratorUser) and node or api_node)) + hl_icon, hl_name = d:highlight_group_icon_name((not d:is(UserDecorator) and node or api_node)) table.insert(icon_groups, hl_icon) table.insert(name_groups, hl_name) diff --git a/lua/nvim-tree/renderer/decorator/bookmarks.lua b/lua/nvim-tree/renderer/decorator/bookmarks.lua index b50073d4464..c661748ef21 100644 --- a/lua/nvim-tree/renderer/decorator/bookmarks.lua +++ b/lua/nvim-tree/renderer/decorator/bookmarks.lua @@ -1,16 +1,16 @@ local Decorator = require("nvim-tree.renderer.decorator") ----@class (exact) DecoratorBookmarks: Decorator +---@class (exact) BookmarkDecorator: Decorator ---@field private explorer Explorer ---@field private icon HighlightedString? -local DecoratorBookmarks = Decorator:extend() +local BookmarkDecorator = Decorator:extend() ----@class DecoratorBookmarks ----@overload fun(args: DecoratorArgs): DecoratorBookmarks +---@class BookmarkDecorator +---@overload fun(args: DecoratorArgs): BookmarkDecorator ---@protected ---@param args DecoratorArgs -function DecoratorBookmarks:new(args) +function BookmarkDecorator:new(args) self.explorer = args.explorer self.enabled = true @@ -29,7 +29,7 @@ end ---Bookmark icon: renderer.icons.show.bookmarks and node is marked ---@param node Node ---@return HighlightedString[]? icons -function DecoratorBookmarks:icons(node) +function BookmarkDecorator:icons(node) if self.explorer.marks:get(node) then return { self.icon } end @@ -38,10 +38,10 @@ end ---Bookmark highlight: renderer.highlight_bookmarks and node is marked ---@param node Node ---@return string? highlight_group -function DecoratorBookmarks:highlight_group(node) +function BookmarkDecorator:highlight_group(node) if self.highlight_range ~= "none" and self.explorer.marks:get(node) then return "NvimTreeBookmarkHL" end end -return DecoratorBookmarks +return BookmarkDecorator diff --git a/lua/nvim-tree/renderer/decorator/copied.lua b/lua/nvim-tree/renderer/decorator/copied.lua index 5289a7617e8..4c452e09e2f 100644 --- a/lua/nvim-tree/renderer/decorator/copied.lua +++ b/lua/nvim-tree/renderer/decorator/copied.lua @@ -1,15 +1,15 @@ local Decorator = require("nvim-tree.renderer.decorator") ----@class (exact) DecoratorCopied: Decorator +---@class (exact) CopiedDecorator: Decorator ---@field private explorer Explorer -local DecoratorCopied = Decorator:extend() +local CopiedDecorator = Decorator:extend() ----@class DecoratorCopied ----@overload fun(args: DecoratorArgs): DecoratorCopied +---@class CopiedDecorator +---@overload fun(args: DecoratorArgs): CopiedDecorator ---@protected ---@param args DecoratorArgs -function DecoratorCopied:new(args) +function CopiedDecorator:new(args) self.explorer = args.explorer self.enabled = true @@ -20,10 +20,10 @@ end ---Copied highlight: renderer.highlight_clipboard and node is copied ---@param node Node ---@return string? highlight_group -function DecoratorCopied:highlight_group(node) +function CopiedDecorator:highlight_group(node) if self.highlight_range ~= "none" and self.explorer.clipboard:is_copied(node) then return "NvimTreeCopiedHL" end end -return DecoratorCopied +return CopiedDecorator diff --git a/lua/nvim-tree/renderer/decorator/cut.lua b/lua/nvim-tree/renderer/decorator/cut.lua index 64b9b96a099..8a212da5d68 100644 --- a/lua/nvim-tree/renderer/decorator/cut.lua +++ b/lua/nvim-tree/renderer/decorator/cut.lua @@ -1,15 +1,15 @@ local Decorator = require("nvim-tree.renderer.decorator") ----@class (exact) DecoratorCut: Decorator +---@class (exact) CutDecorator: Decorator ---@field private explorer Explorer -local DecoratorCut = Decorator:extend() +local CutDecorator = Decorator:extend() ----@class DecoratorCut ----@overload fun(args: DecoratorArgs): DecoratorCut +---@class CutDecorator +---@overload fun(args: DecoratorArgs): CutDecorator ---@protected ---@param args DecoratorArgs -function DecoratorCut:new(args) +function CutDecorator:new(args) self.explorer = args.explorer self.enabled = true @@ -20,10 +20,10 @@ end ---Cut highlight: renderer.highlight_clipboard and node is cut ---@param node Node ---@return string? highlight_group -function DecoratorCut:highlight_group(node) +function CutDecorator:highlight_group(node) if self.highlight_range ~= "none" and self.explorer.clipboard:is_cut(node) then return "NvimTreeCutHL" end end -return DecoratorCut +return CutDecorator diff --git a/lua/nvim-tree/renderer/decorator/diagnostics.lua b/lua/nvim-tree/renderer/decorator/diagnostics.lua index 9802ba05e46..35f76109251 100644 --- a/lua/nvim-tree/renderer/decorator/diagnostics.lua +++ b/lua/nvim-tree/renderer/decorator/diagnostics.lua @@ -30,17 +30,17 @@ local ICON_KEYS = { ["hint"] = vim.diagnostic.severity.HINT, } ----@class (exact) DecoratorDiagnostics: Decorator +---@class (exact) DiagnosticsDecorator: Decorator ---@field private explorer Explorer ---@field private diag_icons HighlightedString[]? -local DecoratorDiagnostics = Decorator:extend() +local DiagnosticsDecorator = Decorator:extend() ----@class DecoratorDiagnostics ----@overload fun(args: DecoratorArgs): DecoratorDiagnostics +---@class DiagnosticsDecorator +---@overload fun(args: DecoratorArgs): DiagnosticsDecorator ---@protected ---@param args DecoratorArgs -function DecoratorDiagnostics:new(args) +function DiagnosticsDecorator:new(args) self.explorer = args.explorer self.enabled = true @@ -62,7 +62,7 @@ end ---Diagnostic icon: diagnostics.enable, renderer.icons.show.diagnostics and node has status ---@param node Node ---@return HighlightedString[]? icons -function DecoratorDiagnostics:icons(node) +function DiagnosticsDecorator:icons(node) if node and self.diag_icons then local diag_status = diagnostics.get_diag_status(node) local diag_value = diag_status and diag_status.value @@ -76,7 +76,7 @@ end ---Diagnostic highlight: diagnostics.enable, renderer.highlight_diagnostics and node has status ---@param node Node ---@return string? highlight_group -function DecoratorDiagnostics:highlight_group(node) +function DiagnosticsDecorator:highlight_group(node) if self.highlight_range == "none" then return nil end @@ -102,4 +102,4 @@ function DecoratorDiagnostics:highlight_group(node) end end -return DecoratorDiagnostics +return DiagnosticsDecorator diff --git a/lua/nvim-tree/renderer/decorator/git.lua b/lua/nvim-tree/renderer/decorator/git.lua index 6d5b9ec3db2..c62ef00ae03 100644 --- a/lua/nvim-tree/renderer/decorator/git.lua +++ b/lua/nvim-tree/renderer/decorator/git.lua @@ -12,20 +12,20 @@ local DirectoryNode = require("nvim-tree.node.directory") ---@alias GitIconsByXY table porcelain status ---@alias GitGlyphsByStatus table from opts ----@class (exact) DecoratorGit: Decorator +---@class (exact) GitDecorator: Decorator ---@field private explorer Explorer ---@field private file_hl_by_xy table? ---@field private folder_hl_by_xy table? ---@field private icons_by_status GitIconsByStatus? ---@field private icons_by_xy GitIconsByXY? -local DecoratorGit = Decorator:extend() +local GitDecorator = Decorator:extend() ----@class DecoratorGit ----@overload fun(args: DecoratorArgs): DecoratorGit +---@class GitDecorator +---@overload fun(args: DecoratorArgs): GitDecorator ---@protected ---@param args DecoratorArgs -function DecoratorGit:new(args) +function GitDecorator:new(args) self.explorer = args.explorer self.enabled = self.explorer.opts.git.enable @@ -51,7 +51,7 @@ function DecoratorGit:new(args) end ---@param glyphs GitGlyphsByStatus -function DecoratorGit:build_icons_by_status(glyphs) +function GitDecorator:build_icons_by_status(glyphs) self.icons_by_status = {} self.icons_by_status.staged = { str = glyphs.staged, hl = { "NvimTreeGitStagedIcon" }, ord = 1 } self.icons_by_status.unstaged = { str = glyphs.unstaged, hl = { "NvimTreeGitDirtyIcon" }, ord = 2 } @@ -63,7 +63,7 @@ function DecoratorGit:build_icons_by_status(glyphs) end ---@param icons GitIconsByXY -function DecoratorGit:build_icons_by_xy(icons) +function GitDecorator:build_icons_by_xy(icons) self.icons_by_xy = { ["M "] = { icons.staged }, [" M"] = { icons.unstaged }, @@ -100,7 +100,7 @@ function DecoratorGit:build_icons_by_xy(icons) } end -function DecoratorGit:build_file_folder_hl_by_xy() +function GitDecorator:build_file_folder_hl_by_xy() self.file_hl_by_xy = { ["M "] = "NvimTreeGitFileStagedHL", ["C "] = "NvimTreeGitFileStagedHL", @@ -143,7 +143,7 @@ end ---Git icons: git.enable, renderer.icons.show.git and node has status ---@param node Node ---@return HighlightedString[]? icons -function DecoratorGit:icons(node) +function GitDecorator:icons(node) if not self.icons_by_xy then return nil end @@ -190,7 +190,7 @@ end ---Get the first icon as the sign if appropriate ---@param node Node ---@return string|nil name -function DecoratorGit:sign_name(node) +function GitDecorator:sign_name(node) if self.icon_placement ~= "signcolumn" then return end @@ -204,7 +204,7 @@ end ---Git highlight: git.enable, renderer.highlight_git and node has status ---@param node Node ---@return string? highlight_group -function DecoratorGit:highlight_group(node) +function GitDecorator:highlight_group(node) if self.highlight_range == "none" then return nil end @@ -221,4 +221,4 @@ function DecoratorGit:highlight_group(node) end end -return DecoratorGit +return GitDecorator diff --git a/lua/nvim-tree/renderer/decorator/hidden.lua b/lua/nvim-tree/renderer/decorator/hidden.lua index d35a022d148..87168ceb82b 100644 --- a/lua/nvim-tree/renderer/decorator/hidden.lua +++ b/lua/nvim-tree/renderer/decorator/hidden.lua @@ -1,17 +1,17 @@ local Decorator = require("nvim-tree.renderer.decorator") local DirectoryNode = require("nvim-tree.node.directory") ----@class (exact) DecoratorHidden: Decorator +---@class (exact) HiddenDecorator: Decorator ---@field private explorer Explorer ---@field private icon HighlightedString? -local DecoratorHidden = Decorator:extend() +local HiddenDecorator = Decorator:extend() ----@class DecoratorHidden ----@overload fun(args: DecoratorArgs): DecoratorHidden +---@class HiddenDecorator +---@overload fun(args: DecoratorArgs): HiddenDecorator ---@protected ---@param args DecoratorArgs -function DecoratorHidden:new(args) +function HiddenDecorator:new(args) self.explorer = args.explorer self.enabled = true @@ -30,7 +30,7 @@ end ---Hidden icon: renderer.icons.show.hidden and node starts with `.` (dotfile). ---@param node Node ---@return HighlightedString[]? icons -function DecoratorHidden:icons(node) +function HiddenDecorator:icons(node) if node:is_dotfile() then return { self.icon } end @@ -39,7 +39,7 @@ end ---Hidden highlight: renderer.highlight_hidden and node starts with `.` (dotfile). ---@param node Node ---@return string? highlight_group -function DecoratorHidden:highlight_group(node) +function HiddenDecorator:highlight_group(node) if self.highlight_range == "none" or not node:is_dotfile() then return nil end @@ -51,4 +51,4 @@ function DecoratorHidden:highlight_group(node) end end -return DecoratorHidden +return HiddenDecorator diff --git a/lua/nvim-tree/renderer/decorator/modified.lua b/lua/nvim-tree/renderer/decorator/modified.lua index bece8c6ee00..c182e300afc 100644 --- a/lua/nvim-tree/renderer/decorator/modified.lua +++ b/lua/nvim-tree/renderer/decorator/modified.lua @@ -3,17 +3,17 @@ local buffers = require("nvim-tree.buffers") local Decorator = require("nvim-tree.renderer.decorator") local DirectoryNode = require("nvim-tree.node.directory") ----@class (exact) DecoratorModified: Decorator +---@class (exact) ModifiedDecorator: Decorator ---@field private explorer Explorer ---@field private icon HighlightedString? -local DecoratorModified = Decorator:extend() +local ModifiedDecorator = Decorator:extend() ----@class DecoratorModified ----@overload fun(args: DecoratorArgs): DecoratorModified +---@class ModifiedDecorator +---@overload fun(args: DecoratorArgs): ModifiedDecorator ---@protected ---@param args DecoratorArgs -function DecoratorModified:new(args) +function ModifiedDecorator:new(args) self.explorer = args.explorer self.enabled = true @@ -32,7 +32,7 @@ end ---Modified icon: modified.enable, renderer.icons.show.modified and node is modified ---@param node Node ---@return HighlightedString[]? icons -function DecoratorModified:icons(node) +function ModifiedDecorator:icons(node) if buffers.is_modified(node) then return { self.icon } end @@ -41,7 +41,7 @@ end ---Modified highlight: modified.enable, renderer.highlight_modified and node is modified ---@param node Node ---@return string? highlight_group -function DecoratorModified:highlight_group(node) +function ModifiedDecorator:highlight_group(node) if self.highlight_range == "none" or not buffers.is_modified(node) then return nil end @@ -53,4 +53,4 @@ function DecoratorModified:highlight_group(node) end end -return DecoratorModified +return ModifiedDecorator diff --git a/lua/nvim-tree/renderer/decorator/opened.lua b/lua/nvim-tree/renderer/decorator/opened.lua index 31c7a551293..240dce4948a 100644 --- a/lua/nvim-tree/renderer/decorator/opened.lua +++ b/lua/nvim-tree/renderer/decorator/opened.lua @@ -2,17 +2,17 @@ local buffers = require("nvim-tree.buffers") local Decorator = require("nvim-tree.renderer.decorator") ----@class (exact) DecoratorOpened: Decorator +---@class (exact) OpenDecorator: Decorator ---@field private explorer Explorer ---@field private icon HighlightedString|nil -local DecoratorOpened = Decorator:extend() +local OpenDecorator = Decorator:extend() ----@class DecoratorOpened ----@overload fun(args: DecoratorArgs): DecoratorOpened +---@class OpenDecorator +---@overload fun(args: DecoratorArgs): OpenDecorator ---@protected ---@param args DecoratorArgs -function DecoratorOpened:new(args) +function OpenDecorator:new(args) self.explorer = args.explorer self.enabled = true @@ -23,10 +23,10 @@ end ---Opened highlight: renderer.highlight_opened_files and node has an open buffer ---@param node Node ---@return string? highlight_group -function DecoratorOpened:highlight_group(node) +function OpenDecorator:highlight_group(node) if self.highlight_range ~= "none" and buffers.is_opened(node) then return "NvimTreeOpenedHL" end end -return DecoratorOpened +return OpenDecorator diff --git a/lua/nvim-tree/renderer/decorator/user.lua b/lua/nvim-tree/renderer/decorator/user.lua index 8e554986436..df55f543936 100644 --- a/lua/nvim-tree/renderer/decorator/user.lua +++ b/lua/nvim-tree/renderer/decorator/user.lua @@ -1,7 +1,7 @@ local Decorator = require("nvim-tree.renderer.decorator") ----Exposed as nvim_tree.api.decorator.DecoratorUser ----@class (exact) DecoratorUser: Decorator -local DecoratorUser = Decorator:extend() +---Exposed as nvim_tree.api.decorator.UserDecorator +---@class (exact) UserDecorator: Decorator +local UserDecorator = Decorator:extend() -return DecoratorUser +return UserDecorator From fd49b1fbe87411f0e48779ac7ebcb03fee954a82 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 1 Dec 2024 15:49:17 +1100 Subject: [PATCH 22/27] feat(#2948): improve doc --- doc/nvim-tree-lua.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 5252cae796e..3c8553be568 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -53,6 +53,7 @@ CONTENTS *nvim-tree* 9. Events |nvim-tree-events| 10. Prompts |nvim-tree-prompts| 11. Decorators |nvim-tree-decorators| + 11.1 Decorator Example |nvim-tree-decorator-example| 12. OS Specific Restrictions |nvim-tree-os-specific| 13. Netrw |nvim-tree-netrw| 14. Legacy |nvim-tree-legacy| @@ -426,7 +427,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. >lua special_files = { "Cargo.toml", "Makefile", "README.md", "readme.md" }, hidden_display = "none", symlink_destination = true, - decorators = { "Git", "Opened", "Hidden", "Modified", "Bookmarks", "Diagnostics", "Copied", "Cut", }, + decorators = { "Git", "Open", "Hidden", "Modified", "Bookmark", "Diagnostics", "Copied", "Cut", }, highlight_git = "none", highlight_diagnostics = "none", highlight_opened_files = "none", @@ -933,10 +934,10 @@ Uses strings to specify builtin decorators otherwise specify your Type: `nvim_tree.api.decorator.Name[]`, Default: >lua { "Git", - "Opened", + "Open", "Hidden", "Modified", - "Bookmarks", + "Bookmark", "Diagnostics", "Copied", "Cut", @@ -2777,26 +2778,25 @@ Decorators may: - Set highlight group for the name or icons - Override node icon -Create your decorator class via `api.decorator.UserDecorator:extend()` and add it -to |nvim-tree.renderer.decorators| +See `api_decorator.lua` for decorator class definition and full documentation. -e.g. default decorators with an user decorator being overridden only by Cut: >lua +Specify decorators and their precedence via |nvim-tree.renderer.decorators| +e.g. defaults with a user decorator being overridden only by Cut: >lua { "Git", - "Opened", + "Open", "Hidden", "Modified", - "Bookmarks", + "Bookmark", "Diagnostics", "Copied", MyDecorator, "Cut", } < -See `api_decorator.lua` for decorator class definition and full documentation. - -Example decorator: >lua - +============================================================================== + 11.1. DECORATOR EXAMPLE *nvim-tree-decorator-example* +>lua ---Create your decorator class ---@class (exact) MyDecorator: nvim_tree.api.decorator.UserDecorator ---@field private my_icon nvim_tree.api.HighlightedString From dcfcecbb66eb5450da180847e26158e03543dad3 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 1 Dec 2024 15:52:45 +1100 Subject: [PATCH 23/27] feat(#2948): improve doc --- lua/nvim-tree/api.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lua/nvim-tree/api.lua b/lua/nvim-tree/api.lua index fe7545d9b64..455d4b0df08 100644 --- a/lua/nvim-tree/api.lua +++ b/lua/nvim-tree/api.lua @@ -314,6 +314,7 @@ Api.commands.get = wrap(function() end) ---Create a decorator class by calling :extend() +---See :help nvim-tree-decorators ---@type nvim_tree.api.decorator.UserDecorator Api.decorator.UserDecorator = UserDecorator --[[@as nvim_tree.api.decorator.UserDecorator]] From 9e30e9fa4d4b9564b85d34c0e0ced6041e78067f Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 1 Dec 2024 15:55:55 +1100 Subject: [PATCH 24/27] feat(#2948): improve doc --- lua/nvim-tree/node/init.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/nvim-tree/node/init.lua b/lua/nvim-tree/node/init.lua index f8898d12691..da0dcc5b0eb 100644 --- a/lua/nvim-tree/node/init.lua +++ b/lua/nvim-tree/node/init.lua @@ -12,7 +12,6 @@ local Class = require("nvim-tree.classic") ---@field hidden boolean ---@field name string ---@field parent DirectoryNode? ----TODO split this into diag_severity and diag_severity_cache_version ---@field diag_status DiagStatus? ---@field private is_dot boolean cached is_dotfile local Node = Class:extend() From a063280df0823163796ab7329d818c3d6919504e Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 2 Dec 2024 10:32:57 +1100 Subject: [PATCH 25/27] feat(#2948): additional user decorator safety --- 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 c94af0e2a5a..e08eb9e6363 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -84,7 +84,7 @@ function Builder:new(args) builtin = BUILTIN_DECORATORS[d] ---@type UserDecorator - user = d.as and d:as(UserDecorator) + user = type(d) == "table" and type(d.as) == "function" and d:as(UserDecorator) if builtin then table.insert(self.decorators, builtin({ explorer = self.explorer })) From 47156b3cad391ba08e30398182183426496f704a Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 2 Dec 2024 10:34:10 +1100 Subject: [PATCH 26/27] feat(#2948): create nvim_tree.api.decorator.UserDecorator class in API, add :extend --- lua/nvim-tree/_meta/api_decorator.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lua/nvim-tree/_meta/api_decorator.lua b/lua/nvim-tree/_meta/api_decorator.lua index f0862ac160a..d85fe02fff0 100644 --- a/lua/nvim-tree/_meta/api_decorator.lua +++ b/lua/nvim-tree/_meta/api_decorator.lua @@ -1,7 +1,7 @@ ---@meta error("Cannot require a meta file") -local nvim_tree = {} +local nvim_tree = { api = { decorator = {} } } ---Highlight group range as per nvim-tree.renderer.highlight_* ---@alias nvim_tree.api.decorator.HighlightRange "none" | "icon" | "name" | "all" @@ -18,6 +18,11 @@ local nvim_tree = {} ---@field protected enabled boolean ---@field protected highlight_range nvim_tree.api.decorator.HighlightRange ---@field protected icon_placement nvim_tree.api.decorator.IconPlacement +nvim_tree.api.decorator.UserDecorator = {} + +---Create your decorator class +--- +function nvim_tree.api.decorator.UserDecorator:extend() end ---Abstract: no-args constructor must be implemented and will be called once per tree render. ---Must set all fields. From 72ef08b997c8f8c0ee8a95418cec76fea9411e52 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 2 Dec 2024 10:42:38 +1100 Subject: [PATCH 27/27] feat(#2948): improve doc --- doc/nvim-tree-lua.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 3c8553be568..07985f841fd 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -2770,7 +2770,7 @@ configurations for different types of prompts. ============================================================================== 11. DECORATORS *nvim-tree-decorators* -Highlighting and icons for nodes are is provided by Decorators. You may provide +Highlighting and icons for nodes are provided by Decorators. You may provide your own in addition to the builtin decorators. Decorators may: @@ -2778,10 +2778,8 @@ Decorators may: - Set highlight group for the name or icons - Override node icon -See `api_decorator.lua` for decorator class definition and full documentation. - Specify decorators and their precedence via |nvim-tree.renderer.decorators| -e.g. defaults with a user decorator being overridden only by Cut: >lua +e.g. defaults with a user decorator class being overridden only by Cut: >lua { "Git", "Open", @@ -2793,6 +2791,9 @@ e.g. defaults with a user decorator being overridden only by Cut: >lua MyDecorator, "Cut", } + +See `nvim-tree/_meta/api_decorator.lua` for full +`nvim_tree.api.decorator.UserDecorator` class documentation. < ============================================================================== 11.1. DECORATOR EXAMPLE *nvim-tree-decorator-example*