patch 9.2.0004: Changing hidden prompt buffer cancels :startinsert/:stopinsert

Commit: 
https://github.com/vim/vim/commit/8b81a6b6e1d514cf0544e0c6d12412ba813564b0
Author: zeertzjq <[email protected]>
Date:   Sun Feb 15 15:38:19 2026 +0000

    patch 9.2.0004: Changing hidden prompt buffer cancels 
:startinsert/:stopinsert
    
    Problem:  Changing hidden prompt buffer cancels :startinsert/:stopinsert
              (after 9.0.1439).
    Solution: Don't change mode for a prompt buffer in an autocommand
              window (zeertzjq).
    
    closes: #19410
    
    Signed-off-by: zeertzjq <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/autocmd.c b/src/autocmd.c
index 7c0cc50a7..acf7bb140 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -1627,7 +1627,6 @@ aucmd_prepbuf(
 
     aco->save_curwin_id = curwin->w_id;
     aco->save_prevwin_id = prevwin == NULL ? 0 : prevwin->w_id;
-    aco->save_State = State;
 #ifdef FEAT_JOB_CHANNEL
     if (bt_prompt(curbuf))
        aco->save_prompt_insert = curbuf->b_prompt_insert;
@@ -1727,14 +1726,6 @@ aucmd_restbuf(
        }
 win_found:
        --curbuf->b_nwindows;
-#ifdef FEAT_JOB_CHANNEL
-       int save_stop_insert_mode = stop_insert_mode;
-       // May need to stop Insert mode if we were in a prompt buffer.
-       leaving_window(curwin);
-       // Do not stop Insert mode when already in Insert mode before.
-       if (aco->save_State & MODE_INSERT)
-           stop_insert_mode = save_stop_insert_mode;
-#endif
        // Remove the window and frame from the tree of frames.
        (void)winframe_remove(curwin, &dummy, NULL, NULL);
        win_remove(curwin, NULL);
diff --git a/src/structs.h b/src/structs.h
index 83d35c53f..df296b35d 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -4575,7 +4575,6 @@ typedef struct
     char_u     *tp_localdir;       // saved value of tp_localdir
     char_u     *globaldir;         // saved value of globaldir
     int                save_VIsual_active; // saved VIsual_active
-    int                save_State;         // saved State
 #ifdef FEAT_JOB_CHANNEL
     int                save_prompt_insert; // saved b_prompt_insert
 #endif
diff --git a/src/testdir/test_prompt_buffer.vim 
b/src/testdir/test_prompt_buffer.vim
index 72882e29e..357492b40 100644
--- a/src/testdir/test_prompt_buffer.vim
+++ b/src/testdir/test_prompt_buffer.vim
@@ -266,10 +266,18 @@ func Test_prompt_appending_while_hidden()
       endfunc
       call prompt_setcallback(bufnr(), function('s:TextEntered'))
 
-      func DoAppend()
+      func DoAppend(cmd_before = '')
+        exe a:cmd_before
         call appendbufline('prompt', '$', 'Test')
         return ''
       endfunc
+
+      autocmd User SwitchTabPages tabprevious | tabnext
+      func DoAutoAll(cmd_before = '')
+        exe a:cmd_before
+        doautoall User SwitchTabPages
+        return ''
+      endfunc
   END
   call writefile(script, 'XpromptBuffer', 'D')
 
@@ -280,18 +288,32 @@ func Test_prompt_appending_while_hidden()
   call TermWait(buf)
 
   call term_sendkeys(buf, "exit\<CR>")
-  call WaitForAssert({-> assert_notmatch('-- INSERT --', term_getline(buf, 
10))})
+  call WaitForAssert({-> assert_notmatch('-- .* --', term_getline(buf, 10))})
 
   call term_sendkeys(buf, ":call DoAppend()\<CR>")
-  call WaitForAssert({-> assert_notmatch('-- INSERT --', term_getline(buf, 
10))})
+  call WaitForAssert({-> assert_notmatch('-- .* --', term_getline(buf, 10))})
 
   call term_sendkeys(buf, "i")
-  call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 10))})
+  call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
 
   call term_sendkeys(buf, "\<C-R>=DoAppend()\<CR>")
-  call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 10))})
+  call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
+
+  call term_sendkeys(buf, "\<C-R>=DoAppend('stopinsert')\<CR>")
+  call WaitForAssert({-> assert_notmatch('-- .* --', term_getline(buf, 10))})
+
+  call term_sendkeys(buf, ":call DoAppend('startreplace')\<CR>")
+  call WaitForAssert({-> assert_match('^-- REPLACE --', term_getline(buf, 
10))})
+
+  call term_sendkeys(buf, "\<Esc>:tabnew\<CR>")
+  call WaitForAssert({-> assert_notmatch('-- .* --', term_getline(buf, 10))})
+
+  call term_sendkeys(buf, ":call DoAutoAll('startinsert')\<CR>")
+  call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
+
+  call term_sendkeys(buf, "\<C-R>=DoAutoAll('stopinsert')\<CR>")
+  call WaitForAssert({-> assert_notmatch('-- .* --', term_getline(buf, 10))})
 
-  call term_sendkeys(buf, "\<Esc>")
   call StopVimInTerminal(buf)
 endfunc
 
@@ -320,16 +342,16 @@ func Test_prompt_leave_modify_hidden()
   call TermWait(buf)
 
   call term_sendkeys(buf, "a")
-  call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 10))})
+  call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
 
   call term_sendkeys(buf, "w")
-  call WaitForAssert({-> assert_notmatch('-- INSERT --', term_getline(buf, 
10))})
+  call WaitForAssert({-> assert_notmatch('-- .* --', term_getline(buf, 10))})
 
   call term_sendkeys(buf, "\<C-W>w")
-  call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 10))})
+  call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
 
   call term_sendkeys(buf, "q")
-  call WaitForAssert({-> assert_notmatch('-- INSERT --', term_getline(buf, 
10))})
+  call WaitForAssert({-> assert_notmatch('-- .* --', term_getline(buf, 10))})
 
   call term_sendkeys(buf, ":bwipe!\<CR>")
   call WaitForAssert({-> assert_equal('Leave', term_getline(buf, 2))})
diff --git a/src/version.c b/src/version.c
index 6b8c29b0c..12365dc35 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 */
+/**/
+    4,
 /**/
     3,
 /**/
diff --git a/src/window.c b/src/window.c
index 457359126..62089bdec 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2436,7 +2436,9 @@ win_equal_rec(
 leaving_window(win_T *win)
 {
     // Only matters for a prompt window.
-    if (!bt_prompt(win->w_buffer))
+    // Don't do mode changes for a prompt buffer in an autocommand window, as
+    // it's only used temporarily during an autocommand.
+    if (!bt_prompt(win->w_buffer) || is_aucmd_win(win))
        return;
 
     // When leaving a prompt window stop Insert mode and perhaps restart
@@ -2461,7 +2463,9 @@ leaving_window(win_T *win)
 entering_window(win_T *win)
 {
     // Only matters for a prompt window.
-    if (!bt_prompt(win->w_buffer))
+    // Don't do mode changes for a prompt buffer in an autocommand window, as
+    // it's only used temporarily during an autocommand.
+    if (!bt_prompt(win->w_buffer) || is_aucmd_win(win))
        return;
 
     // When switching to a prompt buffer that was in Insert mode, don't stop

-- 
-- 
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/E1vreJ0-00DdoE-8V%40256bit.org.

Raspunde prin e-mail lui