Skip to content

refactor(#2826): View tracks winids and bufnrs via events, unused for now #3170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions lua/nvim-tree/explorer/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -165,22 +165,6 @@ function Explorer:create_autocmds()
end,
})

-- prevent new opened file from opening in the same window as nvim-tree
vim.api.nvim_create_autocmd("BufWipeout", {
group = self.augroup_id,
pattern = "NvimTree_*",
callback = function()
if not utils.is_nvim_tree_buf(0) then
return
end
if self.opts.actions.open_file.eject then
self.view:prevent_buffer_override()
else
self.view:abandon_current_window()
end
end,
})

vim.api.nvim_create_autocmd("BufEnter", {
group = self.augroup_id,
pattern = "NvimTree_*",
Expand Down
95 changes: 77 additions & 18 deletions lua/nvim-tree/explorer/view.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ local Class = require("nvim-tree.classic")
---@field private width (fun():integer)|integer|string
---@field private max_width integer
---@field private padding integer
-- TODO multi-instance remove or replace with single member
-- TODO multi-instance replace with single members
---@field private bufnr_by_tabid table<integer, integer>
---@field private winid_by_tabid table<integer, integer>
local View = Class:extend()

---@class View
Expand All @@ -33,13 +34,14 @@ local View = Class:extend()
function View:new(args)
args.explorer:log_new("View")

self.explorer = args.explorer
self.adaptive_size = false
self.side = (self.explorer.opts.view.side == "right") and "right" or "left"
self.live_filter = { prev_focused_node = nil, }
self.bufnr_by_tabid = {}
self.explorer = args.explorer
self.adaptive_size = false
self.side = (self.explorer.opts.view.side == "right") and "right" or "left"
self.live_filter = { prev_focused_node = nil, }
self.bufnr_by_tabid = {}
self.winid_by_tabid = {}

self.winopts = {
self.winopts = {
relativenumber = self.explorer.opts.view.relativenumber,
number = self.explorer.opts.view.number,
list = false,
Expand All @@ -60,10 +62,6 @@ function View:new(args)

self:configure_width(self.explorer.opts.view.width)
self.initial_width = self:get_width()

-- TODO multi-instance remove this; delete buffers rather than retaining them
local tabid = vim.api.nvim_get_current_tabpage()
self.bufnr_by_tabid[tabid] = globals.BUFNR_BY_TABID[tabid]
end

function View:destroy()
Expand All @@ -80,6 +78,64 @@ local BUFFER_OPTIONS = {
{ name = "swapfile", value = false },
}

---Buffer local autocommands to track state, deleted on buffer wipeout
---@private
---@param bufnr integer
function View:create_autocmds(bufnr)
-- clear bufnr and winid
-- eject buffer opened in the nvim-tree window and create a new buffer
vim.api.nvim_create_autocmd("BufWipeout", {
group = self.explorer.augroup_id,
buffer = bufnr,
callback = function(data)
log.line("dev",
"View BufWipeout\n bufnr = %s\n data.buf = %s\n self.bufnr_by_tabid = %s\n self.winid_by_tabid = %s",
bufnr,
data.buf,
vim.inspect(self.bufnr_by_tabid, { newline = "" }),
vim.inspect(self.winid_by_tabid, { newline = "" }),
vim.inspect(data, { newline = "" })
)

-- clear the tab's buffer
self.bufnr_by_tabid = vim.tbl_map(function(b)
return b ~= bufnr and b or nil
end, self.bufnr_by_tabid)

-- clear the tab's window(s)
local winids = vim.fn.win_findbuf(bufnr)
self.winid_by_tabid = vim.tbl_map(function(winid)
return not vim.tbl_contains(winids, winid) and winid or nil
end, self.winid_by_tabid)

if self.explorer.opts.actions.open_file.eject then
self:prevent_buffer_override()
else
self:abandon_current_window()
end
end,
})

-- set winid
vim.api.nvim_create_autocmd("BufWinEnter", {
group = self.explorer.augroup_id,
buffer = bufnr,
callback = function(data)
local tabid = vim.api.nvim_get_current_tabpage()

log.line("dev",
"View BufWinEnter\n bufnr = %s\n data.buf = %s\n self.bufnr_by_tabid = %s\n self.winid_by_tabid = %s",
bufnr,
data.buf,
vim.inspect(self.bufnr_by_tabid, { newline = "" }),
vim.inspect(self.winid_by_tabid, { newline = "" })
)

self.winid_by_tabid[tabid] = vim.fn.bufwinid(data.buf) -- first on current tabpage
end,
})
end

-- TODO multi-instance remove this; delete buffers rather than retaining them
---@private
---@param bufnr integer
Expand Down Expand Up @@ -112,16 +168,18 @@ function View:create_buffer(bufnr)

bufnr = bufnr or vim.api.nvim_create_buf(false, false)

-- set both bufnr registries
globals.BUFNR_BY_TABID[tabid] = bufnr
self.bufnr_by_tabid[tabid] = bufnr

globals.BUFNR_BY_TABID[tabid] = bufnr

vim.api.nvim_buf_set_name(bufnr, "NvimTree_" .. tabid)

for _, option in ipairs(BUFFER_OPTIONS) do
vim.api.nvim_set_option_value(option.name, option.value, { buf = bufnr })
end

self:create_autocmds(bufnr)

require("nvim-tree.keymap").on_attach(bufnr)

events._dispatch_tree_attached_post(bufnr)
Expand Down Expand Up @@ -158,7 +216,9 @@ local move_tbl = {

---@private
function View:set_window_options_and_buffer()
pcall(vim.api.nvim_command, "buffer " .. self:get_bufnr())
if not pcall(vim.api.nvim_command, "buffer " .. self:get_bufnr()) then
return
end

if vim.fn.has("nvim-0.10") == 1 then
local eventignore = vim.api.nvim_get_option_value("eventignore", {})
Expand Down Expand Up @@ -446,9 +506,7 @@ end
function View:abandon_current_window()
local tab = vim.api.nvim_get_current_tabpage()

-- reset both bufnr registries
globals.BUFNR_BY_TABID[tab] = nil
self.bufnr_by_tabid[tab] = nil

globals.WINID_BY_TABID[tab] = nil
end
Expand Down Expand Up @@ -532,7 +590,7 @@ end
---@param tabid number|nil (optional) the number of the chosen tabpage. Defaults to current tabpage.
---@return integer? winid
function View:winid(tabid)
local bufnr = self.bufnr_by_tabid[tabid]
local bufnr = globals.BUFNR_BY_TABID[tabid]

if bufnr then
for _, winid in pairs(vim.api.nvim_tabpage_list_wins(tabid or 0)) do
Expand All @@ -543,6 +601,7 @@ function View:winid(tabid)
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
---@param tabid number|nil (optional) the number of the chosen tabpage. Defaults to current tabpage.
---@return number|nil
Expand All @@ -556,7 +615,7 @@ end
function View:get_bufnr()
local tab = vim.api.nvim_get_current_tabpage()

return self.bufnr_by_tabid[tab]
return globals.BUFNR_BY_TABID[tab]
end

function View:prevent_buffer_override()
Expand Down
Loading