diff options
author | bfredl <bjorn.linse@gmail.com> | 2025-01-20 11:02:58 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-20 11:02:58 +0100 |
commit | 71922cd1dc3bb6e040d7ab1ecd4d457f979a98fa (patch) | |
tree | 73b996f8b40ec429f76cad646464972920e26f4d | |
parent | 5b025b499ec430f1733409f0fb5ba3f88ce25a88 (diff) | |
parent | 59da82abd91e3be7eb5403c14de012cd149a1c84 (diff) | |
download | rneovim-71922cd1dc3bb6e040d7ab1ecd4d457f979a98fa.tar.gz rneovim-71922cd1dc3bb6e040d7ab1ecd4d457f979a98fa.tar.bz2 rneovim-71922cd1dc3bb6e040d7ab1ecd4d457f979a98fa.zip |
Merge pull request #31597 from bfredl/deletionism
fix(wininfo): when freeing windows, free the lowest priority wininfo
-rw-r--r-- | src/nvim/window.c | 11 | ||||
-rw-r--r-- | test/functional/api/window_spec.lua | 42 |
2 files changed, 49 insertions, 4 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c index 1c0d8c1027..fa2bfec138 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5243,11 +5243,13 @@ void win_free(win_T *wp, tabpage_T *tp) // freed memory is re-used for another window. FOR_ALL_BUFFERS(buf) { WinInfo *wip_wp = NULL; + size_t pos_wip = kv_size(buf->b_wininfo); size_t pos_null = kv_size(buf->b_wininfo); for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) { WinInfo *wip = kv_A(buf->b_wininfo, i); if (wip->wi_win == wp) { wip_wp = wip; + pos_wip = i; } else if (wip->wi_win == NULL) { pos_null = i; } @@ -5255,11 +5257,12 @@ void win_free(win_T *wp, tabpage_T *tp) if (wip_wp) { wip_wp->wi_win = NULL; - // If there already is an entry with "wi_win" set to NULL it - // must be removed, it would never be used. + // 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)) { - free_wininfo(kv_A(buf->b_wininfo, pos_null), buf); - kv_shift(buf->b_wininfo, pos_null, 1); + size_t pos_delete = MAX(pos_null, pos_wip); + free_wininfo(kv_A(buf->b_wininfo, pos_delete), buf); + kv_shift(buf->b_wininfo, pos_delete, 1); } } } diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index 078d581b6f..028f0beb38 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -506,6 +506,48 @@ describe('API/win', function() assert_alive() end) + describe('after closing', function() + local buf, win0, win1, win2 + + before_each(function() + win0 = api.nvim_get_current_win() + command('new') + buf = api.nvim_get_current_buf() + win1 = api.nvim_get_current_win() + command('set numberwidth=10') + command('split') + win2 = api.nvim_get_current_win() + command('set numberwidth=15') + command('enew') + api.nvim_set_current_win(win1) + command('normal ix') + command('enew') + api.nvim_set_current_win(win0) + eq(4, api.nvim_get_option_value('numberwidth', {})) + end) + + -- at this point buffer `buf` is current in no windows. Closing shouldn't affect its defaults + it('0 windows', function() + api.nvim_set_current_buf(buf) + eq(10, api.nvim_get_option_value('numberwidth', {})) + end) + + it('1 window', function() + api.nvim_win_close(win1, false) + + api.nvim_set_current_buf(buf) + eq(10, api.nvim_get_option_value('numberwidth', {})) + end) + + it('2 windows', function() + api.nvim_win_close(win1, false) + api.nvim_win_close(win2, false) + + api.nvim_set_current_buf(buf) + eq(10, api.nvim_get_option_value('numberwidth', {})) + end) + end) + it('returns values for unset local options', function() eq(-1, api.nvim_get_option_value('scrolloff', { win = 0, scope = 'local' })) end) |