* feat(#2415): granular highlight_diagnostics, normalise groups (#2454) * chore: normalise colours and enable cterm (#2471) * feat(#2415): granular highlight_git, normalise git groups (#2487) * docs: update CONTRIBUTING.md (#2485) * feat(#2415): granular highlight_git, normalise git groups * feat(#2415): normalise and add modified groups * feat(#2415): create Decorator class for modified and bookmarks * feat(#2415): create DecoratorDiagnostics * feat(#2415): create DecoratorGit * feat(#2415): create DecoratorGit * add DecoratorCopied DecoratorCut * add DecoratorOpened * remove unloaded_bufnr checks as the view debouncer takes care of it * Add `renderer.highlight_git` to accepted strings * fix(#2415): builder refactor (#2538) * simplify builder signs * decorators take care of themselves and are priority ordered * simplify builder hl groups * refactor builder for icon arrays * builder use decorators generically * fix(#2415): harden sign creation (#2539) * fix(#2415): harden unicode signs * Decorator tidy * normalise git sign creation and tidy * tidy builder * NvimTreeBookmarkIcon * tidy HL doc * tidy HL doc * tidy HL doc * tidy builder doc * standardise on '---@param' * DiagnosticWarning -> DiagnosticWarn * annotate decorators * limit to two highlight groups for line rendering * style * apply #2519 * feat(#2415): combined hl groups (#2601) * feat(#2415): create combined highlight groups * feat(#2415): create combined highlight groups * feat(#2415): create combined highlight groups * ci: allow workflow_dispatch (#2620) * one and only one hl namespace, required winhl removal * small tidies * colors.lua -> appearance.lua * full-name uses one and only namespace * don't highlight fast, just apply to namespace, safer win_set_hl * gut builder (#2622) collapse Builder * fix group_empty function check * feat(#2415): highlight-overhaul release date --------- Co-authored-by: Akmadan23 <azadahmadi@mailo.com>
This commit is contained in:
committed by
GitHub
parent
f24afa2cef
commit
e9c5abe073
51
lua/nvim-tree/renderer/decorator/bookmarks.lua
Normal file
51
lua/nvim-tree/renderer/decorator/bookmarks.lua
Normal file
@@ -0,0 +1,51 @@
|
||||
local marks = require "nvim-tree.marks"
|
||||
|
||||
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
|
||||
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
|
||||
|
||||
local Decorator = require "nvim-tree.renderer.decorator"
|
||||
|
||||
---@class DecoratorBookmarks: Decorator
|
||||
---@field icon HighlightedString
|
||||
local DecoratorBookmarks = Decorator:new()
|
||||
|
||||
---@param opts table
|
||||
---@return DecoratorBookmarks
|
||||
function DecoratorBookmarks:new(opts)
|
||||
local o = Decorator.new(self, {
|
||||
enabled = true,
|
||||
hl_pos = HL_POSITION[opts.renderer.highlight_bookmarks] or HL_POSITION.none,
|
||||
icon_placement = ICON_PLACEMENT[opts.renderer.icons.bookmarks_placement] or ICON_PLACEMENT.none,
|
||||
})
|
||||
---@cast o DecoratorBookmarks
|
||||
|
||||
if opts.renderer.icons.show.bookmarks then
|
||||
o.icon = {
|
||||
str = opts.renderer.icons.glyphs.bookmark,
|
||||
hl = { "NvimTreeBookmarkIcon" },
|
||||
}
|
||||
o:define_sign(o.icon)
|
||||
end
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
---Bookmark icon: renderer.icons.show.bookmarks and node is marked
|
||||
---@param node Node
|
||||
---@return HighlightedString[]|nil icons
|
||||
function DecoratorBookmarks:calculate_icons(node)
|
||||
if marks.get_mark(node) then
|
||||
return { self.icon }
|
||||
end
|
||||
end
|
||||
|
||||
---Bookmark highlight: renderer.highlight_bookmarks and node is marked
|
||||
---@param node Node
|
||||
---@return string|nil group
|
||||
function DecoratorBookmarks:calculate_highlight(node)
|
||||
if self.hl_pos ~= HL_POSITION.none and marks.get_mark(node) then
|
||||
return "NvimTreeBookmarkHL"
|
||||
end
|
||||
end
|
||||
|
||||
return DecoratorBookmarks
|
||||
38
lua/nvim-tree/renderer/decorator/copied.lua
Normal file
38
lua/nvim-tree/renderer/decorator/copied.lua
Normal file
@@ -0,0 +1,38 @@
|
||||
local copy_paste
|
||||
|
||||
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
|
||||
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
|
||||
|
||||
local Decorator = require "nvim-tree.renderer.decorator"
|
||||
|
||||
---@class DecoratorCopied: Decorator
|
||||
---@field enabled boolean
|
||||
---@field icon HighlightedString|nil
|
||||
local DecoratorCopied = Decorator:new()
|
||||
|
||||
---@param opts table
|
||||
---@return DecoratorCopied
|
||||
function DecoratorCopied:new(opts)
|
||||
local o = Decorator.new(self, {
|
||||
enabled = true,
|
||||
hl_pos = HL_POSITION[opts.renderer.highlight_clipboard] or HL_POSITION.none,
|
||||
icon_placement = ICON_PLACEMENT.none,
|
||||
})
|
||||
---@cast o DecoratorCopied
|
||||
|
||||
-- cyclic
|
||||
copy_paste = copy_paste or require "nvim-tree.actions.fs.copy-paste"
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
---Copied highlight: renderer.highlight_clipboard and node is copied
|
||||
---@param node Node
|
||||
---@return string|nil group
|
||||
function DecoratorCopied:calculate_highlight(node)
|
||||
if self.hl_pos ~= HL_POSITION.none and copy_paste.is_copied(node) then
|
||||
return "NvimTreeCopiedHL"
|
||||
end
|
||||
end
|
||||
|
||||
return DecoratorCopied
|
||||
38
lua/nvim-tree/renderer/decorator/cut.lua
Normal file
38
lua/nvim-tree/renderer/decorator/cut.lua
Normal file
@@ -0,0 +1,38 @@
|
||||
local copy_paste
|
||||
|
||||
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
|
||||
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
|
||||
|
||||
local Decorator = require "nvim-tree.renderer.decorator"
|
||||
|
||||
---@class DecoratorCut: Decorator
|
||||
---@field enabled boolean
|
||||
---@field icon HighlightedString|nil
|
||||
local DecoratorCut = Decorator:new()
|
||||
|
||||
---@param opts table
|
||||
---@return DecoratorCut
|
||||
function DecoratorCut:new(opts)
|
||||
local o = Decorator.new(self, {
|
||||
enabled = true,
|
||||
hl_pos = HL_POSITION[opts.renderer.highlight_clipboard] or HL_POSITION.none,
|
||||
icon_placement = ICON_PLACEMENT.none,
|
||||
})
|
||||
---@cast o DecoratorCut
|
||||
|
||||
-- cyclic
|
||||
copy_paste = copy_paste or require "nvim-tree.actions.fs.copy-paste"
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
---Cut highlight: renderer.highlight_clipboard and node is cut
|
||||
---@param node Node
|
||||
---@return string|nil group
|
||||
function DecoratorCut:calculate_highlight(node)
|
||||
if self.hl_pos ~= HL_POSITION.none and copy_paste.is_cut(node) then
|
||||
return "NvimTreeCutHL"
|
||||
end
|
||||
end
|
||||
|
||||
return DecoratorCut
|
||||
110
lua/nvim-tree/renderer/decorator/diagnostics.lua
Normal file
110
lua/nvim-tree/renderer/decorator/diagnostics.lua
Normal file
@@ -0,0 +1,110 @@
|
||||
local diagnostics = require "nvim-tree.diagnostics"
|
||||
|
||||
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
|
||||
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
|
||||
|
||||
local Decorator = require "nvim-tree.renderer.decorator"
|
||||
|
||||
-- highlight groups by severity
|
||||
local HG_ICON = {
|
||||
[vim.diagnostic.severity.ERROR] = "NvimTreeDiagnosticErrorIcon",
|
||||
[vim.diagnostic.severity.WARN] = "NvimTreeDiagnosticWarnIcon",
|
||||
[vim.diagnostic.severity.INFO] = "NvimTreeDiagnosticInfoIcon",
|
||||
[vim.diagnostic.severity.HINT] = "NvimTreeDiagnosticHintIcon",
|
||||
}
|
||||
local HG_FILE = {
|
||||
[vim.diagnostic.severity.ERROR] = "NvimTreeDiagnosticErrorFileHL",
|
||||
[vim.diagnostic.severity.WARN] = "NvimTreeDiagnosticWarnFileHL",
|
||||
[vim.diagnostic.severity.INFO] = "NvimTreeDiagnosticInfoFileHL",
|
||||
[vim.diagnostic.severity.HINT] = "NvimTreeDiagnosticHintFileHL",
|
||||
}
|
||||
local HG_FOLDER = {
|
||||
[vim.diagnostic.severity.ERROR] = "NvimTreeDiagnosticErrorFolderHL",
|
||||
[vim.diagnostic.severity.WARN] = "NvimTreeDiagnosticWarnFolderHL",
|
||||
[vim.diagnostic.severity.INFO] = "NvimTreeDiagnosticInfoFolderHL",
|
||||
[vim.diagnostic.severity.HINT] = "NvimTreeDiagnosticHintFolderHL",
|
||||
}
|
||||
-- opts.diagnostics.icons.
|
||||
local ICON_KEYS = {
|
||||
["error"] = vim.diagnostic.severity.ERROR,
|
||||
["warning"] = vim.diagnostic.severity.WARN,
|
||||
["info"] = vim.diagnostic.severity.INFO,
|
||||
["hint"] = vim.diagnostic.severity.HINT,
|
||||
}
|
||||
|
||||
---@class DecoratorDiagnostics: Decorator
|
||||
---@field icons HighlightedString[]
|
||||
local DecoratorDiagnostics = Decorator:new()
|
||||
|
||||
---@param opts table
|
||||
---@return DecoratorDiagnostics
|
||||
function DecoratorDiagnostics:new(opts)
|
||||
local o = Decorator.new(self, {
|
||||
enabled = opts.diagnostics.enable,
|
||||
hl_pos = HL_POSITION[opts.renderer.highlight_diagnostics] or HL_POSITION.none,
|
||||
icon_placement = ICON_PLACEMENT[opts.renderer.icons.diagnostics_placement] or ICON_PLACEMENT.none,
|
||||
})
|
||||
---@cast o DecoratorDiagnostics
|
||||
|
||||
if not o.enabled then
|
||||
return o
|
||||
end
|
||||
|
||||
if opts.renderer.icons.show.diagnostics then
|
||||
o.icons = {}
|
||||
for name, sev in pairs(ICON_KEYS) do
|
||||
o.icons[sev] = {
|
||||
str = opts.diagnostics.icons[name],
|
||||
hl = { HG_ICON[sev] },
|
||||
}
|
||||
o:define_sign(o.icons[sev])
|
||||
end
|
||||
end
|
||||
|
||||
return o
|
||||
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
|
||||
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] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---Diagnostic highlight: diagnostics.enable, renderer.highlight_diagnostics and node has status
|
||||
---@param node Node
|
||||
---@return string|nil group
|
||||
function DecoratorDiagnostics:calculate_highlight(node)
|
||||
if not node or not self.enabled or self.hl_pos == HL_POSITION.none then
|
||||
return nil
|
||||
end
|
||||
|
||||
local diag_status = diagnostics.get_diag_status(node)
|
||||
local diag_value = diag_status and diag_status.value
|
||||
|
||||
if not diag_value then
|
||||
return nil
|
||||
end
|
||||
|
||||
local group
|
||||
if node.nodes then
|
||||
group = HG_FOLDER[diag_value]
|
||||
else
|
||||
group = HG_FILE[diag_value]
|
||||
end
|
||||
|
||||
if group then
|
||||
return group
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
return DecoratorDiagnostics
|
||||
221
lua/nvim-tree/renderer/decorator/git.lua
Normal file
221
lua/nvim-tree/renderer/decorator/git.lua
Normal file
@@ -0,0 +1,221 @@
|
||||
local notify = require "nvim-tree.notify"
|
||||
local explorer_node = require "nvim-tree.explorer.node"
|
||||
|
||||
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
|
||||
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
|
||||
|
||||
local Decorator = require "nvim-tree.renderer.decorator"
|
||||
|
||||
---@class HighlightedStringGit: HighlightedString
|
||||
---@field ord number decreasing priority
|
||||
|
||||
---@class DecoratorGit: Decorator
|
||||
---@field file_hl table<string, string> by porcelain status e.g. "AM"
|
||||
---@field folder_hl table<string, string> by porcelain status
|
||||
---@field icons_by_status HighlightedStringGit[] by human status
|
||||
---@field icons_by_xy table<string, HighlightedStringGit[]> by porcelain status
|
||||
local DecoratorGit = Decorator:new()
|
||||
|
||||
---@param opts table
|
||||
---@return DecoratorGit
|
||||
function DecoratorGit:new(opts)
|
||||
local o = Decorator.new(self, {
|
||||
enabled = opts.git.enable,
|
||||
hl_pos = HL_POSITION[opts.renderer.highlight_git] or HL_POSITION.none,
|
||||
icon_placement = ICON_PLACEMENT[opts.renderer.icons.git_placement] or ICON_PLACEMENT.none,
|
||||
})
|
||||
---@cast o DecoratorGit
|
||||
|
||||
if not o.enabled then
|
||||
return o
|
||||
end
|
||||
|
||||
if o.hl_pos ~= HL_POSITION.none then
|
||||
o:build_hl_table()
|
||||
end
|
||||
|
||||
if opts.renderer.icons.show.git then
|
||||
o:build_icons_by_status(opts.renderer.icons.glyphs.git)
|
||||
o:build_icons_by_xy(o.icons_by_status)
|
||||
|
||||
for _, icon in pairs(o.icons_by_status) do
|
||||
self:define_sign(icon)
|
||||
end
|
||||
end
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
---@param glyphs table<string, string> user glyps
|
||||
function DecoratorGit:build_icons_by_status(glyphs)
|
||||
self.icons_by_status = {
|
||||
staged = { str = glyphs.staged, hl = { "NvimTreeGitStagedIcon" }, ord = 1 },
|
||||
unstaged = { str = glyphs.unstaged, hl = { "NvimTreeGitDirtyIcon" }, ord = 2 },
|
||||
renamed = { str = glyphs.renamed, hl = { "NvimTreeGitRenamedIcon" }, ord = 3 },
|
||||
deleted = { str = glyphs.deleted, hl = { "NvimTreeGitDeletedIcon" }, ord = 4 },
|
||||
unmerged = { str = glyphs.unmerged, hl = { "NvimTreeGitMergeIcon" }, ord = 5 },
|
||||
untracked = { str = glyphs.untracked, hl = { "NvimTreeGitNewIcon" }, ord = 6 },
|
||||
ignored = { str = glyphs.ignored, hl = { "NvimTreeGitIgnoredIcon" }, ord = 7 },
|
||||
}
|
||||
end
|
||||
|
||||
---@param icons HighlightedStringGit[]
|
||||
function DecoratorGit:build_icons_by_xy(icons)
|
||||
self.icons_by_xy = {
|
||||
["M "] = { icons.staged },
|
||||
[" M"] = { icons.unstaged },
|
||||
["C "] = { icons.staged },
|
||||
[" C"] = { icons.unstaged },
|
||||
["CM"] = { icons.unstaged },
|
||||
[" T"] = { icons.unstaged },
|
||||
["T "] = { icons.staged },
|
||||
["TM"] = { icons.staged, icons.unstaged },
|
||||
["MM"] = { icons.staged, icons.unstaged },
|
||||
["MD"] = { icons.staged },
|
||||
["A "] = { icons.staged },
|
||||
["AD"] = { icons.staged },
|
||||
[" A"] = { icons.untracked },
|
||||
-- not sure about this one
|
||||
["AA"] = { icons.unmerged, icons.untracked },
|
||||
["AU"] = { icons.unmerged, icons.untracked },
|
||||
["AM"] = { icons.staged, icons.unstaged },
|
||||
["??"] = { icons.untracked },
|
||||
["R "] = { icons.renamed },
|
||||
[" R"] = { icons.renamed },
|
||||
["RM"] = { icons.unstaged, icons.renamed },
|
||||
["UU"] = { icons.unmerged },
|
||||
["UD"] = { icons.unmerged },
|
||||
["UA"] = { icons.unmerged },
|
||||
[" D"] = { icons.deleted },
|
||||
["D "] = { icons.deleted },
|
||||
["DA"] = { icons.unstaged },
|
||||
["RD"] = { icons.deleted },
|
||||
["DD"] = { icons.deleted },
|
||||
["DU"] = { icons.deleted, icons.unmerged },
|
||||
["!!"] = { icons.ignored },
|
||||
dirty = { icons.unstaged },
|
||||
}
|
||||
end
|
||||
|
||||
function DecoratorGit:build_hl_table()
|
||||
self.file_hl = {
|
||||
["M "] = "NvimTreeGitFileStagedHL",
|
||||
["C "] = "NvimTreeGitFileStagedHL",
|
||||
["AA"] = "NvimTreeGitFileStagedHL",
|
||||
["AD"] = "NvimTreeGitFileStagedHL",
|
||||
["MD"] = "NvimTreeGitFileStagedHL",
|
||||
["T "] = "NvimTreeGitFileStagedHL",
|
||||
["TT"] = "NvimTreeGitFileStagedHL",
|
||||
[" M"] = "NvimTreeGitFileDirtyHL",
|
||||
["CM"] = "NvimTreeGitFileDirtyHL",
|
||||
[" C"] = "NvimTreeGitFileDirtyHL",
|
||||
[" T"] = "NvimTreeGitFileDirtyHL",
|
||||
["MM"] = "NvimTreeGitFileDirtyHL",
|
||||
["AM"] = "NvimTreeGitFileDirtyHL",
|
||||
dirty = "NvimTreeGitFileDirtyHL",
|
||||
["A "] = "NvimTreeGitFileStagedHL",
|
||||
["??"] = "NvimTreeGitFileNewHL",
|
||||
["AU"] = "NvimTreeGitFileMergeHL",
|
||||
["UU"] = "NvimTreeGitFileMergeHL",
|
||||
["UD"] = "NvimTreeGitFileMergeHL",
|
||||
["DU"] = "NvimTreeGitFileMergeHL",
|
||||
["UA"] = "NvimTreeGitFileMergeHL",
|
||||
[" D"] = "NvimTreeGitFileDeletedHL",
|
||||
["DD"] = "NvimTreeGitFileDeletedHL",
|
||||
["RD"] = "NvimTreeGitFileDeletedHL",
|
||||
["D "] = "NvimTreeGitFileDeletedHL",
|
||||
["R "] = "NvimTreeGitFileRenamedHL",
|
||||
["RM"] = "NvimTreeGitFileRenamedHL",
|
||||
[" R"] = "NvimTreeGitFileRenamedHL",
|
||||
["!!"] = "NvimTreeGitFileIgnoredHL",
|
||||
[" A"] = "none",
|
||||
}
|
||||
|
||||
self.folder_hl = {}
|
||||
for k, v in pairs(self.file_hl) do
|
||||
self.folder_hl[k] = v:gsub("File", "Folder")
|
||||
end
|
||||
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)
|
||||
if not node or not self.enabled or not self.icons_by_xy then
|
||||
return nil
|
||||
end
|
||||
|
||||
local git_status = explorer_node.get_git_status(node)
|
||||
if git_status == nil then
|
||||
return nil
|
||||
end
|
||||
|
||||
local inserted = {}
|
||||
local iconss = {}
|
||||
|
||||
for _, s in pairs(git_status) do
|
||||
local icons = self.icons_by_xy[s]
|
||||
if not icons then
|
||||
if self.hl_pos == HL_POSITION.none then
|
||||
notify.warn(string.format("Unrecognized git state '%s'", git_status))
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
for _, icon in pairs(icons) do
|
||||
if #icon.str > 0 then
|
||||
if not inserted[icon] then
|
||||
table.insert(iconss, icon)
|
||||
inserted[icon] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #iconss == 0 then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- sort icons so it looks slightly better
|
||||
table.sort(iconss, function(a, b)
|
||||
return a.ord < b.ord
|
||||
end)
|
||||
|
||||
return iconss
|
||||
end
|
||||
|
||||
---Get the first icon as the sign if appropriate
|
||||
---@param node Node
|
||||
---@return string|nil name
|
||||
function DecoratorGit:sign_name(node)
|
||||
if self.icon_placement ~= ICON_PLACEMENT.signcolumn then
|
||||
return
|
||||
end
|
||||
|
||||
local icons = self:calculate_icons(node)
|
||||
if icons and #icons > 0 then
|
||||
return icons[1].hl[1]
|
||||
end
|
||||
end
|
||||
|
||||
---Git highlight: git.enable, renderer.highlight_git and node has status
|
||||
---@param node Node
|
||||
---@return string|nil group
|
||||
function DecoratorGit:calculate_highlight(node)
|
||||
if not node or not self.enabled or self.hl_pos == HL_POSITION.none then
|
||||
return nil
|
||||
end
|
||||
|
||||
local git_status = explorer_node.get_git_status(node)
|
||||
if not git_status then
|
||||
return nil
|
||||
end
|
||||
|
||||
if node.nodes then
|
||||
return self.folder_hl[git_status[1]]
|
||||
else
|
||||
return self.file_hl[git_status[1]]
|
||||
end
|
||||
end
|
||||
|
||||
return DecoratorGit
|
||||
122
lua/nvim-tree/renderer/decorator/init.lua
Normal file
122
lua/nvim-tree/renderer/decorator/init.lua
Normal file
@@ -0,0 +1,122 @@
|
||||
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
|
||||
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
|
||||
|
||||
---@class Decorator
|
||||
---@field protected enabled boolean
|
||||
---@field protected hl_pos HL_POSITION
|
||||
---@field protected icon_placement ICON_PLACEMENT
|
||||
local Decorator = {}
|
||||
|
||||
---@param o Decorator|nil
|
||||
---@return Decorator
|
||||
function Decorator:new(o)
|
||||
o = o or {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
---Maybe highlight groups
|
||||
---@param node Node
|
||||
---@return string|nil icon highlight group
|
||||
---@return string|nil name highlight group
|
||||
function Decorator:groups_icon_name(node)
|
||||
local icon_hl, name_hl
|
||||
|
||||
if self.enabled and self.hl_pos ~= HL_POSITION.none then
|
||||
local hl = self:calculate_highlight(node)
|
||||
|
||||
if self.hl_pos == HL_POSITION.all or self.hl_pos == HL_POSITION.icon then
|
||||
icon_hl = hl
|
||||
end
|
||||
if self.hl_pos == HL_POSITION.all or self.hl_pos == HL_POSITION.name then
|
||||
name_hl = hl
|
||||
end
|
||||
end
|
||||
|
||||
return icon_hl, name_hl
|
||||
end
|
||||
|
||||
---Maybe icon sign
|
||||
---@param node Node
|
||||
---@return string|nil name
|
||||
function Decorator:sign_name(node)
|
||||
if not self.enabled or self.icon_placement ~= ICON_PLACEMENT.signcolumn then
|
||||
return
|
||||
end
|
||||
|
||||
local icons = self:calculate_icons(node)
|
||||
if icons and #icons > 0 then
|
||||
return icons[1].hl[1]
|
||||
end
|
||||
end
|
||||
|
||||
---Icons when ICON_PLACEMENT.before
|
||||
---@param node Node
|
||||
---@return HighlightedString[]|nil icons
|
||||
function Decorator:icons_before(node)
|
||||
if not self.enabled or self.icon_placement ~= ICON_PLACEMENT.before then
|
||||
return
|
||||
end
|
||||
|
||||
return self:calculate_icons(node)
|
||||
end
|
||||
|
||||
---Icons when ICON_PLACEMENT.after
|
||||
---@param node Node
|
||||
---@return HighlightedString[]|nil icons
|
||||
function Decorator:icons_after(node)
|
||||
if not self.enabled or self.icon_placement ~= ICON_PLACEMENT.after then
|
||||
return
|
||||
end
|
||||
|
||||
return self:calculate_icons(node)
|
||||
end
|
||||
|
||||
---Maybe icons, optionally implemented
|
||||
---@protected
|
||||
---@param _ Node
|
||||
---@return HighlightedString[]|nil icons
|
||||
function Decorator:calculate_icons(_)
|
||||
return nil
|
||||
end
|
||||
|
||||
---Maybe highlight group, optionally implemented
|
||||
---@protected
|
||||
---@param _ Node
|
||||
---@return string|nil group
|
||||
function Decorator:calculate_highlight(_)
|
||||
return nil
|
||||
end
|
||||
|
||||
---Define a sign
|
||||
---@protected
|
||||
---@param icon HighlightedString|nil
|
||||
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 = 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
|
||||
61
lua/nvim-tree/renderer/decorator/modified.lua
Normal file
61
lua/nvim-tree/renderer/decorator/modified.lua
Normal file
@@ -0,0 +1,61 @@
|
||||
local buffers = require "nvim-tree.buffers"
|
||||
|
||||
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
|
||||
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
|
||||
|
||||
local Decorator = require "nvim-tree.renderer.decorator"
|
||||
|
||||
---@class DecoratorModified: Decorator
|
||||
---@field icon HighlightedString|nil
|
||||
local DecoratorModified = Decorator:new()
|
||||
|
||||
---@param opts table
|
||||
---@return DecoratorModified
|
||||
function DecoratorModified:new(opts)
|
||||
local o = Decorator.new(self, {
|
||||
enabled = opts.modified.enable,
|
||||
hl_pos = HL_POSITION[opts.renderer.highlight_modified] or HL_POSITION.none,
|
||||
icon_placement = ICON_PLACEMENT[opts.renderer.icons.modified_placement] or ICON_PLACEMENT.none,
|
||||
})
|
||||
---@cast o DecoratorModified
|
||||
|
||||
if not o.enabled then
|
||||
return o
|
||||
end
|
||||
|
||||
if opts.renderer.icons.show.modified then
|
||||
o.icon = {
|
||||
str = opts.renderer.icons.glyphs.modified,
|
||||
hl = { "NvimTreeModifiedIcon" },
|
||||
}
|
||||
o:define_sign(o.icon)
|
||||
end
|
||||
|
||||
return o
|
||||
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)
|
||||
if self.enabled and buffers.is_modified(node) then
|
||||
return { self.icon }
|
||||
end
|
||||
end
|
||||
|
||||
---Modified highlight: modified.enable, renderer.highlight_modified and node is modified
|
||||
---@param node Node
|
||||
---@return string|nil group
|
||||
function DecoratorModified:calculate_highlight(node)
|
||||
if not self.enabled or self.hl_pos == HL_POSITION.none or not buffers.is_modified(node) then
|
||||
return nil
|
||||
end
|
||||
|
||||
if node.nodes then
|
||||
return "NvimTreeModifiedFolderHL"
|
||||
else
|
||||
return "NvimTreeModifiedFileHL"
|
||||
end
|
||||
end
|
||||
|
||||
return DecoratorModified
|
||||
35
lua/nvim-tree/renderer/decorator/opened.lua
Normal file
35
lua/nvim-tree/renderer/decorator/opened.lua
Normal file
@@ -0,0 +1,35 @@
|
||||
local buffers = require "nvim-tree.buffers"
|
||||
|
||||
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
|
||||
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
|
||||
|
||||
local Decorator = require "nvim-tree.renderer.decorator"
|
||||
|
||||
---@class DecoratorOpened: Decorator
|
||||
---@field enabled boolean
|
||||
---@field icon HighlightedString|nil
|
||||
local DecoratorOpened = Decorator:new()
|
||||
|
||||
---@param opts table
|
||||
---@return DecoratorOpened
|
||||
function DecoratorOpened:new(opts)
|
||||
local o = Decorator.new(self, {
|
||||
enabled = true,
|
||||
hl_pos = HL_POSITION[opts.renderer.highlight_opened_files] or HL_POSITION.none,
|
||||
icon_placement = ICON_PLACEMENT.none,
|
||||
})
|
||||
---@cast o DecoratorOpened
|
||||
|
||||
return o
|
||||
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.hl_pos ~= HL_POSITION.none and buffers.is_opened(node) then
|
||||
return "NvimTreeOpenedHL"
|
||||
end
|
||||
end
|
||||
|
||||
return DecoratorOpened
|
||||
Reference in New Issue
Block a user