From ff3dd126b9ea42e25c5e60e8db57c53653af9c7b Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sat, 9 Nov 2024 16:11:16 +1100 Subject: [PATCH] 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