refactor(#2826): add View.bufnr and use for all public methods

This commit is contained in:
Alexander Courtis 2025-07-28 17:16:36 +10:00
parent a9156c0139
commit 6702bc5fa0
3 changed files with 64 additions and 52 deletions

View File

@ -21,9 +21,7 @@ end
---@return table with valid win_ids ---@return table with valid win_ids
local function usable_win_ids() local function usable_win_ids()
local explorer = core.get_explorer() local explorer = core.get_explorer()
local tabpage = vim.api.nvim_get_current_tabpage() local tree_winid = explorer and explorer.view:get_winid()
local win_ids = vim.api.nvim_tabpage_list_wins(tabpage)
local tree_winid = explorer and explorer.view:get_winid(tabpage)
return vim.tbl_filter(function(id) return vim.tbl_filter(function(id)
local bufid = vim.api.nvim_win_get_buf(id) local bufid = vim.api.nvim_win_get_buf(id)
@ -47,7 +45,7 @@ local function usable_win_ids()
and not win_config.hide and not win_config.hide
and not win_config.external and not win_config.external
or false or false
end, win_ids) end, vim.api.nvim_tabpage_list_wins(0))
end end
---Get user to pick a window in the tab that is not NvimTree. ---Get user to pick a window in the tab that is not NvimTree.

View File

@ -12,6 +12,7 @@ local Class = require("nvim-tree.classic")
---@field live_filter table ---@field live_filter table
---@field side string ---@field side string
---@field private explorer Explorer ---@field private explorer Explorer
---@field private bufnr integer?
---@field private adaptive_size boolean ---@field private adaptive_size boolean
---@field private winopts table ---@field private winopts table
---@field private initial_width integer ---@field private initial_width integer
@ -80,51 +81,29 @@ local BUFFER_OPTIONS = {
{ name = "swapfile", value = false }, { name = "swapfile", value = false },
} }
-- TODO multi-instance remove this; delete buffers rather than retaining them
---@private
---@param bufnr integer
---@return boolean
function View:matches_bufnr(bufnr)
for _, b in pairs(globals.BUFNR_BY_TABID) do
if b == bufnr then
return true
end
end
return false
end
-- TODO multi-instance remove this; delete buffers rather than retaining them
---@private
function View:wipe_rogue_buffer()
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
if not self:matches_bufnr(bufnr) and utils.is_nvim_tree_buf(bufnr) then
pcall(vim.api.nvim_buf_delete, bufnr, { force = true })
end
end
end
---@private ---@private
---@param bufnr integer|false|nil ---@param bufnr integer|false|nil
function View:create_buffer(bufnr) function View:create_buffer(bufnr)
self:wipe_rogue_buffer() -- maybe wipe existing
pcall(vim.api.nvim_buf_delete, self.bufnr, { force = true })
local tabid = vim.api.nvim_get_current_tabpage() local tabid = vim.api.nvim_get_current_tabpage()
bufnr = bufnr or vim.api.nvim_create_buf(false, false) self.bufnr = bufnr or vim.api.nvim_create_buf(false, false)
-- set both bufnr registries -- set both bufnr registries
globals.BUFNR_BY_TABID[tabid] = bufnr globals.BUFNR_BY_TABID[tabid] = self.bufnr
self.bufnr_by_tabid[tabid] = bufnr self.bufnr_by_tabid[tabid] = self.bufnr
vim.api.nvim_buf_set_name(bufnr, "NvimTree_" .. tabid) vim.api.nvim_buf_set_name(self.bufnr, "NvimTree_" .. tabid)
for _, option in ipairs(BUFFER_OPTIONS) do for _, option in ipairs(BUFFER_OPTIONS) do
vim.api.nvim_set_option_value(option.name, option.value, { buf = bufnr }) vim.api.nvim_set_option_value(option.name, option.value, { buf = self.bufnr })
end end
require("nvim-tree.keymap").on_attach(bufnr) require("nvim-tree.keymap").on_attach(self.bufnr)
events._dispatch_tree_attached_post(bufnr) events._dispatch_tree_attached_post(self.bufnr)
end end
---@private ---@private
@ -158,7 +137,7 @@ local move_tbl = {
---@private ---@private
function View:set_window_options_and_buffer() function View:set_window_options_and_buffer()
pcall(vim.api.nvim_command, "buffer " .. self:get_bufnr()) pcall(vim.api.nvim_command, "buffer " .. self:get_bufnr_internal())
if vim.fn.has("nvim-0.10") == 1 then if vim.fn.has("nvim-0.10") == 1 then
local eventignore = vim.api.nvim_get_option_value("eventignore", {}) local eventignore = vim.api.nvim_get_option_value("eventignore", {})
@ -241,7 +220,7 @@ end
---@param tabid integer ---@param tabid integer
function View:save_state(tabid) function View:save_state(tabid)
tabid = tabid or vim.api.nvim_get_current_tabpage() tabid = tabid or vim.api.nvim_get_current_tabpage()
globals.CURSORS[tabid] = vim.api.nvim_win_get_cursor(self:get_winid(tabid) or 0) globals.CURSORS[tabid] = vim.api.nvim_win_get_cursor(self:get_winid_internal(tabid) or 0)
end end
---@private ---@private
@ -252,7 +231,7 @@ function View:close_internal(tabid)
end end
self:save_state(tabid) self:save_state(tabid)
switch_buf_if_last_buf() switch_buf_if_last_buf()
local tree_win = self:get_winid(tabid) local tree_win = self:get_winid_internal(tabid)
local current_win = vim.api.nvim_get_current_win() local current_win = vim.api.nvim_get_current_win()
for _, win in pairs(vim.api.nvim_tabpage_list_wins(tabid)) do for _, win in pairs(vim.api.nvim_tabpage_list_wins(tabid)) do
if vim.api.nvim_win_get_config(win).relative == "" then if vim.api.nvim_win_get_config(win).relative == "" then
@ -319,12 +298,12 @@ end
---@private ---@private
function View:grow() function View:grow()
local starts_at = self:is_root_folder_visible(require("nvim-tree.core").get_cwd()) and 1 or 0 local starts_at = self:is_root_folder_visible(require("nvim-tree.core").get_cwd()) and 1 or 0
local lines = vim.api.nvim_buf_get_lines(self:get_bufnr(), starts_at, -1, false) local lines = vim.api.nvim_buf_get_lines(self:get_bufnr_internal(), starts_at, -1, false)
-- number of columns of right-padding to indicate end of path -- number of columns of right-padding to indicate end of path
local padding = self:get_size(self.padding) local padding = self:get_size(self.padding)
-- account for sign/number columns etc. -- account for sign/number columns etc.
local wininfo = vim.fn.getwininfo(self:get_winid()) local wininfo = vim.fn.getwininfo(self:get_winid_internal())
if type(wininfo) == "table" and type(wininfo[1]) == "table" then if type(wininfo) == "table" and type(wininfo[1]) == "table" then
padding = padding + wininfo[1].textoff padding = padding + wininfo[1].textoff
end end
@ -343,7 +322,7 @@ function View:grow()
for line_nr, l in pairs(lines) do for line_nr, l in pairs(lines) do
local count = vim.fn.strchars(l) local count = vim.fn.strchars(l)
-- also add space for right-aligned icons -- also add space for right-aligned icons
local extmarks = vim.api.nvim_buf_get_extmarks(self:get_bufnr(), ns_id, { line_nr, 0 }, { line_nr, -1 }, { details = true }) local extmarks = vim.api.nvim_buf_get_extmarks(self:get_bufnr_internal(), ns_id, { line_nr, 0 }, { line_nr, -1 }, { details = true })
count = count + utils.extmarks_length(extmarks) count = count + utils.extmarks_length(extmarks)
if resizing_width < count then if resizing_width < count then
resizing_width = count resizing_width = count
@ -392,7 +371,7 @@ function View:resize(size)
return return
end end
local winid = self:get_winid() or 0 local winid = self:get_winid_internal() or 0
local new_size = self:get_width() local new_size = self:get_width()
@ -444,6 +423,8 @@ function View:open_in_win(opts)
end end
function View:abandon_current_window() function View:abandon_current_window()
self.bufnr = nil
local tab = vim.api.nvim_get_current_tabpage() local tab = vim.api.nvim_get_current_tabpage()
-- reset both bufnr registries -- reset both bufnr registries
@ -479,26 +460,26 @@ function View:is_visible(opts)
return false return false
end end
local winid = self:get_winid() local winid = self:get_winid_internal()
return winid ~= nil and vim.api.nvim_win_is_valid(winid or 0) return winid ~= nil and vim.api.nvim_win_is_valid(winid or 0)
end end
---@param opts table|nil ---@param opts table|nil
function View:set_cursor(opts) function View:set_cursor(opts)
if self:is_visible() then if self:is_visible() then
pcall(vim.api.nvim_win_set_cursor, self:get_winid(), opts) pcall(vim.api.nvim_win_set_cursor, self:get_winid_internal(), opts)
end end
end end
---@param winid number|nil ---@param winid number|nil
---@param open_if_closed boolean|nil ---@param open_if_closed boolean|nil
function View:focus(winid, open_if_closed) function View:focus(winid, open_if_closed)
local wid = winid or self:get_winid(nil) local wid = winid or self:get_winid_internal(nil)
if vim.api.nvim_win_get_tabpage(wid or 0) ~= vim.api.nvim_win_get_tabpage(0) then if vim.api.nvim_win_get_tabpage(wid or 0) ~= vim.api.nvim_win_get_tabpage(0) then
self:close() self:close()
self:open() self:open()
wid = self:get_winid(nil) wid = self:get_winid_internal(nil)
elseif open_if_closed and not self:is_visible() then elseif open_if_closed and not self:is_visible() then
self:open() self:open()
end end
@ -517,7 +498,7 @@ function View:api_winid(opts)
tabpage = vim.api.nvim_get_current_tabpage() tabpage = vim.api.nvim_get_current_tabpage()
end end
if self:is_visible({ tabpage = tabpage }) then if self:is_visible({ tabpage = tabpage }) then
return self:get_winid(tabpage) return self:get_winid_internal(tabpage)
else else
return nil return nil
end end
@ -543,25 +524,41 @@ function View:winid(tabid)
end end
end end
--- TODO this needs to be refactored away; it's private now to contain it
--- Returns the window number for nvim-tree within the tabpage specified --- Returns the window number for nvim-tree within the tabpage specified
---@private
---@param tabid number|nil (optional) the number of the chosen tabpage. Defaults to current tabpage. ---@param tabid number|nil (optional) the number of the chosen tabpage. Defaults to current tabpage.
---@return number|nil ---@return number|nil
function View:get_winid(tabid) function View:get_winid_internal(tabid)
tabid = tabid or vim.api.nvim_get_current_tabpage() tabid = tabid or vim.api.nvim_get_current_tabpage()
return self:winid(tabid) return self:winid(tabid)
end end
---first window containing this view's buffer
---@return integer? winid
function View:get_winid()
return utils.first_window_containing_buf(self.bufnr)
end
--- TODO this needs to be refactored away; it's private now to contain it
--- Returns the current nvim tree bufnr --- Returns the current nvim tree bufnr
---@private
---@return number ---@return number
function View:get_bufnr() function View:get_bufnr_internal()
local tab = vim.api.nvim_get_current_tabpage() local tab = vim.api.nvim_get_current_tabpage()
return self.bufnr_by_tabid[tab] return self.bufnr_by_tabid[tab]
end end
---buffer for this view
---@return integer?
function View:get_bufnr()
return self.bufnr
end
function View:prevent_buffer_override() function View:prevent_buffer_override()
local view_winid = self:get_winid() local view_winid = self:get_winid_internal()
local view_bufnr = self:get_bufnr() local view_bufnr = self:get_bufnr_internal()
-- need to schedule to let the new buffer populate the window -- need to schedule to let the new buffer populate the window
-- because this event needs to be run on bufWipeout. -- because this event needs to be run on bufWipeout.
@ -615,7 +612,7 @@ end
-- used on ColorScheme event -- used on ColorScheme event
function View:reset_winhl() function View:reset_winhl()
local winid = self:get_winid() local winid = self:get_winid_internal()
if winid and vim.api.nvim_win_is_valid(winid) then if winid and vim.api.nvim_win_is_valid(winid) then
vim.wo[winid].winhl = appearance.WIN_HL vim.wo[winid].winhl = appearance.WIN_HL
end end

View File

@ -649,6 +649,23 @@ function M.is_nvim_tree_buf(bufnr)
return false return false
end end
---First window that contains a buffer
---@param bufnr integer?
---@return integer? winid
function M.first_window_containing_buf(bufnr)
if not bufnr then
return nil
end
for _, winid in pairs(vim.api.nvim_list_wins()) do
if vim.api.nvim_win_get_buf(winid) == bufnr then
return winid
end
end
return nil
end
--- path is an executable file or directory --- path is an executable file or directory
---@param absolute_path string ---@param absolute_path string
---@return boolean ---@return boolean