From b65ecd69a95e387587b3aee4ba614e35e3b61687 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Sat, 17 Dec 2022 14:41:18 +1300 Subject: [PATCH 01/22] Outlined new options --- doc/nvim-tree-lua.txt | 51 ++++++++++++++++++++++++++++++++++++++++++- lua/nvim-tree.lua | 9 ++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 11e672fee6f..477393f6c1e 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -222,6 +222,7 @@ Subsequent calls to setup will replace the previous configuration. highlight_git = false, full_name = false, highlight_opened_files = "none", + highlight_modified = false, root_folder_label = ":~:s?$?/..?", indent_width = 2, indent_markers = { @@ -240,6 +241,8 @@ Subsequent calls to setup will replace the previous configuration. git_placement = "before", padding = " ", symlink_arrow = " ➛ ", + modified = "[+]", + modified_placement = "after", show = { file = true, folder = true, @@ -324,6 +327,12 @@ Subsequent calls to setup will replace the previous configuration. show_on_open_dirs = true, timeout = 400, }, + modified = { + enable = false, + show_on_dirs = true, + show_on_open_dirs = false, + debounce_delay = 50, + }, actions = { use_system_clipboard = true, change_dir = { @@ -542,6 +551,7 @@ Configuration options for the system open command. *nvim-tree.diagnostics* Show LSP and COC diagnostics in the signcolumn +Note that the modified sign will take precedence over the diagnostics signs. `NOTE`: it will use the default diagnostic color groups to highlight the signs. If you wish to customize, you can override these groups: @@ -617,6 +627,28 @@ Git integration with icons and colors. milliseconds but a few seconds), it will not render anything until the git process returned the data. +*nvim-tree.modified* +Indicate which file have unsaved modification. + + *nvim-tree.modified.enable* + Enable / disable the feature. + Type: `boolean`, Default: `false` + + *nvim-tree.modified.show_on_dirs* + Show modified indication on directory whose children are modified. + Type: `boolean`, Default: `true` + + *nvim-tree.modified.show_on_open_dirs* + Show modified indication on open directories. + Only relevant when |modified.show_on_dirs| is `true`. + Type: `boolean`, Default: `false` + + *nvim-tree.modified.debounce_delay* + Idle milliseconds between the file is modified and action. + This helps performance when large number of files are modified in quick + succession (e.g. lsp rename). + Type: `number`, Default: `50` (ms) + *nvim-tree.filesystem_watchers* Will use file system watcher (libuv fs_event) to watch the filesystem for changes. @@ -773,6 +805,12 @@ UI rendering setup Value can be `"none"`, `"icon"`, `"name"` or `"all"`. Type: `string`, Default: `"none"` + *nvim-tree.renderer.highlight_modified* + Enable file highlight for modified files using NvimTreeModified highlight + groups. + This can be used with or without the icons. + Type: `boolean`, Default `false` + *nvim-tree.renderer.root_folder_label* (previously `renderer.root_folder_modifier`) In what format to show root folder. See `:help filename-modifiers` for available `string` options. @@ -815,7 +853,7 @@ UI rendering setup Place where the git icons will be rendered. Can be `"after"` or `"before"` filename (after the file/folders icons) or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled). - Note that the diagnostic signs will take precedence over the git signs. + Note that the diagnostic signs and the modified sign will take precedence over the git signs. Type: `string`, Default: `before` *nvim-tree.renderer.icons.padding* @@ -827,6 +865,17 @@ UI rendering setup Used as a separator between symlinks' source and target. Type: `string`, Default: `" ➛ "` + *nvim-tree.renderer.icons.modified* + Icon to display for modified files. Can be multiple characters if + |renderer.icons.modified_placement| isn't `"signcolumn"`. + Type: `string`, Default: `"[+]"` + + *nvim-tree.renderer.icons.modified_placement* + Place where the modified icon will be rendered. + Can be `"after"` or `"before"` filename (after the file/folders icons) + or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled). + Type: `string`, Default: `after` + *nvim-tree.renderer.icons.show* Configuration options for showing icon types. diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 375ecda7624..c5baf05e145 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -523,6 +523,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS highlight_git = false, full_name = false, highlight_opened_files = "none", + highlight_modified = false, root_folder_label = ":~:s?$?/..?", indent_width = 2, indent_markers = { @@ -541,6 +542,8 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS git_placement = "before", padding = " ", symlink_arrow = " ➛ ", + modified = "[+]", + modified_placement = "after", show = { file = true, folder = true, @@ -625,6 +628,12 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS show_on_open_dirs = true, timeout = 400, }, + modified = { + enable = false, + show_on_dirs = true, + show_on_open_dirs = false, + debounce_delay = 50, + }, actions = { use_system_clipboard = true, change_dir = { From ece4c378878128bbba82ea9b815b7a764779ffec Mon Sep 17 00:00:00 2001 From: chomosuke Date: Sun, 18 Dec 2022 16:12:24 +1300 Subject: [PATCH 02/22] highlight_modified is highlight_opened_files --- doc/nvim-tree-lua.txt | 9 +++++---- lua/nvim-tree.lua | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index a57785192ee..11bd1baab98 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -222,7 +222,7 @@ Subsequent calls to setup will replace the previous configuration. highlight_git = false, full_name = false, highlight_opened_files = "none", - highlight_modified = false, + highlight_modified = "none", root_folder_label = ":~:s?$?/..?", indent_width = 2, indent_markers = { @@ -806,10 +806,11 @@ UI rendering setup Type: `string`, Default: `"none"` *nvim-tree.renderer.highlight_modified* - Enable file highlight for modified files using NvimTreeModified highlight - groups. + Highlight icons and/or names for modified files using `NvimTreeModified` + highlight groups. + Value can be `"none"`, `"icon"`, `"name"` or `"all"` This can be used with or without the icons. - Type: `boolean`, Default `false` + Type: `string`, Default `"none"` *nvim-tree.renderer.root_folder_label* (previously `renderer.root_folder_modifier`) In what format to show root folder. See `:help filename-modifiers` for diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index c5baf05e145..457c9b15e12 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -523,7 +523,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS highlight_git = false, full_name = false, highlight_opened_files = "none", - highlight_modified = false, + highlight_modified = "none", root_folder_label = ":~:s?$?/..?", indent_width = 2, indent_markers = { From a34c9078d2e9061c780c8e48570265ba75154380 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Sun, 18 Dec 2022 16:45:09 +1300 Subject: [PATCH 03/22] prototype with autocmd --- lua/nvim-tree.lua | 10 ++++++++++ lua/nvim-tree/renderer/builder.lua | 19 ++++++++++++++++--- lua/nvim-tree/renderer/init.lua | 2 ++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 457c9b15e12..91cfbbe9364 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -468,6 +468,16 @@ local function setup_autocommands(opts) end, }) end + + if opts.modified.enable then + create_nvim_tree_autocmd("BufModifiedSet", { + callback = function() + utils.debounce("BufModifiedSet:modified_files", opts.modified.debounce_delay, function() + reloaders.reload_explorer() + end) + end, + }) + end end local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index bcffeb377d1..cdc9b111b46 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -68,6 +68,13 @@ function Builder:configure_git_icons_placement(where) return self end +function Builder:configure_modified(modified_icon, modified_placement, modified) + self.modified = modified + self.modified.icon = modified_icon + self.modified.placement = modified_placement + return self +end + function Builder:configure_symlink_destination(show) self.symlink_destination = show return self @@ -206,7 +213,7 @@ function Builder:_highlight_opened_files(node, offset, icon_length, git_icons_le self:_insert_highlight("NvimTreeOpenedFile", from, to) end -function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr) +function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr, modified) local offset = string.len(padding) local icon = self:_build_file_icon(node, offset) @@ -214,7 +221,11 @@ function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unload 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) - self:_insert_line(self:_format_line(padding .. icon, node.name, git_icons)) + local name = node.name + if modified then + name = name .. self.modified.icon + end + self:_insert_line(self:_format_line(padding .. icon, name, git_icons)) local git_icons_length = self.is_git_after and 0 or #git_icons local col_start = offset + #icon + git_icons_length @@ -263,6 +274,8 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr) end end + local modified = vim.fn.bufloaded(node.absolute_path) > 0 and vim.fn.getbufinfo(node.absolute_path)[1].changed == 1 + local is_folder = node.nodes ~= nil local is_symlink = node.link_to ~= nil @@ -271,7 +284,7 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr) elseif is_symlink then self:_build_symlink(node, padding, git_highlight, git_icons_tbl) else - self:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr) + self:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr, modified) end self.index = self.index + 1 diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 132c5326ad7..501b16f4a66 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -70,6 +70,7 @@ function M.draw(unloaded_bufnr) :configure_opened_file_highlighting(M.config.highlight_opened_files) :configure_git_icons_padding(M.config.icons.padding) :configure_git_icons_placement(M.config.icons.git_placement) + :configure_modified(M.config.icons.modified, M.config.icons.modified_placement, M.config.modified) :configure_symlink_destination(M.config.symlink_destination) :configure_filter(live_filter.filter, live_filter.prefix) :build_header(view.is_root_folder_visible(core.get_cwd())) @@ -100,6 +101,7 @@ end function M.setup(opts) M.config = opts.renderer + M.config.modified = opts.modified _padding.setup(opts) full_name.setup(opts) From e501f167848ffde2ed61ca04f89c6910d98f9176 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Tue, 20 Dec 2022 11:49:28 +1300 Subject: [PATCH 04/22] moved modified into glyphs --- doc/nvim-tree-lua.txt | 12 ++++++------ lua/nvim-tree.lua | 2 +- lua/nvim-tree/renderer/init.lua | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 11bd1baab98..187888bd557 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -241,7 +241,6 @@ Subsequent calls to setup will replace the previous configuration. git_placement = "before", padding = " ", symlink_arrow = " ➛ ", - modified = "[+]", modified_placement = "after", show = { file = true, @@ -253,6 +252,7 @@ Subsequent calls to setup will replace the previous configuration. default = "", symlink = "", bookmark = "", + modified = "●", folder = { arrow_closed = "", arrow_open = "", @@ -866,11 +866,6 @@ UI rendering setup Used as a separator between symlinks' source and target. Type: `string`, Default: `" ➛ "` - *nvim-tree.renderer.icons.modified* - Icon to display for modified files. Can be multiple characters if - |renderer.icons.modified_placement| isn't `"signcolumn"`. - Type: `string`, Default: `"[+]"` - *nvim-tree.renderer.icons.modified_placement* Place where the modified icon will be rendered. Can be `"after"` or `"before"` filename (after the file/folders icons) @@ -909,6 +904,11 @@ UI rendering setup Glyph for symlinks to files. Type: `string`, Default: `""` + *nvim-tree.renderer.icons.glyphs.modified* + Icon to display for modified files. Can be multiple characters if + |renderer.icons.modified_placement| isn't `"signcolumn"`. + Type: `string`, Default: `"●"` + *nvim-tree.renderer.icons.glyphs.folder* Glyphs for directories. Type: `table`, Default: diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index cbbdd11abd5..9216316d442 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -560,7 +560,6 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS git_placement = "before", padding = " ", symlink_arrow = " ➛ ", - modified = "[+]", modified_placement = "after", show = { file = true, @@ -572,6 +571,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS default = "", symlink = "", bookmark = "", + modified = "●", folder = { arrow_closed = "", arrow_open = "", diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 501b16f4a66..2ef657c4521 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -70,7 +70,7 @@ function M.draw(unloaded_bufnr) :configure_opened_file_highlighting(M.config.highlight_opened_files) :configure_git_icons_padding(M.config.icons.padding) :configure_git_icons_placement(M.config.icons.git_placement) - :configure_modified(M.config.icons.modified, M.config.icons.modified_placement, M.config.modified) + :configure_modified(M.config.icons.glyphs.modified, M.config.icons.modified_placement, M.config.modified) :configure_symlink_destination(M.config.symlink_destination) :configure_filter(live_filter.filter, live_filter.prefix) :build_header(view.is_root_folder_visible(core.get_cwd())) From 00d373986381247a800b15b1b598e5c915cd2b7d Mon Sep 17 00:00:00 2001 From: chomosuke Date: Wed, 21 Dec 2022 17:27:26 +1300 Subject: [PATCH 05/22] show_on_dirs and show_on_open_dirs --- lua/nvim-tree.lua | 3 +++ lua/nvim-tree/modified.lua | 34 ++++++++++++++++++++++++++++++ lua/nvim-tree/renderer/builder.lua | 21 ++++++++++-------- lua/nvim-tree/renderer/init.lua | 2 +- 4 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 lua/nvim-tree/modified.lua diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 9216316d442..d34e8878a16 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -12,6 +12,7 @@ local copy_paste = require "nvim-tree.actions.fs.copy-paste" local collapse_all = require "nvim-tree.actions.tree-modifiers.collapse-all" local git = require "nvim-tree.git" local filters = require "nvim-tree.explorer.filters" +local modified = require "nvim-tree.modified" local _config = {} @@ -481,6 +482,7 @@ local function setup_autocommands(opts) create_nvim_tree_autocmd("BufModifiedSet", { callback = function() utils.debounce("BufModifiedSet:modified_files", opts.modified.debounce_delay, function() + modified.reload() reloaders.reload_explorer() end) end, @@ -828,6 +830,7 @@ function M.setup(conf) require("nvim-tree.renderer").setup(opts) require("nvim-tree.live-filter").setup(opts) require("nvim-tree.marks").setup(opts) + require("nvim-tree.modified").setup(opts) if M.config.renderer.icons.show.file and pcall(require, "nvim-web-devicons") then require("nvim-web-devicons").setup() end diff --git a/lua/nvim-tree/modified.lua b/lua/nvim-tree/modified.lua new file mode 100644 index 00000000000..17d607414d3 --- /dev/null +++ b/lua/nvim-tree/modified.lua @@ -0,0 +1,34 @@ +local M = {} + +---@type table record of which file is modified +M.record = {} + +---refresh M.record +function M.reload() + M.record = {} + local bufs = vim.fn.getbufinfo { bufmodified = true, buflisted = true } + for _, buf in pairs(bufs) do + local path = buf.name + M.record[path] = true + while path ~= vim.fn.getcwd() and path ~= "/" do + path = vim.fn.fnamemodify(path, ":h") + M.record[path] = true + end + end +end + +---@param node table TODO: we should probably have a Node type +---@return boolean +function M.is_modified(node) + return M.config.enable + and M.record[node.absolute_path] + and (not node.nodes or M.config.show_on_dirs) + and (not node.open or M.config.show_on_open_dirs) +end + +---@param opts table +function M.setup(opts) + M.config = opts.modified +end + +return M diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index cdc9b111b46..db642066358 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -1,5 +1,6 @@ local utils = require "nvim-tree.utils" local core = require "nvim-tree.core" +local modified = require "nvim-tree.modified" local git = require "nvim-tree.renderer.components.git" local pad = require "nvim-tree.renderer.components.padding" @@ -68,10 +69,11 @@ function Builder:configure_git_icons_placement(where) return self end -function Builder:configure_modified(modified_icon, modified_placement, modified) - self.modified = modified - self.modified.icon = modified_icon - self.modified.placement = modified_placement +function Builder:configure_modified(modified_icon, modified_placement) + self.modified = { + icon = modified_icon, + placement = modified_placement, + } return self end @@ -118,6 +120,9 @@ function Builder:_build_folder(node, padding, git_hl, git_icons_tbl) local offset = string.len(padding) local name = get_folder_name(node) + if modified.is_modified(node) then + name = name .. self.modified.icon + end local has_children = #node.nodes ~= 0 or node.has_children local icon = icons.get_folder_icon(node.open, node.link_to ~= nil, has_children) @@ -213,7 +218,7 @@ function Builder:_highlight_opened_files(node, offset, icon_length, git_icons_le self:_insert_highlight("NvimTreeOpenedFile", from, to) end -function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr, modified) +function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr) local offset = string.len(padding) local icon = self:_build_file_icon(node, offset) @@ -222,7 +227,7 @@ function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unload local git_icons = self:_unwrap_git_data(git_icons_tbl, git_icons_starts_at) local name = node.name - if modified then + if modified.is_modified(node) then name = name .. self.modified.icon end self:_insert_line(self:_format_line(padding .. icon, name, git_icons)) @@ -274,8 +279,6 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr) end end - local modified = vim.fn.bufloaded(node.absolute_path) > 0 and vim.fn.getbufinfo(node.absolute_path)[1].changed == 1 - local is_folder = node.nodes ~= nil local is_symlink = node.link_to ~= nil @@ -284,7 +287,7 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr) elseif is_symlink then self:_build_symlink(node, padding, git_highlight, git_icons_tbl) else - self:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr, modified) + self:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr) end self.index = self.index + 1 diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 2ef657c4521..415704554b5 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -70,7 +70,7 @@ function M.draw(unloaded_bufnr) :configure_opened_file_highlighting(M.config.highlight_opened_files) :configure_git_icons_padding(M.config.icons.padding) :configure_git_icons_placement(M.config.icons.git_placement) - :configure_modified(M.config.icons.glyphs.modified, M.config.icons.modified_placement, M.config.modified) + :configure_modified(M.config.icons.glyphs.modified, M.config.icons.modified_placement) :configure_symlink_destination(M.config.symlink_destination) :configure_filter(live_filter.filter, live_filter.prefix) :build_header(view.is_root_folder_visible(core.get_cwd())) From 2ad61255fc5df226ac2172af755856b4b0f18ad8 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Wed, 21 Dec 2022 19:07:38 +1300 Subject: [PATCH 06/22] icon placement before & after --- lua/nvim-tree/modified.lua | 10 ++--- lua/nvim-tree/renderer/builder.lua | 61 +++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/lua/nvim-tree/modified.lua b/lua/nvim-tree/modified.lua index 17d607414d3..f38874b46da 100644 --- a/lua/nvim-tree/modified.lua +++ b/lua/nvim-tree/modified.lua @@ -1,18 +1,18 @@ local M = {} ---@type table record of which file is modified -M.record = {} +M._record = {} ---refresh M.record function M.reload() - M.record = {} + M._record = {} local bufs = vim.fn.getbufinfo { bufmodified = true, buflisted = true } for _, buf in pairs(bufs) do local path = buf.name - M.record[path] = true + M._record[path] = true while path ~= vim.fn.getcwd() and path ~= "/" do path = vim.fn.fnamemodify(path, ":h") - M.record[path] = true + M._record[path] = true end end end @@ -21,7 +21,7 @@ end ---@return boolean function M.is_modified(node) return M.config.enable - and M.record[node.absolute_path] + and M._record[node.absolute_path] and (not node.nodes or M.config.show_on_dirs) and (not node.open or M.config.show_on_open_dirs) end diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index db642066358..43beda4c3f2 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -116,17 +116,24 @@ function Builder:_unwrap_git_data(git_icons_and_hl_groups, offset) return icon end +---return modified icon if node is modified, otherwise return empty string +---@param node table +---@return string modified icon +function Builder:_get_modified_icon(node) + if not modified.is_modified(node) or self.modified.placement == "signcolumn" then + return "" + end + + return self.modified.placement == "before" and self.modified.icon .. " " or " " .. self.modified.icon +end + function Builder:_build_folder(node, padding, git_hl, git_icons_tbl) local offset = string.len(padding) - local name = get_folder_name(node) - if modified.is_modified(node) then - name = name .. self.modified.icon - end 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 foldername = name .. self.trailing_slash + local foldername = get_folder_name(node) .. self.trailing_slash if node.link_to and self.symlink_destination then local arrow = icons.i.symlink_arrow local link_to = utils.path_relative(node.link_to, core.get_cwd()) @@ -134,8 +141,14 @@ function Builder:_build_folder(node, padding, git_hl, git_icons_tbl) end 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_after and 0 or #git_icons) - local line = self:_format_line(padding .. icon, foldername, git_icons) + local modified_icon = self:_get_modified_icon(node) + + -- TODO: this is duplicated logic with _build_file & _build_symlink + local fname_starts_at = offset + + #icon + + (self.is_git_after and 0 or #git_icons) + + (self.modified.placement ~= "before" and 0 or #modified_icon) + local line = self:_format_line(padding .. icon, foldername, git_icons, modified_icon) self:_insert_line(line) if #icon > 0 then @@ -162,13 +175,24 @@ function Builder:_build_folder(node, padding, git_hl, git_icons_tbl) end end -function Builder:_format_line(before, after, git_icons) +---format line +---@param before string +---@param after string +---@param git_icons string|nil +---@param modified_icon string +---@return string +function Builder:_format_line(before, after, git_icons, modified_icon) git_icons = self.is_git_after and git_icons and " " .. git_icons or git_icons + + local is_modified_after = self.modified.placement ~= "before" + return string.format( - "%s%s%s%s", + "%s%s%s%s%s%s", before, self.is_git_after and "" or git_icons, + is_modified_after and "" or modified_icon, after, + is_modified_after and modified_icon or "", self.is_git_after and git_icons or "" ) end @@ -188,9 +212,14 @@ function Builder:_build_symlink(node, padding, git_highlight, git_icons_tbl) 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) + local modified_icon = self:_get_modified_icon(node) + local line = self:_format_line(padding .. icon, symlink_formatted, git_icons, modified_icon) - self:_insert_highlight(link_highlight, offset + (self.is_git_after and 0 or #git_icons), string.len(line)) + self:_insert_highlight( + link_highlight, + offset + (self.is_git_after and 0 or #git_icons) + (self.modified.placement ~= "before" and 0 or #modified_icon), + string.len(line) + ) self:_insert_line(line) end @@ -226,14 +255,12 @@ function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unload 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) - local name = node.name - if modified.is_modified(node) then - name = name .. self.modified.icon - end - self:_insert_line(self:_format_line(padding .. icon, name, git_icons)) + local modified_icon = self:_get_modified_icon(node) + self:_insert_line(self:_format_line(padding .. icon, node.name, git_icons, modified_icon)) local git_icons_length = self.is_git_after and 0 or #git_icons - local col_start = offset + #icon + git_icons_length + local modified_icon_length = self.modified.placement ~= "before" and 0 or #modified_icon + local col_start = offset + #icon + git_icons_length + modified_icon_length local col_end = col_start + #node.name if vim.tbl_contains(self.special_files, node.absolute_path) or vim.tbl_contains(self.special_files, node.name) then From b3ed7c9662b30774ae469f3dc62400219b775acd Mon Sep 17 00:00:00 2001 From: chomosuke Date: Wed, 21 Dec 2022 19:21:30 +1300 Subject: [PATCH 07/22] _get_filename_offset --- lua/nvim-tree.lua | 1 + lua/nvim-tree/renderer/builder.lua | 25 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index d34e8878a16..49d2b983d83 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -479,6 +479,7 @@ local function setup_autocommands(opts) end if opts.modified.enable then + -- TODO: :wq doesn't update properly create_nvim_tree_autocmd("BufModifiedSet", { callback = function() utils.debounce("BufModifiedSet:modified_files", opts.modified.debounce_delay, function() diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 43beda4c3f2..31aa2833c11 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -143,11 +143,7 @@ function Builder:_build_folder(node, padding, git_hl, git_icons_tbl) local git_icons = self:_unwrap_git_data(git_icons_tbl, offset + #icon + (self.is_git_after and #foldername + 1 or 0)) local modified_icon = self:_get_modified_icon(node) - -- TODO: this is duplicated logic with _build_file & _build_symlink - local fname_starts_at = offset - + #icon - + (self.is_git_after and 0 or #git_icons) - + (self.modified.placement ~= "before" and 0 or #modified_icon) + local fname_starts_at = self:_get_filename_offset(offset, icon, git_icons, modified_icon) local line = self:_format_line(padding .. icon, foldername, git_icons, modified_icon) self:_insert_line(line) @@ -197,6 +193,18 @@ function Builder:_format_line(before, after, git_icons, modified_icon) ) end +---@param offset integer +---@param icon string +---@param git_icons string +---@param modified_icon string +---@return integer +function Builder:_get_filename_offset(offset, icon, git_icons, modified_icon) + return offset + + #icon + + (self.is_git_after and 0 or #git_icons) + + (self.modified.placement ~= "before" and 0 or #modified_icon) +end + function Builder:_build_symlink(node, padding, git_highlight, git_icons_tbl) local offset = string.len(padding) @@ -217,6 +225,7 @@ function Builder:_build_symlink(node, padding, git_highlight, git_icons_tbl) self:_insert_highlight( link_highlight, + -- TODO: is this a bug? where's icon? offset + (self.is_git_after and 0 or #git_icons) + (self.modified.placement ~= "before" and 0 or #modified_icon), string.len(line) ) @@ -258,9 +267,7 @@ function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unload local modified_icon = self:_get_modified_icon(node) self:_insert_line(self:_format_line(padding .. icon, node.name, git_icons, modified_icon)) - local git_icons_length = self.is_git_after and 0 or #git_icons - local modified_icon_length = self.modified.placement ~= "before" and 0 or #modified_icon - local col_start = offset + #icon + git_icons_length + modified_icon_length + local col_start = self:_get_filename_offset(offset, icon, git_icons, modified_icon) local col_end = col_start + #node.name if vim.tbl_contains(self.special_files, node.absolute_path) or vim.tbl_contains(self.special_files, node.name) then @@ -275,7 +282,7 @@ function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unload and vim.fn.bufloaded(node.absolute_path) > 0 and vim.fn.bufnr(node.absolute_path) ~= unloaded_bufnr if should_highlight_opened_files then - self:_highlight_opened_files(node, offset, #icon, git_icons_length) + self:_highlight_opened_files(node, offset, #icon, self.is_git_after and 0 or #git_icons) end if git_highlight then From b4ef5e0a9452393af133f34aef2a656f00c2072f Mon Sep 17 00:00:00 2001 From: chomosuke Date: Thu, 22 Dec 2022 14:41:09 +1300 Subject: [PATCH 08/22] fixed :wq doesn't update modified indicator --- lua/nvim-tree.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 49d2b983d83..f52f3170995 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -479,8 +479,7 @@ local function setup_autocommands(opts) end if opts.modified.enable then - -- TODO: :wq doesn't update properly - create_nvim_tree_autocmd("BufModifiedSet", { + create_nvim_tree_autocmd({ "BufModifiedSet", "BufWritePost" }, { callback = function() utils.debounce("BufModifiedSet:modified_files", opts.modified.debounce_delay, function() modified.reload() From e95d3a5891e2bca6c17250a05b60a91d2ee099c8 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Fri, 23 Dec 2022 17:19:25 +1300 Subject: [PATCH 09/22] highlight_modified, signcolumn modified_placement Refactored to make everything use HighlightedString to remove all the complex `insert_highlight` calculation. Not tested. --- doc/nvim-tree-lua.txt | 11 + lua/nvim-tree.lua | 1 + lua/nvim-tree/colors.lua | 1 + lua/nvim-tree/renderer/builder.lua | 322 +++++++++--------- lua/nvim-tree/renderer/components/git.lua | 25 +- lua/nvim-tree/renderer/components/icons.lua | 8 +- .../renderer/components/modified.lua | 38 +++ lua/nvim-tree/renderer/components/padding.lua | 8 +- lua/nvim-tree/renderer/init.lua | 12 +- 9 files changed, 246 insertions(+), 180 deletions(-) create mode 100644 lua/nvim-tree/renderer/components/modified.lua diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 187888bd557..3e72cf9cd03 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -247,6 +247,7 @@ Subsequent calls to setup will replace the previous configuration. folder = true, folder_arrow = true, git = true, + modified = true, }, glyphs = { default = "", @@ -649,6 +650,10 @@ Indicate which file have unsaved modification. succession (e.g. lsp rename). Type: `number`, Default: `50` (ms) + You will still need to set |renderer.icons.show.modified| `= true` or + |renderer.highlight_modified| `= true` to be able to see things in the + tree. + *nvim-tree.filesystem_watchers* Will use file system watcher (libuv fs_event) to watch the filesystem for changes. @@ -893,6 +898,11 @@ UI rendering setup Requires |git.enable| `= true` Type: `boolean`, Default: `true` + *nvim-tree.renderer.icons.show.modified* + Show a modified icon, see |renderer.icons.modified_placement| + Requires |modified.enable| `= true` + Type: `boolean`, Default: `true` + *nvim-tree.renderer.icons.glyphs* Configuration options for icon glyphs. @@ -1515,6 +1525,7 @@ NvimTreeEmptyFolderName (Directory) NvimTreeOpenedFolderName (Directory) NvimTreeExecFile NvimTreeOpenedFile +NvimTreeModifiedFile NvimTreeSpecialFile NvimTreeImageFile NvimTreeIndentMarker diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index f52f3170995..a91ca7921f7 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -568,6 +568,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS folder = true, folder_arrow = true, git = true, + modified = true, }, glyphs = { default = "", diff --git a/lua/nvim-tree/colors.lua b/lua/nvim-tree/colors.lua index d490661d86c..e10c7668a8d 100644 --- a/lua/nvim-tree/colors.lua +++ b/lua/nvim-tree/colors.lua @@ -40,6 +40,7 @@ local function get_hl_groups() SpecialFile = { gui = "bold,underline", fg = colors.yellow }, ImageFile = { gui = "bold", fg = colors.purple }, OpenedFile = { gui = "bold", fg = colors.green }, + ModifiedFile = { fg = colors.green }, GitDirty = { fg = colors.dark_red }, GitDeleted = { fg = colors.dark_red }, diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 31aa2833c11..aab31f0cd1a 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -1,10 +1,10 @@ local utils = require "nvim-tree.utils" local core = require "nvim-tree.core" -local modified = require "nvim-tree.modified" local git = require "nvim-tree.renderer.components.git" local pad = require "nvim-tree.renderer.components.padding" local icons = require "nvim-tree.renderer.components.icons" +local modified = require "nvim-tree.renderer.components.modified" local Builder = {} Builder.__index = Builder @@ -51,29 +51,21 @@ end function Builder:configure_opened_file_highlighting(highlight_opened_files) self.highlight_opened_files = highlight_opened_files - return self end -function Builder:configure_git_icons_padding(padding) - self.git_icon_padding = padding or " " +function Builder:configure_icon_padding(padding) + self.icon_padding = padding or " " return self end function Builder:configure_git_icons_placement(where) - if where == "signcolumn" then - vim.fn.sign_unplace(git.SIGN_GROUP) - self.is_git_sign = true - end - self.is_git_after = where == "after" and not self.is_git_sign + self.git_placement = where return self end -function Builder:configure_modified(modified_icon, modified_placement) - self.modified = { - icon = modified_icon, - placement = modified_placement, - } +function Builder:configure_modified_placement(modified_placement) + self.modified_placement = modified_placement return self end @@ -100,36 +92,32 @@ local function get_folder_name(node) return name end -function Builder:_unwrap_git_data(git_icons_and_hl_groups, offset) - if not git_icons_and_hl_groups then +---@class HighlightedString +---@field str string +---@field hl string|nil + +---@param highlighted_strings HighlightedString[] +---@return string +function Builder:_unwrap_highlighted_strings(highlighted_strings) + if not highlighted_strings then return "" end - local icon = "" - for i, 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) - local remove_padding = self.is_git_after and i == #git_icons_and_hl_groups - icon = icon .. v.icon .. (remove_padding and "" or self.git_icon_padding) + local string = "" + for _, v in ipairs(highlighted_strings) do + if #v.str > 0 then + if v.hl then + self:_insert_highlight(v.hl, #string, #string + #v.str) + end + string = string .. v.str end end - return icon + return string end ----return modified icon if node is modified, otherwise return empty string ---@param node table ----@return string modified icon -function Builder:_get_modified_icon(node) - if not modified.is_modified(node) or self.modified.placement == "signcolumn" then - return "" - end - - return self.modified.placement == "before" and self.modified.icon .. " " or " " .. self.modified.icon -end - -function Builder:_build_folder(node, padding, git_hl, git_icons_tbl) - local offset = string.len(padding) - +---@return HighlightedString icon, HighlightedString name +function Builder:_build_folder(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) @@ -140,18 +128,12 @@ function Builder:_build_folder(node, padding, git_hl, git_icons_tbl) foldername = foldername .. arrow .. link_to end - local git_icons = self:_unwrap_git_data(git_icons_tbl, offset + #icon + (self.is_git_after and #foldername + 1 or 0)) - local modified_icon = self:_get_modified_icon(node) - - local fname_starts_at = self:_get_filename_offset(offset, icon, git_icons, modified_icon) - local line = self:_format_line(padding .. icon, foldername, git_icons, modified_icon) - self:_insert_line(line) - + local icon_hl if #icon > 0 then if node.open then - self:_insert_highlight("NvimTreeOpenedFolderIcon", offset, offset + #icon) + icon_hl = "NvimTreeOpenedFolderIcon" else - self:_insert_highlight("NvimTreeClosedFolderIcon", offset, offset + #icon) + icon_hl = "NvimTreeClosedFolderIcon" end end @@ -164,50 +146,12 @@ function Builder:_build_folder(node, padding, git_hl, git_icons_tbl) foldername_hl = "NvimTreeEmptyFolderName" end - self:_insert_highlight(foldername_hl, fname_starts_at, fname_starts_at + #foldername) - - if git_hl then - self:_insert_highlight(git_hl, fname_starts_at, fname_starts_at + #foldername) - end -end - ----format line ----@param before string ----@param after string ----@param git_icons string|nil ----@param modified_icon string ----@return string -function Builder:_format_line(before, after, git_icons, modified_icon) - git_icons = self.is_git_after and git_icons and " " .. git_icons or git_icons - - local is_modified_after = self.modified.placement ~= "before" - - return string.format( - "%s%s%s%s%s%s", - before, - self.is_git_after and "" or git_icons, - is_modified_after and "" or modified_icon, - after, - is_modified_after and modified_icon or "", - self.is_git_after and git_icons or "" - ) -end - ----@param offset integer ----@param icon string ----@param git_icons string ----@param modified_icon string ----@return integer -function Builder:_get_filename_offset(offset, icon, git_icons, modified_icon) - return offset - + #icon - + (self.is_git_after and 0 or #git_icons) - + (self.modified.placement ~= "before" and 0 or #modified_icon) + return { str = icon, hl = icon_hl }, { str = foldername, hl = foldername_hl } end -function Builder:_build_symlink(node, padding, git_highlight, git_icons_tbl) - local offset = string.len(padding) - +---@param node table +---@return HighlightedString icon, HighlightedString name +function Builder:_build_symlink(node) local icon = icons.i.symlink local arrow = icons.i.symlink_arrow local symlink_formatted = node.name @@ -216,113 +160,169 @@ function Builder:_build_symlink(node, padding, git_highlight, git_icons_tbl) symlink_formatted = symlink_formatted .. arrow .. link_to end - local link_highlight = git_highlight or "NvimTreeSymlink" + local link_highlight = "NvimTreeSymlink" - 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 modified_icon = self:_get_modified_icon(node) - local line = self:_format_line(padding .. icon, symlink_formatted, git_icons, modified_icon) - - self:_insert_highlight( - link_highlight, - -- TODO: is this a bug? where's icon? - offset + (self.is_git_after and 0 or #git_icons) + (self.modified.placement ~= "before" and 0 or #modified_icon), - string.len(line) - ) - self:_insert_line(line) + return { str = icon }, { str = symlink_formatted, hl = link_highlight } end -function Builder:_build_file_icon(node, offset) +---@param node table +---@return HighlightedString icon +function Builder:_build_file_icon(node) 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 + return { str = icon, hl = hl_group } end -function Builder:_highlight_opened_files(node, offset, icon_length, git_icons_length) - local from = offset - local to = offset - - if self.highlight_opened_files == "icon" then - to = from + icon_length - elseif self.highlight_opened_files == "name" then - from = offset + icon_length + git_icons_length - to = from + #node.name - elseif self.highlight_opened_files == "all" then - to = from + icon_length + git_icons_length + #node.name +---@param node table +---@return HighlightedString icon, HighlightedString name +function Builder:_build_file(node) + local icon = self:_build_file_icon(node) + + local hl + if vim.tbl_contains(self.special_files, node.absolute_path) or vim.tbl_contains(self.special_files, node.name) then + hl = "NvimTreeSpecialFile" + elseif node.executable then + hl = "NvimTreeExecFile" + elseif self.picture_map[node.extension] then + hl = "NvimTreeImageFile" end - self:_insert_highlight("NvimTreeOpenedFile", from, to) + return icon, { str = node.name, hl = hl } end -function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr) - local offset = string.len(padding) - - local icon = self:_build_file_icon(node, offset) - - 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) +---@param node table +---@return HighlightedString[]|nil icon +function Builder:_get_git_icons(node) + local git_icons = git.get_icons(node) + if git_icons and #git_icons > 0 and self.is_git_sign then + local sign = git_icons[1] + table.insert(self.signs, { sign = sign.hl, lnum = self.index + 1, priority = 1 }) + git_icons = nil + end + return git_icons +end - local modified_icon = self:_get_modified_icon(node) - self:_insert_line(self:_format_line(padding .. icon, node.name, git_icons, modified_icon)) +---@param node table +---@return HighlightedString|nil icon +function Builder:_get_modified_icon(node) + local modified_icon = modified.get_icon(node) + if modified_icon and self.modified_placement == "signcolumn" then + local sign = modified_icon + table.insert(self.signs, { sign = sign.hl, lnum = self.index + 1, priority = 3 }) + modified_icon = nil + end + return modified_icon +end - local col_start = self:_get_filename_offset(offset, icon, git_icons, modified_icon) - local col_end = col_start + #node.name +---@param node table +---@return string icon_highlight, string name_highlight +function Builder:_get_highlight_override(node, unloaded_bufnr) + -- highlights precedence: + -- original < git < opened_file < modified + local name_hl, icon_hl - if vim.tbl_contains(self.special_files, node.absolute_path) or vim.tbl_contains(self.special_files, 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, col_end) + -- git + local git_highlight = git.get_highlight(node) + if git_highlight then + name_hl = git_highlight end - local should_highlight_opened_files = self.highlight_opened_files + -- opened file + if + self.highlight_opened_files and vim.fn.bufloaded(node.absolute_path) > 0 and vim.fn.bufnr(node.absolute_path) ~= unloaded_bufnr - if should_highlight_opened_files then - self:_highlight_opened_files(node, offset, #icon, self.is_git_after and 0 or #git_icons) + then + if self.highlight_opened_files == "all" or self.highlight_opened_files == "name" then + name_hl = "NvimTreeOpenedFile" + end + if self.highlight_opened_files == "all" or self.highlight_opened_files == "icon" then + icon_hl = "NvimTreeOpenedFile" + end end - if git_highlight then - self:_insert_highlight(git_highlight, col_start, col_end) + -- modified file + local modified_highlight = modified.get_highlight(node) + if modified_highlight then + if self.highlight_opened_files == "all" or self.highlight_opened_files == "name" then + name_hl = modified_highlight + end + if self.highlight_opened_files == "all" or self.highlight_opened_files == "icon" then + icon_hl = modified_highlight + end end + + return icon_hl, name_hl end -function Builder:_build_line(node, idx, num_children, unloaded_bufnr) - local padding = pad.get_padding(self.depth, idx, num_children, node, self.markers) +---@param padding HighlightedString +---@param icon HighlightedString +---@param name HighlightedString +---@param git_icons HighlightedString[]|nil +---@param modified_icon HighlightedString|nil +---@return HighlightedString[] +function Builder:_format_line(padding, icon, name, git_icons, modified_icon) + local function add_to_end(t1, t2) + local added_len = 0 + for _, v in ipairs(t2) do + added_len = added_len + #v.str + end + + for _, v in ipairs(t2) do + if added_len > 0 then + table.insert(t1, { str = self.icon_padding }) + end + table.insert(t1, v) + end + end - if string.len(padding) > 0 then - self:_insert_highlight("NvimTreeIndentMarker", 0, string.len(padding)) + local line = { padding, icon } + if git_icons and self.git_placement == "before" then + add_to_end(line, git_icons) + end + if modified_icon and self.modified_placement == "before" then + add_to_end(line, { modified_icon }) + end + add_to_end(line, { name }) + if git_icons and self.git_placement == "after" then + add_to_end(line, git_icons) + end + if modified_icon and self.modified_placement == "after" then + add_to_end(line, { modified_icon }) end - local git_highlight = git.get_highlight(node) - local git_icons_tbl = git.get_icons(node) + return line +end - if git_icons_tbl and #git_icons_tbl > 0 then - if self.is_git_sign then - local git_info = git_icons_tbl[1] - table.insert(self.signs, { sign = git_info.hl, lnum = self.index + 1 }) - git_icons_tbl = {} - else - -- sort icons so it looks slightly better - table.sort(git_icons_tbl, function(a, b) - return a.ord < b.ord - end) - end - end +function Builder:_build_line(node, idx, num_children, unloaded_bufnr) + -- various components + local padding = pad.get_padding(self.depth, idx, num_children, node, self.markers) + local git_icons = self:_get_git_icons(node) + local modified_icon = self:_get_modified_icon(node) + -- main components local is_folder = node.nodes ~= nil local is_symlink = node.link_to ~= nil - + local icon, name if is_folder then - self:_build_folder(node, padding, git_highlight, git_icons_tbl) + icon, name = self:_build_folder(node) elseif is_symlink then - self:_build_symlink(node, padding, git_highlight, git_icons_tbl) + icon, name = self:_build_symlink(node) else - self:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr) + icon, name = self:_build_file(node) end + + -- highlight override + local icon_hl, name_hl = self:_get_highlight_override(node, unloaded_bufnr) + if icon_hl then + icon.hl = icon_hl + end + if name_hl then + name.hl = name_hl + end + + local line = self:_format_line(padding, icon, name, git_icons, modified_icon) + self:_insert_line(self:_unwrap_highlighted_strings(line)) + self.index = self.index + 1 if node.open then diff --git a/lua/nvim-tree/renderer/components/git.lua b/lua/nvim-tree/renderer/components/git.lua index 1c51eb1d3ea..8e3435baa89 100644 --- a/lua/nvim-tree/renderer/components/git.lua +++ b/lua/nvim-tree/renderer/components/git.lua @@ -1,19 +1,17 @@ local notify = require "nvim-tree.notify" local explorer_node = require "nvim-tree.explorer.node" -local M = { - SIGN_GROUP = "NvimTreeGitSigns", -} +local M = {} local function build_icons_table(i) local icons = { - staged = { icon = i.staged, hl = "NvimTreeGitStaged", ord = 1 }, - unstaged = { icon = i.unstaged, hl = "NvimTreeGitDirty", ord = 2 }, - renamed = { icon = i.renamed, hl = "NvimTreeGitRenamed", ord = 3 }, - deleted = { icon = i.deleted, hl = "NvimTreeGitDeleted", ord = 4 }, - unmerged = { icon = i.unmerged, hl = "NvimTreeGitMerge", ord = 5 }, - untracked = { icon = i.untracked, hl = "NvimTreeGitNew", ord = 6 }, - ignored = { icon = i.ignored, hl = "NvimTreeGitIgnored", ord = 7 }, + staged = { str = i.staged, hl = "NvimTreeGitStaged", ord = 1 }, + unstaged = { str = i.unstaged, hl = "NvimTreeGitDirty", ord = 2 }, + renamed = { str = i.renamed, hl = "NvimTreeGitRenamed", ord = 3 }, + deleted = { str = i.deleted, hl = "NvimTreeGitDeleted", ord = 4 }, + unmerged = { str = i.unmerged, hl = "NvimTreeGitMerge", ord = 5 }, + untracked = { str = i.untracked, hl = "NvimTreeGitNew", ord = 6 }, + ignored = { str = i.ignored, hl = "NvimTreeGitIgnored", ord = 7 }, } return { ["M "] = { icons.staged }, @@ -59,6 +57,8 @@ local function warn_status(git_status) ) end +---@param node table +---@return HighlightedString[]|nil local function get_icons_(node) local git_status = explorer_node.get_git_status(node) if git_status == nil then @@ -85,6 +85,11 @@ local function get_icons_(node) end end + -- sort icons so it looks slightly better + table.sort(iconss, function(a, b) + return a.ord < b.ord + end) + return iconss end diff --git a/lua/nvim-tree/renderer/components/icons.lua b/lua/nvim-tree/renderer/components/icons.lua index 3c5d27b82e1..5cf1940815a 100644 --- a/lua/nvim-tree/renderer/components/icons.lua +++ b/lua/nvim-tree/renderer/components/icons.lua @@ -1,7 +1,7 @@ local M = { i = {} } local function config_symlinks() - M.i.symlink = #M.config.glyphs.symlink > 0 and M.config.glyphs.symlink .. M.config.padding or "" + M.i.symlink = #M.config.glyphs.symlink > 0 and M.config.glyphs.symlink or "" M.i.symlink_arrow = M.config.symlink_arrow end @@ -28,14 +28,14 @@ local function get_folder_icon(open, is_symlink, has_children) n = M.config.glyphs.folder.empty end end - return n .. M.config.padding + return n end local function get_file_icon_default() local hl_group = "NvimTreeFileIcon" local icon = M.config.glyphs.default if #icon > 0 then - return icon .. M.config.padding, hl_group + return icon, hl_group else return "" end @@ -47,7 +47,7 @@ local function get_file_icon_webdev(fname, extension) hl_group = "NvimTreeFileIcon" end if icon and hl_group ~= "DevIconDefault" then - return icon .. M.config.padding, hl_group + return icon, hl_group 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_webdev(fname, string.match(extension, "%.(.*)")) diff --git a/lua/nvim-tree/renderer/components/modified.lua b/lua/nvim-tree/renderer/components/modified.lua new file mode 100644 index 00000000000..d0cd959679e --- /dev/null +++ b/lua/nvim-tree/renderer/components/modified.lua @@ -0,0 +1,38 @@ +local modified = require "nvim-tree.modified" + +local M = {} + +local HIGHLIGHT = "NvimTreeModifiedFile" + +---return modified icon if node is modified, otherwise return empty string +---@param node table +---@return HighlightedString|nil modified icon +function M.get_icon(node) + if not modified.is_modified(node) then + return nil + end + + return { str = M.icon, hl = HIGHLIGHT } +end + +function M.setup_signs() + vim.fn.sign_define(HIGHLIGHT, { text = M.icon, texthl = HIGHLIGHT }) +end + +---@param node table +---@return string|nil +function M.get_highlight(node) + if not modified.is_modified(node) then + return nil + end + + return HIGHLIGHT +end + +function M.setup(opts) + M.icon = opts.renderer.icons.show.modified and opts.renderer.icons.glyphs.modified or nil + + M.setup_signs() +end + +return M diff --git a/lua/nvim-tree/renderer/components/padding.lua b/lua/nvim-tree/renderer/components/padding.lua index e24bb84302c..3ab7a9880e2 100644 --- a/lua/nvim-tree/renderer/components/padding.lua +++ b/lua/nvim-tree/renderer/components/padding.lua @@ -68,6 +68,12 @@ local function get_padding_arrows(node, indent) end end +---@param depth integer +---@param idx integer +---@param nodes_number integer +---@param node table +---@param markers table +---@return HighlightedString function M.get_padding(depth, idx, nodes_number, node, markers) local padding = "" @@ -86,7 +92,7 @@ function M.get_padding(depth, idx, nodes_number, node, markers) padding = padding .. get_padding_arrows(node, not show_markers) end - return padding + return { str = padding, hl = "NvimTreeIndentMarker" } end function M.setup(opts) diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 415704554b5..c5bf620e23b 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -2,6 +2,7 @@ local core = require "nvim-tree.core" local diagnostics = require "nvim-tree.diagnostics" local log = require "nvim-tree.log" local view = require "nvim-tree.view" +local modified = require "nvim-tree.renderer.components.modified" local _padding = require "nvim-tree.renderer.components.padding" local icon_component = require "nvim-tree.renderer.components.icons" @@ -16,6 +17,8 @@ local M = { last_highlights = {}, } +local SIGN_GROUP = "NvimTreeRendererSigns" + local namespace_id = vim.api.nvim_create_namespace "NvimTreeHighlights" local function _draw(bufnr, lines, hl, signs) @@ -23,9 +26,9 @@ local function _draw(bufnr, lines, hl, signs) vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) M.render_hl(bufnr, hl) vim.api.nvim_buf_set_option(bufnr, "modifiable", false) - vim.fn.sign_unplace(git.SIGN_GROUP) + vim.fn.sign_unplace(SIGN_GROUP) for _, sign in pairs(signs) do - vim.fn.sign_place(0, git.SIGN_GROUP, sign.sign, bufnr, { lnum = sign.lnum, priority = 1 }) + vim.fn.sign_place(0, SIGN_GROUP, sign.sign, bufnr, { lnum = sign.lnum, priority = sign.priority }) end end @@ -68,9 +71,9 @@ function M.draw(unloaded_bufnr) :configure_special_files(M.config.special_files) :configure_picture_map(picture_map) :configure_opened_file_highlighting(M.config.highlight_opened_files) - :configure_git_icons_padding(M.config.icons.padding) + :configure_icon_padding(M.config.icons.padding) :configure_git_icons_placement(M.config.icons.git_placement) - :configure_modified(M.config.icons.glyphs.modified, M.config.icons.modified_placement) + :configure_modified_placement(M.config.icons.modified_placement) :configure_symlink_destination(M.config.symlink_destination) :configure_filter(live_filter.filter, live_filter.prefix) :build_header(view.is_root_folder_visible(core.get_cwd())) @@ -106,6 +109,7 @@ function M.setup(opts) _padding.setup(opts) full_name.setup(opts) git.setup(opts) + modified.setup(opts) icon_component.setup(opts) end From 9b04ff536f0cc46cd2f35659a40b8eb5fab686fe Mon Sep 17 00:00:00 2001 From: chomosuke Date: Fri, 23 Dec 2022 17:53:58 +1300 Subject: [PATCH 10/22] updated doc to match the reality of no multi char for glyphs.modified --- doc/nvim-tree-lua.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 3e72cf9cd03..0ac70859a22 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -915,8 +915,7 @@ UI rendering setup Type: `string`, Default: `""` *nvim-tree.renderer.icons.glyphs.modified* - Icon to display for modified files. Can be multiple characters if - |renderer.icons.modified_placement| isn't `"signcolumn"`. + Icon to display for modified files. Type: `string`, Default: `"●"` *nvim-tree.renderer.icons.glyphs.folder* From 8bf609cb7f777bf17a38fa3332bbc2d0c90861f9 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Fri, 23 Dec 2022 18:00:40 +1300 Subject: [PATCH 11/22] fixed git signcolumn doesn't show --- lua/nvim-tree/renderer/builder.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index aab31f0cd1a..7d62c1aec99 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -193,7 +193,7 @@ end ---@return HighlightedString[]|nil icon function Builder:_get_git_icons(node) local git_icons = git.get_icons(node) - if git_icons and #git_icons > 0 and self.is_git_sign then + if git_icons and #git_icons > 0 and self.git_placement == "signcolumn" then local sign = git_icons[1] table.insert(self.signs, { sign = sign.hl, lnum = self.index + 1, priority = 1 }) git_icons = nil From c7b20ca8bb2c3533672c223fd47fc75a28df98b8 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Fri, 23 Dec 2022 19:21:32 +1300 Subject: [PATCH 12/22] fixed highlight_modified gets replaced by highlight_opened_files --- lua/nvim-tree/renderer/builder.lua | 9 +++++++-- lua/nvim-tree/renderer/init.lua | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 7d62c1aec99..f986e505505 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -54,6 +54,11 @@ function Builder:configure_opened_file_highlighting(highlight_opened_files) return self end +function Builder:configure_modified_highlighting(highlight_modified) + self.highlight_modified = highlight_modified + return self +end + function Builder:configure_icon_padding(padding) self.icon_padding = padding or " " return self @@ -243,10 +248,10 @@ function Builder:_get_highlight_override(node, unloaded_bufnr) -- modified file local modified_highlight = modified.get_highlight(node) if modified_highlight then - if self.highlight_opened_files == "all" or self.highlight_opened_files == "name" then + if self.highlight_modified == "all" or self.highlight_modified == "name" then name_hl = modified_highlight end - if self.highlight_opened_files == "all" or self.highlight_opened_files == "icon" then + if self.highlight_modified == "all" or self.highlight_modified == "icon" then icon_hl = modified_highlight end end diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index c5bf620e23b..e0520b7aeb0 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -71,6 +71,7 @@ function M.draw(unloaded_bufnr) :configure_special_files(M.config.special_files) :configure_picture_map(picture_map) :configure_opened_file_highlighting(M.config.highlight_opened_files) + :configure_modified_highlighting(M.config.highlight_modified) :configure_icon_padding(M.config.icons.padding) :configure_git_icons_placement(M.config.icons.git_placement) :configure_modified_placement(M.config.icons.modified_placement) From 621d634f6c207fdc4077101099cf546fb6cd4dae Mon Sep 17 00:00:00 2001 From: chomosuke Date: Fri, 23 Dec 2022 19:22:08 +1300 Subject: [PATCH 13/22] fixed renderer.icons.show.modified = false crash --- lua/nvim-tree/renderer/components/modified.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lua/nvim-tree/renderer/components/modified.lua b/lua/nvim-tree/renderer/components/modified.lua index d0cd959679e..4eff4424d7b 100644 --- a/lua/nvim-tree/renderer/components/modified.lua +++ b/lua/nvim-tree/renderer/components/modified.lua @@ -8,7 +8,7 @@ local HIGHLIGHT = "NvimTreeModifiedFile" ---@param node table ---@return HighlightedString|nil modified icon function M.get_icon(node) - if not modified.is_modified(node) then + if not modified.is_modified(node) or not M.show_icon then return nil end @@ -30,7 +30,8 @@ function M.get_highlight(node) end function M.setup(opts) - M.icon = opts.renderer.icons.show.modified and opts.renderer.icons.glyphs.modified or nil + M.icon = opts.renderer.icons.glyphs.modified + M.show_icon = opts.renderer.icons.show.modified M.setup_signs() end From 2bbccb12337cbbbfeb246163a12e8ae4b5b94ac4 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Fri, 23 Dec 2022 22:29:04 +1300 Subject: [PATCH 14/22] updated doc to reflect empty icon not breaking rendering --- doc/nvim-tree-lua.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 0ac70859a22..cb3cc58fcda 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -864,7 +864,6 @@ UI rendering setup *nvim-tree.renderer.icons.padding* Inserted between icon and filename. - Use with caution, it could break rendering if you set an empty string depending on your font. Type: `string`, Default: `" "` *nvim-tree.renderer.icons.symlink_arrow* From 845069d50645b1ac1abe1e35f6f77f39c3506011 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Wed, 28 Dec 2022 12:05:20 +1300 Subject: [PATCH 15/22] removed debounce_delay to implement in a later PR --- doc/nvim-tree-lua.txt | 7 ------- lua/nvim-tree.lua | 7 ++----- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index cb3cc58fcda..1d9be94962b 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -332,7 +332,6 @@ Subsequent calls to setup will replace the previous configuration. enable = false, show_on_dirs = true, show_on_open_dirs = false, - debounce_delay = 50, }, actions = { use_system_clipboard = true, @@ -644,12 +643,6 @@ Indicate which file have unsaved modification. Only relevant when |modified.show_on_dirs| is `true`. Type: `boolean`, Default: `false` - *nvim-tree.modified.debounce_delay* - Idle milliseconds between the file is modified and action. - This helps performance when large number of files are modified in quick - succession (e.g. lsp rename). - Type: `number`, Default: `50` (ms) - You will still need to set |renderer.icons.show.modified| `= true` or |renderer.highlight_modified| `= true` to be able to see things in the tree. diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index a91ca7921f7..2b577db2a29 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -481,10 +481,8 @@ local function setup_autocommands(opts) if opts.modified.enable then create_nvim_tree_autocmd({ "BufModifiedSet", "BufWritePost" }, { callback = function() - utils.debounce("BufModifiedSet:modified_files", opts.modified.debounce_delay, function() - modified.reload() - reloaders.reload_explorer() - end) + modified.reload() + reloaders.reload_explorer() end, }) end @@ -653,7 +651,6 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS enable = false, show_on_dirs = true, show_on_open_dirs = false, - debounce_delay = 50, }, actions = { use_system_clipboard = true, From efb380525feee1ac05bbbeed89aa4628d3daece6 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Fri, 30 Dec 2022 16:45:24 +1100 Subject: [PATCH 16/22] doc nit: order placement --- doc/nvim-tree-lua.txt | 14 +++++++------- lua/nvim-tree.lua | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 1d9be94962b..6d870dec1d6 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -239,9 +239,9 @@ Subsequent calls to setup will replace the previous configuration. icons = { webdev_colors = true, git_placement = "before", + modified_placement = "after", padding = " ", symlink_arrow = " ➛ ", - modified_placement = "after", show = { file = true, folder = true, @@ -855,6 +855,12 @@ UI rendering setup Note that the diagnostic signs and the modified sign will take precedence over the git signs. Type: `string`, Default: `before` + *nvim-tree.renderer.icons.modified_placement* + Place where the modified icon will be rendered. + Can be `"after"` or `"before"` filename (after the file/folders icons) + or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled). + Type: `string`, Default: `after` + *nvim-tree.renderer.icons.padding* Inserted between icon and filename. Type: `string`, Default: `" "` @@ -863,12 +869,6 @@ UI rendering setup Used as a separator between symlinks' source and target. Type: `string`, Default: `" ➛ "` - *nvim-tree.renderer.icons.modified_placement* - Place where the modified icon will be rendered. - Can be `"after"` or `"before"` filename (after the file/folders icons) - or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled). - Type: `string`, Default: `after` - *nvim-tree.renderer.icons.show* Configuration options for showing icon types. diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 2b577db2a29..732ba20685a 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -558,9 +558,9 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS icons = { webdev_colors = true, git_placement = "before", + modified_placement = "after", padding = " ", symlink_arrow = " ➛ ", - modified_placement = "after", show = { file = true, folder = true, From ad6cb10ed5bb720b769ba5e3f858c2e84c47b1c5 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Sat, 31 Dec 2022 13:02:55 +1300 Subject: [PATCH 17/22] change modified dirs default to be consistent with git --- doc/nvim-tree-lua.txt | 4 ++-- lua/nvim-tree.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 6d870dec1d6..8b6aaf981a1 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -331,7 +331,7 @@ Subsequent calls to setup will replace the previous configuration. modified = { enable = false, show_on_dirs = true, - show_on_open_dirs = false, + show_on_open_dirs = true, }, actions = { use_system_clipboard = true, @@ -641,7 +641,7 @@ Indicate which file have unsaved modification. *nvim-tree.modified.show_on_open_dirs* Show modified indication on open directories. Only relevant when |modified.show_on_dirs| is `true`. - Type: `boolean`, Default: `false` + Type: `boolean`, Default: `true` You will still need to set |renderer.icons.show.modified| `= true` or |renderer.highlight_modified| `= true` to be able to see things in the diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 732ba20685a..9b0fe95a9dd 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -650,7 +650,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS modified = { enable = false, show_on_dirs = true, - show_on_open_dirs = false, + show_on_open_dirs = true, }, actions = { use_system_clipboard = true, From 061a1541a4286b5320b99f456df7d8af8b7a2924 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Sat, 31 Dec 2022 13:05:51 +1300 Subject: [PATCH 18/22] illegal git & modified placement changed to default --- lua/nvim-tree/renderer/builder.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index f986e505505..435adeac32a 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -65,12 +65,18 @@ function Builder:configure_icon_padding(padding) end function Builder:configure_git_icons_placement(where) + if where ~= "after" and where ~= "before" and where ~= "signcolumn" then + where = "before" -- default before + end self.git_placement = where return self end -function Builder:configure_modified_placement(modified_placement) - self.modified_placement = modified_placement +function Builder:configure_modified_placement(where) + if where ~= "after" and where ~= "before" and where ~= "signcolumn" then + where = "after" -- default after + end + self.modified_placement = where return self end From 38846abd654913349bf89b644838e12f75f3bf14 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Sat, 31 Dec 2022 13:23:41 +1300 Subject: [PATCH 19/22] don't assume icon exist --- lua/nvim-tree/renderer/builder.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 435adeac32a..03ce3585cb2 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -272,21 +272,25 @@ end ---@param modified_icon HighlightedString|nil ---@return HighlightedString[] function Builder:_format_line(padding, icon, name, git_icons, modified_icon) + local added_len = 0 local function add_to_end(t1, t2) - local added_len = 0 - for _, v in ipairs(t2) do - added_len = added_len + #v.str - end - for _, v in ipairs(t2) do if added_len > 0 then table.insert(t1, { str = self.icon_padding }) end table.insert(t1, v) end + + -- first add_to_end don't need padding + -- hence added_len is calculated at the end to be used next time + added_len = 0 + for _, v in ipairs(t2) do + added_len = added_len + #v.str + end end - local line = { padding, icon } + local line = { padding } + add_to_end(line, { icon }) if git_icons and self.git_placement == "before" then add_to_end(line, git_icons) end From 9e15b329195efd97701faef6a68301aece2ad46f Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sat, 31 Dec 2022 12:00:37 +1100 Subject: [PATCH 20/22] nit remove comment --- lua/nvim-tree/modified.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/nvim-tree/modified.lua b/lua/nvim-tree/modified.lua index f38874b46da..eff1a18e9ed 100644 --- a/lua/nvim-tree/modified.lua +++ b/lua/nvim-tree/modified.lua @@ -17,7 +17,7 @@ function M.reload() end end ----@param node table TODO: we should probably have a Node type +---@param node table ---@return boolean function M.is_modified(node) return M.config.enable From 4554681520a6ffddf9edeaf884ebe9ec7c061dea Mon Sep 17 00:00:00 2001 From: chomosuke Date: Sat, 31 Dec 2022 17:07:09 +1300 Subject: [PATCH 21/22] Noted in doc that glyphs can't have more than 2 characters if in signcolumn --- doc/nvim-tree-lua.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 62d10bbaefb..e72b998b8ec 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -898,6 +898,8 @@ UI rendering setup *nvim-tree.renderer.icons.glyphs* Configuration options for icon glyphs. + NOTE: Do not set any glyphs to more than two characters if it's going + to appear in the signcolumn. *nvim-tree.renderer.icons.glyphs.default* Glyph for files. Will be overridden by `nvim-web-devicons` if available. From 413dc30c3c94d380591b6e380c0c04aa8d1b7853 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Sat, 31 Dec 2022 17:48:05 +1300 Subject: [PATCH 22/22] Don't sign_define if placement isn't signcolumn --- lua/nvim-tree/renderer/components/git.lua | 4 +++- lua/nvim-tree/renderer/components/modified.lua | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lua/nvim-tree/renderer/components/git.lua b/lua/nvim-tree/renderer/components/git.lua index 8e3435baa89..31dfa049cef 100644 --- a/lua/nvim-tree/renderer/components/git.lua +++ b/lua/nvim-tree/renderer/components/git.lua @@ -150,7 +150,9 @@ function M.setup(opts) M.git_icons = build_icons_table(opts.renderer.icons.glyphs.git) - M.setup_signs(opts.renderer.icons.glyphs.git) + if opts.renderer.icons.git_placement == "signcolumn" then + M.setup_signs(opts.renderer.icons.glyphs.git) + end if opts.renderer.icons.show.git then M.get_icons = get_icons_ diff --git a/lua/nvim-tree/renderer/components/modified.lua b/lua/nvim-tree/renderer/components/modified.lua index 4eff4424d7b..1ae9870b405 100644 --- a/lua/nvim-tree/renderer/components/modified.lua +++ b/lua/nvim-tree/renderer/components/modified.lua @@ -33,7 +33,9 @@ function M.setup(opts) M.icon = opts.renderer.icons.glyphs.modified M.show_icon = opts.renderer.icons.show.modified - M.setup_signs() + if opts.renderer.icons.modified_placement == "signcolumn" then + M.setup_signs() + end end return M