patch 9.2.0004: Changing hidden prompt buffer cancels :startinsert/:stopinsert
Commit:
https://github.com/vim/vim/commit/8b81a6b6e1d514cf0544e0c6d12412ba813564b0
Author: zeertzjq <
zeer...@outlook.com>
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 <
zeer...@outlook.com>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
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