# HG changeset patch # User Bram Moolenaar # Date 1651698902 -7200 # Node ID 264fa41e6704ebeff9c22cdc6cc240c7d07275bd # Parent b7aa8a9e166a1073972da8192a2ab7aeb054dd3d patch 8.2.4868: when closing help window autocmds triggered for wrong window Commit: https://github.com/vim/vim/commit/2a2707d03337d0bb7d5fd1770238809618653d4a Author: LemonBoy 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) diff --git a/src/testdir/test_help.vim b/src/testdir/test_help.vim --- 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:') diff --git a/src/version.c b/src/version.c --- 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, diff --git a/src/window.c b/src/window.c --- 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.