From fbcb7a056cef7a5efd7aa7f494365a04b1c86895 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 27 Jul 2026 11:12:47 -0400 Subject: [PATCH] feat(exmode): "1q:", :exmode #41010 Problem: Want `gQ` for _le multicursor_. Solution: - Don't use `gQ` for exmode. - Introduce `:exmode`. - Introduce `[count]q:` as an alias to `:exmode`. --- runtime/doc/index.txt | 5 ++-- runtime/doc/intro.txt | 8 ++++--- runtime/doc/news.txt | 3 ++- runtime/doc/quickref.txt | 2 +- runtime/doc/vim_diff.txt | 3 ++- runtime/lua/vim/_core/exmode.lua | 5 ++-- src/nvim/ex_cmds.lua | 6 +++++ src/nvim/ex_docmd.c | 15 ++++++++++++ src/nvim/main.c | 3 +-- src/nvim/normal.c | 25 +++++++------------ test/functional/api/vim_spec.lua | 2 +- test/functional/core/exit_spec.lua | 2 +- test/functional/core/startup_spec.lua | 6 ++--- test/functional/ex_cmds/normal_spec.lua | 8 +++---- test/functional/legacy/ex_mode_spec.lua | 32 +++++++++++++++++-------- test/functional/legacy/global_spec.lua | 4 ++-- test/functional/ui/cmdline_spec.lua | 12 +++++----- test/functional/ui/messages_spec.lua | 2 +- test/old/testdir/setup.vim | 2 +- test/old/testdir/test_cmdline.vim | 2 +- test/old/testdir/test_ex_mode.vim | 16 ++++++------- 21 files changed, 97 insertions(+), 66 deletions(-) diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt index 993e6f60a4..ee667bed3e 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -403,7 +403,8 @@ Tag Char Note Normal-mode action ~ {0-9a-zA-Z"} (uppercase to append) |q| q (while recording) stops recording |Q| Q 2 replay last recorded register -|q:| q: edit : command-line in command-line window +|q:| [count]q: edit : command-line in command-line window, + with [count]: switch to |Ex-mode| |q/| q/ edit / command-line in command-line window |q?| q? edit ? command-line in command-line window |r| r{char} 2 replace N chars with {char} @@ -743,7 +744,6 @@ Tag Char Note Normal-mode action ~ search pattern and Visually select it |gP| ["x]gP 2 put the text [from register x] before the cursor N times, leave the cursor after it -|gQ| gQ switch to "Ex" mode with Vim editing |gR| gR 2 enter Virtual Replace mode |gT| gT go to the previous tabpage |gU| gU{motion} 2 make Nmove text uppercase @@ -1312,6 +1312,7 @@ Tag Command Action ~ |:ex| :ex same as ":edit" |:execute| :exe[cute] execute result of expressions |:exit| :exi[t] same as ":xit" +|:exmode| :exm[ode] switch to |Ex-mode| |:exusage| :exu[sage] overview of Ex commands |:fclose| :fc[lose] close floating window |:file| :f[ile] show or set the current file name diff --git a/runtime/doc/intro.txt b/runtime/doc/intro.txt index 53ecd1c51b..45890af1b9 100644 --- a/runtime/doc/intro.txt +++ b/runtime/doc/intro.txt @@ -340,7 +340,7 @@ CTRL-O in Insert mode you get a beep but you are still in Insert mode, type > FROM mode TO mode Normal Visual Select Insert Replace Cmd-line Ex > - Normal v V ^V *4 *1 R gR : / ? ! gQ + Normal v V ^V *4 *1 R gR : / ? ! 1q: Visual *2 ^G c C -- : -- Select *5 ^O ^G *6 -- -- -- Insert -- -- -- -- @@ -386,10 +386,12 @@ a command that takes an argument, such as |f| or |m|, the timeout set with *CTRL-\_CTRL-G* *i_CTRL-\_CTRL-G* *c_CTRL-\_CTRL-G* *v_CTRL-\_CTRL-G* CTRL-\ CTRL-G works the same as |CTRL-\_CTRL-N| for backward compatibility. - *gQ* *mode-Ex* *Ex-mode* *Ex* *EX* *E501* -gQ Switch to Ex mode. This is like typing ":" commands + *:exm* *:exmode* *gQ* *mode-Ex* *Ex-mode* *Ex* *EX* *E501* +:exm[ode] +[count]q: Switch to Ex mode. This is like typing ":" commands one after another, except you don't have to keep pressing ":". Use |:visual| to exit this mode. + Without [count], "q:" opens the regular |cmdwin|. Implementation details: a persistent |cmdwin| where executes the current line as a command diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 4e08457c14..3b3914acf1 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -93,10 +93,11 @@ DIAGNOSTICS EDITOR -• Interactive |Ex-mode| (|gQ|, `nvim -e`) is a persistent |cmdwin|. This is much +• Interactive |Ex-mode| (|:exmode|, `nvim -e`) is a persistent |cmdwin|. This is much more flexible and makes "Ex mode" more useful as a kind of "cmdline REPL", with the tradeoff of dropping some POSIX Ex-mode quirks. • |mode()| returns "n" or "i"; "cv" indicates |-es| (script mode) only. + • Ex mode is entered with "1q:" or |:exmode|, not "gQ". • ":global/pat/visual" no longer switches to Normal mode per matching line. • Non-interactive Ex-mode (|-es|, "script mode") executes stdin as Ex commands directly. It is a "script host", not "POSIX Ex mode". diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt index 3de268c57c..e2c5c64629 100644 --- a/runtime/doc/quickref.txt +++ b/runtime/doc/quickref.txt @@ -1019,7 +1019,7 @@ Short explanation of each option: *option-list* |:version| :ve[rsion] show version information |:normal| :norm[al][!] {commands} execute Normal mode commands -|gQ| gQ switch to |Ex-mode| +|:exmode| 1q: switch to |Ex-mode| |:redir| :redir >{file} redirect messages to {file} |:silent| :silent[!] {command} execute {command} silently diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index b10f7bedc5..f77c8a03c6 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -401,7 +401,8 @@ Input/Mappings: Normal commands: - |gO| shows a filetype-defined "outline" of the current buffer. -- |Q| replays the last recorded macro instead of switching to Ex mode (|gQ|). +- |Q| replays the last recorded macro instead of switching to Ex mode. +- [count]q: enters |Ex-mode|. - |ZR| performs |:restart| - |v_al| selects the whole buffer; |v_il| selects the current line without leading or trailing white space. diff --git a/runtime/lua/vim/_core/exmode.lua b/runtime/lua/vim/_core/exmode.lua index c13a91ba9f..c0817f8567 100644 --- a/runtime/lua/vim/_core/exmode.lua +++ b/runtime/lua/vim/_core/exmode.lua @@ -1,6 +1,6 @@ --- Ex mode. --- - `run()`: non-interactive (`nvim -es`): executes stdin as Ex commands. ---- - `open()`: interactive (`gQ`, `nvim -e`), a keep-open "cmdwin" REPL. +--- - `open()`: interactive (`[count]q:`, `nvim -e`), a keep-open "cmdwin" REPL. local api = vim.api local N_ = vim.fn.gettext @@ -101,6 +101,7 @@ function M.open() return -- cmdwin failed to open (E1292 already echoed). end local buf = api.nvim_get_current_buf() + api.nvim_buf_set_name(buf, N_('[Ex mode]')) local block_start = api.nvim_buf_line_count(buf) cont_lines = {} vim.wo[0][0].statuscolumn = '%#NonText#%{v:lua.require("vim._core.exmode")._statuscolumn()}' @@ -216,7 +217,7 @@ function M.open() vim.keymap.set({ 'n', 'i' }, '', run, { buffer = buf }) vim.keymap.set({ 'n', 'i' }, '', run, { buffer = buf }) - -- Enter Insert mode before any already-typed keys, so `gQcmd` types "cmd" into the REPL. + -- Enter Insert mode before any already-typed keys, so `1q:cmd` types "cmd" into the REPL. api.nvim_feedkeys('i', 'ni', false) end diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 5654206351..dc5c478500 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -962,6 +962,12 @@ M.cmds = { addr_type = 'ADDR_LINES', func = 'ex_exit', }, + { + command = 'exmode', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_exmode', + }, { command = 'exusage', flags = bit.bor(TRLBAR), diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 816614f26c..af0cc12ee4 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -4846,6 +4846,21 @@ static void ex_quitall(exarg_T *eap) not_exiting(save_exiting); } +/// ":exmode": Enter interactive Ex mode. +static void ex_exmode(exarg_T *eap) +{ + if (silent_mode) { + return; + } + if (ex_normal_busy > 0 || global_busy) { + // Ex mode cannot run inside ":normal" or ":global"; discard the rest of the command. + flush_buffers(FLUSH_TYPEAHEAD); + return; + } + typval_T args[] = { { .v_type = VAR_UNKNOWN } }; + nlua_call_typval("vim._core.exmode", "open", args, NULL); +} + /// ":restart": restart the Nvim server (using ":qall!"). /// ":restart +cmd": restart the Nvim server using ":cmd". /// ":restart +cmd ": restart the Nvim server using ":cmd" and runs in the new server. diff --git a/src/nvim/main.c b/src/nvim/main.c index 257a2d1b37..8ecd860f5d 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -687,8 +687,7 @@ int main(int argc, char **argv) if (params.exmode) { // Interactive Ex mode (-e/-E): cmdwin REPL. #40962 - typval_T args[] = { { .v_type = VAR_UNKNOWN } }; - nlua_call_typval("vim._core.exmode", "open", args, NULL); + do_cmdline_cmd("exmode"); } TIME_MSG("before starting main loop"); diff --git a/src/nvim/normal.c b/src/nvim/normal.c index e33ca7741b..96ec70a257 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -279,7 +279,7 @@ static const struct nv_cmd { { 'n', nv_next, 0, 0 }, { 'o', nv_open, 0, 0 }, { 'p', nv_put, 0, 0 }, - { 'q', nv_record, NV_NCH, 0 }, + { 'q', nv_q, NV_NCH, 0 }, { 'r', nv_replace, NV_NCH_NOP|NV_LANG, 0 }, { 's', nv_subst, NV_KEEPREG, 0 }, { 't', nv_csearch, NV_NCH_ALW|NV_LANG, FORWARD }, @@ -5673,19 +5673,6 @@ static void nv_g_cmd(cmdarg_T *cap) goto_byte(cap->count0); break; - // "gQ": improved Ex mode - case 'Q': - if (!check_text_locked(cap->oap) && !checkclearopq(oap)) { - if (ex_normal_busy > 0 || global_busy) { - // Ex mode cannot run inside ":normal" or ":global"; discard the rest of the command. - flush_buffers(FLUSH_TYPEAHEAD); - } else if (!silent_mode) { - typval_T args[] = { { .v_type = VAR_UNKNOWN } }; - nlua_call_typval("vim._core.exmode", "open", args, NULL); - } - } - break; - case ',': nv_pcmark(cap); break; @@ -6370,9 +6357,10 @@ static void nv_object(cmdarg_T *cap) curwin->w_set_curswant = true; } -/// "q" command: Start/stop recording. +/// "q" command: Start/stop macro recording. /// "q:", "q/", "q?": cmdwin. -static void nv_record(cmdarg_T *cap) +/// "[count]q:": interactive Ex-mode. +static void nv_q(cmdarg_T *cap) { if (cap->oap->op_type == OP_FORMAT) { // "gqq" is the same as "gqgq": format line @@ -6391,6 +6379,11 @@ static void nv_record(cmdarg_T *cap) emsg(_(e_cmdline_window_already_open)); return; } + if (cap->nchar == ':' && cap->count0 > 0) { + // "[count]q:": interactive Ex mode. E565 on textlock. + do_cmdline_cmd("exmode"); + return; + } bool insert_range = Visual.active && cap->nchar == ':'; char fc[2] = { (char)cap->nchar, 0 }; typval_T tv_args[] = { diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 218b81362c..5b76d8a8c7 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -5321,7 +5321,7 @@ describe('API', function() insert([[ foo bar]]) - feed('gQ1') + feed('1q:1') screen:expect({ any = vim.pesc('{1::}1^') }) eq('Parsing command-line', pcall_err(api.nvim_parse_cmd, '', {})) -- Executing the line still auto-prints it. diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua index ffbc946bae..19cad4f4d2 100644 --- a/test/functional/core/exit_spec.lua +++ b/test/functional/core/exit_spec.lua @@ -56,7 +56,7 @@ describe('exit:', function() it('v:exiting=0, v:exitreason=quit on exit from Ex mode try-catch vim-patch:8.0.0184', function() test_exiting(function() - feed('gQ') + feed('1q:') feed_command('try', 'call NoFunction()', 'catch', 'echo "bye"', 'endtry', 'quit') end) end) diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index 1eaef3fdea..6904fdc1a5 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -870,7 +870,7 @@ describe('startup', function() {1:~ }|*6 {2:[No Name] [+] }| {1::}^ | - {3:[Command Line] }| + {3:[Ex mode] }| {5:-- INSERT --} | ]]) @@ -883,7 +883,7 @@ describe('startup', function() {1:~ }|*6 {2:[No Name] [+] }| {1::}^ | - {3:[Command Line] }| + {3:[Ex mode] }| {5:-- INSERT --} | ]]) end) @@ -892,7 +892,7 @@ describe('startup', function() clear('-e') local screen = Screen.new(40, 12) -- The keep-open cmdwin REPL is focused, in Insert mode. #40962 - screen:expect({ any = vim.pesc('[Command Line]') }) + screen:expect({ any = vim.pesc('[Ex mode]') }) eq(':', fn.getcmdwintype()) feed('visual') eq('n', fn.mode(1)) diff --git a/test/functional/ex_cmds/normal_spec.lua b/test/functional/ex_cmds/normal_spec.lua index db0a0bc976..cb14bf9c88 100644 --- a/test/functional/ex_cmds/normal_spec.lua +++ b/test/functional/ex_cmds/normal_spec.lua @@ -14,19 +14,19 @@ before_each(clear) describe(':normal!', function() it('can get out of Insert mode if called from Ex mode #17924', function() - feed('gQnormal! Ifoo') + feed('1q:normal! Ifoo') feed('visual') expect('foo') end) it('does not execute command in Ex mode when running out of characters', function() command('let g:var = 0') - command('normal! gQlet g:var = 1') + command('normal! 1q:let g:var = 1') eq(0, eval('g:var')) end) - it('gQinsert does not hang #17980', function() - command('normal! gQinsert') + it('"1q:insert" does not hang #17980', function() + command('normal! 1q:insert') expect('') end) diff --git a/test/functional/legacy/ex_mode_spec.lua b/test/functional/legacy/ex_mode_spec.lua index 996b5a6b38..8c7b8aa9f7 100644 --- a/test/functional/legacy/ex_mode_spec.lua +++ b/test/functional/legacy/ex_mode_spec.lua @@ -11,18 +11,18 @@ local fn = n.fn before_each(clear) --- Interactive Ex mode (gQ) is a keep-open |cmdwin| REPL. #40962 +-- Interactive Ex mode ([count]q:) is a keep-open |cmdwin| REPL. #40962 describe('Ex mode', function() it('executes commands against the caller window, auto-prints, records history', function() local screen = Screen.new(60, 10) command([[call setline(1, ['line1', 'line2', 'line3'])]]) - feed('gQ') + feed('1q:') screen:expect([[ line1 | {2:[No Name] [+] }| {1::}^ | {1:~ }|*5 - {3:[Command Line] }| + {3:[Ex mode] }| {5:-- INSERT --} | ]]) t.matches('Entering Ex mode%.', n.exec_capture('messages')) @@ -32,12 +32,24 @@ describe('Ex mode', function() eq({ 'line1', 'inserted', 'line2', 'line3' }, fn.getline(1, '$')) eq('visual', fn.histget('cmd', -1)) eq("put ='inserted'", fn.histget('cmd', -2)) + -- Ex mode can be re-entered (the "[Ex mode]" buffer name is not duplicated). + feed('1q:') + screen:expect({ any = vim.pesc('{3:[Ex mode]') }) + feed('visual') + eq('n', fn.mode(1)) + -- ":exmode" (but not ":ex", which is ":edit") also enters Ex mode. + eq('ex', fn.fullcommand('ex')) + eq('exmode', fn.fullcommand('exm')) + command('exmode') + screen:expect({ any = vim.pesc('{3:[Ex mode]') }) + feed('visual') + eq('n', fn.mode(1)) end) it('bare address and empty line move the cursor and auto-print', function() local screen = Screen.new(60, 8) command([[call setline(1, ['line1', 'line2'])]]) - feed('gQ') + feed('1q:') feed('1') -- Bare address: move and auto-print. screen:expect({ any = vim.pesc('" line1') }) feed('') -- Empty line: advance and auto-print (POSIX ex "+"). @@ -50,7 +62,7 @@ describe('Ex mode', function() it('explicit :print is not doubled by auto-print', function() command([[call setline(1, ['line1', 'line2'])]]) - feed('gQ') + feed('1q:') feed('1,2print') -- Transcript records each printed line once, not the cursor line again. eq({ '1,2print', '" line1', '" line2', '' }, n.api.nvim_buf_get_lines(0, 0, -1, false)) @@ -61,7 +73,7 @@ describe('Ex mode', function() local screen = Screen.new(60, 8) command('set inccommand=') command([[call setline(1, repeat(['foo foo'], 2))]]) - feed('gQ') + feed('1q:') feed('%s/foo/bar/gc') screen:expect({ any = vim.pesc('replace with bar? (y)es/(n)o/(a)ll') }) feed('y') -- Replace the first match ... @@ -73,7 +85,7 @@ describe('Ex mode', function() it('collects multi-line commands until the block is complete', function() local screen = Screen.new(60, 10) - feed('gQ') + feed('1q:') feed('append') -- Continuation lines should not have ":" prefix in 'statuscolumn'. screen:expect([[ @@ -82,7 +94,7 @@ describe('Ex mode', function() {1::}append | {1: }^ | {1:~ }|*4 - {3:[Command Line] }| + {3:[Ex mode] }| {5:-- INSERT --} | ]]) feed('x1x2.') @@ -102,7 +114,7 @@ describe('Ex mode', function() {1::}let g:x = 0 | {1::}if 1 | {1: }^ | - {3:[Command Line] }| + {3:[Ex mode] }| {5:-- INSERT --} | ]]) feed('let g:x = 1endif') @@ -116,7 +128,7 @@ describe('Ex mode', function() end) it('pressing Ctrl-C in :append inside a loop does not hang', function() - feed('gQ') + feed('1q:') feed('for i in range(1)') feed('append') -- CTRL-C cancels the cmdwin (ends Ex mode): back to the ":" cmdline, like |q:|. diff --git a/test/functional/legacy/global_spec.lua b/test/functional/legacy/global_spec.lua index 7e427881c2..da82d07655 100644 --- a/test/functional/legacy/global_spec.lua +++ b/test/functional/legacy/global_spec.lua @@ -31,7 +31,7 @@ describe(':global', function() ]]) -- Also test in Ex mode (keep-open cmdwin REPL) - feed('gQg/foo/norm :;') + feed('1q:g/foo/norm :;') poke_eventloop() -- Wait for :sleep to start feed('') screen:expect([[ @@ -39,7 +39,7 @@ describe(':global', function() {2:[No Name] [+] }| {1::}" Keyboard interrupt | {1::}^ | - {3:[Command Line] }| + {3:[Ex mode] }| {5:-- INSERT --} | ]]) end) diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua index 39612cf072..aeabb4ad88 100644 --- a/test/functional/ui/cmdline_spec.lua +++ b/test/functional/ui/cmdline_spec.lua @@ -783,14 +783,14 @@ local function test_cmdline(linegrid) it('works with exmode', function() screen:try_resize(60, 12) - feed('gQ') + feed('1q:') screen:expect([[ | {1:~ }| {2:[No Name] }| {1::}^ | {1:~ }|*6 - {3:[Command Line] }| + {3:[Ex mode] }| {5:-- INSERT --} | ]]) feed('echo "foo"') @@ -802,7 +802,7 @@ local function test_cmdline(linegrid) {1::}" foo | {1::}^ | {1:~ }|*4 - {3:[Command Line] }| + {3:[Ex mode] }| {5:-- INSERT --} | ]]) feed('vis') @@ -1229,14 +1229,14 @@ it('tabline is not redrawn in Ex mode #24122', function() endfunction ]]) - feed('gQ') + feed('1q:') screen:expect([[ {2:foo }| | {2:[No Name] }| {1::}^ | {1:~ }|*2 - {3:[Command Line] }| + {3:[Ex mode] }| {5:-- INSERT --} | ]]) feed('echo 1') @@ -1247,7 +1247,7 @@ it('tabline is not redrawn in Ex mode #24122', function() {1::}echo 1 | {1::}" 1 | {1::}^ | - {3:[Command Line] }| + {3:[Ex mode] }| {5:-- INSERT --} | ]]) end) diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index 6e8dac1c2a..e63068fe56 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -2091,7 +2091,7 @@ describe('ui/builtin messages', function() command('set number') api.nvim_buf_set_lines(0, 0, 0, true, { 'aaa', 'bbb', 'ccc' }) -- Empty lines advance the cursor and print; a bare address moves and prints. - feed('gggQ1') + feed('gg1q:1') screen:expect({ any = vim.pesc('" bbb') }) feed('vi') screen:expect([[ diff --git a/test/old/testdir/setup.vim b/test/old/testdir/setup.vim index efc63d24b1..23ada4b84f 100644 --- a/test/old/testdir/setup.vim +++ b/test/old/testdir/setup.vim @@ -38,7 +38,7 @@ if exists('s:did_load') if g:testname !~ 'test_mapping\.vim$' " Make "Q" switch to Ex mode. " This does not work for all tests as Nvim only supports Vim Ex mode. - nnoremap Q gQcallExStart() + nnoremap Q 1q:callExStart() endif endif diff --git a/test/old/testdir/test_cmdline.vim b/test/old/testdir/test_cmdline.vim index b3acb81a2e..0369b15b8f 100644 --- a/test/old/testdir/test_cmdline.vim +++ b/test/old/testdir/test_cmdline.vim @@ -2606,7 +2606,7 @@ func Test_cmdwin_ex_mode_with_modifier() " this was accessing memory after allocated text in Ex mode new call setline(1, ['some', 'text', 'lines']) - silent! call feedkeys("gQnormal vq:atopleft\\\", 'xt') + silent! call feedkeys("1q:normal vq:atopleft\\\", 'xt') bwipe! endfunc diff --git a/test/old/testdir/test_ex_mode.vim b/test/old/testdir/test_ex_mode.vim index dd36f6aa91..a3d2c85be7 100644 --- a/test/old/testdir/test_ex_mode.vim +++ b/test/old/testdir/test_ex_mode.vim @@ -71,7 +71,7 @@ func Test_Ex_substitute() call term_sendkeys(buf, ":call setline(1, repeat(['foo foo'], 4))\") call term_sendkeys(buf, ":set number\") - call term_sendkeys(buf, "gQ") + call term_sendkeys(buf, "1q:") call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000) call term_sendkeys(buf, "%s/foo/bar/gc\") @@ -217,7 +217,7 @@ func Test_Ex_append_in_loop() CheckRunVimInTerminal let buf = RunVimInTerminal('', {'rows': 6}) - call term_sendkeys(buf, "gQ") + call term_sendkeys(buf, "1q:") call term_sendkeys(buf, "for i in range(1)\") call term_sendkeys(buf, "append\") call WaitForAssert({-> assert_match(': append', term_getline(buf, 5))}, 1000) @@ -260,7 +260,7 @@ endfunc func Test_ex_mode_errors() " Not allowed to enter ex mode when text is locked - au InsertCharPre normal! gQ + au InsertCharPre normal! 1q: let caught_e565 = 0 try call feedkeys("ix\", 'xt') @@ -275,13 +275,13 @@ func Test_ex_mode_errors() func ExEnterFunc() endfunc - call feedkeys("gQvi\r", 'xt') + call feedkeys("1q:vi\r", 'xt') au! CmdLineEnter delfunc ExEnterFunc au CmdlineEnter * : - call feedkeys("gQecho 1\r", 'xt') + call feedkeys("1q:echo 1\r", 'xt') au! CmdlineEnter @@ -298,7 +298,7 @@ func Test_ex_mode_with_global() " call ch_logfile('logfile', 'w') pedit func FeedQ(id) - call feedkeys('gQ', 't') + call feedkeys('1q:', 't') endfunc call timer_start(10, 'FeedQ') g/^/vi|HJ @@ -320,7 +320,7 @@ func Test_ex_mode_count_overflow() " this used to cause a crash let lines =<< trim END - call feedkeys("\gQ\") + call feedkeys("\1q:\") v9|9silent! vi|333333233333y32333333%O call writefile(['done'], 'Xdidexmode') qall! @@ -337,7 +337,7 @@ func Test_ex_mode_large_indent() new set ts=500 ai call setline(1, "\t") - exe "normal gQi\." + exe "normal 1q:i\." set ts=8 noai bwipe! endfunc