patch 9.1.2001: cursor may end up in wrong window after :botright copen

Commit: 
https://github.com/vim/vim/commit/b43f9ded7e98261e3e662a8e919f54e7399b0316
Author: glepnir <[email protected]>
Date:   Sat Dec 20 17:26:39 2025 +0000

    patch 9.1.2001: cursor may end up in wrong window after :botright copen
    
    Problem:  After :botright copen and closing the quikfix window, the
              cursor ends up in the wrong window. The problem is fr_child
              always points to the first (leftmost for FR_ROW, topmost for
              FR_COL) child frame. When do :vsplit, the new window is
              created on the left, and frame_insert() updates the parent's
              fr_child to point to this new left window.
    Solution: Create a snapshot before open the quickfix window and restore
              it when close it (glepnir).
    
    closes: #18961
    
    Signed-off-by: glepnir <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/quickfix.c b/src/quickfix.c
index cc4abcd00..c3c1ea84f 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -4612,6 +4612,12 @@ qf_open_new_cwindow(qf_info_T *qi, int height)
     if (cmdmod.cmod_split == 0)
        flags = WSP_BELOW;
     flags |= WSP_NEWLOC;
+
+    // Create a snapshot for quickfix window (not for location list)
+    // so that when closing it, we can restore to the previous window
+    if (IS_QF_STACK(qi))
+       flags |= WSP_QUICKFIX;
+
     if (win_split(height, flags) == FAIL)
        return FAIL;            // not enough room for window
     RESET_BINDING(curwin);
diff --git a/src/structs.h b/src/structs.h
index d2043bbfb..bc2f49f7d 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3693,9 +3693,10 @@ typedef void diffline_T;
 typedef void diffline_change_T;
 #endif
 
-#define SNAP_HELP_IDX  0
-#define SNAP_AUCMD_IDX 1
-#define SNAP_COUNT     2
+#define SNAP_HELP_IDX      0
+#define SNAP_AUCMD_IDX     1
+#define SNAP_QUICKFIX_IDX   2
+#define SNAP_COUNT         3
 
 /*
  * Tab pages point to the top frame of each tab page.
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index fed9dcf8d..6e939a653 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -6958,4 +6958,15 @@ func Test_vimgrep_dummy_buffer_keep()
   %bw!
 endfunc
 
+func Test_quickfix_restore_current_win()
+  let curwin = win_getid()
+  vsplit Xb
+  wincmd p
+  botright copen
+  cclose
+
+  call assert_equal(curwin, win_getid())
+  bw! Xb
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index f080339dc..a8602f71b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2001,
 /**/
     2000,
 /**/
diff --git a/src/vim.h b/src/vim.h
index fccb31b3d..4bd6c7001 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1314,6 +1314,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t 
*envstring);
 #define WSP_ABOVE      0x80    // put new window above/left
 #define WSP_NEWLOC     0x100   // don't copy location list
 #define WSP_FORCE_ROOM 0x200   // ignore "not enough room" errors
+#define WSP_QUICKFIX   0x400   // creating the quickfix window
 
 /*
  * arguments for gui_set_shellsize()
diff --git a/src/window.c b/src/window.c
index 28c68800c..3ceee02f6 100644
--- a/src/window.c
+++ b/src/window.c
@@ -959,6 +959,11 @@ win_split(int size, int flags)
     else
        clear_snapshot(curtab, SNAP_HELP_IDX);
 
+    if (flags & WSP_QUICKFIX)
+       make_snapshot(SNAP_QUICKFIX_IDX);
+    else
+       clear_snapshot(curtab, SNAP_QUICKFIX_IDX);
+
     return win_split_ins(size, flags, NULL, 0, NULL);
 }
 
@@ -2688,6 +2693,7 @@ win_close(win_T *win, int free_buf)
     int                close_curwin = FALSE;
     int                dir;
     int                help_window = FALSE;
+    int                quickfix_window = FALSE;
     tabpage_T   *prev_curtab = curtab;
     frame_T    *win_frame = win->w_frame->fr_parent;
 #ifdef FEAT_DIFF
@@ -2740,6 +2746,11 @@ win_close(win_T *win, int free_buf)
     else
        clear_snapshot(curtab, SNAP_HELP_IDX);
 
+    if (bt_quickfix(win->w_buffer))
+       quickfix_window = TRUE;
+    else
+       clear_snapshot(curtab, SNAP_QUICKFIX_IDX);
+
     if (win == curwin)
     {
 #ifdef FEAT_JOB_CHANNEL
@@ -2845,11 +2856,11 @@ win_close(win_T *win, int free_buf)
     // the screen space.
     wp = win_free_mem(win, &dir, NULL);
 
-    if (help_window)
+    if (help_window || quickfix_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);
+       win_T *prev_win = get_snapshot_curwin(help_window ? SNAP_HELP_IDX : 
SNAP_QUICKFIX_IDX);
 
        if (win_valid(prev_win))
            wp = prev_win;
@@ -2939,10 +2950,11 @@ win_close(win_T *win, int free_buf)
        --dont_parse_messages;
 #endif
 
-    // After closing the help window, try restoring the window layout from
-    // before it was opened.
-    if (help_window)
-       restore_snapshot(SNAP_HELP_IDX, close_curwin);
+    // After closing the help or quickfix window, try restoring the window
+    // layout from before it was opened.
+    if (help_window || quickfix_window)
+       restore_snapshot(help_window ? SNAP_HELP_IDX : SNAP_QUICKFIX_IDX,
+                       close_curwin);
 
 #ifdef FEAT_DIFF
     // If the window had 'diff' set and now there is only one window left in

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1vX0mJ-007Fpf-Hd%40256bit.org.

Raspunde prin e-mail lui