patch 9.1.1295: clientserver: does not handle :stopinsert correctly Commit: https://github.com/vim/vim/commit/cf665ccd3771d59584f2f44a7c644c017a2ad84f Author: Christian Brabandt <c...@256bit.org> 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 <c...@256bit.org> 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 vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1u3dVZ-00GMHO-8v%40256bit.org.