fix(window): style=minimal window loses local options when switching buffers #38138

Problem: 5943a81 skips saving window options in `buflist_altfpos` for
style=minimal windows, which also prevents the window from restoring its own
options when switching buffers.

Solution: revert the change. In `get_winopts`, don't restore options from the
`WinInfo` of style=minimal windows when reusing values for a different window.
In `win_free`, clear `wi_optset` for minimal windows.
This commit is contained in:
glepnir
2026-03-03 19:51:58 +08:00
committed by GitHub
parent b23d00ce99
commit 84d84e9b5b
3 changed files with 35 additions and 5 deletions

View File

@@ -599,7 +599,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
}
buflist_setfpos(buf, win,
win->w_cursor.lnum == 1 ? 0 : win->w_cursor.lnum,
win->w_cursor.col, win->w_config.style != kWinStyleMinimal);
win->w_cursor.col, true);
}
bufref_T bufref;
@@ -2856,13 +2856,16 @@ void get_winopts(buf_T *buf)
WinInfo *const wip = find_wininfo(buf, true, true);
if (wip != NULL && wip->wi_win != curwin && wip->wi_win != NULL
&& wip->wi_win->w_buffer == buf) {
&& wip->wi_win->w_buffer == buf
&& wip->wi_win->w_config.style != kWinStyleMinimal) {
win_T *wp = wip->wi_win;
copy_winopt(&wp->w_onebuf_opt, &curwin->w_onebuf_opt);
curwin->w_fold_manual = wp->w_fold_manual;
curwin->w_foldinvalid = true;
cloneFoldGrowArray(&wp->w_folds, &curwin->w_folds);
} else if (wip != NULL && wip->wi_optset) {
} else if (wip != NULL && wip->wi_optset
&& (wip->wi_win == NULL || wip->wi_win == curwin
|| wip->wi_win->w_config.style != kWinStyleMinimal)) {
copy_winopt(&wip->wi_opt, &curwin->w_onebuf_opt);
curwin->w_fold_manual = wip->wi_fold_manual;
curwin->w_foldinvalid = true;
@@ -3215,8 +3218,7 @@ void buflist_slash_adjust(void)
/// Also save the local window option values.
void buflist_altfpos(win_T *win)
{
buflist_setfpos(curbuf, win, win->w_cursor.lnum, win->w_cursor.col,
win->w_config.style != kWinStyleMinimal);
buflist_setfpos(curbuf, win, win->w_cursor.lnum, win->w_cursor.col, true);
}
/// Check that "ffname" is not the same file as current file.

View File

@@ -5549,6 +5549,11 @@ void win_free(win_T *wp, tabpage_T *tp)
if (wip_wp) {
wip_wp->wi_win = NULL;
// Discard saved options if the style is minimal.
if (wp->w_config.style == kWinStyleMinimal && wip_wp->wi_optset) {
clear_winopt(&wip_wp->wi_opt);
wip_wp->wi_optset = false;
}
// If there already is an entry with "wi_win" set to NULL, only
// the first entry with NULL will ever be used, delete the other one.
if (pos_null < kv_size(buf->b_wininfo)) {

View File

@@ -409,12 +409,18 @@ describe('float window', function()
it("should re-apply 'style' when present and not leak to normal windows", function()
local buf = api.nvim_create_buf(true, false)
local buf2 = api.nvim_create_buf(true, false)
local float_opts = { style = 'minimal', relative = 'editor', row = 1, col = 1, width = 1, height = 1 }
local float_win = api.nvim_open_win(buf, true, float_opts)
api.nvim_set_option_value('number', true, { win = float_win })
float_opts.row = 2
api.nvim_win_set_config(float_win, float_opts)
eq(false, api.nvim_get_option_value('number', { win = float_win }))
-- minimal float should preserve its own options when switching buffers
api.nvim_set_option_value('listchars', 'extends:…,precedes:…', { win = float_win, scope = 'local' })
api.nvim_win_set_buf(float_win, buf2)
api.nvim_win_set_buf(float_win, buf)
eq('extends:…,precedes:…', api.nvim_get_option_value('listchars', { win = float_win, scope = 'local' }))
-- closing the float should not leak minimal style options to normal windows
api.nvim_win_close(float_win, true)
api.nvim_set_option_value('number', true, { win = 0 })
@@ -422,6 +428,23 @@ describe('float window', function()
eq(true, api.nvim_get_option_value('number', { win = 0 }))
end)
it('style=minimal options should not leak to other windows via wininfo', function()
command('set noswapfile cursorline')
command('edit foo')
local foo_buf = api.nvim_get_current_buf()
fn.setline(1, 'foo')
command('edit bar')
local bar_buf = api.nvim_get_current_buf()
fn.setline(1, 'bar')
local float_opts = { style = 'minimal', relative = 'editor', row = 5, col = 5, width = 5, height = 5 }
local minimal_win = api.nvim_open_win(foo_buf, false, float_opts)
eq(false, api.nvim_get_option_value('cursorline', { win = minimal_win }))
api.nvim_win_set_buf(minimal_win, bar_buf)
eq('', api.nvim_win_get_config(0).relative)
command('split foo')
eq(true, api.nvim_get_option_value('cursorline', { win = 0 }))
end)
it("should not re-apply 'style' when missing", function()
local float_opts = { style = 'minimal', relative = 'editor', row = 1, col = 1, width = 1, height = 1 }
local float_win = api.nvim_open_win(0, true, float_opts)