feat(#2948): add UserDecorator, proof of concept

This commit is contained in:
Alexander Courtis 2024-11-09 16:11:16 +11:00
parent c7639482a1
commit ff3dd126b9
12 changed files with 114 additions and 81 deletions

View File

@ -276,6 +276,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
}, },
}, },
renderer = { renderer = {
user_decorators = {},
add_trailing = false, add_trailing = false,
group_empty = false, group_empty = false,
full_name = false, full_name = false,

View File

@ -13,12 +13,14 @@ local DecoratorGit = require("nvim-tree.renderer.decorator.git")
local DecoratorModified = require("nvim-tree.renderer.decorator.modified") local DecoratorModified = require("nvim-tree.renderer.decorator.modified")
local DecoratorHidden = require("nvim-tree.renderer.decorator.hidden") local DecoratorHidden = require("nvim-tree.renderer.decorator.hidden")
local DecoratorOpened = require("nvim-tree.renderer.decorator.opened") local DecoratorOpened = require("nvim-tree.renderer.decorator.opened")
local UserDecoratorExample = require("nvim-tree.renderer.decorator.example")
local pad = require("nvim-tree.renderer.components.padding") local pad = require("nvim-tree.renderer.components.padding")
---@class (exact) HighlightedString ----TODO move all these classes to API meta
---@field str string ----@class (exact) HighlightedString
---@field hl string[] ----@field str string
----@field hl string[]
---@class (exact) AddHighlightArgs ---@class (exact) AddHighlightArgs
---@field group string[] ---@field group string[]
@ -62,16 +64,20 @@ function Builder:new(args)
self.virtual_lines = {} self.virtual_lines = {}
self.decorators = { self.decorators = {
-- priority order -- priority order
DecoratorCut({ explorer = args.explorer }), DecoratorCut(self.explorer),
DecoratorCopied({ explorer = args.explorer }), DecoratorCopied(self.explorer),
DecoratorDiagnostics({ explorer = args.explorer }), DecoratorDiagnostics(self.explorer),
DecoratorBookmarks({ explorer = args.explorer }), DecoratorBookmarks(self.explorer),
DecoratorModified({ explorer = args.explorer }), DecoratorModified(self.explorer),
DecoratorHidden({ explorer = args.explorer }), DecoratorHidden(self.explorer),
DecoratorOpened({ explorer = args.explorer }), DecoratorOpened(self.explorer),
DecoratorGit({ explorer = args.explorer }) DecoratorGit(self.explorer),
} }
self.hidden_display = Builder:setup_hidden_display_function(self.explorer.opts) 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 end
---Insert ranged highlight groups into self.highlights ---Insert ranged highlight groups into self.highlights

View File

@ -1,20 +1,22 @@
local Decorator = require("nvim-tree.renderer.decorator") local Decorator = require("nvim-tree.renderer.decorator")
---@class (exact) DecoratorBookmarks: Decorator ---@class (exact) DecoratorBookmarks: Decorator
---@field icon HighlightedString? ---@field private explorer Explorer
---@field private icon HighlightedString?
local DecoratorBookmarks = Decorator:extend() local DecoratorBookmarks = Decorator:extend()
---@class DecoratorBookmarks ---@class DecoratorBookmarks
---@overload fun(explorer: DecoratorArgs): DecoratorBookmarks ---@overload fun(explorer: Explorer): DecoratorBookmarks
---@protected ---@protected
---@param args DecoratorArgs ---@param explorer Explorer
function DecoratorBookmarks:new(args) function DecoratorBookmarks:new(explorer)
Decorator.new(self, { self.explorer = explorer
explorer = args.explorer,
DecoratorBookmarks.super.new(self, {
enabled = true, enabled = true,
hl_pos = args.explorer.opts.renderer.highlight_bookmarks or "none", hl_pos = self.explorer.opts.renderer.highlight_bookmarks or "none",
icon_placement = args.explorer.opts.renderer.icons.bookmarks_placement or "none", icon_placement = self.explorer.opts.renderer.icons.bookmarks_placement or "none",
}) })
if self.explorer.opts.renderer.icons.show.bookmarks then if self.explorer.opts.renderer.icons.show.bookmarks then

View File

@ -1,18 +1,20 @@
local Decorator = require("nvim-tree.renderer.decorator") local Decorator = require("nvim-tree.renderer.decorator")
---@class (exact) DecoratorCopied: Decorator ---@class (exact) DecoratorCopied: Decorator
---@field private explorer Explorer
local DecoratorCopied = Decorator:extend() local DecoratorCopied = Decorator:extend()
---@class DecoratorCopied ---@class DecoratorCopied
---@overload fun(explorer: DecoratorArgs): DecoratorCopied ---@overload fun(explorer: Explorer): DecoratorCopied
---@protected ---@protected
---@param args DecoratorArgs ---@param explorer Explorer
function DecoratorCopied:new(args) function DecoratorCopied:new(explorer)
Decorator.new(self, { self.explorer = explorer
explorer = args.explorer,
DecoratorCopied.super.new(self, {
enabled = true, 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", icon_placement = "none",
}) })
end end

View File

@ -1,18 +1,20 @@
local Decorator = require("nvim-tree.renderer.decorator") local Decorator = require("nvim-tree.renderer.decorator")
---@class (exact) DecoratorCut: Decorator ---@class (exact) DecoratorCut: Decorator
---@field private explorer Explorer
local DecoratorCut = Decorator:extend() local DecoratorCut = Decorator:extend()
---@class DecoratorCut ---@class DecoratorCut
---@overload fun(explorer: DecoratorArgs): DecoratorCut ---@overload fun(explorer: Explorer): DecoratorCut
---@protected ---@protected
---@param args DecoratorArgs ---@param explorer Explorer
function DecoratorCut:new(args) function DecoratorCut:new(explorer)
Decorator.new(self, { self.explorer = explorer
explorer = args.explorer,
DecoratorCut.super.new(self, {
enabled = true, 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", icon_placement = "none",
}) })
end end

View File

@ -31,20 +31,22 @@ local ICON_KEYS = {
} }
---@class (exact) DecoratorDiagnostics: Decorator ---@class (exact) DecoratorDiagnostics: Decorator
---@field icons HighlightedString[]? ---@field private explorer Explorer
---@field private icons HighlightedString[]?
local DecoratorDiagnostics = Decorator:extend() local DecoratorDiagnostics = Decorator:extend()
---@class DecoratorDiagnostics ---@class DecoratorDiagnostics
---@overload fun(explorer: DecoratorArgs): DecoratorDiagnostics ---@overload fun(explorer: Explorer): DecoratorDiagnostics
---@protected ---@protected
---@param args DecoratorArgs ---@param explorer Explorer
function DecoratorDiagnostics:new(args) function DecoratorDiagnostics:new(explorer)
Decorator.new(self, { self.explorer = explorer
explorer = args.explorer,
DecoratorDiagnostics.super.new(self, {
enabled = true, enabled = true,
hl_pos = args.explorer.opts.renderer.highlight_diagnostics or "none", hl_pos = self.explorer.opts.renderer.highlight_diagnostics or "none",
icon_placement = args.explorer.opts.renderer.icons.diagnostics_placement or "none", icon_placement = self.explorer.opts.renderer.icons.diagnostics_placement or "none",
}) })
if not self.enabled then if not self.enabled then

View File

@ -13,23 +13,25 @@ local DirectoryNode = require("nvim-tree.node.directory")
---@alias GitGlyphsByStatus table<GitStatusStrings, string> from opts ---@alias GitGlyphsByStatus table<GitStatusStrings, string> from opts
---@class (exact) DecoratorGit: Decorator ---@class (exact) DecoratorGit: Decorator
---@field file_hl_by_xy table<GitXY, string>? ---@field private explorer Explorer
---@field folder_hl_by_xy table<GitXY, string>? ---@field private file_hl_by_xy table<GitXY, string>?
---@field icons_by_status GitIconsByStatus? ---@field private folder_hl_by_xy table<GitXY, string>?
---@field icons_by_xy GitIconsByXY? ---@field private icons_by_status GitIconsByStatus?
---@field private icons_by_xy GitIconsByXY?
local DecoratorGit = Decorator:extend() local DecoratorGit = Decorator:extend()
---@class DecoratorGit ---@class DecoratorGit
---@overload fun(explorer: DecoratorArgs): DecoratorGit ---@overload fun(explorer: Explorer): DecoratorGit
---@protected ---@protected
---@param args DecoratorArgs ---@param explorer Explorer
function DecoratorGit:new(args) function DecoratorGit:new(explorer)
Decorator.new(self, { self.explorer = explorer
explorer = args.explorer,
enabled = args.explorer.opts.git.enable, DecoratorGit.super.new(self, {
hl_pos = args.explorer.opts.renderer.highlight_git or "none", enabled = self.explorer.opts.git.enable,
icon_placement = args.explorer.opts.renderer.icons.git_placement or "none", 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 if not self.enabled then

View File

@ -2,20 +2,22 @@ local Decorator = require("nvim-tree.renderer.decorator")
local DirectoryNode = require("nvim-tree.node.directory") local DirectoryNode = require("nvim-tree.node.directory")
---@class (exact) DecoratorHidden: Decorator ---@class (exact) DecoratorHidden: Decorator
---@field icon HighlightedString? ---@field private explorer Explorer
---@field private icon HighlightedString?
local DecoratorHidden = Decorator:extend() local DecoratorHidden = Decorator:extend()
---@class DecoratorHidden ---@class DecoratorHidden
---@overload fun(explorer: DecoratorArgs): DecoratorHidden ---@overload fun(explorer: Explorer): DecoratorHidden
---@protected ---@protected
---@param args DecoratorArgs ---@param explorer Explorer
function DecoratorHidden:new(args) function DecoratorHidden:new(explorer)
Decorator.new(self, { self.explorer = explorer
explorer = args.explorer,
DecoratorHidden.super.new(self, {
enabled = true, enabled = true,
hl_pos = args.explorer.opts.renderer.highlight_hidden or "none", hl_pos = self.explorer.opts.renderer.highlight_hidden or "none",
icon_placement = args.explorer.opts.renderer.icons.hidden_placement or "none", icon_placement = self.explorer.opts.renderer.icons.hidden_placement or "none",
}) })
if self.explorer.opts.renderer.icons.show.hidden then if self.explorer.opts.renderer.icons.show.hidden then

View File

@ -4,26 +4,20 @@ local Class = require("nvim-tree.classic")
---@alias DecoratorIconPlacement "none" | "before" | "after" | "signcolumn" | "right_align" ---@alias DecoratorIconPlacement "none" | "before" | "after" | "signcolumn" | "right_align"
---Abstract Decorator ---Abstract Decorator
---Uses the factory pattern to instantiate child instances.
---@class (exact) Decorator: Class ---@class (exact) Decorator: Class
---@field protected explorer Explorer
---@field protected enabled boolean ---@field protected enabled boolean
---@field protected range DecoratorRange ---@field protected range DecoratorRange
---@field protected icon_placement DecoratorIconPlacement ---@field protected icon_placement DecoratorIconPlacement
local Decorator = Class:extend() local Decorator = Class:extend()
---@class (exact) DecoratorArgs ---@class (exact) DecoratorArgs
---@field explorer Explorer
---@class (exact) AbstractDecoratorArgs: DecoratorArgs
---@field enabled boolean ---@field enabled boolean
---@field hl_pos DecoratorRange ---@field hl_pos DecoratorRange
---@field icon_placement DecoratorIconPlacement ---@field icon_placement DecoratorIconPlacement
---@protected ---@protected
---@param args AbstractDecoratorArgs ---@param args DecoratorArgs
function Decorator:new(args) function Decorator:new(args)
self.explorer = args.explorer
self.enabled = args.enabled self.enabled = args.enabled
self.range = args.hl_pos self.range = args.hl_pos
self.icon_placement = args.icon_placement self.icon_placement = args.icon_placement

View File

@ -4,20 +4,22 @@ local Decorator = require("nvim-tree.renderer.decorator")
local DirectoryNode = require("nvim-tree.node.directory") local DirectoryNode = require("nvim-tree.node.directory")
---@class (exact) DecoratorModified: Decorator ---@class (exact) DecoratorModified: Decorator
---@field icon HighlightedString? ---@field private explorer Explorer
---@field private icon HighlightedString?
local DecoratorModified = Decorator:extend() local DecoratorModified = Decorator:extend()
---@class DecoratorModified ---@class DecoratorModified
---@overload fun(explorer: DecoratorArgs): DecoratorModified ---@overload fun(explorer: Explorer): DecoratorModified
---@protected ---@protected
---@param args DecoratorArgs ---@param explorer Explorer
function DecoratorModified:new(args) function DecoratorModified:new(explorer)
Decorator.new(self, { self.explorer = explorer
explorer = args.explorer,
DecoratorModified.super.new(self, {
enabled = true, enabled = true,
hl_pos = args.explorer.opts.renderer.highlight_modified or "none", hl_pos = self.explorer.opts.renderer.highlight_modified or "none",
icon_placement = args.explorer.opts.renderer.icons.modified_placement or "none", icon_placement = self.explorer.opts.renderer.icons.modified_placement or "none",
}) })
if not self.enabled then if not self.enabled then

View File

@ -3,19 +3,21 @@ local buffers = require("nvim-tree.buffers")
local Decorator = require("nvim-tree.renderer.decorator") local Decorator = require("nvim-tree.renderer.decorator")
---@class (exact) DecoratorOpened: Decorator ---@class (exact) DecoratorOpened: Decorator
---@field icon HighlightedString|nil ---@field private explorer Explorer
---@field private icon HighlightedString|nil
local DecoratorOpened = Decorator:extend() local DecoratorOpened = Decorator:extend()
---@class DecoratorOpened ---@class DecoratorOpened
---@overload fun(explorer: DecoratorArgs): DecoratorOpened ---@overload fun(explorer: Explorer): DecoratorOpened
---@protected ---@protected
---@param args DecoratorArgs ---@param explorer Explorer
function DecoratorOpened:new(args) function DecoratorOpened:new(explorer)
Decorator.new(self, { self.explorer = explorer
explorer = args.explorer,
DecoratorOpened.super.new(self, {
enabled = true, 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", icon_placement = "none",
}) })
end end

View File

@ -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