local Class = require("nvim-tree.classic") ---Abstract Decorator ---@class (exact) Decorator: Class ---@field protected enabled boolean ---@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 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 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 ---@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 ---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