@@ -16,12 +16,14 @@ local api, uv = vim.api, vim.uv
1616--- @field enter boolean
1717--- @field prev_win integer
1818--- @field is_backdrop boolean
19+ --- @field kind " float" | " tab" | " replace"
1920
2021--- @class feed.win
2122--- @field opts feed.win.Config
2223--- @field id number
2324--- @field win integer
2425--- @field buf integer
26+ --- @field prev_buf integer
2527--- @field keys table
2628--- @field open fun ( feed.win : self )
2729--- @field close fun ( feed.win : self )
@@ -38,6 +40,7 @@ function M.new(opts, enter)
3840 local width = opts .zen and Config .zen .width or vim .o .columns
3941 local height = opts .zen and vim .o .lines or vim .o .lines - (vim .o .cmdheight + 1 )
4042 opts = vim .tbl_deep_extend (" force" , {
43+ kind = " float" ,
4144 relative = " editor" ,
4245 height = height ,
4346 width = width ,
@@ -154,7 +157,18 @@ function M:show()
154157 end
155158 end
156159
157- self .win = api .nvim_open_win (self .buf , self .opts .enter , self :win_opts ())
160+ local kind = self .opts .kind
161+
162+ if kind == " float" then
163+ self .win = api .nvim_open_win (self .buf , self .opts .enter , self :win_opts ())
164+ elseif kind == " tab" then
165+ vim .cmd (" tab sb " .. self .buf )
166+ self .win = api .nvim_get_current_win ()
167+ elseif kind == " replace" then
168+ self .prev_buf = api .nvim_get_current_buf ()
169+ api .nvim_set_current_buf (self .buf )
170+ self .win = api .nvim_get_current_win ()
171+ end
158172
159173 ut .bo (self .buf , self .opts .bo )
160174 ut .wo (self .win , self .opts .wo )
@@ -221,42 +235,10 @@ function M:show()
221235 api .nvim_win_set_config (self .win , opts )
222236 end ,
223237 })
224-
225- -- swap buffers when opening a new buffer in the same window
226- api .nvim_create_autocmd (" BufWinEnter" , {
227- group = self .augroup ,
228- callback = function ()
229- -- window closes, so delete the autocmd
230- if not self :win_valid () then
231- return true
232- end
233-
234- local buf = api .nvim_win_get_buf (self .win )
235-
236- -- same buffer
237- if buf == self .buf then
238- return
239- end
240-
241- -- another buffer was opened in this window
242- -- find another window to swap with
243- for _ , win in ipairs (api .nvim_list_wins ()) do
244- if win ~= self .win and vim .bo [api .nvim_win_get_buf (win )].buftype == " " then
245- vim .schedule (function ()
246- api .nvim_win_set_buf (self .win , self .buf )
247- api .nvim_win_set_buf (win , buf )
248- api .nvim_set_current_win (win )
249- vim .cmd .stopinsert ()
250- end )
251- return
252- end
253- end
254- end ,
255- })
256238end
257239
258240function M :update ()
259- if self :valid () then
241+ if self :valid () and self . opts . kind == " float " then
260242 ut .bo (self .buf , self .opts .bo )
261243 ut .wo (self .win , self .opts .wo )
262244 local opts = self :win_opts ()
@@ -272,6 +254,14 @@ function M:update()
272254end
273255
274256function M :close ()
257+ if self .opts .kind == " replace" then
258+ api .nvim_buf_delete (self .buf , { force = true })
259+ if self .prev_buf then
260+ api .nvim_win_set_buf (self .win , self .prev_buf )
261+ end
262+ return
263+ end
264+
275265 local close = function (win , buf )
276266 if win and api .nvim_win_is_valid (win ) then
277267 api .nvim_win_close (win , true )
@@ -298,6 +288,40 @@ function M:close()
298288 end
299289end
300290
291+ --- @param fn fun ( ... ): any
292+ --- @param ...any
293+ --- @return boolean | any
294+ local function try (fn , ...)
295+ local ok , result = pcall (fn , ... )
296+ if not ok then
297+ require (" neogit.logger" ).error (result )
298+ return false
299+ else
300+ return result or true
301+ end
302+ end
303+
304+ --- Safely close a window
305+ --- @param winid integer
306+ --- @param force boolean
307+ local function safe_win_close (winid , force )
308+ local success = try (vim .api .nvim_win_close , winid , force )
309+ if not success then
310+ pcall (vim .cmd , " b#" )
311+ end
312+ end
313+
314+ function M :hide ()
315+ if self .opts .kind == " replace" then
316+ if self .prev_buf and api .nvim_buf_is_loaded (self .prev_buf ) then
317+ api .nvim_set_current_buf (self .prev_buf )
318+ self .prev_buf = nil
319+ end
320+ else
321+ safe_win_close (self .win , true )
322+ end
323+ end
324+
301325function M :buf_valid ()
302326 return self .buf and api .nvim_buf_is_valid (self .buf )
303327end
0 commit comments