From 28134f4e78819c2bbf0344326b9d44f21eb0d736 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Sun, 3 Oct 2021 13:57:01 +0100 Subject: vim-patch:8.1.0035: not easy to switch between prompt buffer and other windows Problem: Not easy to switch between prompt buffer and other windows. Solution: Accept CTRL-W commands in Insert mode. Start and stop Insert mode as one would expect. https://github.com/vim/vim/commit/6d41c78e353b630bc1a72cbff9160311d2a81e8c Cherry-pick channel.txt change from: https://github.com/vim/vim/commit/d2f3a8b8787333abf2300d38836b196955f10c00 b_prompt_insert was already ported. --- src/nvim/edit.c | 29 +++++++++++++++++++++++- src/nvim/testdir/test_prompt_buffer.vim | 7 +++--- src/nvim/window.c | 39 +++++++++++++++++++++++++++++---- 3 files changed, 66 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index fe69da7fcb..16601d327d 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -655,10 +655,17 @@ static int insert_check(VimState *state) static int insert_execute(VimState *state, int key) { + InsertState *const s = (InsertState *)state; + if (stop_insert_mode) { + // Insert mode ended, possibly from a callback. + s->count = 0; + s->nomove = true; + return 0; + } + if (key == K_IGNORE || key == K_NOP) { return -1; // get another key } - InsertState *s = (InsertState *)state; s->c = key; // Don't want K_EVENT with cursorhold for the second key, e.g., after CTRL-V. @@ -984,6 +991,15 @@ static int insert_handle_key(InsertState *s) break; case Ctrl_W: // delete word before the cursor + if (bt_prompt(curbuf) && (mod_mask & MOD_MASK_SHIFT) == 0) { + // In a prompt window CTRL-W is used for window commands. + // Use Shift-CTRL-W to delete a word. + stuffcharReadbuff(Ctrl_W); + restart_edit = 'i'; + s->nomove = true; + s->count = 0; + return 0; + } s->did_backspace = ins_bs(s->c, BACKSPACE_WORD, &s->inserted_space); auto_format(false, true); break; @@ -1653,6 +1669,17 @@ static void init_prompt(int cmdchar_todo) coladvance(MAXCOL); changed_bytes(curbuf->b_ml.ml_line_count, 0); } + + // Insert always starts after the prompt, allow editing text after it. + if (Insstart_orig.lnum != curwin->w_cursor.lnum || Insstart_orig.col != (colnr_T)STRLEN(prompt)) { + Insstart.lnum = curwin->w_cursor.lnum; + Insstart.col = STRLEN(prompt); + Insstart_orig = Insstart; + Insstart_textlen = Insstart.col; + Insstart_blank_vcol = MAXCOL; + arrow_used = false; + } + if (cmdchar_todo == 'A') { coladvance(MAXCOL); } diff --git a/src/nvim/testdir/test_prompt_buffer.vim b/src/nvim/testdir/test_prompt_buffer.vim index c59a00afcc..fde97a66a8 100644 --- a/src/nvim/testdir/test_prompt_buffer.vim +++ b/src/nvim/testdir/test_prompt_buffer.vim @@ -145,10 +145,9 @@ func Test_prompt_buffer_edit() call assert_beeps("normal! \") " pressing CTRL-W in the prompt buffer should trigger the window commands call assert_equal(1, winnr()) - " In Nvim, CTRL-W commands aren't usable from insert mode in a prompt buffer - " exe "normal A\\" - " call assert_equal(2, winnr()) - " wincmd w + exe "normal A\\" + call assert_equal(2, winnr()) + wincmd w close! call assert_equal(0, prompt_setprompt([], '')) endfunc diff --git a/src/nvim/window.c b/src/nvim/window.c index 3e6e42dec2..1da6c3704f 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2229,6 +2229,28 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int } } +static void leaving_window(win_T *const win) + FUNC_ATTR_NONNULL_ALL +{ + // When leaving a prompt window stop Insert mode and perhaps restart + // it when entering that window again. + win->w_buffer->b_prompt_insert = restart_edit; + restart_edit = NUL; + + // When leaving the window (or closing the window) was done from a + // callback we need to break out of the Insert mode loop. + if (State & INSERT) { + stop_insert_mode = true; + } +} + +static void entering_window(win_T *const win) + FUNC_ATTR_NONNULL_ALL +{ + // When entering the prompt window may restart Insert mode. + restart_edit = win->w_buffer->b_prompt_insert; +} + /// Closes all windows for buffer `buf`. /// /// @param keep_curwin don't close `curwin` @@ -2367,6 +2389,7 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev shell_new_rows(); } } + entering_window(curwin); // Since goto_tabpage_tp above did not trigger *Enter autocommands, do // that now. @@ -2434,10 +2457,10 @@ int win_close(win_T *win, bool free_buf) } if (win == curwin) { - /* - * Guess which window is going to be the new current window. - * This may change because of the autocommands (sigh). - */ + leaving_window(curwin); + + // Guess which window is going to be the new current window. + // This may change because of the autocommands (sigh). if (!win->w_floating) { wp = frame2win(win_altframe(win, NULL)); } else { @@ -3801,6 +3824,8 @@ int win_new_tabpage(int after, char_u *filename) lastused_tabpage = old_curtab; + entering_window(curwin); + apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf); apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf); apply_autocmds(EVENT_TABNEW, filename, filename, false, curbuf); @@ -3956,6 +3981,7 @@ static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds) { tabpage_T *tp = curtab; + leaving_window(curwin); reset_VIsual_and_resel(); // stop Visual mode if (trigger_leave_autocmds) { if (new_curbuf != curbuf) { @@ -4478,6 +4504,10 @@ static void win_enter_ext(win_T *const wp, const int flags) return; } + if (!curwin_invalid) { + leaving_window(curwin); + } + if (!curwin_invalid && (flags & WEE_TRIGGER_LEAVE_AUTOCMDS)) { // Be careful: If autocommands delete the window, return now. if (wp->w_buffer != curbuf) { @@ -4525,6 +4555,7 @@ static void win_enter_ext(win_T *const wp, const int flags) fix_current_dir(); + entering_window(curwin); // Careful: autocommands may close the window and make "wp" invalid if (flags & WEE_TRIGGER_NEW_AUTOCMDS) { apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf); -- cgit From d6ea0741c92e39e4f6c3ec639117d9f39ec08094 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Sun, 3 Oct 2021 14:00:24 +0100 Subject: fix(prompt): add missing changes from v8.1.0036 v8.1.0036 is already marked as ported, but missed out changes that depended on v8.1.0035. --- src/nvim/window.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/nvim/window.c b/src/nvim/window.c index 1da6c3704f..9f4c5c68f6 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2241,12 +2241,21 @@ static void leaving_window(win_T *const win) // callback we need to break out of the Insert mode loop. if (State & INSERT) { stop_insert_mode = true; + if (bt_prompt(win->w_buffer) && win->w_buffer->b_prompt_insert == NUL) { + win->w_buffer->b_prompt_insert = 'A'; + } } } static void entering_window(win_T *const win) FUNC_ATTR_NONNULL_ALL { + // When switching to a prompt buffer that was in Insert mode, don't stop + // Insert mode, it may have been set in leaving_window(). + if (bt_prompt(win->w_buffer) && win->w_buffer->b_prompt_insert != NUL) { + stop_insert_mode = false; + } + // When entering the prompt window may restart Insert mode. restart_edit = win->w_buffer->b_prompt_insert; } -- cgit From b9ab4c1dea0ee65950f8c1ec374ccab744a81acb Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Sun, 7 Nov 2021 14:50:01 +0000 Subject: vim-patch:8.1.0042: if omni completion opens a window Insert mode is stopped Problem: If omni completion opens a window Insert mode is stopped. (Hirohito Higashi) Solution: Only set stop_insert_mode in a prompt buffer window. https://github.com/vim/vim/commit/f98b845dd185dfadfa7a622a42452bfa6809d4e0 popupmenu_spec.lua fails without this. --- src/nvim/window.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/window.c b/src/nvim/window.c index 9f4c5c68f6..e0d05e1d47 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2232,16 +2232,22 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int static void leaving_window(win_T *const win) FUNC_ATTR_NONNULL_ALL { + // Only matters for a prompt window. + if (!bt_prompt(win->w_buffer)) { + return; + } + // When leaving a prompt window stop Insert mode and perhaps restart // it when entering that window again. win->w_buffer->b_prompt_insert = restart_edit; restart_edit = NUL; // When leaving the window (or closing the window) was done from a - // callback we need to break out of the Insert mode loop. + // callback we need to break out of the Insert mode loop and restart Insert + // mode when entering the window again. if (State & INSERT) { stop_insert_mode = true; - if (bt_prompt(win->w_buffer) && win->w_buffer->b_prompt_insert == NUL) { + if (win->w_buffer->b_prompt_insert == NUL) { win->w_buffer->b_prompt_insert = 'A'; } } @@ -2250,13 +2256,19 @@ static void leaving_window(win_T *const win) static void entering_window(win_T *const win) FUNC_ATTR_NONNULL_ALL { + // Only matters for a prompt window. + if (!bt_prompt(win->w_buffer)) { + return; + } + // When switching to a prompt buffer that was in Insert mode, don't stop // Insert mode, it may have been set in leaving_window(). - if (bt_prompt(win->w_buffer) && win->w_buffer->b_prompt_insert != NUL) { + if (win->w_buffer->b_prompt_insert != NUL) { stop_insert_mode = false; } - // When entering the prompt window may restart Insert mode. + // When entering the prompt window restart Insert mode if we were in Insert + // mode when we left it. restart_edit = win->w_buffer->b_prompt_insert; } -- cgit From 1fffccc5d62e4fa01c1ce52405da359723defb1c Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Sun, 7 Nov 2021 20:57:09 +0000 Subject: vim-patch:8.1.0064: typing CTRL-W in a prompt buffer shows mode "-- --" Problem: Typing CTRL-W in a prompt buffer shows mode "-- --". Solution: Set restart_edit to 'A' and check for it. https://github.com/vim/vim/commit/942b4541a2d8e8df8369ab70e112dbbbe0c7c0aa Nvim already checked for 'i' in showmode(), so this bug was fixed with (though this patch now changes to use 'A'). However, the missing changes I ported for v8.1.0036 use 'A' when a callback leaves the window in insert mode and edit gets restarted, so this bug was possible there. Modify showmode() restart_edit condition to match v8.2.1978: https://github.com/vim/vim/commit/957cf67d50516ba98716f59c9e1cb6412ec1535d --- src/nvim/edit.c | 2 +- src/nvim/screen.c | 4 ++-- src/nvim/window.c | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 16601d327d..6e3efe8bba 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -995,7 +995,7 @@ static int insert_handle_key(InsertState *s) // In a prompt window CTRL-W is used for window commands. // Use Shift-CTRL-W to delete a word. stuffcharReadbuff(Ctrl_W); - restart_edit = 'i'; + restart_edit = 'A'; s->nomove = true; s->count = 0; return 0; diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 2ce2be0bfd..d015ef110e 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -6930,7 +6930,7 @@ int showmode(void) do_mode = ((p_smd && msg_silent == 0) && ((State & TERM_FOCUS) || (State & INSERT) - || restart_edit + || restart_edit != NUL || VIsual_active)); if (do_mode || reg_recording != 0) { // Don't show mode right now, when not redrawing or inside a mapping. @@ -7010,7 +7010,7 @@ int showmode(void) } msg_puts_attr(_(" INSERT"), attr); } else if (restart_edit == 'I' || restart_edit == 'i' - || restart_edit == 'a') { + || restart_edit == 'a' || restart_edit == 'A') { msg_puts_attr(_(" (insert)"), attr); } else if (restart_edit == 'R') { msg_puts_attr(_(" (replace)"), attr); diff --git a/src/nvim/window.c b/src/nvim/window.c index e0d05e1d47..ddf50b47a7 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2240,6 +2240,9 @@ static void leaving_window(win_T *const win) // When leaving a prompt window stop Insert mode and perhaps restart // it when entering that window again. win->w_buffer->b_prompt_insert = restart_edit; + if (restart_edit != NUL && mode_displayed) { + clear_cmdline = true; // unshow mode later + } restart_edit = NUL; // When leaving the window (or closing the window) was done from a -- cgit From 38cd91de5f0f89daccdcbac16508af830d8001d7 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Sun, 7 Nov 2021 21:28:11 +0000 Subject: vim-patch:8.2.1781: writing to prompt buffer interferes with insert mode Problem: Writing to prompt buffer interferes with insert mode. Solution: Use win_enter() instead of just setting "curwin". (Ben Jackson, closes vim/vim#7035) https://github.com/vim/vim/commit/4537bcc88956f86267c25edf8008e0dbde598652 Vim test will be skipped, so add a Lua test. The problem boils down to the use of aucmd_restbuf in a callback, so just test that (via nvim_buf_set_lines). --- src/nvim/autocmd.c | 2 +- src/nvim/testdir/test_prompt_buffer.vim | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 490fe5a0ac..e274d00a77 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -1208,7 +1208,7 @@ win_found: win_T *const save_curwin = win_find_by_handle(aco->save_curwin_handle); if (save_curwin != NULL) { - curwin = save_curwin; + win_enter(save_curwin, true); } else { // Hmm, original window disappeared. Just use the first one. curwin = firstwin; diff --git a/src/nvim/testdir/test_prompt_buffer.vim b/src/nvim/testdir/test_prompt_buffer.vim index fde97a66a8..72b037dd37 100644 --- a/src/nvim/testdir/test_prompt_buffer.vim +++ b/src/nvim/testdir/test_prompt_buffer.vim @@ -186,4 +186,38 @@ func Test_prompt_buffer_getbufinfo() %bwipe! endfunc +function! Test_prompt_while_writing_to_hidden_buffer() + throw 'skipped: TODO' + call CanTestPromptBuffer() + CheckUnix + + " Make a job continuously write to a hidden buffer, check that the prompt + " buffer is not affected. + let scriptName = 'XpromptscriptHiddenBuf' + let script =<< trim END + set buftype=prompt + call prompt_setprompt( bufnr(), 'cmd:' ) + let job = job_start(['/bin/sh', '-c', + \ 'while true; + \ do echo line; + \ sleep 0.1; + \ done'], #{out_io: 'buffer', out_name: ''}) + startinsert + END + eval script->writefile(scriptName) + + let buf = RunVimInTerminal('-S ' .. scriptName, {}) + call WaitForAssert({-> assert_equal('cmd:', term_getline(buf, 1))}) + + call term_sendkeys(buf, 'test') + call WaitForAssert({-> assert_equal('cmd:test', term_getline(buf, 1))}) + call term_sendkeys(buf, 'test') + call WaitForAssert({-> assert_equal('cmd:testtest', term_getline(buf, 1))}) + call term_sendkeys(buf, 'test') + call WaitForAssert({-> assert_equal('cmd:testtesttest', term_getline(buf, 1))}) + + call StopVimInTerminal(buf) + call delete(scriptName) +endfunc + " vim: shiftwidth=2 sts=2 expandtab -- cgit From a128b64e73322a41b175811dc88a7f7046278de3 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Sun, 7 Nov 2021 21:46:06 +0000 Subject: vim-patch:8.2.1783: try-catch test fails Problem: Try-catch test fails. Solution: Don't call win_enter(), only call enterering_window(). https://github.com/vim/vim/commit/bdf931c25b4fe78877106ca529baee7899d0f6a4 v8.2.1781 caused Test_reload_in_try_catch() from v8.2.0004 to fail in Vim, but it has not been ported yet. --- src/nvim/autocmd.c | 7 +++++-- src/nvim/testdir/runtest.vim | 5 +++++ src/nvim/window.c | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index e274d00a77..9044657358 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -1208,15 +1208,18 @@ win_found: win_T *const save_curwin = win_find_by_handle(aco->save_curwin_handle); if (save_curwin != NULL) { - win_enter(save_curwin, true); + curwin = save_curwin; } else { // Hmm, original window disappeared. Just use the first one. curwin = firstwin; } + curbuf = curwin->w_buffer; + // May need to restore insert mode for a prompt buffer. + entering_window(curwin); + prevwin = win_find_by_handle(aco->save_prevwin_handle); vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab - curbuf = curwin->w_buffer; xfree(globaldir); globaldir = aco->globaldir; diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim index 49993c03aa..ab047fd2a8 100644 --- a/src/nvim/testdir/runtest.vim +++ b/src/nvim/testdir/runtest.vim @@ -197,7 +197,12 @@ func RunTheTest(test) " Close any extra tab pages and windows and make the current one not modified. while tabpagenr('$') > 1 + let winid = win_getid() quit! + if winid == win_getid() + echoerr 'Could not quit window' + break + endif endwhile while 1 diff --git a/src/nvim/window.c b/src/nvim/window.c index ddf50b47a7..e0ba4b72f3 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2256,7 +2256,7 @@ static void leaving_window(win_T *const win) } } -static void entering_window(win_T *const win) +void entering_window(win_T *const win) FUNC_ATTR_NONNULL_ALL { // Only matters for a prompt window. -- cgit From c2d0a1041e215634be316c4e824c1b1b2f242e76 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Sun, 7 Nov 2021 21:14:36 +0000 Subject: vim-patch:8.2.1976: cannot backspace in prompt buffer after using cursor-left Problem: Cannot backspace in prompt buffer after using cursor-left. (Maxim Kim) Solution: Ignore "arrow_used" in a prompt buffer. (closes vim/vim#7281) https://github.com/vim/vim/commit/6f6244855fbce5aaa718cd5001a29aac3c5c15d6 cmdchar_todo wasn't adapted properly for Nvim's state system, which caused it to be a dead store and such was removed in #11900. Re-introduce cmdchar_todo properly. --- src/nvim/edit.c | 7 +++++-- src/nvim/testdir/test_prompt_buffer.vim | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 6e3efe8bba..dfdefddc20 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -227,6 +227,7 @@ typedef struct insert_state { cmdarg_T *ca; int mincol; int cmdchar; + int cmdchar_todo; // cmdchar to handle once in init_prompt int startln; long count; int c; @@ -290,6 +291,7 @@ static void insert_enter(InsertState *s) s->did_backspace = true; s->old_topfill = -1; s->replaceState = REPLACE; + s->cmdchar_todo = s->cmdchar; // Remember whether editing was restarted after CTRL-O did_restart_edit = restart_edit; // sleep before redrawing, needed for "CTRL-O :" that results in an @@ -585,7 +587,8 @@ static int insert_check(VimState *state) } if (bt_prompt(curbuf)) { - init_prompt(s->cmdchar); + init_prompt(s->cmdchar_todo); + s->cmdchar_todo = NUL; } // If we inserted a character at the last position of the last line in the @@ -8268,7 +8271,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) || (!revins_on && ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0) || (!can_bs(BS_START) - && (arrow_used + && ((arrow_used && !bt_prompt(curbuf)) || (curwin->w_cursor.lnum == Insstart_orig.lnum && curwin->w_cursor.col <= Insstart_orig.col))) || (!can_bs(BS_INDENT) && !arrow_used && ai_col > 0 diff --git a/src/nvim/testdir/test_prompt_buffer.vim b/src/nvim/testdir/test_prompt_buffer.vim index 72b037dd37..af7231c9c0 100644 --- a/src/nvim/testdir/test_prompt_buffer.vim +++ b/src/nvim/testdir/test_prompt_buffer.vim @@ -126,6 +126,14 @@ func Test_prompt_garbage_collect() bwipe! endfunc +func Test_prompt_backspace() + new + set buftype=prompt + call feedkeys("A123456\\\", 'xt') + call assert_equal('% 12346', getline(1)) + bwipe! +endfunc + " Test for editing the prompt buffer func Test_prompt_buffer_edit() new -- cgit From d6258a9bad10e97d2582a102750e0e931bb9321a Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Sun, 7 Nov 2021 13:12:17 +0000 Subject: vim-patch:8.2.2014: using CTRL-O in a prompt buffer moves cursor to start Problem: Using CTRL-O in a prompt buffer moves cursor to start of the line. Solution: Do not move the cursor when restarting edit. (closes vim/vim#7330) https://github.com/vim/vim/commit/ee8b787bcd15f63a938243770065e704c9b5c85f Test_prompt_editing is skipped, so edit the Lua test in prompt_buffer_spec. --- src/nvim/edit.c | 2 +- src/nvim/testdir/test_prompt_buffer.vim | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index dfdefddc20..9bfb8a9d4a 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1686,7 +1686,7 @@ static void init_prompt(int cmdchar_todo) if (cmdchar_todo == 'A') { coladvance(MAXCOL); } - if (cmdchar_todo == 'I' || curwin->w_cursor.col <= (int)STRLEN(prompt)) { + if (curwin->w_cursor.col < (colnr_T)STRLEN(prompt)) { curwin->w_cursor.col = STRLEN(prompt); } // Make sure the cursor is in a valid position. diff --git a/src/nvim/testdir/test_prompt_buffer.vim b/src/nvim/testdir/test_prompt_buffer.vim index af7231c9c0..4212dcb36e 100644 --- a/src/nvim/testdir/test_prompt_buffer.vim +++ b/src/nvim/testdir/test_prompt_buffer.vim @@ -89,9 +89,12 @@ func Test_prompt_editing() call term_sendkeys(buf, left . left . left . bs . '-') call WaitForAssert({-> assert_equal('cmd: -hel', term_getline(buf, 1))}) + call term_sendkeys(buf, "\lz") + call WaitForAssert({-> assert_equal('cmd: -hzel', term_getline(buf, 1))}) + let end = "\" call term_sendkeys(buf, end . "x") - call WaitForAssert({-> assert_equal('cmd: -helx', term_getline(buf, 1))}) + call WaitForAssert({-> assert_equal('cmd: -hzelx', term_getline(buf, 1))}) call term_sendkeys(buf, "\exit\") call WaitForAssert({-> assert_equal('other buffer', term_getline(buf, 1))}) -- cgit From 361f548437a0a9b620db620356fdd405d24a7b34 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Thu, 25 Nov 2021 22:53:14 +0000 Subject: vim-patch:8.2.3671: restarting Insert mode in prompt buffer too often Problem: Restarting Insert mode in prompt buffer too often when a callback switches windows and comes back. (Sean Dewar) Solution: Do not set "restart_edit" when already in Insert mode. https://github.com/vim/vim/commit/34c20ff85b87be587ea5d0398812441b502ee6a5 As Test_prompt_switch_windows is skipped, implement it in prompt_buffer_spec. Replace the 50ms term_wait calls with poke_eventloop (test seems to work anyway without them, so maybe they're not required?) The new test does include a duplicate screen test that may generate a "screen test succeeded immediately" warning, but this is done to match the Vim test. --- src/nvim/testdir/test_prompt_buffer.vim | 26 ++++++++++++++++++++++++++ src/nvim/window.c | 6 ++++-- 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_prompt_buffer.vim b/src/nvim/testdir/test_prompt_buffer.vim index 4212dcb36e..8f94a8572b 100644 --- a/src/nvim/testdir/test_prompt_buffer.vim +++ b/src/nvim/testdir/test_prompt_buffer.vim @@ -41,6 +41,10 @@ func WriteScript(name) \ ' set nomodified', \ 'endfunc', \ '', + \ 'func SwitchWindows()', + \ ' call timer_start(0, {-> execute("wincmd p|wincmd p", "")})', + \ 'endfunc', + \ '', \ 'call setline(1, "other buffer")', \ 'set nomodified', \ 'new', @@ -103,6 +107,28 @@ func Test_prompt_editing() call delete(scriptName) endfunc +func Test_prompt_switch_windows() + throw 'skipped: TODO' + call CanTestPromptBuffer() + let scriptName = 'XpromptSwitchWindows' + call WriteScript(scriptName) + + let buf = RunVimInTerminal('-S ' . scriptName, {'rows': 12}) + call WaitForAssert({-> assert_equal('cmd:', term_getline(buf, 1))}) + call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 12))}) + + call term_sendkeys(buf, "\:call SwitchWindows()\") + call term_wait(buf, 50) + call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 12))}) + + call term_sendkeys(buf, "\") + call term_wait(buf, 50) + call WaitForAssert({-> assert_match('^ *$', term_getline(buf, 12))}) + + call StopVimInTerminal(buf) + call delete(scriptName) +endfunc + func Test_prompt_garbage_collect() func MyPromptCallback(x, text) " NOP diff --git a/src/nvim/window.c b/src/nvim/window.c index e0ba4b72f3..be963d8374 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2271,8 +2271,10 @@ void entering_window(win_T *const win) } // When entering the prompt window restart Insert mode if we were in Insert - // mode when we left it. - restart_edit = win->w_buffer->b_prompt_insert; + // mode when we left it and not already in Insert mode. + if ((State & INSERT) == 0) { + restart_edit = win->w_buffer->b_prompt_insert; + } } /// Closes all windows for buffer `buf`. -- cgit