refactor(renderer): refactor git handling

Concat and apply git highlight inside the builder.
This allows to not leak private data from builder to the git component.
This will also now allow us to customize git icon placement.
This commit is contained in:
kiyan
2022-04-26 22:59:16 +02:00
parent 0d6c0dda3d
commit ce2cf7131f
3 changed files with 33 additions and 31 deletions

View File

@@ -4,10 +4,6 @@ local git = require "nvim-tree.renderer.components.git"
local pad = require "nvim-tree.renderer.components.padding" local pad = require "nvim-tree.renderer.components.padding"
local icons = require "nvim-tree.renderer.components.icons" 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.
-- Only missing git refactoring
local Builder = {} local Builder = {}
Builder.__index = Builder Builder.__index = Builder
@@ -59,6 +55,11 @@ function Builder:configure_opened_file_highlighting(level)
return self return self
end end
function Builder:configure_git_icons_padding(padding)
self.git_icon_padding = padding or " "
return self
end
function Builder:_insert_highlight(group, start, end_) function Builder:_insert_highlight(group, start, end_)
table.insert(self.highlights, { group, self.index, start, end_ or -1 }) table.insert(self.highlights, { group, self.index, start, end_ or -1 })
end end
@@ -77,13 +78,29 @@ local function get_folder_name(node)
return name return name
end end
function Builder:_unwrap_git_data(git_icons_and_hl_groups, offset)
if not git_icons_and_hl_groups then
return ""
end
local icon = ""
for _, v in ipairs(git_icons_and_hl_groups) do
if #v.icon > 0 then
self:_insert_highlight(v.hl, offset + #icon, offset + #icon + #v.icon)
icon = icon .. v.icon .. self.git_icon_padding
end
end
return icon
end
function Builder:_build_folder(node, padding, git_hl) function Builder:_build_folder(node, padding, git_hl)
local offset = string.len(padding) local offset = string.len(padding)
local name = get_folder_name(node) local name = get_folder_name(node)
local has_children = #node.nodes ~= 0 or node.has_children 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 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 "" local git_icon = self:_unwrap_git_data(git.get_icons(node), offset + #icon)
local line = padding .. icon .. git_icon .. name .. self.trailing_slash local line = padding .. icon .. git_icon .. name .. self.trailing_slash
self:_insert_line(line) self:_insert_line(line)
@@ -122,7 +139,7 @@ end
function Builder:_build_file_icons(node, offset) function Builder:_build_file_icons(node, offset)
if self.special_map[node.absolute_path] or self.special_map[node.name] then if self.special_map[node.absolute_path] or self.special_map[node.name] then
local git_icons = git.get_icons(node, self.index, offset, 0, self.highlights) local git_icons = self:_unwrap_git_data(git.get_icons(node), offset + #icons.i.special)
self:_insert_highlight("NvimTreeSpecialFile", offset + #git_icons) self:_insert_highlight("NvimTreeSpecialFile", offset + #git_icons)
return icons.i.special, git_icons return icons.i.special, git_icons
else else
@@ -130,7 +147,7 @@ function Builder:_build_file_icons(node, offset)
if hl_group then if hl_group then
self:_insert_highlight(hl_group, offset, offset + #icon) self:_insert_highlight(hl_group, offset, offset + #icon)
end end
return icon, git.get_icons(node, self.index, offset, #icon, self.highlights) return icon, self:_unwrap_git_data(git.get_icons(node), offset + #icon)
end end
end end

View File

@@ -65,9 +65,6 @@ local function build_icons_table()
} }
end end
local function empty()
return ""
end
local function nil_() end local function nil_() end
local function warn_status(git_status) local function warn_status(git_status)
@@ -78,28 +75,21 @@ local function warn_status(git_status)
) )
end end
local function get_icons_(node, line, depth, icon_len, hl) local function get_icons_(node)
local git_status = node.git_status local git_status = node.git_status
if not git_status then if not git_status then
return "" return nil
end end
local icon = ""
local icons = M.git_icons[git_status] local icons = M.git_icons[git_status]
if not icons then if not icons then
if vim.g.nvim_tree_git_hl ~= 1 then if vim.g.nvim_tree_git_hl ~= 1 then
warn_status(git_status) warn_status(git_status)
end end
return "" return nil
end
for _, v in ipairs(icons) do
if #v.icon > 0 then
table.insert(hl, { v.hl, line, depth + icon_len + #icon, depth + icon_len + #icon + #v.icon })
icon = icon .. v.icon .. M.icon_padding
end
end end
return icon return icons
end end
local git_hl = { local git_hl = {
@@ -143,26 +133,20 @@ local function get_highlight_(node)
return git_hl[git_status] return git_hl[git_status]
end end
function M.get_icons() M.get_icons = nil_
return empty() M.get_highlight = nil_
end
function M.get_highlight()
return nil_()
end
M.icon_padding = vim.g.nvim_tree_icon_padding or " "
M.icon_state = _icons.get_config() M.icon_state = _icons.get_config()
M.git_icons = build_icons_table() M.git_icons = build_icons_table()
function M.reload() function M.reload()
M.icon_state = _icons.get_config() M.icon_state = _icons.get_config()
M.icon_padding = vim.g.nvim_tree_icon_padding or " "
M.git_icons = build_icons_table() M.git_icons = build_icons_table()
if M.icon_state.show_git_icon then if M.icon_state.show_git_icon then
M.get_icons = get_icons_ M.get_icons = get_icons_
else else
M.get_icons = empty M.get_icons = nil_
end end
if vim.g.nvim_tree_git_hl == 1 then if vim.g.nvim_tree_git_hl == 1 then
M.get_highlight = get_highlight_ M.get_highlight = get_highlight_

View File

@@ -79,6 +79,7 @@ function M.draw()
:configure_special_map(get_special_files_map()) :configure_special_map(get_special_files_map())
:configure_picture_map(picture_map) :configure_picture_map(picture_map)
:configure_opened_file_highlighting(vim.g.nvim_tree_highlight_opened_files) :configure_opened_file_highlighting(vim.g.nvim_tree_highlight_opened_files)
:configure_git_icons_padding(vim.g.nvim_tree_icon_padding)
:build_header(view.is_root_folder_visible(core.get_cwd())) :build_header(view.is_root_folder_visible(core.get_cwd()))
:build(core.get_explorer()) :build(core.get_explorer())
:unwrap() :unwrap()