changeset 28688:264fa41e6704 v8.2.4868

patch 8.2.4868: when closing help window autocmds triggered for wrong window Commit: https://github.com/vim/vim/commit/2a2707d03337d0bb7d5fd1770238809618653d4a Author: LemonBoy <thatlemon@gmail.com> Date: Wed May 4 22:13:47 2022 +0100 patch 8.2.4868: when closing help window autocmds triggered for wrong window Problem: When closing help window autocmds triggered for the wrong window. Solution: Figure out the new current window earlier. (closes https://github.com/vim/vim/issues/10348)
author Bram Moolenaar <Bram@vim.org>
date Wed, 04 May 2022 23:15:02 +0200
parents b7aa8a9e166a
children 0c6c580c01b4
files src/testdir/test_help.vim src/version.c src/window.c
diffstat 3 files changed, 71 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_help.vim
+++ b/src/testdir/test_help.vim
@@ -12,6 +12,30 @@ func Test_help_restore_snapshot()
   helpclose
 endfunc
 
+func Test_help_restore_snapshot_split()
+  " Squeeze the unnamed buffer, Xfoo and the help one side-by-side and focus
+  " the first one before calling :help.
+  let bnr = bufnr()
+  botright vsp Xfoo
+  wincmd h
+  help
+  wincmd L
+  let g:did_bufenter = v:false
+  augroup T
+    au!
+    au BufEnter Xfoo let g:did_bufenter = v:true
+  augroup END
+  helpclose
+  augroup! T
+  " We're back to the unnamed buffer.
+  call assert_equal(bnr, bufnr())
+  " No BufEnter was triggered for Xfoo.
+  call assert_equal(v:false, g:did_bufenter)
+
+  close!
+  bwipe!
+endfunc
+
 func Test_help_errors()
   call assert_fails('help doesnotexist', 'E149:')
   call assert_fails('help!', 'E478:')
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4868,
+/**/
     4867,
 /**/
     4866,
--- a/src/window.c
+++ b/src/window.c
@@ -57,6 +57,7 @@ static void clear_snapshot(tabpage_T *tp
 static void clear_snapshot_rec(frame_T *fr);
 static int check_snapshot_rec(frame_T *sn, frame_T *fr);
 static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr);
+static win_T *get_snapshot_curwin(int idx);
 
 static int frame_check_height(frame_T *topfrp, int height);
 static int frame_check_width(frame_T *topfrp, int width);
@@ -2667,6 +2668,16 @@ win_close(win_T *win, int free_buf)
     // the screen space.
     wp = win_free_mem(win, &dir, NULL);
 
+    if (help_window)
+    {
+	// Closing the help window moves the cursor back to the current window
+	// of the snapshot.
+	win_T *prev_win = get_snapshot_curwin(SNAP_HELP_IDX);
+
+	if (win_valid(prev_win))
+	    wp = prev_win;
+    }
+
     // Make sure curwin isn't invalid.  It can cause severe trouble when
     // printing an error message.  For win_equal() curbuf needs to be valid
     // too.
@@ -6861,6 +6872,40 @@ clear_snapshot_rec(frame_T *fr)
 }
 
 /*
+ * Traverse a snapshot to find the previous curwin.
+ */
+    static win_T *
+get_snapshot_curwin_rec(frame_T *ft)
+{
+    win_T	*wp;
+
+    if (ft->fr_next != NULL)
+    {
+	if ((wp = get_snapshot_curwin_rec(ft->fr_next)) != NULL)
+	    return wp;
+    }
+    if (ft->fr_child != NULL)
+    {
+	if ((wp = get_snapshot_curwin_rec(ft->fr_child)) != NULL)
+	    return wp;
+    }
+
+    return ft->fr_win;
+}
+
+/*
+ * Return the current window stored in the snapshot or NULL.
+ */
+    static win_T *
+get_snapshot_curwin(int idx)
+{
+    if (curtab->tp_snapshot[idx] == NULL)
+	return NULL;
+
+    return get_snapshot_curwin_rec(curtab->tp_snapshot[idx]);
+}
+
+/*
  * Restore a previously created snapshot, if there is any.
  * This is only done if the screen size didn't change and the window layout is
  * still the same.