summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Dewar <seandewar@users.noreply.github.com>2024-01-03 18:52:52 +0100
committerChristian Brabandt <cb@256bit.org>2024-01-03 19:07:21 +0100
commitbf44b69d1f91d9778ae1887128c63d35d9a3d19b (patch)
tree3c66fa07c2c6baa3a2a81c75b64799306e806cf3
parentb5352931b354eb67eb7d223cc09c98dcf1b547b6 (diff)
patch 9.1.0001: when closing window, wincmd p may failv9.1.0001
Avoid `prevwin == curwin` when closing `curwin` Problem: When closing the current window (or when moving it to a tabpage), the previous window may refer to the new current window (`winnr() == winnr('#')`) if that window is selected as the new current window. Solution: Set `prevwin = NULL` when switching away from an invalid `curwin` and the target window was the `prevwin`. (Sean Dewar) related: #4537 closes: #13762 Signed-off-by: Sean Dewar <seandewar@users.noreply.github.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
-rw-r--r--src/testdir/test_window_cmd.vim58
-rw-r--r--src/version.c2
-rw-r--r--src/window.c4
3 files changed, 64 insertions, 0 deletions
diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim
index 818fef0394..6b7dccbb00 100644
--- a/src/testdir/test_window_cmd.vim
+++ b/src/testdir/test_window_cmd.vim
@@ -131,6 +131,64 @@ func Test_window_quit()
bw Xa Xb
endfunc
+func Test_window_curwin_not_prevwin()
+ botright split
+ call assert_equal(2, winnr())
+ call assert_equal(1, winnr('#'))
+ quit
+ call assert_equal(1, winnr())
+ call assert_equal(0, winnr('#'))
+
+ botright split
+ botright split
+ call assert_equal(3, winnr())
+ call assert_equal(2, winnr('#'))
+ 1quit
+ call assert_equal(2, winnr())
+ call assert_equal(1, winnr('#'))
+
+ botright split
+ call assert_equal(1, tabpagenr())
+ call assert_equal(3, winnr())
+ call assert_equal(2, winnr('#'))
+ wincmd T
+ call assert_equal(2, tabpagenr())
+ call assert_equal(1, winnr())
+ call assert_equal(0, winnr('#'))
+ tabfirst
+ call assert_equal(1, tabpagenr())
+ call assert_equal(2, winnr())
+ call assert_equal(0, winnr('#'))
+
+ tabonly
+ botright split
+ wincmd t
+ wincmd p
+ call assert_equal(3, winnr())
+ call assert_equal(1, winnr('#'))
+ quit
+ call assert_equal(2, winnr())
+ call assert_equal(1, winnr('#'))
+
+ botright split
+ wincmd t
+ wincmd p
+ call assert_equal(1, tabpagenr())
+ call assert_equal(3, winnr())
+ call assert_equal(1, winnr('#'))
+ wincmd T
+ call assert_equal(2, tabpagenr())
+ call assert_equal(1, winnr())
+ call assert_equal(0, winnr('#'))
+ tabfirst
+ call assert_equal(1, tabpagenr())
+ call assert_equal(2, winnr())
+ call assert_equal(1, winnr('#'))
+
+ tabonly
+ only
+endfunc
+
func Test_window_horizontal_split()
call assert_equal(1, winnr('$'))
3wincmd s
diff --git a/src/version.c b/src/version.c
index 1fc040ed18..c4e7fa3db7 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1,
+/**/
0
};
diff --git a/src/window.c b/src/window.c
index 9f80657124..54e17be2db 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5381,11 +5381,15 @@ win_enter_ext(win_T *wp, int flags)
// may have to copy the buffer options when 'cpo' contains 'S'
if (wp->w_buffer != curbuf)
buf_copy_options(wp->w_buffer, BCO_ENTER | BCO_NOHELP);
+
if (curwin_invalid == 0)
{
prevwin = curwin; // remember for CTRL-W p
curwin->w_redr_status = TRUE;
}
+ else if (wp == prevwin)
+ prevwin = NULL; // don't want it to be the new curwin
+
curwin = wp;
curbuf = wp->w_buffer;
check_cursor();