From 40b34326a9f7406beb185af6ccd6f2d5b397bf93 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 9 Sep 2024 13:39:51 +1000 Subject: [PATCH 01/16] refactor(#2875): multi instance renderer --- lua/nvim-tree/renderer/builder.lua | 200 ++++++++++++++--------------- lua/nvim-tree/renderer/init.lua | 10 +- 2 files changed, 105 insertions(+), 105 deletions(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 23bef62ac8f..e297c16cb70 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -15,45 +15,90 @@ local DecoratorOpened = require "nvim-tree.renderer.decorator.opened" local pad = require "nvim-tree.renderer.components.padding" local icons = require "nvim-tree.renderer.components.icons" -local M = { - opts = {}, - decorators = {}, - picture_map = { - jpg = true, - jpeg = true, - png = true, - gif = true, - webp = true, - jxl = true, - }, +local PICTURE_MAP = { + jpg = true, + jpeg = true, + png = true, + gif = true, + webp = true, + jxl = true, } ----@class HighlightedString +---@class (exact) HighlightedString ---@field str string ---@field hl string[] ----@class AddHighlightArgs +---@class (exact) AddHighlightArgs ---@field group string[] ---@field line number ---@field col_start number ---@field col_end number ----@class Builder +---@class (exact) Builder ---@field lines string[] includes icons etc. ---@field hl_args AddHighlightArgs[] line highlights ---@field signs string[] line signs ---@field extmarks table[] extra marks for right icon placement ---@field virtual_lines table[] virtual lines for hidden count display ----@field private root_cwd string absolute path +---@field private explorer Explorer +---@field private root_cwd string|nil absolute path ---@field private index number ---@field private depth number ---@field private combined_groups table combined group names ---@field private markers boolean[] indent markers +---@field private decorators Decorator[] +---@field private hidden_display fun(node: Node): string|nil local Builder = {} +---@param opts table +---@return fun(node: Node): string|nil +local setup_hidden_display_function = function(opts) + local hidden_display = opts.renderer.hidden_display + -- options are already validated, so ´hidden_display´ can ONLY be `string` or `function` if type(hidden_display) == "string" then + if type(hidden_display) == "string" then + if hidden_display == "none" then + return function() + return nil + end + elseif hidden_display == "simple" then + return function(hidden_stats) + return utils.default_format_hidden_count(hidden_stats, true) + end + else -- "all" + return function(hidden_stats) + return utils.default_format_hidden_count(hidden_stats, false) + end + end + else -- "function + return function(hidden_stats) + -- In case of missing field such as live_filter we zero it, otherwise keep field as is + hidden_stats = vim.tbl_deep_extend("force", { + live_filter = 0, + git = 0, + buf = 0, + dotfile = 0, + custom = 0, + bookmark = 0, + }, hidden_stats or {}) + + local ok, result = pcall(hidden_display, hidden_stats) + if not ok then + notify.warn "Problem occurred in the function ``opts.renderer.hidden_display`` see nvim-tree.renderer.hidden_display on :h nvim-tree" + return nil + end + return result + end + end +end + +---@param opts table user options +---@param explorer Explorer ---@return Builder -function Builder:new() +function Builder:new(opts, explorer) + ---@type Builder local o = { + opts = opts, + explorer = explorer, root_cwd = core.get_cwd(), index = 0, depth = 0, @@ -64,9 +109,21 @@ function Builder:new() signs = {}, extmarks = {}, virtual_lines = {}, + decorators = { + -- priority order + DecoratorCut:new(opts), + DecoratorCopied:new(opts), + DecoratorDiagnostics:new(opts), + DecoratorBookmarks:new(opts), + DecoratorModified:new(opts), + DecoratorHidden:new(opts), + DecoratorOpened:new(opts), + DecoratorGit:new(opts), + }, + hidden_display = setup_hidden_display_function(opts), } - setmetatable(o, self) - self.__index = self + + setmetatable(o, { __index = self }) return o end @@ -89,8 +146,8 @@ function Builder:get_folder_name(node) next = next.group_next end - if node.group_next and type(M.opts.renderer.group_empty) == "function" then - local new_name = M.opts.renderer.group_empty(name) + if node.group_next and type(self.opts.renderer.group_empty) == "function" then + local new_name = self.opts.renderer.group_empty(name) if type(new_name) == "string" then name = new_name else @@ -98,7 +155,7 @@ function Builder:get_folder_name(node) end end - return string.format("%s%s", name, M.opts.renderer.add_trailing and "/" or "") + return string.format("%s%s", name, self.opts.renderer.add_trailing and "/" or "") end ---@private @@ -139,13 +196,13 @@ function Builder:build_folder(node) end local foldername_hl = "NvimTreeFolderName" - if node.link_to and M.opts.renderer.symlink_destination then + if node.link_to and self.opts.renderer.symlink_destination then local arrow = icons.i.symlink_arrow local link_to = utils.path_relative(node.link_to, self.root_cwd) foldername = string.format("%s%s%s", foldername, arrow, link_to) foldername_hl = "NvimTreeSymlinkFolderName" elseif - vim.tbl_contains(M.opts.renderer.special_files, node.absolute_path) or vim.tbl_contains(M.opts.renderer.special_files, node.name) + vim.tbl_contains(self.opts.renderer.special_files, node.absolute_path) or vim.tbl_contains(self.opts.renderer.special_files, node.name) then foldername_hl = "NvimTreeSpecialFolderName" elseif node.open then @@ -165,7 +222,7 @@ function Builder:build_symlink(node) local icon = icons.i.symlink local arrow = icons.i.symlink_arrow local symlink_formatted = node.name - if M.opts.renderer.symlink_destination then + if self.opts.renderer.symlink_destination then local link_to = utils.path_relative(node.link_to, self.root_cwd) symlink_formatted = string.format("%s%s%s", symlink_formatted, arrow, link_to) end @@ -179,11 +236,13 @@ end ---@return HighlightedString name function Builder:build_file(node) local hl - if vim.tbl_contains(M.opts.renderer.special_files, node.absolute_path) or vim.tbl_contains(M.opts.renderer.special_files, node.name) then + if + vim.tbl_contains(self.opts.renderer.special_files, node.absolute_path) or vim.tbl_contains(self.opts.renderer.special_files, node.name) + then hl = "NvimTreeSpecialFile" elseif node.executable then hl = "NvimTreeExecFile" - elseif M.picture_map[node.extension] then + elseif PICTURE_MAP[node.extension] then hl = "NvimTreeImageFile" end @@ -206,7 +265,7 @@ function Builder:format_line(indent_markers, arrows, icon, name, node) end for _, v in ipairs(t2) do if added_len > 0 then - table.insert(t1, { str = M.opts.renderer.icons.padding }) + table.insert(t1, { str = self.opts.renderer.icons.padding }) end table.insert(t1, v) end @@ -222,19 +281,19 @@ function Builder:format_line(indent_markers, arrows, icon, name, node) local line = { indent_markers, arrows } add_to_end(line, { icon }) - for i = #M.decorators, 1, -1 do - add_to_end(line, M.decorators[i]:icons_before(node)) + for i = #self.decorators, 1, -1 do + add_to_end(line, self.decorators[i]:icons_before(node)) end add_to_end(line, { name }) - for i = #M.decorators, 1, -1 do - add_to_end(line, M.decorators[i]:icons_after(node)) + for i = #self.decorators, 1, -1 do + add_to_end(line, self.decorators[i]:icons_after(node)) end local rights = {} - for i = #M.decorators, 1, -1 do - add_to_end(rights, M.decorators[i]:icons_right_align(node)) + for i = #self.decorators, 1, -1 do + add_to_end(rights, self.decorators[i]:icons_right_align(node)) end if #rights > 0 then self.extmarks[self.index] = rights @@ -248,7 +307,7 @@ end function Builder:build_signs(node) -- first in priority order local sign_name - for _, d in ipairs(M.decorators) do + for _, d in ipairs(self.decorators) do sign_name = d:sign_name(node) if sign_name then self.signs[self.index] = sign_name @@ -300,8 +359,8 @@ function Builder:add_highlights(node) local icon_groups = {} local name_groups = {} local d, icon, name - for i = #M.decorators, 1, -1 do - d = M.decorators[i] + for i = #self.decorators, 1, -1 do + d = self.decorators[i] icon, name = d:groups_icon_name(node) table.insert(icon_groups, icon) table.insert(name_groups, name) @@ -366,10 +425,10 @@ function Builder:add_hidden_count_string(node, idx, num_children) if not node.open then return end - local hidden_count_string = M.opts.renderer.hidden_display(node.hidden_stats) + local hidden_count_string = self.hidden_display(node.hidden_stats) if hidden_count_string and hidden_count_string ~= "" then local indent_markers = pad.get_indent_markers(self.depth, idx or 0, num_children or 0, node, self.markers, 1) - local indent_width = M.opts.renderer.indent_width + local indent_width = self.opts.renderer.indent_width local indent_padding = string.rep(" ", indent_width) local indent_string = indent_padding .. indent_markers.str @@ -438,16 +497,16 @@ end function Builder:build_header() local explorer = core.get_explorer() if view.is_root_folder_visible(core.get_cwd()) then - local root_name = self:format_root_name(M.opts.renderer.root_folder_label) + local root_name = self:format_root_name(self.opts.renderer.root_folder_label) table.insert(self.lines, root_name) self:insert_highlight({ "NvimTreeRootFolder" }, 0, string.len(root_name)) self.index = 1 end if explorer and explorer.live_filter.filter then - local filter_line = string.format("%s/%s/", M.opts.live_filter.prefix, explorer.live_filter.filter) + local filter_line = string.format("%s/%s/", self.opts.live_filter.prefix, explorer.live_filter.filter) table.insert(self.lines, filter_line) - local prefix_length = string.len(M.opts.live_filter.prefix) + local prefix_length = string.len(self.opts.live_filter.prefix) self:insert_highlight({ "NvimTreeLiveFilterPrefix" }, 0, prefix_length) self:insert_highlight({ "NvimTreeLiveFilterValue" }, prefix_length, string.len(filter_line)) self.index = self.index + 1 @@ -472,63 +531,4 @@ function Builder:build() return self end ----@param opts table -local setup_hidden_display_function = function(opts) - local hidden_display = opts.renderer.hidden_display - -- options are already validated, so ´hidden_display´ can ONLY be `string` or `function` if type(hidden_display) == "string" then - if type(hidden_display) == "string" then - if hidden_display == "none" then - opts.renderer.hidden_display = function() - return nil - end - elseif hidden_display == "simple" then - opts.renderer.hidden_display = function(hidden_stats) - return utils.default_format_hidden_count(hidden_stats, true) - end - elseif hidden_display == "all" then - opts.renderer.hidden_display = function(hidden_stats) - return utils.default_format_hidden_count(hidden_stats, false) - end - end - elseif type(hidden_display) == "function" then - local safe_render = function(hidden_stats) - -- In case of missing field such as live_filter we zero it, otherwise keep field as is - hidden_stats = vim.tbl_deep_extend("force", { - live_filter = 0, - git = 0, - buf = 0, - dotfile = 0, - custom = 0, - bookmark = 0, - }, hidden_stats or {}) - - local ok, result = pcall(hidden_display, hidden_stats) - if not ok then - notify.warn "Problem occurred in the function ``opts.renderer.hidden_display`` see nvim-tree.renderer.hidden_display on :h nvim-tree" - return nil - end - return result - end - - opts.renderer.hidden_display = safe_render - end -end - -function Builder.setup(opts) - setup_hidden_display_function(opts) - M.opts = opts - - -- priority order - M.decorators = { - DecoratorCut:new(opts), - DecoratorCopied:new(opts), - DecoratorDiagnostics:new(opts), - DecoratorBookmarks:new(opts), - DecoratorModified:new(opts), - DecoratorHidden:new(opts), - DecoratorOpened:new(opts), - DecoratorGit:new(opts), - } -end - return Builder diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 729164aea5b..3e0983ba3ed 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -77,8 +77,10 @@ function M.render_hl(bufnr, hl) end function M.draw() + local explorer = core.get_explorer() + local bufnr = view.get_bufnr() - if not core.get_explorer() or not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then + if not explorer or not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then return end @@ -87,7 +89,7 @@ function M.draw() local cursor = vim.api.nvim_win_get_cursor(view.get_winnr() or 0) icon_component.reset_config() - local builder = Builder:new():build() + local builder = Builder:new(M.opts, explorer):build() _draw(bufnr, builder.lines, builder.hl_args, builder.signs, builder.extmarks, builder.virtual_lines) @@ -103,13 +105,11 @@ function M.draw() end function M.setup(opts) - M.config = opts.renderer + M.opts = opts _padding.setup(opts) full_name.setup(opts) icon_component.setup(opts) - - Builder.setup(opts) end return M From f4d74cd4af5eff0bb6c02cc64126c8799da18a5a Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 9 Sep 2024 13:52:47 +1000 Subject: [PATCH 02/16] refactor(#2875): multi instance renderer --- lua/nvim-tree/renderer/builder.lua | 16 ++++++++-------- lua/nvim-tree/renderer/decorator/bookmarks.lua | 12 ++++++------ lua/nvim-tree/renderer/decorator/copied.lua | 10 +++++----- lua/nvim-tree/renderer/decorator/cut.lua | 10 +++++----- lua/nvim-tree/renderer/decorator/diagnostics.lua | 6 ++++-- lua/nvim-tree/renderer/decorator/git.lua | 6 ++++-- lua/nvim-tree/renderer/decorator/hidden.lua | 6 ++++-- lua/nvim-tree/renderer/decorator/init.lua | 7 ++++--- lua/nvim-tree/renderer/decorator/modified.lua | 6 ++++-- lua/nvim-tree/renderer/decorator/opened.lua | 6 ++++-- 10 files changed, 48 insertions(+), 37 deletions(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index e297c16cb70..7811db81135 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -111,14 +111,14 @@ function Builder:new(opts, explorer) virtual_lines = {}, decorators = { -- priority order - DecoratorCut:new(opts), - DecoratorCopied:new(opts), - DecoratorDiagnostics:new(opts), - DecoratorBookmarks:new(opts), - DecoratorModified:new(opts), - DecoratorHidden:new(opts), - DecoratorOpened:new(opts), - DecoratorGit:new(opts), + DecoratorCut:new(opts, explorer), + DecoratorCopied:new(opts, explorer), + DecoratorDiagnostics:new(opts, explorer), + DecoratorBookmarks:new(opts, explorer), + DecoratorModified:new(opts, explorer), + DecoratorHidden:new(opts, explorer), + DecoratorOpened:new(opts, explorer), + DecoratorGit:new(opts, explorer), }, hidden_display = setup_hidden_display_function(opts), } diff --git a/lua/nvim-tree/renderer/decorator/bookmarks.lua b/lua/nvim-tree/renderer/decorator/bookmarks.lua index 56065fd7895..29f0f649743 100644 --- a/lua/nvim-tree/renderer/decorator/bookmarks.lua +++ b/lua/nvim-tree/renderer/decorator/bookmarks.lua @@ -1,18 +1,18 @@ -local core = require "nvim-tree.core" - local HL_POSITION = require("nvim-tree.enum").HL_POSITION local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT local Decorator = require "nvim-tree.renderer.decorator" ----@class DecoratorBookmarks: Decorator +---@class (exact) DecoratorBookmarks: Decorator ---@field icon HighlightedString local DecoratorBookmarks = Decorator:new() ---@param opts table +---@param explorer Explorer ---@return DecoratorBookmarks -function DecoratorBookmarks:new(opts) +function DecoratorBookmarks:new(opts, explorer) local o = Decorator.new(self, { + explorer = explorer, enabled = true, hl_pos = HL_POSITION[opts.renderer.highlight_bookmarks] or HL_POSITION.none, icon_placement = ICON_PLACEMENT[opts.renderer.icons.bookmarks_placement] or ICON_PLACEMENT.none, @@ -34,7 +34,7 @@ end ---@param node Node ---@return HighlightedString[]|nil icons function DecoratorBookmarks:calculate_icons(node) - if core.get_explorer() and core.get_explorer().marks:get(node) then + if self.explorer.marks:get(node) then return { self.icon } end end @@ -43,7 +43,7 @@ end ---@param node Node ---@return string|nil group function DecoratorBookmarks:calculate_highlight(node) - if self.hl_pos ~= HL_POSITION.none and core.get_explorer() and core.get_explorer().marks:get(node) then + if self.hl_pos ~= HL_POSITION.none and self.explorer.marks:get(node) then return "NvimTreeBookmarkHL" end end diff --git a/lua/nvim-tree/renderer/decorator/copied.lua b/lua/nvim-tree/renderer/decorator/copied.lua index ba187e7d5be..3d7e131fc7e 100644 --- a/lua/nvim-tree/renderer/decorator/copied.lua +++ b/lua/nvim-tree/renderer/decorator/copied.lua @@ -1,19 +1,19 @@ -local core = require "nvim-tree.core" - local HL_POSITION = require("nvim-tree.enum").HL_POSITION local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT local Decorator = require "nvim-tree.renderer.decorator" ----@class DecoratorCopied: Decorator +---@class (exact) DecoratorCopied: Decorator ---@field enabled boolean ---@field icon HighlightedString|nil local DecoratorCopied = Decorator:new() ---@param opts table +---@param explorer Explorer ---@return DecoratorCopied -function DecoratorCopied:new(opts) +function DecoratorCopied:new(opts, explorer) local o = Decorator.new(self, { + explorer = explorer, enabled = true, hl_pos = HL_POSITION[opts.renderer.highlight_clipboard] or HL_POSITION.none, icon_placement = ICON_PLACEMENT.none, @@ -27,7 +27,7 @@ end ---@param node Node ---@return string|nil group function DecoratorCopied:calculate_highlight(node) - if self.hl_pos ~= HL_POSITION.none and core.get_explorer() and core.get_explorer().clipboard:is_copied(node) then + if self.hl_pos ~= HL_POSITION.none and self.explorer.clipboard:is_copied(node) then return "NvimTreeCopiedHL" end end diff --git a/lua/nvim-tree/renderer/decorator/cut.lua b/lua/nvim-tree/renderer/decorator/cut.lua index 615168f8907..8710e36f9a1 100644 --- a/lua/nvim-tree/renderer/decorator/cut.lua +++ b/lua/nvim-tree/renderer/decorator/cut.lua @@ -1,19 +1,19 @@ -local core = require "nvim-tree.core" - local HL_POSITION = require("nvim-tree.enum").HL_POSITION local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT local Decorator = require "nvim-tree.renderer.decorator" ----@class DecoratorCut: Decorator +---@class (exact) DecoratorCut: Decorator ---@field enabled boolean ---@field icon HighlightedString|nil local DecoratorCut = Decorator:new() ---@param opts table +---@param explorer Explorer ---@return DecoratorCut -function DecoratorCut:new(opts) +function DecoratorCut:new(opts, explorer) local o = Decorator.new(self, { + explorer = explorer, enabled = true, hl_pos = HL_POSITION[opts.renderer.highlight_clipboard] or HL_POSITION.none, icon_placement = ICON_PLACEMENT.none, @@ -27,7 +27,7 @@ end ---@param node Node ---@return string|nil group function DecoratorCut:calculate_highlight(node) - if self.hl_pos ~= HL_POSITION.none and core.get_explorer() and core.get_explorer().clipboard:is_cut(node) then + if self.hl_pos ~= HL_POSITION.none and self.explorer.clipboard:is_cut(node) then return "NvimTreeCutHL" end end diff --git a/lua/nvim-tree/renderer/decorator/diagnostics.lua b/lua/nvim-tree/renderer/decorator/diagnostics.lua index d18ff4d43d2..770fe07473e 100644 --- a/lua/nvim-tree/renderer/decorator/diagnostics.lua +++ b/lua/nvim-tree/renderer/decorator/diagnostics.lua @@ -32,14 +32,16 @@ local ICON_KEYS = { ["hint"] = vim.diagnostic.severity.HINT, } ----@class DecoratorDiagnostics: Decorator +---@class (exact) DecoratorDiagnostics: Decorator ---@field icons HighlightedString[] local DecoratorDiagnostics = Decorator:new() ---@param opts table +---@param explorer Explorer ---@return DecoratorDiagnostics -function DecoratorDiagnostics:new(opts) +function DecoratorDiagnostics:new(opts, explorer) local o = Decorator.new(self, { + explorer = explorer, enabled = opts.diagnostics.enable, hl_pos = HL_POSITION[opts.renderer.highlight_diagnostics] or HL_POSITION.none, icon_placement = ICON_PLACEMENT[opts.renderer.icons.diagnostics_placement] or ICON_PLACEMENT.none, diff --git a/lua/nvim-tree/renderer/decorator/git.lua b/lua/nvim-tree/renderer/decorator/git.lua index de2477880bd..412d3361bc8 100644 --- a/lua/nvim-tree/renderer/decorator/git.lua +++ b/lua/nvim-tree/renderer/decorator/git.lua @@ -9,7 +9,7 @@ local Decorator = require "nvim-tree.renderer.decorator" ---@class HighlightedStringGit: HighlightedString ---@field ord number decreasing priority ----@class DecoratorGit: Decorator +---@class (exact) DecoratorGit: Decorator ---@field file_hl table by porcelain status e.g. "AM" ---@field folder_hl table by porcelain status ---@field icons_by_status HighlightedStringGit[] by human status @@ -17,9 +17,11 @@ local Decorator = require "nvim-tree.renderer.decorator" local DecoratorGit = Decorator:new() ---@param opts table +---@param explorer Explorer ---@return DecoratorGit -function DecoratorGit:new(opts) +function DecoratorGit:new(opts, explorer) local o = Decorator.new(self, { + explorer = explorer, enabled = opts.git.enable, hl_pos = HL_POSITION[opts.renderer.highlight_git] or HL_POSITION.none, icon_placement = ICON_PLACEMENT[opts.renderer.icons.git_placement] or ICON_PLACEMENT.none, diff --git a/lua/nvim-tree/renderer/decorator/hidden.lua b/lua/nvim-tree/renderer/decorator/hidden.lua index bf21c2d25cc..f7aa58b57e4 100644 --- a/lua/nvim-tree/renderer/decorator/hidden.lua +++ b/lua/nvim-tree/renderer/decorator/hidden.lua @@ -3,14 +3,16 @@ local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT local explorer_node = require "nvim-tree.explorer.node" local Decorator = require "nvim-tree.renderer.decorator" ----@class DecoratorHidden: Decorator +---@class (exact) DecoratorHidden: Decorator ---@field icon HighlightedString|nil local DecoratorHidden = Decorator:new() ---@param opts table +---@param explorer Explorer ---@return DecoratorHidden -function DecoratorHidden:new(opts) +function DecoratorHidden:new(opts, explorer) local o = Decorator.new(self, { + explorer = explorer, enabled = true, hl_pos = HL_POSITION[opts.renderer.highlight_hidden] or HL_POSITION.none, icon_placement = ICON_PLACEMENT[opts.renderer.icons.hidden_placement] or ICON_PLACEMENT.none, diff --git a/lua/nvim-tree/renderer/decorator/init.lua b/lua/nvim-tree/renderer/decorator/init.lua index f2d047767b5..1b9c7f38d73 100644 --- a/lua/nvim-tree/renderer/decorator/init.lua +++ b/lua/nvim-tree/renderer/decorator/init.lua @@ -1,7 +1,8 @@ local HL_POSITION = require("nvim-tree.enum").HL_POSITION local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT ----@class Decorator +---@class (exact) Decorator +---@field protected explorer Explorer ---@field protected enabled boolean ---@field protected hl_pos HL_POSITION ---@field protected icon_placement ICON_PLACEMENT @@ -11,8 +12,8 @@ local Decorator = {} ---@return Decorator function Decorator:new(o) o = o or {} - setmetatable(o, self) - self.__index = self + + setmetatable(o, { __index = self }) return o end diff --git a/lua/nvim-tree/renderer/decorator/modified.lua b/lua/nvim-tree/renderer/decorator/modified.lua index 1ec546d1d65..e20433d75aa 100644 --- a/lua/nvim-tree/renderer/decorator/modified.lua +++ b/lua/nvim-tree/renderer/decorator/modified.lua @@ -5,14 +5,16 @@ local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT local Decorator = require "nvim-tree.renderer.decorator" ----@class DecoratorModified: Decorator +---@class (exact) DecoratorModified: Decorator ---@field icon HighlightedString|nil local DecoratorModified = Decorator:new() ---@param opts table +---@param explorer Explorer ---@return DecoratorModified -function DecoratorModified:new(opts) +function DecoratorModified:new(opts, explorer) local o = Decorator.new(self, { + explorer = explorer, enabled = opts.modified.enable, hl_pos = HL_POSITION[opts.renderer.highlight_modified] or HL_POSITION.none, icon_placement = ICON_PLACEMENT[opts.renderer.icons.modified_placement] or ICON_PLACEMENT.none, diff --git a/lua/nvim-tree/renderer/decorator/opened.lua b/lua/nvim-tree/renderer/decorator/opened.lua index 848faae42e6..9b3f2de87de 100644 --- a/lua/nvim-tree/renderer/decorator/opened.lua +++ b/lua/nvim-tree/renderer/decorator/opened.lua @@ -5,15 +5,17 @@ local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT local Decorator = require "nvim-tree.renderer.decorator" ----@class DecoratorOpened: Decorator +---@class (exact) DecoratorOpened: Decorator ---@field enabled boolean ---@field icon HighlightedString|nil local DecoratorOpened = Decorator:new() ---@param opts table +---@param explorer Explorer ---@return DecoratorOpened -function DecoratorOpened:new(opts) +function DecoratorOpened:new(opts, explorer) local o = Decorator.new(self, { + explorer = explorer, enabled = true, hl_pos = HL_POSITION[opts.renderer.highlight_opened_files] or HL_POSITION.none, icon_placement = ICON_PLACEMENT.none, From 8f6dcc0d0886b3b1db8c004b842afeed98db8cab Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 9 Sep 2024 13:56:38 +1000 Subject: [PATCH 03/16] refactor(#2875): multi instance renderer --- lua/nvim-tree/renderer/init.lua | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 3e0983ba3ed..2ab4c96f579 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -16,6 +16,20 @@ local namespace_highlights_id = vim.api.nvim_create_namespace "NvimTreeHighlight local namespace_extmarks_id = vim.api.nvim_create_namespace "NvimTreeExtmarks" local namespace_virtual_lines_id = vim.api.nvim_create_namespace "NvimTreeVirtualLines" +local function render_hl(bufnr, hl) + if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then + return + end + vim.api.nvim_buf_clear_namespace(bufnr, namespace_highlights_id, 0, -1) + for _, data in ipairs(hl) do + if type(data[1]) == "table" then + for _, group in ipairs(data[1]) do + vim.api.nvim_buf_add_highlight(bufnr, namespace_highlights_id, group, data[2], data[3], data[4]) + end + end + end +end + ---@param bufnr number ---@param lines string[] ---@param hl_args AddHighlightArgs[] @@ -28,7 +42,7 @@ local function _draw(bufnr, lines, hl_args, signs, extmarks, virtual_lines) end vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) - M.render_hl(bufnr, hl_args) + render_hl(bufnr, hl_args) if vim.fn.has "nvim-0.10" == 1 then vim.api.nvim_set_option_value("modifiable", false, { buf = bufnr }) @@ -62,20 +76,6 @@ local function _draw(bufnr, lines, hl_args, signs, extmarks, virtual_lines) end end -function M.render_hl(bufnr, hl) - if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then - return - end - vim.api.nvim_buf_clear_namespace(bufnr, namespace_highlights_id, 0, -1) - for _, data in ipairs(hl) do - if type(data[1]) == "table" then - for _, group in ipairs(data[1]) do - vim.api.nvim_buf_add_highlight(bufnr, namespace_highlights_id, group, data[2], data[3], data[4]) - end - end - end -end - function M.draw() local explorer = core.get_explorer() From fe1974c497bd45e5f74591bb3faa5d6910b37343 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 9 Sep 2024 16:25:37 +1000 Subject: [PATCH 04/16] refactor(#2875): multi instance renderer --- lua/nvim-tree.lua | 17 +++-- lua/nvim-tree/actions/finders/find-file.lua | 3 +- lua/nvim-tree/actions/fs/clipboard.lua | 7 +- lua/nvim-tree/actions/moves/parent.lua | 12 ++- lua/nvim-tree/actions/reloaders.lua | 73 +++++++++++++++++++ lua/nvim-tree/actions/root/change-dir.lua | 5 +- .../actions/tree/modifiers/collapse-all.lua | 3 +- .../actions/tree/modifiers/expand-all.lua | 8 +- lua/nvim-tree/diagnostics.lua | 6 +- lua/nvim-tree/explorer/init.lua | 18 +++-- lua/nvim-tree/explorer/live-filter.lua | 10 +-- lua/nvim-tree/explorer/watch.lua | 2 +- lua/nvim-tree/git/init.lua | 5 +- lua/nvim-tree/lib.lua | 31 ++++++-- lua/nvim-tree/marks/init.lua | 5 +- lua/nvim-tree/renderer/init.lua | 39 +++++++--- lua/nvim-tree/view.lua | 7 +- 17 files changed, 192 insertions(+), 59 deletions(-) create mode 100644 lua/nvim-tree/actions/reloaders.lua diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index aa48597d2c2..b1376fc19d3 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -1,7 +1,6 @@ local lib = require "nvim-tree.lib" local log = require "nvim-tree.log" local appearance = require "nvim-tree.appearance" -local renderer = require "nvim-tree.renderer" local view = require "nvim-tree.view" local commands = require "nvim-tree.commands" local utils = require "nvim-tree.utils" @@ -97,7 +96,11 @@ function M.tab_enter() end end view.open { focus_tree = false } - renderer.draw() + + local explorer = core.get_explorer() + if explorer then + explorer.renderer:draw() + end end end @@ -179,7 +182,11 @@ local function setup_autocommands(opts) callback = function() appearance.setup() view.reset_winhl() - renderer.draw() + + local explorer = core.get_explorer() + if explorer then + explorer.renderer:draw() + end end, }) @@ -217,7 +224,7 @@ local function setup_autocommands(opts) return end if - (explorer.filters.config.filter_no_buffer or renderer.config.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == "" + (explorer.filters.config.filter_no_buffer or explorer.opts.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == "" then utils.debounce("Buf:filter_buffer", opts.view.debounce_delay, function() explorer:reload_explorer() @@ -234,7 +241,7 @@ local function setup_autocommands(opts) return end if - (explorer.filters.config.filter_no_buffer or renderer.config.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == "" + (explorer.filters.config.filter_no_buffer or explorer.opts.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == "" then utils.debounce("Buf:filter_buffer", opts.view.debounce_delay, function() explorer:reload_explorer() diff --git a/lua/nvim-tree/actions/finders/find-file.lua b/lua/nvim-tree/actions/finders/find-file.lua index fcfd24941ff..7798de4b05b 100644 --- a/lua/nvim-tree/actions/finders/find-file.lua +++ b/lua/nvim-tree/actions/finders/find-file.lua @@ -1,7 +1,6 @@ local log = require "nvim-tree.log" local view = require "nvim-tree.view" local utils = require "nvim-tree.utils" -local renderer = require "nvim-tree.renderer" local core = require "nvim-tree.core" local Iterator = require "nvim-tree.iterators.node-iterator" @@ -76,7 +75,7 @@ function M.fn(path) :iterate() if found and view.is_visible() then - renderer.draw() + explorer.renderer:draw() view.set_cursor { line, 0 } end diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index fccb7c1159c..8ee7554a3f2 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -4,7 +4,6 @@ local utils = require "nvim-tree.utils" local core = require "nvim-tree.core" local events = require "nvim-tree.events" local notify = require "nvim-tree.notify" -local renderer = require "nvim-tree.renderer" local find_file = require("nvim-tree.actions.finders.find-file").fn @@ -193,7 +192,7 @@ function Clipboard:clear_clipboard() self.data[ACTION.copy] = {} self.data[ACTION.cut] = {} notify.info "Clipboard has been emptied." - renderer.draw() + self.explorer.renderer:draw() end ---Copy one node @@ -201,7 +200,7 @@ end function Clipboard:copy(node) utils.array_remove(self.data[ACTION.cut], node) toggle(node, self.data[ACTION.copy]) - renderer.draw() + self.explorer.renderer:draw() end ---Cut one node @@ -209,7 +208,7 @@ end function Clipboard:cut(node) utils.array_remove(self.data[ACTION.copy], node) toggle(node, self.data[ACTION.cut]) - renderer.draw() + self.explorer.renderer:draw() end ---Paste cut or cop diff --git a/lua/nvim-tree/actions/moves/parent.lua b/lua/nvim-tree/actions/moves/parent.lua index 598483eb120..c9367763dfe 100644 --- a/lua/nvim-tree/actions/moves/parent.lua +++ b/lua/nvim-tree/actions/moves/parent.lua @@ -1,4 +1,3 @@ -local renderer = require "nvim-tree.renderer" local view = require "nvim-tree.view" local utils = require "nvim-tree.utils" local core = require "nvim-tree.core" @@ -11,11 +10,16 @@ local M = {} function M.fn(should_close) should_close = should_close or false + local explorer = core.get_explorer() + return function(node) node = lib.get_last_group_node(node) if should_close and node.open then node.open = false - return renderer.draw() + if explorer then + explorer.renderer:draw() + end + return end local parent = utils.get_parent_of_group(node).parent @@ -31,7 +35,9 @@ function M.fn(should_close) view.set_cursor { line + 1, 0 } if should_close then parent.open = false - renderer.draw() + if explorer then + explorer.renderer:draw() + end end end end diff --git a/lua/nvim-tree/actions/reloaders.lua b/lua/nvim-tree/actions/reloaders.lua new file mode 100644 index 00000000000..bec976d9c67 --- /dev/null +++ b/lua/nvim-tree/actions/reloaders.lua @@ -0,0 +1,73 @@ +local git = require "nvim-tree.git" +local view = require "nvim-tree.view" +local core = require "nvim-tree.core" +local explorer_node = require "nvim-tree.explorer.node" +local Iterator = require "nvim-tree.iterators.node-iterator" + +local M = {} + +---@param explorer Explorer|nil +---@param projects table +local function refresh_nodes(explorer, projects) + Iterator.builder({ explorer }) + :applier(function(n) + if n.nodes then + local toplevel = git.get_toplevel(n.cwd or n.link_to or n.absolute_path) + if explorer then + explorer:reload(n, projects[toplevel] or {}) + end + end + end) + :recursor(function(n) + return n.group_next and { n.group_next } or (n.open and n.nodes) + end) + :iterate() +end + +---@param parent_node Node|nil +---@param projects table +function M.reload_node_status(parent_node, projects) + if parent_node == nil then + return + end + + local toplevel = git.get_toplevel(parent_node.absolute_path) + local status = projects[toplevel] or {} + for _, node in ipairs(parent_node.nodes) do + explorer_node.update_git_status(node, explorer_node.is_git_ignored(parent_node), status) + if node.nodes and #node.nodes > 0 then + M.reload_node_status(node, projects) + end + end +end + +local event_running = false +function M.reload_explorer() + local explorer = core.get_explorer() + if event_running or not explorer or vim.v.exiting ~= vim.NIL then + return + end + event_running = true + + local projects = git.reload() + refresh_nodes(explorer, projects) + if view.is_visible() then + explorer.renderer:draw() + end + event_running = false +end + +function M.reload_git() + local explorer = core.get_explorer() + if not explorer or not git.config.git.enable or event_running then + return + end + event_running = true + + local projects = git.reload() + M.reload_node_status(explorer, projects) + explorer.renderer:draw() + event_running = false +end + +return M diff --git a/lua/nvim-tree/actions/root/change-dir.lua b/lua/nvim-tree/actions/root/change-dir.lua index 954b2081ccf..8ba5763d151 100644 --- a/lua/nvim-tree/actions/root/change-dir.lua +++ b/lua/nvim-tree/actions/root/change-dir.lua @@ -91,7 +91,10 @@ M.force_dirchange = add_profiling_to(function(foldername, should_open_view) if should_open_view then require("nvim-tree.lib").open() else - require("nvim-tree.renderer").draw() + local explorer = core.get_explorer() + if explorer then + explorer.renderer:draw() + end end end) diff --git a/lua/nvim-tree/actions/tree/modifiers/collapse-all.lua b/lua/nvim-tree/actions/tree/modifiers/collapse-all.lua index c6add436f1e..e15f185ab69 100644 --- a/lua/nvim-tree/actions/tree/modifiers/collapse-all.lua +++ b/lua/nvim-tree/actions/tree/modifiers/collapse-all.lua @@ -1,4 +1,3 @@ -local renderer = require "nvim-tree.renderer" local utils = require "nvim-tree.utils" local core = require "nvim-tree.core" local lib = require "nvim-tree.lib" @@ -46,7 +45,7 @@ function M.fn(keep_buffers) end) :iterate() - renderer.draw() + explorer.renderer:draw() utils.focus_node_or_parent(node) end diff --git a/lua/nvim-tree/actions/tree/modifiers/expand-all.lua b/lua/nvim-tree/actions/tree/modifiers/expand-all.lua index 6af62e6ae49..22fe97cea97 100644 --- a/lua/nvim-tree/actions/tree/modifiers/expand-all.lua +++ b/lua/nvim-tree/actions/tree/modifiers/expand-all.lua @@ -1,5 +1,4 @@ local core = require "nvim-tree.core" -local renderer = require "nvim-tree.renderer" local Iterator = require "nvim-tree.iterators.node-iterator" local notify = require "nvim-tree.notify" local lib = require "nvim-tree.lib" @@ -65,11 +64,14 @@ end ---@param base_node table function M.fn(base_node) - local node = base_node.nodes and base_node or core.get_explorer() + local explorer = core.get_explorer() + local node = base_node.nodes and base_node or explorer if gen_iterator()(node) then notify.warn("expansion iteration was halted after " .. M.MAX_FOLDER_DISCOVERY .. " discovered folders") end - renderer.draw() + if explorer then + explorer.renderer:draw() + end end function M.setup(opts) diff --git a/lua/nvim-tree/diagnostics.lua b/lua/nvim-tree/diagnostics.lua index 7cfc585122c..4fa314d67ac 100644 --- a/lua/nvim-tree/diagnostics.lua +++ b/lua/nvim-tree/diagnostics.lua @@ -1,3 +1,4 @@ +local core = require "nvim-tree.core" local utils = require "nvim-tree.utils" local view = require "nvim-tree.view" local log = require "nvim-tree.log" @@ -165,7 +166,10 @@ function M.update() end log.profile_end(profile) if view.is_buf_valid(view.get_bufnr()) then - require("nvim-tree.renderer").draw() + local explorer = core.get_explorer() + if explorer then + explorer.renderer:draw() + end end end) end diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index 1b6b6d12b3a..e518ab2ef64 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -13,19 +13,26 @@ local NodeIterator = require "nvim-tree.iterators.node-iterator" local Watcher = require "nvim-tree.watcher" local Filters = require "nvim-tree.explorer.filters" -local Marks = {} -- circular dependencies +---@type Marks +local Marks -- circular dependencies local LiveFilter = require "nvim-tree.explorer.live-filter" local Sorters = require "nvim-tree.explorer.sorters" -local Clipboard = {} -- circular dependencies +---@type Clipboard +local Clipboard -- circular dependencies +---@type Renderer +local Renderer -- circular dependencies local FILTER_REASON = require("nvim-tree.enum").FILTER_REASON local config ---@class Explorer +---@field opts table user options ---@field absolute_path string ---@field nodes Node[] ---@field open boolean +---@field watcher Watcher|nil +---@field renderer Renderer ---@field filters Filters ---@field live_filter LiveFilter ---@field sorters Sorter @@ -48,17 +55,18 @@ function Explorer:new(path) return end - ---@class Explorer + ---@type Explorer local o = setmetatable({ + opts = config, absolute_path = path, nodes = {}, open = true, sorters = Sorters:new(config), }, Explorer) - setmetatable(o, self) - self.__index = self + setmetatable(o, { __index = self }) o.watcher = watch.create_watcher(o) + o.renderer = Renderer:new(o.opts, o) o.filters = Filters:new(config, o) o.live_filter = LiveFilter:new(config, o) o.marks = Marks:new(config, o) diff --git a/lua/nvim-tree/explorer/live-filter.lua b/lua/nvim-tree/explorer/live-filter.lua index ed9dd6c44ce..be2848969cc 100644 --- a/lua/nvim-tree/explorer/live-filter.lua +++ b/lua/nvim-tree/explorer/live-filter.lua @@ -23,10 +23,6 @@ function LiveFilter:new(opts, explorer) return o end -local function redraw() - require("nvim-tree.renderer").draw() -end - ---@param node_ Node|nil local function reset_filter(self, node_) node_ = node_ or self.explorer @@ -129,7 +125,7 @@ local function record_char(self) vim.schedule(function() self.filter = vim.api.nvim_buf_get_lines(overlay_bufnr, 0, -1, false)[1] self:apply_filter() - redraw() + self.explorer.renderer:draw() end) end @@ -199,7 +195,7 @@ function LiveFilter:start_filtering() view.View.live_filter.prev_focused_node = require("nvim-tree.lib").get_node_at_cursor() self.filter = self.filter or "" - redraw() + self.explorer.renderer:draw() local row = require("nvim-tree.core").get_nodes_starting_line() - 1 local col = #self.prefix > 0 and #self.prefix - 1 or 1 view.set_cursor { row, col } @@ -215,7 +211,7 @@ function LiveFilter:clear_filter() self.filter = nil reset_filter(self) - redraw() + self.explorer.renderer:draw() if node then utils.focus_file(node.absolute_path) diff --git a/lua/nvim-tree/explorer/watch.lua b/lua/nvim-tree/explorer/watch.lua index 90ccedb20de..ad7b9254f73 100644 --- a/lua/nvim-tree/explorer/watch.lua +++ b/lua/nvim-tree/explorer/watch.lua @@ -79,7 +79,7 @@ function M.create_watcher(node) local explorer = require("nvim-tree.core").get_explorer() if explorer then explorer:refresh_node(node, function() - require("nvim-tree.renderer").draw() + explorer.renderer:draw() end) end end) diff --git a/lua/nvim-tree/git/init.lua b/lua/nvim-tree/git/init.lua index 6c1dbc1b3a5..4889c12766f 100644 --- a/lua/nvim-tree/git/init.lua +++ b/lua/nvim-tree/git/init.lua @@ -216,7 +216,10 @@ local function reload_tree_at(toplevel) end) :iterate() - require("nvim-tree.renderer").draw() + local explorer = require("nvim-tree.core").get_explorer() + if explorer then + explorer.renderer:draw() + end end) end diff --git a/lua/nvim-tree/lib.lua b/lua/nvim-tree/lib.lua index 6efb42e4156..83c0b61268e 100644 --- a/lua/nvim-tree/lib.lua +++ b/lua/nvim-tree/lib.lua @@ -1,4 +1,3 @@ -local renderer = require "nvim-tree.renderer" local view = require "nvim-tree.view" local core = require "nvim-tree.core" local utils = require "nvim-tree.utils" @@ -150,13 +149,15 @@ end ---@param node Node function M.expand_or_collapse(node, toggle_group) + local explorer = core.get_explorer() + toggle_group = toggle_group or false if node.has_children then node.has_children = false end - if #node.nodes == 0 then - core.get_explorer():expand(node) + if #node.nodes == 0 and explorer then + explorer:expand(node) end local head_node = utils.get_parent_of_group(node) @@ -175,7 +176,9 @@ function M.expand_or_collapse(node, toggle_group) n.open = next_open end - renderer.draw() + if explorer then + explorer.renderer:draw() + end end function M.set_target_win() @@ -200,7 +203,11 @@ local function open_view_and_draw() local cwd = vim.fn.getcwd() view.open() handle_buf_cwd(cwd) - renderer.draw() + + local explorer = core.get_explorer() + if explorer then + explorer.renderer:draw() + end end local function should_hijack_current_buf() @@ -256,6 +263,8 @@ end function M.open(opts) opts = opts or {} + local explorer = core.get_explorer() + M.set_target_win() if not core.get_explorer() or opts.path then if opts.path then @@ -272,13 +281,19 @@ function M.open(opts) if should_hijack_current_buf() then view.close_this_tab_only() view.open_in_win() - renderer.draw() + if explorer then + explorer.renderer:draw() + end elseif opts.winid then view.open_in_win { hijack_current_buf = false, resize = false, winid = opts.winid } - renderer.draw() + if explorer then + explorer.renderer:draw() + end elseif opts.current_window then view.open_in_win { hijack_current_buf = false, resize = false } - renderer.draw() + if explorer then + explorer.renderer:draw() + end else open_view_and_draw() end diff --git a/lua/nvim-tree/marks/init.lua b/lua/nvim-tree/marks/init.lua index 85d87fdc2b2..32670e162f8 100644 --- a/lua/nvim-tree/marks/init.lua +++ b/lua/nvim-tree/marks/init.lua @@ -5,7 +5,6 @@ local notify = require "nvim-tree.notify" local open_file = require "nvim-tree.actions.node.open-file" local remove_file = require "nvim-tree.actions.fs.remove-file" local rename_file = require "nvim-tree.actions.fs.rename-file" -local renderer = require "nvim-tree.renderer" local trash = require "nvim-tree.actions.fs.trash" local utils = require "nvim-tree.utils" @@ -46,7 +45,7 @@ end ---@public function Marks:clear() self.marks = {} - renderer.draw() + self.explorer.renderer:draw() end ---@public @@ -62,7 +61,7 @@ function Marks:toggle(node) self.marks[node.absolute_path] = node end - renderer.draw() + self.explorer.renderer:draw() end ---Return node if marked diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 2ab4c96f579..6d552380a32 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -1,4 +1,3 @@ -local core = require "nvim-tree.core" local log = require "nvim-tree.log" local view = require "nvim-tree.view" local events = require "nvim-tree.events" @@ -8,14 +7,34 @@ local icon_component = require "nvim-tree.renderer.components.icons" local full_name = require "nvim-tree.renderer.components.full-name" local Builder = require "nvim-tree.renderer.builder" -local M = {} - local SIGN_GROUP = "NvimTreeRendererSigns" local namespace_highlights_id = vim.api.nvim_create_namespace "NvimTreeHighlights" local namespace_extmarks_id = vim.api.nvim_create_namespace "NvimTreeExtmarks" local namespace_virtual_lines_id = vim.api.nvim_create_namespace "NvimTreeVirtualLines" +---@class Renderer +---@field private opts table user options +---@field private explorer Explorer +---@field private builder Builder +local Renderer = {} + +---@param opts table user options +---@param explorer Explorer +---@return Renderer +function Renderer:new(opts, explorer) + ---@type Renderer + local o = { + opts = opts, + explorer = explorer, + builder = Builder:new(opts, explorer), + } + + setmetatable(o, { __index = self }) + + return o +end + local function render_hl(bufnr, hl) if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then return @@ -76,11 +95,9 @@ local function _draw(bufnr, lines, hl_args, signs, extmarks, virtual_lines) end end -function M.draw() - local explorer = core.get_explorer() - +function Renderer:draw() local bufnr = view.get_bufnr() - if not explorer or not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then + if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then return end @@ -89,7 +106,7 @@ function M.draw() local cursor = vim.api.nvim_win_get_cursor(view.get_winnr() or 0) icon_component.reset_config() - local builder = Builder:new(M.opts, explorer):build() + local builder = Builder:new(self.opts, self.explorer):build() _draw(bufnr, builder.lines, builder.hl_args, builder.signs, builder.extmarks, builder.virtual_lines) @@ -104,12 +121,10 @@ function M.draw() events._dispatch_on_tree_rendered(bufnr, view.get_winnr()) end -function M.setup(opts) - M.opts = opts - +function Renderer.setup(opts) _padding.setup(opts) full_name.setup(opts) icon_component.setup(opts) end -return M +return Renderer diff --git a/lua/nvim-tree/view.lua b/lua/nvim-tree/view.lua index f30eb2720a4..75f0d0c9e09 100644 --- a/lua/nvim-tree/view.lua +++ b/lua/nvim-tree/view.lua @@ -526,7 +526,12 @@ function M._prevent_buffer_override() vim.cmd "setlocal nowinfixwidth" vim.cmd "setlocal nowinfixheight" M.open { focus_tree = false } - require("nvim-tree.renderer").draw() + + local explorer = require("nvim-tree.core").get_explorer() + if explorer then + explorer.renderer:draw() + end + pcall(vim.api.nvim_win_close, curwin, { force = true }) -- to handle opening a file using :e when nvim-tree is on floating mode From 9add2e72a389cd57543222acfb424dab122b3794 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 9 Sep 2024 16:35:48 +1000 Subject: [PATCH 05/16] refactor(#2875): deal with some cyclic require --- lua/nvim-tree/core.lua | 3 +-- lua/nvim-tree/explorer/init.lua | 9 +++------ lua/nvim-tree/renderer/init.lua | 8 ++++---- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/lua/nvim-tree/core.lua b/lua/nvim-tree/core.lua index a255233dab3..186a8b17d77 100644 --- a/lua/nvim-tree/core.lua +++ b/lua/nvim-tree/core.lua @@ -1,5 +1,4 @@ local events = require "nvim-tree.events" -local explorer = require "nvim-tree.explorer" local view = require "nvim-tree.view" local log = require "nvim-tree.log" @@ -16,7 +15,7 @@ function M.init(foldername) if TreeExplorer then TreeExplorer:destroy() end - TreeExplorer = explorer:new(foldername) + TreeExplorer = require("nvim-tree.explorer"):new(foldername) if not first_init_done then events._dispatch_ready() first_init_done = true diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index e518ab2ef64..e28b6ace84b 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -13,14 +13,11 @@ local NodeIterator = require "nvim-tree.iterators.node-iterator" local Watcher = require "nvim-tree.watcher" local Filters = require "nvim-tree.explorer.filters" ----@type Marks -local Marks -- circular dependencies +local Marks = require "nvim-tree.marks" local LiveFilter = require "nvim-tree.explorer.live-filter" local Sorters = require "nvim-tree.explorer.sorters" ----@type Clipboard -local Clipboard -- circular dependencies ----@type Renderer -local Renderer -- circular dependencies +local Clipboard = require "nvim-tree.actions.fs.clipboard" +local Renderer = require "nvim-tree.renderer" local FILTER_REASON = require("nvim-tree.enum").FILTER_REASON diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 6d552380a32..0fbf72d1c4e 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -2,9 +2,8 @@ local log = require "nvim-tree.log" local view = require "nvim-tree.view" local events = require "nvim-tree.events" -local _padding = require "nvim-tree.renderer.components.padding" local icon_component = require "nvim-tree.renderer.components.icons" -local full_name = require "nvim-tree.renderer.components.full-name" + local Builder = require "nvim-tree.renderer.builder" local SIGN_GROUP = "NvimTreeRendererSigns" @@ -122,9 +121,10 @@ function Renderer:draw() end function Renderer.setup(opts) - _padding.setup(opts) - full_name.setup(opts) icon_component.setup(opts) + + require "nvim-tree.renderer.components.padding".setup(opts) + require "nvim-tree.renderer.components.full-name".setup(opts) end return Renderer From 9735e0094d6a9043d9beaa68eacb20e2b548835a Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 9 Sep 2024 16:51:38 +1000 Subject: [PATCH 06/16] refactor(#2875): multi instance renderer --- lua/nvim-tree.lua | 4 +++- lua/nvim-tree/renderer/init.lua | 9 +-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index b1376fc19d3..ca0ddaca2f7 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -858,7 +858,9 @@ function M.setup(conf) require("nvim-tree.git.utils").setup(opts) require("nvim-tree.view").setup(opts) require("nvim-tree.lib").setup(opts) - require("nvim-tree.renderer").setup(opts) + require("nvim-tree.renderer.components.padding").setup(opts) + require("nvim-tree.renderer.components.full-name").setup(opts) + require("nvim-tree.renderer.components.icons").setup(opts) require("nvim-tree.buffers").setup(opts) require("nvim-tree.help").setup(opts) require("nvim-tree.watcher").setup(opts) diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 0fbf72d1c4e..7c8022e7e44 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -12,7 +12,7 @@ local namespace_highlights_id = vim.api.nvim_create_namespace "NvimTreeHighlight local namespace_extmarks_id = vim.api.nvim_create_namespace "NvimTreeExtmarks" local namespace_virtual_lines_id = vim.api.nvim_create_namespace "NvimTreeVirtualLines" ----@class Renderer +---@class (exact) Renderer ---@field private opts table user options ---@field private explorer Explorer ---@field private builder Builder @@ -120,11 +120,4 @@ function Renderer:draw() events._dispatch_on_tree_rendered(bufnr, view.get_winnr()) end -function Renderer.setup(opts) - icon_component.setup(opts) - - require "nvim-tree.renderer.components.padding".setup(opts) - require "nvim-tree.renderer.components.full-name".setup(opts) -end - return Renderer From 2f404ec1598c531ffb95b2db9452860b2d530106 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sat, 14 Sep 2024 15:46:25 +1000 Subject: [PATCH 07/16] refactor(#2875): multi instance renderer --- lua/nvim-tree/explorer/init.lua | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index e28b6ace84b..70b86fe5c80 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -2,7 +2,6 @@ local builders = require "nvim-tree.explorer.node-builders" local git = require "nvim-tree.git" local log = require "nvim-tree.log" local notify = require "nvim-tree.notify" -local renderer = {} -- circular dependency, will become a member local utils = require "nvim-tree.utils" local view = require "nvim-tree.view" local watch = require "nvim-tree.explorer.watch" @@ -459,7 +458,7 @@ function Explorer:reload_explorer() local projects = git.reload() self:refresh_nodes(projects) if view.is_visible() then - renderer.draw() + self.renderer:draw() end event_running = false end @@ -472,7 +471,7 @@ function Explorer:reload_git() local projects = git.reload() explorer_node.reload_node_status(self, projects) - renderer.draw() + self.renderer:draw() event_running = false end @@ -481,8 +480,6 @@ function Explorer.setup(opts) require("nvim-tree.explorer.node").setup(opts) require("nvim-tree.explorer.watch").setup(opts) - renderer = require "nvim-tree.renderer" - Marks = require "nvim-tree.marks" Clipboard = require "nvim-tree.actions.fs.clipboard" end From 7212b4452a4bfb68b69fbc6779a7dec9ec7f9f12 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sat, 14 Sep 2024 15:48:24 +1000 Subject: [PATCH 08/16] refactor(#2875): multi instance renderer --- lua/nvim-tree/actions/reloaders.lua | 73 ----------------------------- 1 file changed, 73 deletions(-) delete mode 100644 lua/nvim-tree/actions/reloaders.lua diff --git a/lua/nvim-tree/actions/reloaders.lua b/lua/nvim-tree/actions/reloaders.lua deleted file mode 100644 index bec976d9c67..00000000000 --- a/lua/nvim-tree/actions/reloaders.lua +++ /dev/null @@ -1,73 +0,0 @@ -local git = require "nvim-tree.git" -local view = require "nvim-tree.view" -local core = require "nvim-tree.core" -local explorer_node = require "nvim-tree.explorer.node" -local Iterator = require "nvim-tree.iterators.node-iterator" - -local M = {} - ----@param explorer Explorer|nil ----@param projects table -local function refresh_nodes(explorer, projects) - Iterator.builder({ explorer }) - :applier(function(n) - if n.nodes then - local toplevel = git.get_toplevel(n.cwd or n.link_to or n.absolute_path) - if explorer then - explorer:reload(n, projects[toplevel] or {}) - end - end - end) - :recursor(function(n) - return n.group_next and { n.group_next } or (n.open and n.nodes) - end) - :iterate() -end - ----@param parent_node Node|nil ----@param projects table -function M.reload_node_status(parent_node, projects) - if parent_node == nil then - return - end - - local toplevel = git.get_toplevel(parent_node.absolute_path) - local status = projects[toplevel] or {} - for _, node in ipairs(parent_node.nodes) do - explorer_node.update_git_status(node, explorer_node.is_git_ignored(parent_node), status) - if node.nodes and #node.nodes > 0 then - M.reload_node_status(node, projects) - end - end -end - -local event_running = false -function M.reload_explorer() - local explorer = core.get_explorer() - if event_running or not explorer or vim.v.exiting ~= vim.NIL then - return - end - event_running = true - - local projects = git.reload() - refresh_nodes(explorer, projects) - if view.is_visible() then - explorer.renderer:draw() - end - event_running = false -end - -function M.reload_git() - local explorer = core.get_explorer() - if not explorer or not git.config.git.enable or event_running then - return - end - event_running = true - - local projects = git.reload() - M.reload_node_status(explorer, projects) - explorer.renderer:draw() - event_running = false -end - -return M From 001400806a95fcaa597d9ecb64d16516d53ce66b Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sat, 14 Sep 2024 15:56:31 +1000 Subject: [PATCH 09/16] refactor(#2875): multi instance renderer --- lua/nvim-tree/renderer/builder.lua | 85 +++++++++++++++--------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 7811db81135..040ebf1585c 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -50,47 +50,6 @@ local PICTURE_MAP = { ---@field private hidden_display fun(node: Node): string|nil local Builder = {} ----@param opts table ----@return fun(node: Node): string|nil -local setup_hidden_display_function = function(opts) - local hidden_display = opts.renderer.hidden_display - -- options are already validated, so ´hidden_display´ can ONLY be `string` or `function` if type(hidden_display) == "string" then - if type(hidden_display) == "string" then - if hidden_display == "none" then - return function() - return nil - end - elseif hidden_display == "simple" then - return function(hidden_stats) - return utils.default_format_hidden_count(hidden_stats, true) - end - else -- "all" - return function(hidden_stats) - return utils.default_format_hidden_count(hidden_stats, false) - end - end - else -- "function - return function(hidden_stats) - -- In case of missing field such as live_filter we zero it, otherwise keep field as is - hidden_stats = vim.tbl_deep_extend("force", { - live_filter = 0, - git = 0, - buf = 0, - dotfile = 0, - custom = 0, - bookmark = 0, - }, hidden_stats or {}) - - local ok, result = pcall(hidden_display, hidden_stats) - if not ok then - notify.warn "Problem occurred in the function ``opts.renderer.hidden_display`` see nvim-tree.renderer.hidden_display on :h nvim-tree" - return nil - end - return result - end - end -end - ---@param opts table user options ---@param explorer Explorer ---@return Builder @@ -120,7 +79,7 @@ function Builder:new(opts, explorer) DecoratorOpened:new(opts, explorer), DecoratorGit:new(opts, explorer), }, - hidden_display = setup_hidden_display_function(opts), + hidden_display = Builder:setup_hidden_display_function(opts), } setmetatable(o, { __index = self }) @@ -531,4 +490,46 @@ function Builder:build() return self end +---TODO refactor back to function; this was left here to reduce PR noise +---@param opts table +---@return fun(node: Node): string|nil +function Builder:setup_hidden_display_function(opts) + local hidden_display = opts.renderer.hidden_display + -- options are already validated, so ´hidden_display´ can ONLY be `string` or `function` if type(hidden_display) == "string" then + if type(hidden_display) == "string" then + if hidden_display == "none" then + return function() + return nil + end + elseif hidden_display == "simple" then + return function(hidden_stats) + return utils.default_format_hidden_count(hidden_stats, true) + end + else -- "all" + return function(hidden_stats) + return utils.default_format_hidden_count(hidden_stats, false) + end + end + else -- "function + return function(hidden_stats) + -- In case of missing field such as live_filter we zero it, otherwise keep field as is + hidden_stats = vim.tbl_deep_extend("force", { + live_filter = 0, + git = 0, + buf = 0, + dotfile = 0, + custom = 0, + bookmark = 0, + }, hidden_stats or {}) + + local ok, result = pcall(hidden_display, hidden_stats) + if not ok then + notify.warn "Problem occurred in the function ``opts.renderer.hidden_display`` see nvim-tree.renderer.hidden_display on :h nvim-tree" + return nil + end + return result + end + end +end + return Builder From c866a37e1c01c2eba17284a3faa76c64ef2619f8 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sat, 14 Sep 2024 16:00:26 +1000 Subject: [PATCH 10/16] refactor(#2875): multi instance renderer --- lua/nvim-tree/renderer/init.lua | 36 +++++++++++++++++---------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 7c8022e7e44..3d3aeabcb98 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -34,25 +34,12 @@ function Renderer:new(opts, explorer) return o end -local function render_hl(bufnr, hl) - if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then - return - end - vim.api.nvim_buf_clear_namespace(bufnr, namespace_highlights_id, 0, -1) - for _, data in ipairs(hl) do - if type(data[1]) == "table" then - for _, group in ipairs(data[1]) do - vim.api.nvim_buf_add_highlight(bufnr, namespace_highlights_id, group, data[2], data[3], data[4]) - end - end - end -end - +---@private ---@param bufnr number ---@param lines string[] ---@param hl_args AddHighlightArgs[] ---@param signs string[] -local function _draw(bufnr, lines, hl_args, signs, extmarks, virtual_lines) +function Renderer:_draw(bufnr, lines, hl_args, signs, extmarks, virtual_lines) if vim.fn.has "nvim-0.10" == 1 then vim.api.nvim_set_option_value("modifiable", true, { buf = bufnr }) else @@ -60,7 +47,7 @@ local function _draw(bufnr, lines, hl_args, signs, extmarks, virtual_lines) end vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) - render_hl(bufnr, hl_args) + self:render_hl(bufnr, hl_args) if vim.fn.has "nvim-0.10" == 1 then vim.api.nvim_set_option_value("modifiable", false, { buf = bufnr }) @@ -94,6 +81,21 @@ local function _draw(bufnr, lines, hl_args, signs, extmarks, virtual_lines) end end +---@private +function Renderer:render_hl(bufnr, hl) + if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then + return + end + vim.api.nvim_buf_clear_namespace(bufnr, namespace_highlights_id, 0, -1) + for _, data in ipairs(hl) do + if type(data[1]) == "table" then + for _, group in ipairs(data[1]) do + vim.api.nvim_buf_add_highlight(bufnr, namespace_highlights_id, group, data[2], data[3], data[4]) + end + end + end +end + function Renderer:draw() local bufnr = view.get_bufnr() if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then @@ -107,7 +109,7 @@ function Renderer:draw() local builder = Builder:new(self.opts, self.explorer):build() - _draw(bufnr, builder.lines, builder.hl_args, builder.signs, builder.extmarks, builder.virtual_lines) + self:_draw(bufnr, builder.lines, builder.hl_args, builder.signs, builder.extmarks, builder.virtual_lines) if cursor and #builder.lines >= cursor[1] then vim.api.nvim_win_set_cursor(view.get_winnr() or 0, cursor) From f5e795aca2437dd9af7840547f7de4896b28c199 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sat, 14 Sep 2024 16:10:31 +1000 Subject: [PATCH 11/16] refactor(#2875): multi instance renderer --- lua/nvim-tree/renderer/builder.lua | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 040ebf1585c..3dfb9c15b6d 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -1,4 +1,3 @@ -local core = require "nvim-tree.core" local notify = require "nvim-tree.notify" local utils = require "nvim-tree.utils" local view = require "nvim-tree.view" @@ -41,7 +40,6 @@ local PICTURE_MAP = { ---@field extmarks table[] extra marks for right icon placement ---@field virtual_lines table[] virtual lines for hidden count display ---@field private explorer Explorer ----@field private root_cwd string|nil absolute path ---@field private index number ---@field private depth number ---@field private combined_groups table combined group names @@ -58,7 +56,6 @@ function Builder:new(opts, explorer) local o = { opts = opts, explorer = explorer, - root_cwd = core.get_cwd(), index = 0, depth = 0, hl_args = {}, @@ -157,7 +154,7 @@ function Builder:build_folder(node) local foldername_hl = "NvimTreeFolderName" if node.link_to and self.opts.renderer.symlink_destination then local arrow = icons.i.symlink_arrow - local link_to = utils.path_relative(node.link_to, self.root_cwd) + local link_to = utils.path_relative(node.link_to, self.explorer.absolute_path) foldername = string.format("%s%s%s", foldername, arrow, link_to) foldername_hl = "NvimTreeSymlinkFolderName" elseif @@ -182,7 +179,7 @@ function Builder:build_symlink(node) local arrow = icons.i.symlink_arrow local symlink_formatted = node.name if self.opts.renderer.symlink_destination then - local link_to = utils.path_relative(node.link_to, self.root_cwd) + local link_to = utils.path_relative(node.link_to, self.explorer.absolute_path) symlink_formatted = string.format("%s%s%s", symlink_formatted, arrow, link_to) end @@ -406,8 +403,7 @@ end ---@private function Builder:get_nodes_number(nodes) - local explorer = core.get_explorer() - if not explorer or not explorer.live_filter.filter then + if not self.explorer.live_filter.filter then return #nodes end @@ -423,7 +419,7 @@ end ---@private function Builder:build_lines(node) if not node then - node = core.get_explorer() + node = self.explorer end local num_children = self:get_nodes_number(node.nodes) local idx = 1 @@ -442,28 +438,27 @@ end ---@return string function Builder:format_root_name(root_label) if type(root_label) == "function" then - local label = root_label(self.root_cwd) + local label = root_label(self.explorer.absolute_path) if type(label) == "string" then return label end elseif type(root_label) == "string" then - return utils.path_remove_trailing(vim.fn.fnamemodify(self.root_cwd, root_label)) + return utils.path_remove_trailing(vim.fn.fnamemodify(self.explorer.absolute_path, root_label)) end return "???" end ---@private function Builder:build_header() - local explorer = core.get_explorer() - if view.is_root_folder_visible(core.get_cwd()) then + if view.is_root_folder_visible(self.explorer.absolute_path) then local root_name = self:format_root_name(self.opts.renderer.root_folder_label) table.insert(self.lines, root_name) self:insert_highlight({ "NvimTreeRootFolder" }, 0, string.len(root_name)) self.index = 1 end - if explorer and explorer.live_filter.filter then - local filter_line = string.format("%s/%s/", self.opts.live_filter.prefix, explorer.live_filter.filter) + if self.explorer.live_filter.filter then + local filter_line = string.format("%s/%s/", self.opts.live_filter.prefix, self.explorer.live_filter.filter) table.insert(self.lines, filter_line) local prefix_length = string.len(self.opts.live_filter.prefix) self:insert_highlight({ "NvimTreeLiveFilterPrefix" }, 0, prefix_length) From 8ff10cec1e72b809057c33b99ca7fe360e90539a Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 15 Sep 2024 12:59:31 +1000 Subject: [PATCH 12/16] refactor(#2875): multi instance renderer --- lua/nvim-tree.lua | 4 +--- lua/nvim-tree/explorer/init.lua | 3 --- lua/nvim-tree/renderer/components/init.lua | 13 +++++++++++++ 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 lua/nvim-tree/renderer/components/init.lua diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index ca0ddaca2f7..4849f4adac8 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -858,9 +858,7 @@ function M.setup(conf) require("nvim-tree.git.utils").setup(opts) require("nvim-tree.view").setup(opts) require("nvim-tree.lib").setup(opts) - require("nvim-tree.renderer.components.padding").setup(opts) - require("nvim-tree.renderer.components.full-name").setup(opts) - require("nvim-tree.renderer.components.icons").setup(opts) + require("nvim-tree.renderer.components").setup(opts) require("nvim-tree.buffers").setup(opts) require("nvim-tree.help").setup(opts) require("nvim-tree.watcher").setup(opts) diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index 70b86fe5c80..412ce46fb56 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -479,9 +479,6 @@ function Explorer.setup(opts) config = opts require("nvim-tree.explorer.node").setup(opts) require("nvim-tree.explorer.watch").setup(opts) - - Marks = require "nvim-tree.marks" - Clipboard = require "nvim-tree.actions.fs.clipboard" end return Explorer diff --git a/lua/nvim-tree/renderer/components/init.lua b/lua/nvim-tree/renderer/components/init.lua new file mode 100644 index 00000000000..e964d0632aa --- /dev/null +++ b/lua/nvim-tree/renderer/components/init.lua @@ -0,0 +1,13 @@ +local M = {} + +M.padding = require "nvim-tree.renderer.components.padding" +M.full_name = require "nvim-tree.renderer.components.full-name" +M.icons = require "nvim-tree.renderer.components.icons" + +function M.setup(opts) + M.padding.setup(opts) + M.full_name.setup(opts) + M.icons.setup(opts) +end + +return M From fb01d1a1c2f17bd8aedc4f6358900e24f7881772 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 15 Sep 2024 13:04:01 +1000 Subject: [PATCH 13/16] refactor(#2875): multi instance renderer --- lua/nvim-tree.lua | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 4849f4adac8..06f8ab74afc 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -2,13 +2,9 @@ local lib = require "nvim-tree.lib" local log = require "nvim-tree.log" local appearance = require "nvim-tree.appearance" local view = require "nvim-tree.view" -local commands = require "nvim-tree.commands" local utils = require "nvim-tree.utils" local actions = require "nvim-tree.actions" -local legacy = require "nvim-tree.legacy" local core = require "nvim-tree.core" -local git = require "nvim-tree.git" -local buffers = require "nvim-tree.buffers" local notify = require "nvim-tree.notify" local _config = {} @@ -358,7 +354,7 @@ local function setup_autocommands(opts) create_nvim_tree_autocmd({ "BufModifiedSet", "BufWritePost" }, { callback = function() utils.debounce("Buf:modified", opts.view.debounce_delay, function() - buffers.reload_modified() + require("nvim-tree.buffers").reload_modified() local explorer = core.get_explorer() if explorer then explorer:reload_explorer() @@ -808,7 +804,7 @@ function M.purge_all_state() view.close_all_tabs() view.abandon_all_windows() if core.get_explorer() ~= nil then - git.purge_state() + require("nvim-tree.git").purge_state() core.reset_explorer() end end @@ -824,7 +820,7 @@ function M.setup(conf) localise_default_opts() - legacy.migrate_legacy_options(conf or {}) + require("nvim-tree.legacy").migrate_legacy_options(conf or {}) validate_options(conf) @@ -870,7 +866,7 @@ function M.setup(conf) if vim.g.NvimTreeSetup ~= 1 then -- first call to setup - commands.setup() + require("nvim-tree.commands").setup() else -- subsequent calls to setup M.purge_all_state() From f7e545a3ed6e32dbd429b2c546e48a52dd0e8dff Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 15 Sep 2024 13:09:41 +1000 Subject: [PATCH 14/16] refactor(#2875): multi instance renderer --- lua/nvim-tree/renderer/components/init.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lua/nvim-tree/renderer/components/init.lua b/lua/nvim-tree/renderer/components/init.lua index e964d0632aa..5cdf6b22a84 100644 --- a/lua/nvim-tree/renderer/components/init.lua +++ b/lua/nvim-tree/renderer/components/init.lua @@ -1,13 +1,15 @@ local M = {} -M.padding = require "nvim-tree.renderer.components.padding" +M.diagnostics = require "nvim-tree.renderer.components.diagnostics" M.full_name = require "nvim-tree.renderer.components.full-name" M.icons = require "nvim-tree.renderer.components.icons" +M.padding = require "nvim-tree.renderer.components.padding" function M.setup(opts) - M.padding.setup(opts) + M.diagnostics.setup(opts) M.full_name.setup(opts) M.icons.setup(opts) + M.padding.setup(opts) end return M From e332271799eaaac8ba560799d8d31f90fab7b63e Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 15 Sep 2024 13:15:11 +1000 Subject: [PATCH 15/16] refactor(#2875): multi instance renderer --- lua/nvim-tree/explorer/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index 412ce46fb56..b43e9761773 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -62,7 +62,7 @@ function Explorer:new(path) setmetatable(o, { __index = self }) o.watcher = watch.create_watcher(o) - o.renderer = Renderer:new(o.opts, o) + o.renderer = Renderer:new(config, o) o.filters = Filters:new(config, o) o.live_filter = LiveFilter:new(config, o) o.marks = Marks:new(config, o) From b1eb87020e15d6d3f82980926ed9d55fa15f307b Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Mon, 16 Sep 2024 14:06:14 +1000 Subject: [PATCH 16/16] refactor(#2875): multi instance renderer --- lua/nvim-tree/explorer/init.lua | 9 +++++---- lua/nvim-tree/renderer/builder.lua | 4 +++- lua/nvim-tree/renderer/decorator/init.lua | 4 +++- lua/nvim-tree/renderer/init.lua | 4 +++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index b43e9761773..0d44217b11e 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -51,15 +51,16 @@ function Explorer:new(path) return end - ---@type Explorer - local o = setmetatable({ + local o = { opts = config, absolute_path = path, nodes = {}, open = true, sorters = Sorters:new(config), - }, Explorer) - setmetatable(o, { __index = self }) + } + + setmetatable(o, self) + self.__index = self o.watcher = watch.create_watcher(o) o.renderer = Renderer:new(config, o) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index 3dfb9c15b6d..2cccec8d033 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -34,6 +34,7 @@ local PICTURE_MAP = { ---@field col_end number ---@class (exact) Builder +---@field private __index? table ---@field lines string[] includes icons etc. ---@field hl_args AddHighlightArgs[] line highlights ---@field signs string[] line signs @@ -79,7 +80,8 @@ function Builder:new(opts, explorer) hidden_display = Builder:setup_hidden_display_function(opts), } - setmetatable(o, { __index = self }) + setmetatable(o, self) + self.__index = self return o end diff --git a/lua/nvim-tree/renderer/decorator/init.lua b/lua/nvim-tree/renderer/decorator/init.lua index 1b9c7f38d73..92fcc579b38 100644 --- a/lua/nvim-tree/renderer/decorator/init.lua +++ b/lua/nvim-tree/renderer/decorator/init.lua @@ -2,6 +2,7 @@ local HL_POSITION = require("nvim-tree.enum").HL_POSITION local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT ---@class (exact) Decorator +---@field private __index? table ---@field protected explorer Explorer ---@field protected enabled boolean ---@field protected hl_pos HL_POSITION @@ -13,7 +14,8 @@ local Decorator = {} function Decorator:new(o) o = o or {} - setmetatable(o, { __index = self }) + setmetatable(o, self) + self.__index = self return o end diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 3d3aeabcb98..46e73186bc8 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -13,6 +13,7 @@ local namespace_extmarks_id = vim.api.nvim_create_namespace "NvimTreeExtmarks" local namespace_virtual_lines_id = vim.api.nvim_create_namespace "NvimTreeVirtualLines" ---@class (exact) Renderer +---@field private __index? table ---@field private opts table user options ---@field private explorer Explorer ---@field private builder Builder @@ -29,7 +30,8 @@ function Renderer:new(opts, explorer) builder = Builder:new(opts, explorer), } - setmetatable(o, { __index = self }) + setmetatable(o, self) + self.__index = self return o end