refactor(#2826): singleton View class, WIP

This commit is contained in:
Alexander Courtis 2025-04-20 13:54:37 +10:00
parent a3fe0c9007
commit 9d3d0d220f
15 changed files with 84 additions and 80 deletions

View File

@ -74,7 +74,7 @@ function M.change_root(path, bufnr)
end
function M.tab_enter()
if view.is_visible({ any_tabpage = true }) then
if view.View:is_visible({ any_tabpage = true }) then
local bufname = vim.api.nvim_buf_get_name(0)
local ft
@ -99,7 +99,7 @@ function M.tab_enter()
end
function M.open_on_directory()
local should_proceed = _config.hijack_directories.auto_open or view.is_visible()
local should_proceed = _config.hijack_directories.auto_open or view.View:is_visible()
if not should_proceed then
return
end
@ -160,7 +160,7 @@ local function setup_autocommands(opts)
if opts.actions.open_file.eject then
view._prevent_buffer_override()
else
view.abandon_current_window()
view.View:abandon_current_window()
end
end,
})
@ -687,7 +687,7 @@ end
function M.purge_all_state()
view.View:close_all_tabs()
view.abandon_all_windows()
view.View:abandon_all_windows()
local explorer = core.get_explorer()
if explorer then
require("nvim-tree.git").purge_state()

View File

@ -14,7 +14,7 @@ local running = {}
---@param path string relative or absolute
function M.fn(path)
local explorer = core.get_explorer()
if not explorer or not view.is_visible() then
if not explorer or not view.View:is_visible() then
return
end
@ -84,9 +84,9 @@ function M.fn(path)
end)
:iterate()
if found and view.is_visible() then
if found and view.View:is_visible() then
explorer.renderer:draw()
view.set_cursor({ line, 0 })
view.View:set_cursor({ line, 0 })
end
running[path_real] = false

View File

@ -67,9 +67,9 @@ local function move(explorer, where, what, skip_gitignored)
end
if nex then
view.set_cursor({ nex, 0 })
view.View:set_cursor({ nex, 0 })
elseif vim.o.wrapscan and first then
view.set_cursor({ first, 0 })
view.View:set_cursor({ first, 0 })
end
end
@ -189,13 +189,13 @@ local function move_prev_recursive(explorer, what, skip_gitignored)
-- 4.3)
if node_init.name == ".." then -- root node
view.set_cursor({ 1, 0 }) -- move to root node (position 1)
view.View:set_cursor({ 1, 0 }) -- move to root node (position 1)
else
local node_init_line = utils.find_node_line(node_init)
if node_init_line < 0 then
return
end
view.set_cursor({ node_init_line, 0 })
view.View:set_cursor({ node_init_line, 0 })
end
-- 4.4)

View File

@ -25,7 +25,7 @@ function M.fn(should_close)
local parent = (node:get_parent_of_group() or node).parent
if not parent or not parent.parent then
view.set_cursor({ 1, 0 })
view.View:set_cursor({ 1, 0 })
return
end
@ -33,7 +33,7 @@ function M.fn(should_close)
return n.absolute_path == parent.absolute_path
end)
view.set_cursor({ line + 1, 0 })
view.View:set_cursor({ line + 1, 0 })
if should_close then
parent.open = false
parent.explorer.renderer:draw()

View File

@ -373,7 +373,7 @@ local function is_already_loaded(filename)
end
local function edit_in_current_buf(filename)
require("nvim-tree.view").abandon_current_window()
require("nvim-tree.view").View:abandon_current_window()
if M.relative_path then
filename = utils.path_relative(filename, vim.fn.getcwd())
end
@ -419,7 +419,7 @@ function M.fn(mode, filename)
end
if M.resize_window then
view.resize()
view.View:resize()
end
if mode == "preview" or mode == "preview_no_picker" then

View File

@ -41,7 +41,7 @@ function M.fn(opts)
return
end
if view.is_visible() then
if view.View:is_visible() then
-- focus
if opts.focus then
lib.set_target_win()

View File

@ -23,7 +23,7 @@ function M.fn(opts)
opts.path = nil
end
if view.is_visible() then
if view.View:is_visible() then
-- focus
lib.set_target_win()
view.focus()

View File

@ -8,7 +8,7 @@ function M.fn(opts)
if opts == nil then
-- reset to config values
view.View:configure_width()
view.resize()
view.View:resize()
return
end
@ -17,7 +17,7 @@ function M.fn(opts)
if width_cfg ~= nil then
view.View:configure_width(width_cfg)
view.resize()
view.View:resize()
return
end
@ -28,7 +28,7 @@ function M.fn(opts)
local absolute = options.absolute
if type(absolute) == "number" then
view.resize(absolute)
view.View:resize(absolute)
return
end
@ -39,7 +39,7 @@ function M.fn(opts)
relative_size = "+" .. relative_size
end
view.resize(relative_size)
view.View:resize(relative_size)
return
end
end

View File

@ -40,7 +40,7 @@ function M.fn(opts, no_focus, cwd, bang)
opts.path = nil
end
if view.is_visible() then
if view.View:is_visible() then
-- close
view.View:close()
else

View File

@ -111,7 +111,7 @@ local CMDS = {
bar = true,
},
command = function(c)
view.resize(c.args)
view.View:resize(c.args)
end,
},
{

View File

@ -486,7 +486,7 @@ function Explorer:reload_explorer()
local projects = git.reload_all_projects()
self:refresh_nodes(projects)
if view.is_visible() then
if view.View:is_visible() then
self.renderer:draw()
end
event_running = false

View File

@ -204,7 +204,7 @@ function LiveFilter:start_filtering()
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 })
view.View:set_cursor({ row, col })
-- needs scheduling to let the cursor move before initializing the window
vim.schedule(function()
return create_overlay(self)

View File

@ -111,17 +111,17 @@ function M.open(opts)
if should_hijack_current_buf() then
view.View:close_this_tab_only()
view.open_in_win()
view.View:open_in_win()
if explorer then
explorer.renderer:draw()
end
elseif opts.winid then
view.open_in_win({ hijack_current_buf = false, resize = false, winid = opts.winid })
view.View:open_in_win({ hijack_current_buf = false, resize = false, winid = opts.winid })
if explorer then
explorer.renderer:draw()
end
elseif opts.current_window then
view.open_in_win({ hijack_current_buf = false, resize = false })
view.View:open_in_win({ hijack_current_buf = false, resize = false })
if explorer then
explorer.renderer:draw()
end

View File

@ -113,7 +113,7 @@ function Renderer:draw()
vim.api.nvim_win_set_cursor(view.get_winnr() or 0, cursor)
end
view.grow_from_content()
view.View:grow_from_content()
log.profile_end(profile)

View File

@ -114,6 +114,7 @@ local tabinitial = {
winnr = nil,
}
-- TODO member
local BUFNR_PER_TAB = {}
---@type { name: string, value: any }[]
@ -244,7 +245,7 @@ function View:open_window()
vim.api.nvim_open_win(0, true, self:open_win_config())
else
vim.api.nvim_command("vsp")
M.reposition_window()
self:reposition_window()
end
self:setup_tabpage(vim.api.nvim_get_current_tabpage())
self:set_window_options_and_buffer()
@ -286,13 +287,13 @@ end
---@param tabnr integer
function View:save_tab_state(tabnr)
local tabpage = tabnr or vim.api.nvim_get_current_tabpage()
M.View.cursors[tabpage] = vim.api.nvim_win_get_cursor(M.get_winnr(tabpage) or 0)
self.cursors[tabpage] = vim.api.nvim_win_get_cursor(M.get_winnr(tabpage) or 0)
end
---@private
---@param tabpage integer
function View:close_internal(tabpage)
if not M.is_visible({ tabpage = tabpage }) then
if not self:is_visible({ tabpage = tabpage }) then
return
end
self:save_tab_state(tabpage)
@ -329,7 +330,7 @@ end
---@param tabpage integer|nil
function View:close(tabpage)
if M.View.tab.sync.close then
if self.tab.sync.close then
self:close_all_tabs()
elseif tabpage then
self:close_internal(tabpage)
@ -340,7 +341,7 @@ end
---@param options table|nil
function View:open(options)
if M.is_visible() then
if self:is_visible() then
return
end
@ -348,7 +349,7 @@ function View:open(options)
self:create_buffer()
self:open_window()
M.resize()
self:resize()
local opts = options or { focus_tree = true }
if not opts.focus_tree then
@ -359,11 +360,12 @@ function View:open(options)
log.profile_end(profile)
end
local function grow()
---@private
function View:grow()
local starts_at = M.is_root_folder_visible(require("nvim-tree.core").get_cwd()) and 1 or 0
local lines = vim.api.nvim_buf_get_lines(M.get_bufnr(), starts_at, -1, false)
-- number of columns of right-padding to indicate end of path
local padding = M.View:get_size(M.View.padding)
local padding = self:get_size(self.padding)
-- account for sign/number columns etc.
local wininfo = vim.fn.getwininfo(M.get_winnr())
@ -371,14 +373,14 @@ local function grow()
padding = padding + wininfo[1].textoff
end
local resizing_width = M.View.initial_width - padding
local resizing_width = self.initial_width - padding
local max_width
-- maybe bound max
if M.View.max_width == -1 then
if self.max_width == -1 then
max_width = -1
else
max_width = M.View:get_width(M.View.max_width) - padding
max_width = self:get_width(self.max_width) - padding
end
local ns_id = vim.api.nvim_get_namespaces()["NvimTreeExtmarks"]
@ -397,23 +399,23 @@ local function grow()
if resizing_width < count then
resizing_width = count
end
if M.View.adaptive_size and max_width >= 0 and resizing_width >= max_width then
if self.adaptive_size and max_width >= 0 and resizing_width >= max_width then
resizing_width = max_width
break
end
end
M.resize(resizing_width + padding)
self:resize(resizing_width + padding)
end
function M.grow_from_content()
if M.View.adaptive_size then
grow()
function View:grow_from_content()
if self.adaptive_size then
self:grow()
end
end
---@param size string|number|nil
function M.resize(size)
if M.View.float.enable and not M.View.adaptive_size then
function View:resize(size)
if self.float.enable and not self.adaptive_size then
-- if the floating windows's adaptive size is not desired, then the
-- float size should be defined in view.float.open_win_config
return
@ -425,7 +427,7 @@ function M.resize(size)
size = tonumber(size)
if first_char == "+" or first_char == "-" then
size = M.View.width + size
size = self.width + size
end
end
@ -434,21 +436,21 @@ function M.resize(size)
end
if size then
M.View.width = size
M.View.height = size
self.width = size
self.height = size
end
if not M.is_visible() then
if not self:is_visible() then
return
end
local winnr = M.get_winnr() or 0
local new_size = M.View:get_width()
local new_size = self:get_width()
if new_size ~= vim.api.nvim_win_get_width(winnr) then
vim.api.nvim_win_set_width(winnr, new_size)
if not M.View.preserve_window_proportions then
if not self.preserve_window_proportions then
vim.cmd(":wincmd =")
end
end
@ -456,65 +458,67 @@ function M.resize(size)
events._dispatch_on_tree_resize(new_size)
end
function M.reposition_window()
local move_to = move_tbl[M.View.side]
---@private
function View:reposition_window()
local move_to = move_tbl[self.side]
vim.api.nvim_command("wincmd " .. move_to)
M.resize()
self:resize()
end
local function set_current_win()
---@private
function View:set_current_win()
local current_tab = vim.api.nvim_get_current_tabpage()
M.View.tabpages[current_tab].winnr = vim.api.nvim_get_current_win()
self.tabpages[current_tab].winnr = vim.api.nvim_get_current_win()
end
---Open the tree in the a window
---@param opts OpenInWinOpts|nil
function M.open_in_win(opts)
function View:open_in_win(opts)
opts = opts or { hijack_current_buf = true, resize = true }
if opts.winid and vim.api.nvim_win_is_valid(opts.winid) then
vim.api.nvim_set_current_win(opts.winid)
end
M.View:create_buffer(opts.hijack_current_buf and vim.api.nvim_get_current_buf())
M.View:setup_tabpage(vim.api.nvim_get_current_tabpage())
set_current_win()
M.View:set_window_options_and_buffer()
self:create_buffer(opts.hijack_current_buf and vim.api.nvim_get_current_buf())
self:setup_tabpage(vim.api.nvim_get_current_tabpage())
self:set_current_win()
self:set_window_options_and_buffer()
if opts.resize then
M.reposition_window()
M.resize()
self:reposition_window()
self:resize()
end
events._dispatch_on_tree_open()
end
function M.abandon_current_window()
function View:abandon_current_window()
local tab = vim.api.nvim_get_current_tabpage()
BUFNR_PER_TAB[tab] = nil
if M.View.tabpages[tab] then
M.View.tabpages[tab].winnr = nil
if self.tabpages[tab] then
self.tabpages[tab].winnr = nil
end
end
function M.abandon_all_windows()
function View:abandon_all_windows()
for tab, _ in pairs(vim.api.nvim_list_tabpages()) do
BUFNR_PER_TAB[tab] = nil
if M.View.tabpages[tab] then
M.View.tabpages[tab].winnr = nil
if self.tabpages[tab] then
self.tabpages[tab].winnr = nil
end
end
end
---@param opts table|nil
---@return boolean
function M.is_visible(opts)
function View:is_visible(opts)
if opts and opts.tabpage then
if M.View.tabpages[opts.tabpage] == nil then
if self.tabpages[opts.tabpage] == nil then
return false
end
local winnr = M.View.tabpages[opts.tabpage].winnr
local winnr = self.tabpages[opts.tabpage].winnr
return winnr and vim.api.nvim_win_is_valid(winnr)
end
if opts and opts.any_tabpage then
for _, v in pairs(M.View.tabpages) do
for _, v in pairs(self.tabpages) do
if v.winnr and vim.api.nvim_win_is_valid(v.winnr) then
return true
end
@ -526,8 +530,8 @@ function M.is_visible(opts)
end
---@param opts table|nil
function M.set_cursor(opts)
if M.is_visible() then
function View:set_cursor(opts)
if self:is_visible() then
pcall(vim.api.nvim_win_set_cursor, M.get_winnr(), opts)
end
end
@ -541,7 +545,7 @@ function M.focus(winnr, open_if_closed)
M.close()
M.View:open()
wnr = M.get_winnr()
elseif open_if_closed and not M.is_visible() then
elseif open_if_closed and not M.View:is_visible() then
M.View:open()
end
@ -558,7 +562,7 @@ function M.winid(opts)
if tabpage == 0 then
tabpage = vim.api.nvim_get_current_tabpage()
end
if M.is_visible({ tabpage = tabpage }) then
if M.View:is_visible({ tabpage = tabpage }) then
return M.get_winnr(tabpage)
else
return nil
@ -568,7 +572,7 @@ end
--- Restores the state of a NvimTree window if it was initialized before.
function M.restore_tab_state()
local tabpage = vim.api.nvim_get_current_tabpage()
M.set_cursor(M.View.cursors[tabpage])
M.View:set_cursor(M.View.cursors[tabpage])
end
--- Returns the window number for nvim-tree within the tabpage specified