From a1600e57f2233db9bdfeb1f602434fd57c43c3ff Mon Sep 17 00:00:00 2001 From: Kiyan Date: Sat, 7 May 2022 14:05:51 +0200 Subject: [PATCH] feat(renderer): allow placing git icons after filename (#1203) This feature allows placing git icons after the filename. --- README.md | 3 +- doc/nvim-tree-lua.txt | 8 +- lua/nvim-tree.lua | 1 + lua/nvim-tree/renderer/builder.lua | 100 ++++++++++++-------- lua/nvim-tree/renderer/components/icons.lua | 9 -- lua/nvim-tree/renderer/init.lua | 1 + 6 files changed, 74 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index ba9f7e2c..71efe78d 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,8 @@ require'nvim-tree'.setup { -- BEGIN_DEFAULT_OPTS }, icons = { webdev_colors = true, - }, + git_placement = "before", + } }, hijack_directories = { enable = true, diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 4a52bbdb..e2e10a4d 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -123,7 +123,8 @@ Values may be functions. Warning: this may result in unexpected behaviour. }, icons = { webdev_colors = true, - }, + git_placement = "before", + } }, hijack_directories = { enable = true, @@ -444,6 +445,11 @@ Here is a list of the options available in the setup call: type: `boolean` default: `true` + - |renderer.icons.git_placement|: place where the git icons will be rendered. + After or before the `filename` (after the file/folders icons). + type: `after` or `before` + default: `before` + *nvim-tree.filters* |filters|: filtering options diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 5c2bffc3..7af73cac 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -351,6 +351,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS }, icons = { webdev_colors = true, + git_placement = "before", }, }, hijack_directories = { diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index c28e54ae..ec2368ca 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -60,6 +60,13 @@ function Builder:configure_git_icons_padding(padding) return self end +function Builder:configure_git_icons_placement(where) + where = where or "before" + self.is_git_before = where == "before" + self.is_git_after = not self.is_git_before + return self +end + function Builder:_insert_highlight(group, start, end_) table.insert(self.highlights, { group, self.index, start, end_ or -1 }) end @@ -93,16 +100,17 @@ function Builder:_unwrap_git_data(git_icons_and_hl_groups, offset) return icon end -function Builder:_build_folder(node, padding, git_hl) +function Builder:_build_folder(node, padding, git_hl, git_icons_tbl) local offset = string.len(padding) local name = get_folder_name(node) 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 = self:_unwrap_git_data(git.get_icons(node), offset + #icon) - - local line = padding .. icon .. git_icon .. name .. self.trailing_slash + local foldername = name .. self.trailing_slash + local git_icons = self:_unwrap_git_data(git_icons_tbl, offset + #icon + (self.is_git_after and #foldername + 1 or 0)) + local fname_starts_at = offset + #icon + (self.is_git_before and #git_icons or 0) + local line = self:_format_line(padding .. icon, foldername, git_icons) self:_insert_line(line) if #icon > 0 then @@ -118,76 +126,93 @@ function Builder:_build_folder(node, padding, git_hl) foldername_hl = "NvimTreeEmptyFolderName" end - self:_insert_highlight(foldername_hl, offset + #icon + #git_icon, #line) + self:_insert_highlight(foldername_hl, fname_starts_at, fname_starts_at + #foldername) if git_hl then - self:_insert_highlight(git_hl, offset + #icon + #git_icon, #line) + self:_insert_highlight(git_hl, fname_starts_at, fname_starts_at + #foldername) end end --- TODO: missing git icon for symlinks -function Builder:_build_symlink(node, padding, git_highlight) +function Builder:_format_line(before, after, git_icons) + return string.format( + "%s%s%s %s", + before, + self.is_git_after and "" or git_icons, + after, + self.is_git_after and git_icons or "" + ) +end + +function Builder:_build_symlink(node, padding, git_highlight, git_icons_tbl) + local offset = string.len(padding) + local icon = icons.i.symlink local arrow = icons.i.symlink_arrow + local symlink_formatted = node.name .. arrow .. node.link_to 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)) + local git_icons_starts_at = offset + #icon + (self.is_git_after and #symlink_formatted + 1 or 0) + local git_icons = self:_unwrap_git_data(git_icons_tbl, git_icons_starts_at) + local line = self:_format_line(padding .. icon, symlink_formatted, git_icons) + + self:_insert_highlight(link_highlight, offset + (self.is_git_after and 0 or #git_icons), string.len(line)) self:_insert_line(line) end -function Builder:_build_file_icons(node, offset) - if self.special_map[node.absolute_path] or self.special_map[node.name] then - local git_icons = self:_unwrap_git_data(git.get_icons(node), offset + #icons.i.special) - self:_insert_highlight("NvimTreeSpecialFile", offset + #git_icons) - return icons.i.special, git_icons - else - local icon, hl_group = icons.get_file_icon(node.name, node.extension) - if hl_group then - self:_insert_highlight(hl_group, offset, offset + #icon) - end - return icon, self:_unwrap_git_data(git.get_icons(node), offset + #icon) +function Builder:_build_file_icon(node, offset) + local icon, hl_group = icons.get_file_icon(node.name, node.extension) + if hl_group then + self:_insert_highlight(hl_group, offset, offset + #icon) end + return icon, false end -function Builder:_highlight_opened_files(node, offset, icon, git_icons) +function Builder:_highlight_opened_files(node, offset, icon_length, git_icons_length) local from = offset local to = offset if self.open_file_highlight == "icon" then - to = from + #icon + to = from + icon_length elseif self.open_file_highlight == "name" then - from = offset + #icon + #git_icons + from = offset + icon_length + git_icons_length to = from + #node.name elseif self.open_file_highlight == "all" then - to = -1 + to = from + icon_length + git_icons_length + #node.name end self:_insert_highlight("NvimTreeOpenedFile", from, to) end -function Builder:_build_file(node, padding, git_highlight) +function Builder:_build_file(node, padding, git_highlight, git_icons_tbl) local offset = string.len(padding) - local icon, git_icons = self:_build_file_icons(node, offset) + local icon = self:_build_file_icon(node, offset) - self:_insert_line(padding .. icon .. git_icons .. node.name) - local col_start = offset + #icon + #git_icons + local git_icons_starts_at = offset + #icon + (self.is_git_after and #node.name + 1 or 0) + local git_icons = self:_unwrap_git_data(git_icons_tbl, git_icons_starts_at) - if node.executable then - self:_insert_highlight("NvimTreeExecFile", col_start) + self:_insert_line(self:_format_line(padding .. icon, node.name, git_icons)) + + local git_icons_length = self.is_git_after and 0 or #git_icons + local col_start = offset + #icon + git_icons_length + local col_end = col_start + #node.name + + if self.special_map[node.absolute_path] or self.special_map[node.name] then + self:_insert_highlight("NvimTreeSpecialFile", col_start, col_end) + elseif node.executable then + self:_insert_highlight("NvimTreeExecFile", col_start, col_end) elseif self.picture_map[node.extension] then - self:_insert_highlight("NvimTreeImageFile", col_start) + self:_insert_highlight("NvimTreeImageFile", col_start, col_end) 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) + self:_highlight_opened_files(node, offset, #icon, git_icons_length) end if git_highlight then - self:_insert_highlight(git_highlight, col_start) + self:_insert_highlight(git_highlight, col_start, col_end) end end @@ -199,16 +224,17 @@ function Builder:_build_line(tree, node, idx) end local git_highlight = git.get_highlight(node) + local git_icons_tbl = git.get_icons(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) + self:_build_folder(node, padding, git_highlight, git_icons_tbl) elseif is_symlink then - self:_build_symlink(node, padding, git_highlight) + self:_build_symlink(node, padding, git_highlight, git_icons_tbl) else - self:_build_file(node, padding, git_highlight) + self:_build_file(node, padding, git_highlight, git_icons_tbl) end self.index = self.index + 1 diff --git a/lua/nvim-tree/renderer/components/icons.lua b/lua/nvim-tree/renderer/components/icons.lua index c85409d3..2981a794 100644 --- a/lua/nvim-tree/renderer/components/icons.lua +++ b/lua/nvim-tree/renderer/components/icons.lua @@ -70,14 +70,6 @@ local function config_file_icon() 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 @@ -94,7 +86,6 @@ function M.reset_config(webdev_colors) M.webdev_colors = webdev_colors config_symlinks() - config_special_icon() config_file_icon() config_folder_icon() end diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 8eb042b0..6ae44b87 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -82,6 +82,7 @@ function M.draw() :configure_picture_map(picture_map) :configure_opened_file_highlighting(vim.g.nvim_tree_highlight_opened_files) :configure_git_icons_padding(vim.g.nvim_tree_icon_padding) + :configure_git_icons_placement(M.config.icons.git_placement) :build_header(view.is_root_folder_visible(core.get_cwd())) :build(core.get_explorer()) :unwrap()