@@ -20,7 +20,6 @@ local Class = require("nvim-tree.classic")
20
20
--- @field private padding integer
21
21
-- TODO multi-instance replace with single members
22
22
--- @field private bufnr_by_tabid table<integer , integer>
23
- --- @field private winid_by_tabid table<integer , integer>
24
23
local View = Class :extend ()
25
24
26
25
--- @class View
@@ -39,7 +38,6 @@ function View:new(args)
39
38
self .side = (self .explorer .opts .view .side == " right" ) and " right" or " left"
40
39
self .live_filter = { prev_focused_node = nil , }
41
40
self .bufnr_by_tabid = {}
42
- self .winid_by_tabid = {}
43
41
44
42
self .winopts = {
45
43
relativenumber = self .explorer .opts .view .relativenumber ,
@@ -78,36 +76,49 @@ local BUFFER_OPTIONS = {
78
76
{ name = " swapfile" , value = false },
79
77
}
80
78
79
+ --- @private
80
+ --- @param data table
81
+ --- @param bufnr integer
82
+ function View :log_event (data , bufnr )
83
+ log .line (" dev" , " View %s\
84
+ bufnr = %s\
85
+ vim.api.nvim_get_current_tabpage() = %s\
86
+ vim.api.nvim_get_current_win() = %s\
87
+ self.bufnr_by_tabid = %s\
88
+ globals.BUFNR_BY_TABID = %s\
89
+ globals.WINID_BY_TABID = %s\
90
+ vim.fn.win_findbuf(bufnr) = %s\
91
+ data = %s\
92
+ vim.v.event = %s" ,
93
+ data .event ,
94
+ bufnr ,
95
+ vim .api .nvim_get_current_tabpage (),
96
+ vim .api .nvim_get_current_win (),
97
+ vim .inspect (self .bufnr_by_tabid , { newline = " " }),
98
+ vim .inspect (globals .BUFNR_BY_TABID , { newline = " " }),
99
+ vim .inspect (globals .WINID_BY_TABID , { newline = " " }),
100
+ vim .inspect (vim .fn .win_findbuf (bufnr ), { newline = " " }),
101
+ vim .inspect (data , { newline = " " }),
102
+ vim .inspect (vim .v .event , { newline = " " })
103
+ )
104
+ end
105
+
81
106
--- Buffer local autocommands to track state, deleted on buffer wipeout
82
107
--- @private
83
108
--- @param bufnr integer
84
109
function View :create_autocmds (bufnr )
85
- -- clear bufnr and winid
86
110
-- eject buffer opened in the nvim-tree window and create a new buffer
87
111
vim .api .nvim_create_autocmd (" BufWipeout" , {
88
112
group = self .explorer .augroup_id ,
89
113
buffer = bufnr ,
90
114
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
- )
115
+ self :log_event (data , bufnr )
99
116
100
117
-- clear the tab's buffer
101
118
self .bufnr_by_tabid = vim .tbl_map (function (b )
102
119
return b ~= bufnr and b or nil
103
120
end , self .bufnr_by_tabid )
104
121
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
-
111
122
if self .explorer .opts .actions .open_file .eject then
112
123
self :prevent_buffer_override ()
113
124
else
@@ -116,26 +127,59 @@ function View:create_autocmds(bufnr)
116
127
end ,
117
128
})
118
129
119
- -- set winid
120
- vim .api .nvim_create_autocmd (" BufWinEnter" , {
130
+ -- not fired when entering the first window, only subsequent event such as following a split
131
+ -- does fire on :tabnew for _any_ buffer
132
+ vim .api .nvim_create_autocmd (" WinEnter" , {
121
133
group = self .explorer .augroup_id ,
122
134
buffer = bufnr ,
123
135
callback = function (data )
124
- local tabid = vim . api . nvim_get_current_tabpage ( )
136
+ self : log_event ( data , bufnr )
125
137
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
- )
138
+ -- ignore other buffers
139
+ if data .buf ~= bufnr then
140
+ return
141
+ end
133
142
134
- self .winid_by_tabid [tabid ] = vim .fn .bufwinid (data .buf ) -- first on current tabpage
143
+ -- ignore other tabs
144
+ -- this event is fired on a a :tabnew window, even though the buffer isn't actually present
145
+ local tabid_cur = vim .api .nvim_get_current_tabpage ()
146
+ if self .bufnr_by_tabid [tabid_cur ] ~= bufnr then
147
+ return
148
+ end
149
+
150
+ -- close other windows in this tab
151
+ self :close_other_windows (bufnr )
135
152
end ,
136
153
})
137
154
end
138
155
156
+ --- Close any other windows containing this buffer and setup current window
157
+ --- Feature gated behind experimental.close_other_windows_in_tab
158
+ --- @param bufnr integer
159
+ function View :close_other_windows (bufnr )
160
+ if not self .explorer .opts .experimental .close_other_windows_in_tab then
161
+ return
162
+ end
163
+
164
+ -- are there any other windows containing bufnr?
165
+ local winids_buf = vim .fn .win_findbuf (bufnr )
166
+ if # winids_buf <= 1 then
167
+ return
168
+ end
169
+
170
+ -- close all other windows
171
+ local winid_cur = vim .api .nvim_get_current_win ()
172
+ for _ , winid in ipairs (winids_buf ) do
173
+ if winid ~= winid_cur then
174
+ pcall (vim .api .nvim_win_close , winid , false )
175
+ end
176
+ end
177
+
178
+ -- setup current window, it may be new e.g. split
179
+ self :set_window_options_and_buffer ()
180
+ self :resize ()
181
+ end
182
+
139
183
-- TODO multi-instance remove this; delete buffers rather than retaining them
140
184
--- @private
141
185
--- @param bufnr integer
0 commit comments