refactor(renderer): line creation into a builder pattern
- use a builder pattern to mount the lines / highlights - i think we lost a little performance, but gain in design - code for file/folder icons is abstracted in components/icons.lua - should also fix the issues where vim.g variables where loaded before setup.
This commit is contained in:
parent
ebf73f0a9d
commit
d44742bee5
234
lua/nvim-tree/renderer/builder.lua
Normal file
234
lua/nvim-tree/renderer/builder.lua
Normal file
@ -0,0 +1,234 @@
|
||||
local utils = require "nvim-tree.utils"
|
||||
|
||||
local git = require "nvim-tree.renderer.components.git"
|
||||
local pad = require "nvim-tree.renderer.components.padding"
|
||||
local icons = require "nvim-tree.renderer.components.icons"
|
||||
|
||||
-- TODO(refactor): the builder abstraction is not perfect yet. We shouldn't leak data in components.
|
||||
-- Components should return only and icon / highlight group pair at most.
|
||||
-- The picture and special map definitions should be abstracted away, or even reconsidered.
|
||||
-- The code was mostly moved from renderer/init.lua and rearranged, so it's still under construction.
|
||||
|
||||
local picture = {
|
||||
jpg = true,
|
||||
jpeg = true,
|
||||
png = true,
|
||||
gif = true,
|
||||
}
|
||||
|
||||
local function get_special_files_map()
|
||||
return vim.g.nvim_tree_special_files
|
||||
or {
|
||||
["Cargo.toml"] = true,
|
||||
Makefile = true,
|
||||
["README.md"] = true,
|
||||
["readme.md"] = true,
|
||||
}
|
||||
end
|
||||
|
||||
local Builder = {}
|
||||
Builder.__index = Builder
|
||||
|
||||
function Builder.new(root_cwd)
|
||||
return setmetatable({
|
||||
index = 0,
|
||||
depth = nil,
|
||||
highlights = {},
|
||||
lines = {},
|
||||
markers = {},
|
||||
root_cwd = root_cwd,
|
||||
}, Builder)
|
||||
end
|
||||
|
||||
function Builder:configure_initial_depth(show_arrows)
|
||||
self.depth = show_arrows and 2 or 0
|
||||
return self
|
||||
end
|
||||
|
||||
function Builder:configure_opened_file_highlighting(level)
|
||||
if level == 1 then
|
||||
self.open_file_highlight = "icon"
|
||||
elseif level == 2 then
|
||||
self.open_file_highlight = "name"
|
||||
elseif level == 3 then
|
||||
self.open_file_highlight = "all"
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Builder:_insert_highlight(group, start, end_)
|
||||
table.insert(self.highlights, { group, self.index, start, end_ or -1 })
|
||||
end
|
||||
|
||||
function Builder:_insert_line(line)
|
||||
table.insert(self.lines, line)
|
||||
end
|
||||
|
||||
function Builder:_build_folder(node, padding, git_hl)
|
||||
local special = get_special_files_map()
|
||||
local offset = string.len(padding)
|
||||
|
||||
local has_children = #node.nodes ~= 0 or node.has_children
|
||||
local icon = icons.get_folder_icon(node.open, node.link_to ~= nil, has_children)
|
||||
local git_icon = git.get_icons(node, self.index, offset, #icon, self.highlights) or ""
|
||||
-- INFO: this is mandatory in order to keep gui attributes (bold/italics)
|
||||
local folder_hl = "NvimTreeFolderName"
|
||||
local name = node.name
|
||||
local next = node.group_next
|
||||
while next do
|
||||
name = name .. "/" .. next.name
|
||||
next = next.group_next
|
||||
end
|
||||
if not has_children then
|
||||
folder_hl = "NvimTreeEmptyFolderName"
|
||||
end
|
||||
if node.open then
|
||||
folder_hl = "NvimTreeOpenedFolderName"
|
||||
end
|
||||
if special[node.absolute_path] then
|
||||
folder_hl = "NvimTreeSpecialFolderName"
|
||||
end
|
||||
icons.set_folder_hl(
|
||||
self.index,
|
||||
offset,
|
||||
#icon + #git_icon,
|
||||
#name,
|
||||
"NvimTreeFolderIcon",
|
||||
folder_hl,
|
||||
self.highlights,
|
||||
self.open_file_highlight
|
||||
)
|
||||
if git_hl then
|
||||
icons.set_folder_hl(
|
||||
self.index,
|
||||
offset,
|
||||
#icon + #git_icon,
|
||||
#name,
|
||||
git_hl,
|
||||
git_hl,
|
||||
self.highlights,
|
||||
self.open_file_highlight
|
||||
)
|
||||
end
|
||||
self:_insert_line(padding .. icon .. git_icon .. name .. (vim.g.nvim_tree_add_trailing == 1 and "/" or ""))
|
||||
end
|
||||
|
||||
-- TODO: missing git icon for symlinks
|
||||
function Builder:_build_symlink(node, padding, git_highlight)
|
||||
local icon = icons.i.symlink
|
||||
local arrow = icons.i.symlink_arrow
|
||||
|
||||
local link_highlight = git_highlight or "NvimTreeSymlink"
|
||||
|
||||
local line = padding .. icon .. node.name .. arrow .. node.link_to
|
||||
self:_insert_highlight(link_highlight, string.len(padding), string.len(line))
|
||||
self:_insert_line(line)
|
||||
end
|
||||
|
||||
function Builder:_build_file_icons(node, offset, special)
|
||||
if special[node.absolute_path] or special[node.name] then
|
||||
local git_icons = git.get_icons(node, self.index, offset, 0, self.highlights)
|
||||
self:_insert_highlight("NvimTreeSpecialFile", offset + #git_icons)
|
||||
return icons.i.special, git_icons
|
||||
else
|
||||
local icon = icons.get_file_icon(node.name, node.extension, self.index, offset, self.highlights)
|
||||
return icon, git.get_icons(node, self.index, offset, #icon, self.highlights)
|
||||
end
|
||||
end
|
||||
|
||||
function Builder:_highlight_opened_files(node, offset, icon, git_icons)
|
||||
local from = offset
|
||||
local to = offset
|
||||
|
||||
if self.open_file_highlight == "icon" then
|
||||
to = from + #icon
|
||||
elseif self.open_file_highlight == "name" then
|
||||
from = offset + #icon + #git_icons
|
||||
to = from + #node.name
|
||||
elseif self.open_file_highlight == "all" then
|
||||
to = -1
|
||||
end
|
||||
|
||||
self:_insert_highlight("NvimTreeOpenedFile", from, to)
|
||||
end
|
||||
|
||||
function Builder:_build_file(node, padding, git_highlight)
|
||||
local offset = string.len(padding)
|
||||
|
||||
local special = get_special_files_map()
|
||||
local icon, git_icons = self:_build_file_icons(node, offset, special)
|
||||
|
||||
self:_insert_line(padding .. icon .. git_icons .. node.name)
|
||||
local col_start = offset + #icon + #git_icons
|
||||
|
||||
if node.executable then
|
||||
self:_insert_highlight("NvimTreeExecFile", col_start)
|
||||
elseif picture[node.extension] then
|
||||
self:_insert_highlight("NvimTreeImageFile", col_start)
|
||||
end
|
||||
|
||||
local should_highlight_opened_files = self.open_file_highlight and vim.fn.bufloaded(node.absolute_path) > 0
|
||||
if should_highlight_opened_files then
|
||||
self:_highlight_opened_files(node, offset, icon, git_icons)
|
||||
end
|
||||
|
||||
if git_highlight then
|
||||
self:_insert_highlight(git_highlight, col_start)
|
||||
end
|
||||
end
|
||||
|
||||
function Builder:build(tree)
|
||||
for idx, node in ipairs(tree.nodes) do
|
||||
local padding = pad.get_padding(self.depth, idx, tree, node, self.markers)
|
||||
|
||||
if self.depth > 0 then
|
||||
self:_insert_highlight("NvimTreeIndentMarker", 0, string.len(padding))
|
||||
end
|
||||
|
||||
local git_highlight = git.get_highlight(node)
|
||||
|
||||
local is_folder = node.nodes ~= nil
|
||||
local is_symlink = node.link_to ~= nil
|
||||
|
||||
if is_folder then
|
||||
self:_build_folder(node, padding, git_highlight)
|
||||
elseif is_symlink then
|
||||
self:_build_symlink(node, padding, git_highlight)
|
||||
else
|
||||
self:_build_file(node, padding, git_highlight)
|
||||
end
|
||||
self.index = self.index + 1
|
||||
|
||||
if node.open then
|
||||
self.depth = self.depth + 2
|
||||
self:build(node)
|
||||
self.depth = self.depth - 2
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
local function format_root_name(root_cwd)
|
||||
local root_folder_modifier = vim.g.nvim_tree_root_folder_modifier or ":~"
|
||||
local base_root = utils.path_remove_trailing(vim.fn.fnamemodify(root_cwd, root_folder_modifier))
|
||||
return utils.path_join { base_root, ".." }
|
||||
end
|
||||
|
||||
function Builder:build_header(show_header)
|
||||
if show_header then
|
||||
local root_name = format_root_name(self.root_cwd)
|
||||
self:_insert_line(root_name)
|
||||
self:_insert_highlight("NvimTreeRootFolder", 0, string.len(root_name))
|
||||
self.index = 1
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Builder:unwrap()
|
||||
return self.lines, self.highlights
|
||||
end
|
||||
|
||||
return Builder
|
||||
120
lua/nvim-tree/renderer/components/icons.lua
Normal file
120
lua/nvim-tree/renderer/components/icons.lua
Normal file
@ -0,0 +1,120 @@
|
||||
local icon_config = require "nvim-tree.renderer.icon-config"
|
||||
|
||||
local M = { i = {} }
|
||||
|
||||
local function config_symlinks()
|
||||
M.i.symlink = #M.icons.symlink > 0 and M.icons.symlink .. M.padding or ""
|
||||
M.i.symlink_arrow = vim.g.nvim_tree_symlink_arrow or " ➛ "
|
||||
end
|
||||
|
||||
local function empty()
|
||||
return ""
|
||||
end
|
||||
|
||||
local function get_trailing_length()
|
||||
return vim.g.nvim_tree_add_trailing and 1 or 0
|
||||
end
|
||||
|
||||
local function set_folder_hl_default(line, depth, git_icon_len, _, hl_group, _, hl)
|
||||
table.insert(hl, { hl_group, line, depth + git_icon_len, -1 })
|
||||
end
|
||||
|
||||
local function get_folder_icon(open, is_symlink, has_children)
|
||||
local n
|
||||
if is_symlink and open then
|
||||
n = M.icons.folder_icons.symlink_open
|
||||
elseif is_symlink then
|
||||
n = M.icons.folder_icons.symlink
|
||||
elseif open then
|
||||
if has_children then
|
||||
n = M.icons.folder_icons.open
|
||||
else
|
||||
n = M.icons.folder_icons.empty_open
|
||||
end
|
||||
else
|
||||
if has_children then
|
||||
n = M.icons.folder_icons.default
|
||||
else
|
||||
n = M.icons.folder_icons.empty
|
||||
end
|
||||
end
|
||||
return n .. M.padding
|
||||
end
|
||||
|
||||
local function set_folder_hl(line, depth, icon_len, name_len, hl_icongroup, hl_fnamegroup, hl, should_hl_opened_files)
|
||||
local hl_icon = should_hl_opened_files and hl_icongroup or "NvimTreeFolderIcon"
|
||||
table.insert(hl, { hl_icon, line, depth, depth + icon_len })
|
||||
table.insert(hl, { hl_fnamegroup, line, depth + icon_len, depth + icon_len + name_len + get_trailing_length() })
|
||||
end
|
||||
|
||||
local function get_file_icon_default(_, _, line, depth, hl)
|
||||
local hl_group = "NvimTreeFileIcon"
|
||||
local icon = M.icons.default
|
||||
if #icon > 0 then
|
||||
table.insert(hl, { hl_group, line, depth, depth + #icon + 1 })
|
||||
end
|
||||
return #icon > 0 and icon .. M.padding or ""
|
||||
end
|
||||
|
||||
local function get_file_icon_webdev(fname, extension, line, depth, hl)
|
||||
local icon, hl_group = M.devicons.get_icon(fname, extension)
|
||||
if not M.webdev_colors then
|
||||
hl_group = "NvimTreeFileIcon"
|
||||
end
|
||||
if icon and hl_group ~= "DevIconDefault" then
|
||||
if hl_group then
|
||||
table.insert(hl, { hl_group, line, depth, depth + #icon + 1 })
|
||||
end
|
||||
return icon .. M.padding
|
||||
elseif string.match(extension, "%.(.*)") then
|
||||
-- If there are more extensions to the file, try to grab the icon for them recursively
|
||||
return M.get_file_icon(fname, string.match(extension, "%.(.*)"), line, depth, hl)
|
||||
else
|
||||
return get_file_icon_default(fname, extension, line, depth, hl)
|
||||
end
|
||||
end
|
||||
|
||||
local function config_file_icon()
|
||||
if M.configs.show_file_icon then
|
||||
if M.devicons then
|
||||
M.get_file_icon = get_file_icon_webdev
|
||||
else
|
||||
M.get_file_icon = get_file_icon_default
|
||||
end
|
||||
else
|
||||
M.get_file_icon = empty
|
||||
end
|
||||
end
|
||||
|
||||
local function config_special_icon()
|
||||
if M.configs.show_file_icon then
|
||||
M.i.special = #M.icons.default > 0 and M.icons.default .. M.padding or ""
|
||||
else
|
||||
M.i.special = ""
|
||||
end
|
||||
end
|
||||
|
||||
local function config_folder_icon()
|
||||
if M.configs.show_folder_icon then
|
||||
M.get_folder_icon = get_folder_icon
|
||||
M.set_folder_hl = set_folder_hl
|
||||
else
|
||||
M.get_file_icon = empty
|
||||
M.set_folder_hl = set_folder_hl_default
|
||||
end
|
||||
end
|
||||
|
||||
function M.reset_config(webdev_colors)
|
||||
M.configs = icon_config.get_config()
|
||||
M.icons = M.configs.icons
|
||||
M.padding = vim.g.nvim_tree_icon_padding or " "
|
||||
M.devicons = M.configs.has_devicons and require "nvim-web-devicons" or nil
|
||||
M.webdev_colors = webdev_colors
|
||||
|
||||
config_symlinks()
|
||||
config_special_icon()
|
||||
config_file_icon()
|
||||
config_folder_icon()
|
||||
end
|
||||
|
||||
return M
|
||||
@ -1,282 +1,39 @@
|
||||
local log = require "nvim-tree.log"
|
||||
local utils = require "nvim-tree.utils"
|
||||
local view = require "nvim-tree.view"
|
||||
local _padding = require "nvim-tree.renderer.components.padding"
|
||||
local _help = require "nvim-tree.renderer.help"
|
||||
local _icons = require "nvim-tree.renderer.icon-config"
|
||||
local icon_component = require "nvim-tree.renderer.components.icons"
|
||||
local help = require "nvim-tree.renderer.help"
|
||||
local git = require "nvim-tree.renderer.components.git"
|
||||
local core = require "nvim-tree.core"
|
||||
local Builder = require "nvim-tree.renderer.builder"
|
||||
|
||||
local api = vim.api
|
||||
|
||||
local M = {}
|
||||
|
||||
local lines = {}
|
||||
local hl = {}
|
||||
local index = 0
|
||||
local namespace_id = api.nvim_create_namespace "NvimTreeHighlights"
|
||||
|
||||
M.icon_state = _icons.get_config()
|
||||
|
||||
local web_devicons = M.icon_state.has_devicons and require "nvim-web-devicons" or nil
|
||||
|
||||
local should_hl_opened_files = (vim.g.nvim_tree_highlight_opened_files or 0) ~= 0
|
||||
|
||||
local icon_padding = vim.g.nvim_tree_icon_padding or " "
|
||||
|
||||
-- ## SYMLINK
|
||||
|
||||
local get_symlink_icon = function()
|
||||
return #M.icon_state.icons.symlink > 0 and M.icon_state.icons.symlink .. icon_padding or ""
|
||||
end
|
||||
|
||||
local function build_symlink(node, padding, offset, git_hl)
|
||||
local icon = get_symlink_icon()
|
||||
local link_hl = git_hl or "NvimTreeSymlink"
|
||||
local arrow = vim.g.nvim_tree_symlink_arrow or " ➛ "
|
||||
table.insert(hl, { link_hl, index, offset, -1 })
|
||||
table.insert(lines, padding .. icon .. node.name .. arrow .. node.link_to)
|
||||
end
|
||||
|
||||
-- ## FILES
|
||||
|
||||
local get_file_icon = function()
|
||||
return ""
|
||||
end
|
||||
|
||||
local get_file_icon_default = function(_, _, line, depth)
|
||||
local hl_group = "NvimTreeFileIcon"
|
||||
local icon = M.icon_state.icons.default
|
||||
if #icon > 0 then
|
||||
table.insert(hl, { hl_group, line, depth, depth + #icon + 1 })
|
||||
end
|
||||
return #icon > 0 and icon .. icon_padding or ""
|
||||
end
|
||||
|
||||
local get_file_icon_webdev = function(fname, extension, line, depth)
|
||||
local icon, hl_group = web_devicons.get_icon(fname, extension)
|
||||
if not M.config.icons.webdev_colors then
|
||||
hl_group = "NvimTreeFileIcon"
|
||||
end
|
||||
if icon and hl_group ~= "DevIconDefault" then
|
||||
if hl_group then
|
||||
table.insert(hl, { hl_group, line, depth, depth + #icon + 1 })
|
||||
end
|
||||
return icon .. icon_padding
|
||||
elseif string.match(extension, "%.(.*)") then
|
||||
-- If there are more extensions to the file, try to grab the icon for them recursively
|
||||
return get_file_icon(fname, string.match(extension, "%.(.*)"), line, depth)
|
||||
else
|
||||
return get_file_icon_default(fname, extension, line, depth)
|
||||
end
|
||||
end
|
||||
|
||||
if M.icon_state.show_file_icon then
|
||||
if web_devicons then
|
||||
get_file_icon = get_file_icon_webdev
|
||||
else
|
||||
get_file_icon = get_file_icon_default
|
||||
end
|
||||
end
|
||||
|
||||
local get_special_icon = function()
|
||||
return ""
|
||||
end
|
||||
if M.icon_state.show_file_icon then
|
||||
get_special_icon = function()
|
||||
return #M.icon_state.icons.default > 0 and M.icon_state.icons.default .. icon_padding or ""
|
||||
end
|
||||
end
|
||||
|
||||
local picture = {
|
||||
jpg = true,
|
||||
jpeg = true,
|
||||
png = true,
|
||||
gif = true,
|
||||
}
|
||||
|
||||
local function get_special_files_map()
|
||||
return vim.g.nvim_tree_special_files
|
||||
or {
|
||||
["Cargo.toml"] = true,
|
||||
Makefile = true,
|
||||
["README.md"] = true,
|
||||
["readme.md"] = true,
|
||||
}
|
||||
end
|
||||
|
||||
local function highlight_opened_files(node, offset, icon, git_icons)
|
||||
local from = offset
|
||||
local to = offset
|
||||
|
||||
if vim.g.nvim_tree_highlight_opened_files == 1 then -- highlight icon only
|
||||
to = from + #icon
|
||||
elseif vim.g.nvim_tree_highlight_opened_files == 2 then -- highlight name only
|
||||
from = offset + #icon + #git_icons
|
||||
to = from + #node.name
|
||||
elseif vim.g.nvim_tree_highlight_opened_files == 3 then -- highlight whole line
|
||||
to = -1
|
||||
end
|
||||
|
||||
table.insert(hl, { "NvimTreeOpenedFile", index, from, to })
|
||||
end
|
||||
|
||||
local function build_file_icons(node, offset, special)
|
||||
if special[node.absolute_path] or special[node.name] then
|
||||
local git_icons = git.get_icons(node, index, offset, 0, hl)
|
||||
table.insert(hl, { "NvimTreeSpecialFile", index, offset + #git_icons, -1 })
|
||||
return get_special_icon(), git_icons
|
||||
else
|
||||
local icon = get_file_icon(node.name, node.extension, index, offset)
|
||||
return icon, git.get_icons(node, index, offset, #icon, hl)
|
||||
end
|
||||
end
|
||||
|
||||
local function build_file(node, padding, offset, git_hl, special)
|
||||
local icon, git_icons = build_file_icons(node, offset, special)
|
||||
|
||||
table.insert(lines, padding .. icon .. git_icons .. node.name)
|
||||
|
||||
if node.executable then
|
||||
table.insert(hl, { "NvimTreeExecFile", index, offset + #icon + #git_icons, -1 })
|
||||
elseif picture[node.extension] then
|
||||
table.insert(hl, { "NvimTreeImageFile", index, offset + #icon + #git_icons, -1 })
|
||||
end
|
||||
|
||||
local should_highlight_opened_files = should_hl_opened_files and vim.fn.bufloaded(node.absolute_path) > 0
|
||||
if should_highlight_opened_files then
|
||||
highlight_opened_files(node, offset, icon, git_icons)
|
||||
end
|
||||
|
||||
if git_hl then
|
||||
table.insert(hl, { git_hl, index, offset + #icon + #git_icons, -1 })
|
||||
end
|
||||
end
|
||||
|
||||
-- ## FOLDERS
|
||||
|
||||
local function get_trailing_length()
|
||||
return vim.g.nvim_tree_add_trailing and 1 or 0
|
||||
end
|
||||
|
||||
local get_folder_icon = function()
|
||||
return ""
|
||||
end
|
||||
|
||||
local set_folder_hl = function(line, depth, git_icon_len, _, hl_group, _)
|
||||
table.insert(hl, { hl_group, line, depth + git_icon_len, -1 })
|
||||
end
|
||||
|
||||
if M.icon_state.show_folder_icon then
|
||||
get_folder_icon = function(open, is_symlink, has_children)
|
||||
local n
|
||||
if is_symlink and open then
|
||||
n = M.icon_state.icons.folder_icons.symlink_open
|
||||
elseif is_symlink then
|
||||
n = M.icon_state.icons.folder_icons.symlink
|
||||
elseif open then
|
||||
if has_children then
|
||||
n = M.icon_state.icons.folder_icons.open
|
||||
else
|
||||
n = M.icon_state.icons.folder_icons.empty_open
|
||||
end
|
||||
else
|
||||
if has_children then
|
||||
n = M.icon_state.icons.folder_icons.default
|
||||
else
|
||||
n = M.icon_state.icons.folder_icons.empty
|
||||
end
|
||||
end
|
||||
return n .. icon_padding
|
||||
end
|
||||
set_folder_hl = function(line, depth, icon_len, name_len, hl_icongroup, hl_fnamegroup)
|
||||
local hl_icon = should_hl_opened_files and hl_icongroup or "NvimTreeFolderIcon"
|
||||
table.insert(hl, { hl_icon, line, depth, depth + icon_len })
|
||||
table.insert(hl, { hl_fnamegroup, line, depth + icon_len, depth + icon_len + name_len + get_trailing_length() })
|
||||
end
|
||||
end
|
||||
|
||||
local function build_folder(node, padding, offset, git_hl, special)
|
||||
local has_children = #node.nodes ~= 0 or node.has_children
|
||||
local icon = get_folder_icon(node.open, node.link_to ~= nil, has_children)
|
||||
local git_icon = git.get_icons(node, index, offset, #icon, hl) or ""
|
||||
-- INFO: this is mandatory in order to keep gui attributes (bold/italics)
|
||||
local folder_hl = "NvimTreeFolderName"
|
||||
local name = node.name
|
||||
local next = node.group_next
|
||||
while next do
|
||||
name = name .. "/" .. next.name
|
||||
next = next.group_next
|
||||
end
|
||||
if not has_children then
|
||||
folder_hl = "NvimTreeEmptyFolderName"
|
||||
end
|
||||
if node.open then
|
||||
folder_hl = "NvimTreeOpenedFolderName"
|
||||
end
|
||||
if special[node.absolute_path] then
|
||||
folder_hl = "NvimTreeSpecialFolderName"
|
||||
end
|
||||
set_folder_hl(index, offset, #icon + #git_icon, #name, "NvimTreeFolderIcon", folder_hl)
|
||||
if git_hl then
|
||||
set_folder_hl(index, offset, #icon + #git_icon, #name, git_hl, git_hl)
|
||||
end
|
||||
if node.open then
|
||||
table.insert(lines, padding .. icon .. git_icon .. name .. (vim.g.nvim_tree_add_trailing == 1 and "/" or ""))
|
||||
else
|
||||
table.insert(lines, padding .. icon .. git_icon .. name .. (vim.g.nvim_tree_add_trailing == 1 and "/" or ""))
|
||||
end
|
||||
end
|
||||
|
||||
local function compute_lines_and_highlights(tree, depth, markers)
|
||||
local special = get_special_files_map()
|
||||
|
||||
for idx, node in ipairs(tree.nodes) do
|
||||
local padding = _padding.get_padding(depth, idx, tree, node, markers)
|
||||
local offset = string.len(padding)
|
||||
if depth > 0 then
|
||||
table.insert(hl, { "NvimTreeIndentMarker", index, 0, offset })
|
||||
end
|
||||
|
||||
local git_hl = git.get_highlight(node)
|
||||
|
||||
if node.nodes then
|
||||
build_folder(node, padding, offset, git_hl, special)
|
||||
elseif node.link_to then
|
||||
build_symlink(node, padding, offset, git_hl)
|
||||
else
|
||||
build_file(node, padding, offset, git_hl, special)
|
||||
end
|
||||
index = index + 1
|
||||
|
||||
if node.open then
|
||||
compute_lines_and_highlights(node, depth + 2, markers)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function compute_header()
|
||||
if view.is_root_folder_visible(core.get_cwd()) then
|
||||
local root_folder_modifier = vim.g.nvim_tree_root_folder_modifier or ":~"
|
||||
local root_name = utils.path_join {
|
||||
utils.path_remove_trailing(vim.fn.fnamemodify(core.get_cwd(), root_folder_modifier)),
|
||||
"..",
|
||||
}
|
||||
table.insert(lines, root_name)
|
||||
table.insert(hl, { "NvimTreeRootFolder", index, 0, string.len(root_name) })
|
||||
index = 1
|
||||
end
|
||||
end
|
||||
|
||||
local function _draw(bufnr)
|
||||
local function _draw(bufnr, lines, hl)
|
||||
api.nvim_buf_set_option(bufnr, "modifiable", true)
|
||||
api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
|
||||
M.render_hl(bufnr)
|
||||
M.render_hl(bufnr, hl)
|
||||
api.nvim_buf_set_option(bufnr, "modifiable", false)
|
||||
end
|
||||
|
||||
function M.render_hl(bufnr, hl)
|
||||
if not bufnr or not api.nvim_buf_is_loaded(bufnr) then
|
||||
return
|
||||
end
|
||||
api.nvim_buf_clear_namespace(bufnr, namespace_id, 0, -1)
|
||||
for _, data in ipairs(hl) do
|
||||
api.nvim_buf_add_highlight(bufnr, namespace_id, data[1], data[2], data[3], data[4])
|
||||
end
|
||||
end
|
||||
|
||||
local function should_show_arrows()
|
||||
return not M.config.indent_markers.enable and M.icon_state.show_folder_icon and M.icon_state.show_folder_arrows
|
||||
return not M.config.indent_markers.enable
|
||||
and icon_component.configs.show_folder_icon
|
||||
and icon_component.configs.show_folder_arrows
|
||||
end
|
||||
|
||||
function M.draw()
|
||||
@ -287,27 +44,24 @@ function M.draw()
|
||||
|
||||
local ps = log.profile_start "draw"
|
||||
|
||||
local cursor
|
||||
if view.is_visible() then
|
||||
cursor = api.nvim_win_get_cursor(view.get_winnr())
|
||||
end
|
||||
index = 0
|
||||
lines = {}
|
||||
hl = {}
|
||||
|
||||
M.icon_state = _icons.get_config()
|
||||
local cursor = api.nvim_win_get_cursor(view.get_winnr())
|
||||
_padding.reload_padding_function()
|
||||
icon_component.reset_config(M.config.icons.webdev_colors)
|
||||
git.reload()
|
||||
|
||||
local lines, hl
|
||||
if view.is_help_ui() then
|
||||
lines, hl = _help.compute_lines()
|
||||
lines, hl = help.compute_lines()
|
||||
else
|
||||
local start_depth = should_show_arrows() and 2 or 0
|
||||
compute_header()
|
||||
compute_lines_and_highlights(core.get_explorer(), start_depth, {})
|
||||
lines, hl = Builder.new(core.get_cwd())
|
||||
:configure_initial_depth(should_show_arrows())
|
||||
:configure_opened_file_highlighting(vim.g.nvim_tree_highlight_opened_files)
|
||||
:build_header(view.is_root_folder_visible(core.get_cwd()))
|
||||
:build(core.get_explorer())
|
||||
:unwrap()
|
||||
end
|
||||
|
||||
_draw(bufnr)
|
||||
_draw(bufnr, lines, hl)
|
||||
|
||||
if cursor and #lines >= cursor[1] then
|
||||
api.nvim_win_set_cursor(view.get_winnr(), cursor)
|
||||
@ -316,16 +70,6 @@ function M.draw()
|
||||
log.profile_end(ps, "draw")
|
||||
end
|
||||
|
||||
function M.render_hl(bufnr)
|
||||
if not bufnr or not api.nvim_buf_is_loaded(bufnr) then
|
||||
return
|
||||
end
|
||||
api.nvim_buf_clear_namespace(bufnr, namespace_id, 0, -1)
|
||||
for _, data in ipairs(hl) do
|
||||
api.nvim_buf_add_highlight(bufnr, namespace_id, data[1], data[2], data[3], data[4])
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup(opts)
|
||||
M.config = {
|
||||
indent_markers = opts.renderer.indent_markers,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user