152 lines
3.5 KiB
Lua
152 lines
3.5 KiB
Lua
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 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
|
|
end
|
|
|
|
---Maybe highlight groups for icon and name
|
|
---@param node Node
|
|
---@return string? icon highlight group
|
|
---@return string? name highlight group
|
|
function Decorator:highlight_group_icon_name(node)
|
|
local icon_hl, name_hl
|
|
|
|
if self.enabled and self.highlight_range ~= "none" then
|
|
local hl = self:highlight_group(node)
|
|
|
|
if self.highlight_range == "all" or self.highlight_range == "icon" then
|
|
icon_hl = hl
|
|
end
|
|
if self.highlight_range == "all" or self.highlight_range == "name" then
|
|
name_hl = hl
|
|
end
|
|
end
|
|
|
|
return icon_hl, name_hl
|
|
end
|
|
|
|
---Maybe icon sign
|
|
---@param node Node
|
|
---@return string? name
|
|
function Decorator:sign_name(node)
|
|
if not self.enabled or self.icon_placement ~= "signcolumn" then
|
|
return
|
|
end
|
|
|
|
local icons = self:icons(node)
|
|
if icons and #icons > 0 then
|
|
return icons[1].hl[1]
|
|
end
|
|
end
|
|
|
|
---Icons when "before"
|
|
---@param node Node
|
|
---@return HighlightedString[]? icons
|
|
function Decorator:icons_before(node)
|
|
if not self.enabled or self.icon_placement ~= "before" then
|
|
return
|
|
end
|
|
|
|
return self:icons(node)
|
|
end
|
|
|
|
---Icons when "after"
|
|
---@param node Node
|
|
---@return HighlightedString[]? icons
|
|
function Decorator:icons_after(node)
|
|
if not self.enabled or self.icon_placement ~= "after" then
|
|
return
|
|
end
|
|
|
|
return self:icons(node)
|
|
end
|
|
|
|
---Icons when "right_align"
|
|
---@param node Node
|
|
---@return HighlightedString[]? icons
|
|
function Decorator:icons_right_align(node)
|
|
if not self.enabled or self.icon_placement ~= "right_align" then
|
|
return
|
|
end
|
|
|
|
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?
|
|
function Decorator:define_sign(icon)
|
|
if icon and #icon.hl > 0 then
|
|
local name = icon.hl[1]
|
|
|
|
if not vim.tbl_isempty(vim.fn.sign_getdefined(name)) then
|
|
vim.fn.sign_undefine(name)
|
|
end
|
|
|
|
-- don't use sign if not defined
|
|
if #icon.str < 1 then
|
|
self.icon_placement = "none"
|
|
return
|
|
end
|
|
|
|
-- byte index of the next character, allowing for wide
|
|
local bi = vim.fn.byteidx(icon.str, 1)
|
|
|
|
-- first (wide) character, falls back to empty string
|
|
local text = string.sub(icon.str, 1, bi)
|
|
vim.fn.sign_define(name, {
|
|
text = text,
|
|
texthl = name,
|
|
})
|
|
end
|
|
end
|
|
|
|
return Decorator
|