mirror of
https://github.com/neovim/neovim.git
synced 2026-03-31 12:52:13 +00:00
fix(window): use real last buffer of closed window
Problem: close_buffer autocmds may switch buffers at the last moment when
closing a window, causing terminal_check_size to prefer the size of a closed
window, or TabClosed to set an old <abuf>.
Solution: use the actual last buffer, similar to what TabClosed did before.
NOTE: If buffer was unloaded/deleted (not wiped), then TabClosed's <abuf> may
not use it. (w_buffer = NULL) Maybe odd, but it's how it worked before anyhow.
Relies on close_buffer reliably setting w_buffer to NULL if freed, otherwise
buf_valid is better. Only concern I see is if the window wasn't in the window
list after closing the buffer (close_buffer won't set it to NULL then), but then
win_close{_othertab} should've returned earlier.
This commit is contained in:
@@ -2976,6 +2976,10 @@ int win_close(win_T *win, bool free_buf, bool force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// About to free the window. Remember its final buffer for terminal_check_size,
|
||||||
|
// which may have changed since the last set_bufref. (e.g: close_buffer autocmds)
|
||||||
|
set_bufref(&bufref, win->w_buffer);
|
||||||
|
|
||||||
// Free the memory used for the window and get the window that received
|
// Free the memory used for the window and get the window that received
|
||||||
// the screen space.
|
// the screen space.
|
||||||
int dir;
|
int dir;
|
||||||
@@ -3262,6 +3266,10 @@ bool win_close_othertab(win_T *win, int free_buf, tabpage_T *tp, bool force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// About to free the window. Remember its final buffer for terminal_check_size/TabClosed,
|
||||||
|
// which may have changed since the last set_bufref. (e.g: close_buffer autocmds)
|
||||||
|
set_bufref(&bufref, win->w_buffer);
|
||||||
|
|
||||||
// Free the memory used for the window.
|
// Free the memory used for the window.
|
||||||
int dir;
|
int dir;
|
||||||
win_free_mem(win, &dir, tp);
|
win_free_mem(win, &dir, tp);
|
||||||
|
|||||||
@@ -80,6 +80,20 @@ describe('TabClosed', function()
|
|||||||
]])
|
]])
|
||||||
eq(true, eval('nvim_buf_is_valid(g:buf)'))
|
eq(true, eval('nvim_buf_is_valid(g:buf)'))
|
||||||
eq(eval('g:buf'), tonumber(eval('g:abuf')))
|
eq(eval('g:buf'), tonumber(eval('g:abuf')))
|
||||||
|
|
||||||
|
exec([[
|
||||||
|
tabnew
|
||||||
|
let s:win = win_getid()
|
||||||
|
|
||||||
|
tabfirst
|
||||||
|
let g:buf = nvim_create_buf(1, 1)
|
||||||
|
au BufHidden * ++once call nvim_win_set_buf(s:win, g:buf)
|
||||||
|
au TabClosed * ++once let g:abuf = expand('<abuf>')
|
||||||
|
|
||||||
|
call nvim_win_close(s:win, 1)
|
||||||
|
]])
|
||||||
|
-- BufHidden switched buffers at the last moment; TabClosed's <abuf> should show that.
|
||||||
|
eq(eval('g:buf'), tonumber(eval('g:abuf')))
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -430,6 +430,8 @@ describe(':terminal window', function()
|
|||||||
[1] = { reverse = true },
|
[1] = { reverse = true },
|
||||||
[2] = { background = 225, foreground = Screen.colors.Gray0 },
|
[2] = { background = 225, foreground = Screen.colors.Gray0 },
|
||||||
[3] = { bold = true },
|
[3] = { bold = true },
|
||||||
|
[4] = { foreground = 12 },
|
||||||
|
[5] = { reverse = true, bold = true },
|
||||||
[17] = { background = 2, foreground = Screen.colors.Grey0 },
|
[17] = { background = 2, foreground = Screen.colors.Grey0 },
|
||||||
[18] = { background = 2, foreground = 8 },
|
[18] = { background = 2, foreground = 8 },
|
||||||
[19] = { underline = true, foreground = Screen.colors.Grey0, background = 7 },
|
[19] = { underline = true, foreground = Screen.colors.Grey0, background = 7 },
|
||||||
@@ -517,6 +519,53 @@ describe(':terminal window', function()
|
|||||||
{17:foo [-] }{18:foo [-] }|
|
{17:foo [-] }{18:foo [-] }|
|
||||||
{3:-- TERMINAL --} |
|
{3:-- TERMINAL --} |
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
-- Sizing logic should only consider the final buffer shown in a window, even if autocommands
|
||||||
|
-- changed it at the last moment.
|
||||||
|
exec_lua(function()
|
||||||
|
vim.g.fired = 0
|
||||||
|
vim.api.nvim_create_autocmd('BufHidden', {
|
||||||
|
callback = function(ev)
|
||||||
|
vim.api.nvim_win_set_buf(vim.fn.win_findbuf(ev.buf)[1], vim.fn.bufnr('foo'))
|
||||||
|
vim.g.fired = vim.g.fired + 1
|
||||||
|
return vim.g.fired == 2
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
command('botright new')
|
||||||
|
screen:expect([[
|
||||||
|
rows: 2, cols: 25 │rows: 5, cols: 50 |
|
||||||
|
│rows: 2, cols: 50 |
|
||||||
|
{18:foo [-] foo [-] }|
|
||||||
|
^ |
|
||||||
|
{4:~ }|
|
||||||
|
{5:[No Name] }|
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
command('quit')
|
||||||
|
eq(1, eval('g:fired'))
|
||||||
|
screen:expect([[
|
||||||
|
rows: 5, cols: 50 │rows: 5, cols: 25 |
|
||||||
|
rows: 5, cols: 25 │rows: 5, cols: 50 |
|
||||||
|
rows: 2, cols: 25 │rows: 2, cols: 50 |
|
||||||
|
rows: 5, cols: 25 │rows: 5, cols: 25 |
|
||||||
|
^ │rows: 5, cols: 40 |
|
||||||
|
{17:foo [-] }{18:foo [-] }|
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
-- Check it doesn't use the size of the closed window in the other tab page; size should only
|
||||||
|
-- change via the :wincmd below. Hide tabline so it doesn't affect sizes.
|
||||||
|
command('set showtabline=0 | tabnew | tabprevious | wincmd > | tabonly')
|
||||||
|
eq(2, eval('g:fired'))
|
||||||
|
screen:expect([[
|
||||||
|
rows: 5, cols: 25 │rows: 5, cols: 25 |
|
||||||
|
rows: 2, cols: 25 │rows: 5, cols: 50 |
|
||||||
|
rows: 5, cols: 25 │rows: 2, cols: 50 |
|
||||||
|
rows: 5, cols: 26 │rows: 5, cols: 25 |
|
||||||
|
^ │rows: 5, cols: 40 |
|
||||||
|
{17:foo [-] }{18:foo [-] }|
|
||||||
|
|
|
||||||
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('restores window options when switching terminals', function()
|
it('restores window options when switching terminals', function()
|
||||||
|
|||||||
Reference in New Issue
Block a user