Skip to content

Commit 498641a

Browse files
committed
feat(#2826): allow only one window with nvim-tree buffer per tab
1 parent 0a7fcdf commit 498641a

File tree

1 file changed

+63
-25
lines changed

1 file changed

+63
-25
lines changed

lua/nvim-tree/explorer/view.lua

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,33 @@ local BUFFER_OPTIONS = {
7878
{ name = "swapfile", value = false },
7979
}
8080

81+
---@private
82+
---@param data table
83+
---@param bufnr integer
84+
function View:log_event(data, bufnr)
85+
log.line("dev", "View %s\
86+
bufnr = %s\
87+
vim.api.nvim_get_current_tabpage() = %s\
88+
vim.api.nvim_get_current_win() = %s\
89+
self.bufnr_by_tabid = %s\
90+
globals.BUFNR_BY_TABID = %s\
91+
globals.WINID_BY_TABID = %s\
92+
vim.fn.win_findbuf(bufnr) = %s\
93+
data = %s\
94+
vim.v.event = %s",
95+
data.event,
96+
bufnr,
97+
vim.api.nvim_get_current_tabpage(),
98+
vim.api.nvim_get_current_win(),
99+
vim.inspect(self.bufnr_by_tabid, { newline = "" }),
100+
vim.inspect(globals.BUFNR_BY_TABID, { newline = "" }),
101+
vim.inspect(globals.WINID_BY_TABID, { newline = "" }),
102+
vim.inspect(vim.fn.win_findbuf(bufnr), { newline = "" }),
103+
vim.inspect(data, { newline = "" }),
104+
vim.inspect(vim.v.event, { newline = "" })
105+
)
106+
end
107+
81108
---Buffer local autocommands to track state, deleted on buffer wipeout
82109
---@private
83110
---@param bufnr integer
@@ -88,26 +115,13 @@ function View:create_autocmds(bufnr)
88115
group = self.explorer.augroup_id,
89116
buffer = bufnr,
90117
callback = function(data)
91-
log.line("dev",
92-
"View BufWipeout\n bufnr = %s\n data.buf = %s\n self.bufnr_by_tabid = %s\n self.winid_by_tabid = %s",
93-
bufnr,
94-
data.buf,
95-
vim.inspect(self.bufnr_by_tabid, { newline = "" }),
96-
vim.inspect(self.winid_by_tabid, { newline = "" }),
97-
vim.inspect(data, { newline = "" })
98-
)
118+
self:log_event(data, bufnr)
99119

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

105-
-- clear the tab's window(s)
106-
local winids = vim.fn.win_findbuf(bufnr)
107-
self.winid_by_tabid = vim.tbl_map(function(winid)
108-
return not vim.tbl_contains(winids, winid) and winid or nil
109-
end, self.winid_by_tabid)
110-
111125
if self.explorer.opts.actions.open_file.eject then
112126
self:prevent_buffer_override()
113127
else
@@ -116,22 +130,46 @@ function View:create_autocmds(bufnr)
116130
end,
117131
})
118132

119-
-- set winid
120-
vim.api.nvim_create_autocmd("BufWinEnter", {
133+
-- close any other windows containing this buffer
134+
-- not fired when entering the first window, only subsequent event such as following a split
135+
-- does fire on :tabnew for _any_ buffer
136+
vim.api.nvim_create_autocmd("WinEnter", {
121137
group = self.explorer.augroup_id,
122138
buffer = bufnr,
123139
callback = function(data)
124-
local tabid = vim.api.nvim_get_current_tabpage()
140+
self:log_event(data, bufnr)
141+
142+
-- ignore other buffers
143+
if data.buf ~= bufnr then
144+
return
145+
end
146+
147+
-- ignore other tabs
148+
-- this event is fired on a a :tabnew window, even though the buffer isn't actually present
149+
local tabid_cur = vim.api.nvim_get_current_tabpage()
150+
if self.bufnr_by_tabid[tabid_cur] ~= bufnr then
151+
return
152+
end
153+
154+
-- are there any other windows containing bufnr?
155+
local winids_buf = vim.fn.win_findbuf(bufnr)
156+
if #winids_buf <= 1 then
157+
return
158+
end
159+
160+
-- close all other windows
161+
local winid_cur = vim.api.nvim_get_current_win()
162+
for _, winid in ipairs(winids_buf) do
163+
if winid ~= winid_cur then
164+
pcall(vim.api.nvim_win_close, winid, false)
165+
end
166+
end
125167

126-
log.line("dev",
127-
"View BufWinEnter\n bufnr = %s\n data.buf = %s\n self.bufnr_by_tabid = %s\n self.winid_by_tabid = %s",
128-
bufnr,
129-
data.buf,
130-
vim.inspect(self.bufnr_by_tabid, { newline = "" }),
131-
vim.inspect(self.winid_by_tabid, { newline = "" })
132-
)
168+
globals.WINID_BY_TABID[tabid_cur] = winid_cur
133169

134-
self.winid_by_tabid[tabid] = vim.fn.bufwinid(data.buf) -- first on current tabpage
170+
-- setup this window, it may be new e.g. split
171+
self:set_window_options_and_buffer()
172+
self:resize()
135173
end,
136174
})
137175
end

0 commit comments

Comments
 (0)