diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index 332786f391..dd8db14a1c 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -1223,9 +1223,12 @@ but it's not possible to open another cmdwin from there. There is no nesting. *E11* -|CTRL-W| navigation/split commands and some operations (e.g. |:terminal|) emit -E11. But mouse clicks may focus other windows. The cmdwin buffer is pinned by -'winfixbuf', so the window cannot switch to a different buffer. +|CTRL-W| commands work as usual: you can navigate between, split, resize, and +close windows while the command-line window is open. E11 is still emitted by +operations that would leave or repurpose the cmdwin: opening a new tab page +(CTRL-W_T, |:tabnew|) or turning its buffer into a terminal (|:terminal|). +The cmdwin buffer is pinned by 'winfixbuf', so its window cannot switch to a +different buffer. CLOSE diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 34ec454817..bb9f81a700 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -188,11 +188,11 @@ EDITOR kind/menu/info/abbr for the popup menu. • |cmdwin| (|q:|, |q/|, |q?|, |c_CTRL-F|) is implemented as a "normal" buffer+window instead of a nested-state modal loop: + • You can create (and navigate) windows while cmdwin is active. Chaos! • 'inccommand' works in cmdwin! • API calls (e.g. |nvim_buf_delete()|) that previously failed with "E11: Invalid in command-line window" while cmdwin was open, now work normally. Async plugins no longer need special |CmdwinLeave| workarounds. - • Removed most cmdwin-specific |E11| guards, except for window navigation. • The |cmdwin-char| is shown via 'statuscolumn'. • |gf| and || support `file://…` URIs. • |:log| opens log files. diff --git a/src/nvim/window.c b/src/nvim/window.c index 994111d195..77ebda0a39 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -271,20 +271,11 @@ void do_window(int nchar, int Prenum, int xchar) int Prenum1 = Prenum == 0 ? 1 : Prenum; -#define CHECK_CMDWIN \ - do { \ - if (cmdwin_buf != NULL) { \ - emsg(_(e_cmdwin)); \ - return; \ - } \ - } while (0) - switch (nchar) { // split current window in two parts, horizontally case 'S': case Ctrl_S: case 's': - CHECK_CMDWIN; reset_VIsual_and_resel(); // stop Visual mode // When splitting the quickfix window open a new buffer in it, // don't replicate the quickfix buffer. @@ -297,7 +288,6 @@ void do_window(int nchar, int Prenum, int xchar) // split current window in two parts, vertically case Ctrl_V: case 'v': - CHECK_CMDWIN; reset_VIsual_and_resel(); // stop Visual mode // When splitting the quickfix window open a new buffer in it, // don't replicate the quickfix buffer. @@ -310,7 +300,6 @@ void do_window(int nchar, int Prenum, int xchar) // split current window and edit alternate file case Ctrl_HAT: case '^': - CHECK_CMDWIN; reset_VIsual_and_resel(); // stop Visual mode if (buflist_findnr(Prenum == 0 ? curwin->w_alt_fnum : Prenum) == NULL) { @@ -331,7 +320,6 @@ void do_window(int nchar, int Prenum, int xchar) // open new window case Ctrl_N: case 'n': - CHECK_CMDWIN; reset_VIsual_and_resel(); // stop Visual mode newwindow: if (Prenum) { @@ -366,7 +354,6 @@ newwindow: // close preview window case Ctrl_Z: case 'z': - CHECK_CMDWIN; reset_VIsual_and_resel(); // stop Visual mode do_cmdline_cmd("pclose"); break; @@ -391,7 +378,6 @@ newwindow: // close all but current window case Ctrl_O: case 'o': - CHECK_CMDWIN; reset_VIsual_and_resel(); // stop Visual mode cmd_with_count("only", cbuf, sizeof(cbuf), Prenum); do_cmdline_cmd(cbuf); @@ -402,7 +388,6 @@ newwindow: case 'w': // cursor to previous window with wrap around case 'W': - CHECK_CMDWIN; if (ONE_WINDOW && Prenum != 1) { // just one window beep_flush(); } else { @@ -454,7 +439,6 @@ newwindow: case 'j': case K_DOWN: case Ctrl_J: - CHECK_CMDWIN; win_goto_ver(false, Prenum1); break; @@ -462,7 +446,6 @@ newwindow: case 'k': case K_UP: case Ctrl_K: - CHECK_CMDWIN; win_goto_ver(true, Prenum1); break; @@ -471,7 +454,6 @@ newwindow: case K_LEFT: case Ctrl_H: case K_BS: - CHECK_CMDWIN; win_goto_hor(true, Prenum1); break; @@ -479,13 +461,11 @@ newwindow: case 'l': case K_RIGHT: case Ctrl_L: - CHECK_CMDWIN; win_goto_hor(false, Prenum1); break; // move window to new tab page case 'T': - CHECK_CMDWIN; if (one_window(curwin, NULL)) { msg(_(m_onlyone), 0); } else { @@ -533,21 +513,18 @@ newwindow: // exchange current and next window case 'x': case Ctrl_X: - CHECK_CMDWIN; win_exchange(Prenum); break; // rotate windows downwards case Ctrl_R: case 'r': - CHECK_CMDWIN; reset_VIsual_and_resel(); // stop Visual mode win_rotate(false, Prenum1); // downwards break; // rotate windows upwards case 'R': - CHECK_CMDWIN; reset_VIsual_and_resel(); // stop Visual mode win_rotate(true, Prenum1); // upwards break; @@ -557,7 +534,6 @@ newwindow: case 'J': case 'H': case 'L': - CHECK_CMDWIN; if (one_window(curwin, NULL)) { beep_flush(); } else { @@ -608,7 +584,6 @@ newwindow: // jump to tag and split window if tag exists (in preview window) case '}': - CHECK_CMDWIN; if (Prenum) { g_do_tagpreview = Prenum; } else { @@ -617,7 +592,6 @@ newwindow: FALLTHROUGH; case ']': case Ctrl_RSB: - CHECK_CMDWIN; // Keep visual mode, can select words to use as a tag. if (Prenum) { postponed_split = Prenum; @@ -640,7 +614,6 @@ newwindow: case 'F': case Ctrl_F: { wingotofile: - CHECK_CMDWIN; if (check_text_or_curbuf_locked(NULL)) { break; } @@ -698,7 +671,6 @@ wingotofile: FALLTHROUGH; case 'd': // Go to definition, using 'define' case Ctrl_D: { - CHECK_CMDWIN; size_t len; char *ptr; if ((len = find_ident_under_cursor(&ptr, FIND_IDENT, NULL)) == 0) { @@ -726,7 +698,6 @@ wingotofile: // CTRL-W g extended commands case 'g': case Ctrl_G: - CHECK_CMDWIN; no_mapping++; allow_keys++; // no mapping for xchar, but allow key codes if (xchar == NUL) { @@ -4936,10 +4907,6 @@ void goto_tabpage(int n) /// @param trigger_leave_autocmds when true trigger *Leave autocommands. void goto_tabpage_tp(tabpage_T *tp, bool trigger_enter_autocmds, bool trigger_leave_autocmds) { - if (trigger_enter_autocmds || trigger_leave_autocmds) { - CHECK_CMDWIN; - } - // Don't repeat a message in another tab page. set_keep_msg(NULL, 0); diff --git a/test/functional/vimscript/api_functions_spec.lua b/test/functional/vimscript/api_functions_spec.lua index b341c191d6..cc08108d15 100644 --- a/test/functional/vimscript/api_functions_spec.lua +++ b/test/functional/vimscript/api_functions_spec.lua @@ -60,7 +60,7 @@ describe('eval-API', function() eq('Vim(call):E5555: API call: Invalid buffer id: 17', err) end) - it('cannot change text or window if textlocked', function() + it('cannot change text or window if textlock', function() command('autocmd TextYankPost ++once call nvim_buf_set_lines(0, 0, -1, v:false, [])') matches( 'Vim%(call%):E5555: API call: E565: Not allowed to change text or change window$', @@ -90,19 +90,16 @@ describe('eval-API', function() api.nvim_get_vvar('errmsg') ) - -- cmdwin behavior (changed since #40312). + -- cmdwin (#40312, #40484): E11 "Invalid in command-line window" restriction was removed. local old_win = api.nvim_get_current_win() feed('q:') local cmdwin_win = api.nvim_get_current_win() - eq( - 'Vim:E11: Invalid in command-line window; executes, CTRL-C quits', - pcall_err(api.nvim_set_current_win, old_win) - ) + neq(old_win, cmdwin_win) + -- Switching to another window from the cmdwin now works (previously E11). + api.nvim_set_current_win(old_win) eq(old_win, api.nvim_get_current_win()) - -- TODO(justinmk): awkward: E11 is raised but the focus switch happens anyway; inherited bug in - -- goto_tabpage_win (calls win_enter unconditionally even when goto_tabpage_tp's CHECK_CMDWIN - -- emsg'd). We should probably just remove CHECK_CMDWIN from goto_tabpage_tp. #40407 - pcall(api.nvim_set_current_win, cmdwin_win) + -- ...and back into the cmdwin. + api.nvim_set_current_win(cmdwin_win) eq(cmdwin_win, api.nvim_get_current_win()) -- nvim_buf_set_lines() in the cmdwin buffer is OK. diff --git a/test/old/testdir/test_normal.vim b/test/old/testdir/test_normal.vim index 4f57251036..1f25bf7c3c 100644 --- a/test/old/testdir/test_normal.vim +++ b/test/old/testdir/test_normal.vim @@ -3242,11 +3242,8 @@ func Test_normal50_commandline() func! DoTimerWork(id) call assert_equal(1, getbufinfo('')[0].command) - " should fail, with E11, but does fail with E23? - "call feedkeys("\", 'tm') - - " should fail with E11 - "Invalid in command-line window" - call assert_fails(":wincmd p", 'E11') + " Nvim removed the E11 "Invalid in command-line window" restriction (#40312, #40484). + "call assert_fails(":wincmd p", 'E11') " Return from commandline window. call feedkeys("\", 't')