patch 9.1.1295: clientserver: does not handle :stopinsert correctly
Commit:
https://github.com/vim/vim/commit/cf665ccd3771d59584f2f44a7c644c017a2ad84f
Author: Christian Brabandt <[email protected]>
Date: Sat Apr 12 18:09:28 2025 +0200
patch 9.1.1295: clientserver: does not handle :stopinsert correctly
Problem: clientserver: When in insert mode, a :stopinsert command
is not correctly processed (user202729)
Solution: If the :stopinsert command is received while waiting for
input, stuff the NOP key into the type-ahead buffer and
detect that :stopinsert was used in edit() so that the
cursor position is decremented.
fixes: #17016
closes: #17024
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/src/edit.c b/src/edit.c
index 53428e0fb..ab67fdc68 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -608,7 +608,16 @@ edit(
if (c != K_IGNORE && c != K_NOP)
vungetc(c);
count = 0;
- nomove = TRUE;
+
+ if (!bt_prompt(curwin->w_buffer)
+#ifdef FEAT_TERMINAL
+ && !bt_terminal(curwin->w_buffer)
+#endif
+ && stop_insert_mode)
+ // :stopinsert command via callback or via server
command
+ nomove = FALSE;
+ else
+ nomove = TRUE;
ins_compl_prep(ESC);
goto doESCkey;
}
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 03eaef420..279a202cd 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -9326,6 +9326,12 @@ ex_stopinsert(exarg_T *eap UNUSED)
{
restart_edit = 0;
stop_insert_mode = TRUE;
+#if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL)
+ // when called from remote_expr in insert mode, make sure insert mode is
+ // ended by adding K_NOP to the typeahead buffer
+ if (vgetc_busy)
+ ins_char_typebuf(K_NOP, 0);
+#endif
clearmode();
}
diff --git a/src/testdir/test_clientserver.vim
b/src/testdir/test_clientserver.vim
index 8be521b9f..02b0c3921 100644
--- a/src/testdir/test_clientserver.vim
+++ b/src/testdir/test_clientserver.vim
@@ -191,6 +191,47 @@ func Test_client_server()
\ has('unix') ? ['E573:.*abc'] : 'E258:')
endfunc
+func Test_client_server_stopinsert()
+ " test does not work on MS-Windows
+ CheckNotMSWindows
+ let g:test_is_flaky = 1
+ let cmd = GetVimCommand()
+ if cmd == ''
+ throw 'GetVimCommand() failed'
+ endif
+ call Check_X11_Connection()
+ let fname = 'Xclientserver_stop.txt'
+ let name = 'XVIMTEST2'
+ call writefile(['one two three'], fname, 'D')
+
+ let cmd .= ' -c "set virtualedit=onemore"'
+ let cmd .= ' -c "call cursor(1, 14)"'
+ let cmd .= ' -c "startinsert"'
+ let cmd .= ' --servername ' . name
+ let cmd .= ' ' .. fname
+ let job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
+ call WaitForAssert({-> assert_equal("run", job_status(job))})
+
+ " Takes a short while for the server to be active.
+ " When using valgrind it takes much longer.
+ call WaitForAssert({-> assert_match(name, serverlist())})
+
+ call remote_expr(name, 'execute("stopinsert")')
+
+ call assert_equal('n', name->remote_expr("mode(1)"))
+ call assert_equal('13', name->remote_expr("col('.')"))
+
+ eval name->remote_send(":qa!\<CR>")
+ try
+ call WaitForAssert({-> assert_equal("dead", job_status(job))})
+ finally
+ if job_status(job) != 'dead'
+ call assert_report('Server did not exit')
+ call job_stop(job, 'kill')
+ endif
+ endtry
+endfunc
+
" Uncomment this line to get a debugging log
" call ch_logfile('channellog', 'w')
diff --git a/src/version.c b/src/version.c
index 2e2debb9d..53b794173 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1295,
/**/
1294,
/**/
--
--
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/E1u3dVZ-00GMHO-8v%40256bit.org.