diff options
Diffstat (limited to 'test/functional/ui/inccommand_spec.lua')
-rw-r--r-- | test/functional/ui/inccommand_spec.lua | 1833 |
1 files changed, 792 insertions, 1041 deletions
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index 3ee67a710c..29c8c43ca1 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -4,18 +4,17 @@ local clear = helpers.clear local command = helpers.command local eq = helpers.eq local eval = helpers.eval -local feed_command = helpers.feed_command local expect = helpers.expect local feed = helpers.feed local insert = helpers.insert -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local neq = helpers.neq local ok = helpers.ok local retry = helpers.retry local source = helpers.source local poke_eventloop = helpers.poke_eventloop -local nvim = helpers.nvim -local sleep = helpers.sleep +local sleep = vim.uv.sleep local testprg = helpers.testprg local assert_alive = helpers.assert_alive @@ -32,7 +31,7 @@ local multiline_text = [[ 7 8 9 ]] -local multimatch_text = [[ +local multimatch_text = [[ a bdc eae a fgl lzia r x ]] @@ -62,70 +61,70 @@ local long_multiline_text = [[ local function common_setup(screen, inccommand, text) if screen then - command("syntax on") - command("set nohlsearch") - command("hi Substitute guifg=red guibg=yellow") + command('syntax on') + command('set nohlsearch') + command('hi Substitute guifg=red guibg=yellow') screen:attach() screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Fuchsia}, - [2] = {foreground = Screen.colors.Brown, bold = true}, - [3] = {foreground = Screen.colors.SlateBlue}, - [4] = {bold = true, foreground = Screen.colors.SlateBlue}, - [5] = {foreground = Screen.colors.DarkCyan}, - [6] = {bold = true}, - [7] = {underline = true, bold = true, foreground = Screen.colors.SlateBlue}, - [8] = {foreground = Screen.colors.Slateblue, underline = true}, - [9] = {background = Screen.colors.Yellow}, - [10] = {reverse = true}, - [11] = {reverse = true, bold=true}, - [12] = {foreground = Screen.colors.Red, background = Screen.colors.Yellow}, - [13] = {bold = true, foreground = Screen.colors.SeaGreen}, - [14] = {foreground = Screen.colors.White, background = Screen.colors.Red}, - [15] = {bold=true, foreground=Screen.colors.Blue}, - [16] = {background=Screen.colors.Grey90}, -- cursorline - [17] = {foreground = Screen.colors.Blue1}, - vis = {background=Screen.colors.LightGrey} + [1] = { foreground = Screen.colors.Fuchsia }, + [2] = { foreground = Screen.colors.Brown, bold = true }, + [3] = { foreground = Screen.colors.SlateBlue }, + [4] = { bold = true, foreground = Screen.colors.SlateBlue }, + [5] = { foreground = Screen.colors.DarkCyan }, + [6] = { bold = true }, + [7] = { underline = true, bold = true, foreground = Screen.colors.SlateBlue }, + [8] = { foreground = Screen.colors.Slateblue, underline = true }, + [9] = { background = Screen.colors.Yellow }, + [10] = { reverse = true }, + [11] = { reverse = true, bold = true }, + [12] = { foreground = Screen.colors.Red, background = Screen.colors.Yellow }, + [13] = { bold = true, foreground = Screen.colors.SeaGreen }, + [14] = { foreground = Screen.colors.White, background = Screen.colors.Red }, + [15] = { bold = true, foreground = Screen.colors.Blue }, + [16] = { background = Screen.colors.Grey90 }, -- cursorline + [17] = { foreground = Screen.colors.Blue1 }, + vis = { background = Screen.colors.LightGrey }, }) end - command("set inccommand=" .. (inccommand or "")) + command('set inccommand=' .. (inccommand or '')) if text then insert(text) end end -describe(":substitute, inccommand=split interactivity", function() +describe(':substitute, inccommand=split interactivity', function() before_each(function() clear() - common_setup(nil, "split", default_text) + common_setup(nil, 'split', default_text) end) -- Test the tests: verify that the `1==bufnr('$')` assertion -- in the "no preview" tests (below) actually means something. - it("previews interactive cmdline", function() + it('previews interactive cmdline', function() feed(':%s/tw/MO/g') retry(nil, 1000, function() eq(2, eval("bufnr('$')")) end) end) - it("no preview if invoked by a script", function() + it('no preview if invoked by a script', function() source('%s/tw/MO/g') poke_eventloop() eq(1, eval("bufnr('$')")) -- sanity check: assert the buffer state - expect(default_text:gsub("tw", "MO")) + expect(default_text:gsub('tw', 'MO')) end) - it("no preview if invoked by feedkeys()", function() + it('no preview if invoked by feedkeys()', function() -- in a script... source([[:call feedkeys(":%s/tw/MO/g\<CR>")]]) -- or interactively... feed([[:call feedkeys(":%s/bs/BUU/g\<lt>CR>")<CR>]]) eq(1, eval("bufnr('$')")) -- sanity check: assert the buffer state - expect(default_text:gsub("tw", "MO"):gsub("bs", "BUU")) + expect(default_text:gsub('tw', 'MO'):gsub('bs', 'BUU')) end) end) @@ -133,17 +132,17 @@ describe(":substitute, 'inccommand' preserves", function() before_each(clear) it('listed buffers (:ls)', function() - local screen = Screen.new(30,10) - common_setup(screen, "split", "ABC") + local screen = Screen.new(30, 10) + common_setup(screen, 'split', 'ABC') - feed_command("%s/AB/BA/") - feed_command("ls") + feed(':%s/AB/BA/') + poke_eventloop() + feed('<CR>') + feed(':ls<CR>') screen:expect([[ BAC | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {11: }| :ls | 1 %a + "[No Name]" | @@ -153,43 +152,68 @@ describe(":substitute, 'inccommand' preserves", function() ]]) end) - for _, case in pairs{"", "split", "nosplit"} do - it("various delimiters (inccommand="..case..")", function() + it("'[ and '] marks #26439", function() + local screen = Screen.new(30, 10) + common_setup(screen, 'nosplit', ('abc\ndef\n'):rep(50)) + + feed('ggyG') + local X = api.nvim_get_vvar('maxcol') + eq({ 0, 1, 1, 0 }, fn.getpos("'[")) + eq({ 0, 101, X, 0 }, fn.getpos("']")) + + feed(":'[,']s/def/") + poke_eventloop() + eq({ 0, 1, 1, 0 }, fn.getpos("'[")) + eq({ 0, 101, X, 0 }, fn.getpos("']")) + + feed('DEF/g') + poke_eventloop() + eq({ 0, 1, 1, 0 }, fn.getpos("'[")) + eq({ 0, 101, X, 0 }, fn.getpos("']")) + + feed('<CR>') + expect(('abc\nDEF\n'):rep(50)) + end) + + for _, case in pairs { '', 'split', 'nosplit' } do + it('various delimiters (inccommand=' .. case .. ')', function() insert(default_text) - feed_command("set inccommand=" .. case) + command('set inccommand=' .. case) local delims = { '/', '#', ';', '%', ',', '@', '!' } - for _,delim in pairs(delims) do - feed_command("%s"..delim.."lines"..delim.."LINES"..delim.."g") + for _, delim in pairs(delims) do + feed(':%s' .. delim .. 'lines' .. delim .. 'LINES' .. delim .. 'g') + poke_eventloop() + feed('<CR>') expect([[ Inc substitution on two LINES ]]) - feed_command("undo") + command('undo') end end) end - for _, case in pairs{"", "split", "nosplit"} do - it("'undolevels' (inccommand="..case..")", function() - feed_command("set undolevels=139") - feed_command("setlocal undolevels=34") - feed_command("split") -- Show the buffer in multiple windows - feed_command("set inccommand=" .. case) - insert("as") - feed(":%s/as/glork/") + for _, case in pairs { '', 'split', 'nosplit' } do + it("'undolevels' (inccommand=" .. case .. ')', function() + command('set undolevels=139') + command('setlocal undolevels=34') + command('split') -- Show the buffer in multiple windows + command('set inccommand=' .. case) + insert('as') + feed(':%s/as/glork/') poke_eventloop() - feed("<enter>") - eq(meths.get_option_value('undolevels', {scope='global'}), 139) - eq(meths.get_option_value('undolevels', {buf=0}), 34) + feed('<enter>') + eq(api.nvim_get_option_value('undolevels', { scope = 'global' }), 139) + eq(api.nvim_get_option_value('undolevels', { buf = 0 }), 34) end) end - for _, case in ipairs({"", "split", "nosplit"}) do - it("empty undotree() (inccommand="..case..")", function() - feed_command("set undolevels=1000") - feed_command("set inccommand=" .. case) - local expected_undotree = eval("undotree()") + for _, case in ipairs({ '', 'split', 'nosplit' }) do + it('empty undotree() (inccommand=' .. case .. ')', function() + command('set undolevels=1000') + command('set inccommand=' .. case) + local expected_undotree = eval('undotree()') -- Start typing an incomplete :substitute command. feed([[:%s/e/YYYY/g]]) @@ -198,15 +222,15 @@ describe(":substitute, 'inccommand' preserves", function() feed([[<C-\><C-N>]]) -- The undo tree should be unchanged. - eq(expected_undotree, eval("undotree()")) - eq({}, eval("undotree()")["entries"]) + eq(expected_undotree, eval('undotree()')) + eq({}, eval('undotree()')['entries']) end) end - for _, case in ipairs({"", "split", "nosplit"}) do - it("undotree() with branches (inccommand="..case..")", function() - feed_command("set undolevels=1000") - feed_command("set inccommand=" .. case) + for _, case in ipairs({ '', 'split', 'nosplit' }) do + it('undotree() with branches (inccommand=' .. case .. ')', function() + command('set undolevels=1000') + command('set inccommand=' .. case) -- Make some changes. feed([[isome text 1<C-\><C-N>]]) feed([[osome text 2<C-\><C-N>]]) @@ -224,8 +248,8 @@ describe(":substitute, 'inccommand' preserves", function() some text 1 some text 3XX some text 5]]) - local expected_undotree = eval("undotree()") - eq(5, #expected_undotree["entries"]) -- sanity + local expected_undotree = eval('undotree()') + eq(5, #expected_undotree['entries']) -- sanity -- Start typing an incomplete :substitute command. feed([[:%s/e/YYYY/g]]) @@ -234,31 +258,31 @@ describe(":substitute, 'inccommand' preserves", function() feed([[<C-\><C-N>]]) -- The undo tree should be unchanged. - eq(expected_undotree, eval("undotree()")) + eq(expected_undotree, eval('undotree()')) end) end - for _, case in pairs{"", "split", "nosplit"} do - it("b:changedtick (inccommand="..case..")", function() - feed_command("set inccommand=" .. case) + for _, case in pairs { '', 'split', 'nosplit' } do + it('b:changedtick (inccommand=' .. case .. ')', function() + command('set inccommand=' .. case) feed([[isome text 1<C-\><C-N>]]) feed([[osome text 2<C-\><C-N>]]) - local expected_tick = eval("b:changedtick") + local expected_tick = eval('b:changedtick') ok(expected_tick > 0) expect([[ some text 1 some text 2]]) - feed(":%s/e/XXX/") + feed(':%s/e/XXX/') poke_eventloop() - eq(expected_tick, eval("b:changedtick")) + eq(expected_tick, eval('b:changedtick')) end) end - for _, case in ipairs({'', 'split', 'nosplit'}) do - it('previous substitute string ~ (inccommand='..case..') #12109', function() - local screen = Screen.new(30,10) + for _, case in ipairs({ '', 'split', 'nosplit' }) do + it('previous substitute string ~ (inccommand=' .. case .. ') #12109', function() + local screen = Screen.new(30, 10) common_setup(screen, case, default_text) feed(':%s/Inc/SUB<CR>') @@ -323,47 +347,51 @@ describe(":substitute, 'inccommand' preserves", function() end) describe(":substitute, 'inccommand' preserves undo", function() - local cases = { "", "split", "nosplit" } + local cases = { '', 'split', 'nosplit' } local substrings = { - ":%s/1", - ":%s/1/", - ":%s/1/<bs>", - ":%s/1/a", - ":%s/1/a<bs>", - ":%s/1/ax", - ":%s/1/ax<bs>", - ":%s/1/ax<bs><bs>", - ":%s/1/ax<bs><bs><bs>", - ":%s/1/ax/", - ":%s/1/ax/<bs>", - ":%s/1/ax/<bs>/", - ":%s/1/ax/g", - ":%s/1/ax/g<bs>", - ":%s/1/ax/g<bs><bs>" + { ':%s/', '1' }, + { ':%s/', '1', '/' }, + { ':%s/', '1', '/', '<bs>' }, + { ':%s/', '1', '/', 'a' }, + { ':%s/', '1', '/', 'a', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x' }, + { ':%s/', '1', '/', 'a', 'x', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x', '<bs>', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x', '<bs>', '<bs>', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x', '/' }, + { ':%s/', '1', '/', 'a', 'x', '/', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x', '/', '<bs>', '/' }, + { ':%s/', '1', '/', 'a', 'x', '/', 'g' }, + { ':%s/', '1', '/', 'a', 'x', '/', 'g', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x', '/', 'g', '<bs>', '<bs>' }, } local function test_sub(substring, split, redoable) command('bwipe!') - feed_command("set inccommand=" .. split) + command('set inccommand=' .. split) - insert("1") - feed("o2<esc>") - feed_command("undo") - feed("o3<esc>") + insert('1') + feed('o2<esc>') + command('undo') + feed('o3<esc>') if redoable then - feed("o4<esc>") - feed_command("undo") + feed('o4<esc>') + command('undo') + end + for _, s in pairs(substring) do + feed(s) end - feed(substring.. "<enter>") - feed_command("undo") + poke_eventloop() + feed('<enter>') + command('undo') - feed("g-") + feed('g-') expect([[ 1 2]]) - feed("g+") + feed('g+') expect([[ 1 3]]) @@ -371,30 +399,34 @@ describe(":substitute, 'inccommand' preserves undo", function() local function test_notsub(substring, split, redoable) command('bwipe!') - feed_command("set inccommand=" .. split) + command('set inccommand=' .. split) - insert("1") - feed("o2<esc>") - feed_command("undo") - feed("o3<esc>") + insert('1') + feed('o2<esc>') + command('undo') + feed('o3<esc>') if redoable then - feed("o4<esc>") - feed_command("undo") + feed('o4<esc>') + command('undo') + end + for _, s in pairs(substring) do + feed(s) end - feed(substring .. "<esc>") + poke_eventloop() + feed('<esc>') - feed("g-") + feed('g-') expect([[ 1 2]]) - feed("g+") + feed('g+') expect([[ 1 3]]) if redoable then - feed("<c-r>") + feed('<c-r>') expect([[ 1 3 @@ -402,20 +434,19 @@ describe(":substitute, 'inccommand' preserves undo", function() end end - local function test_threetree(substring, split) command('bwipe!') - feed_command("set inccommand=" .. split) - - insert("1") - feed("o2<esc>") - feed("o3<esc>") - feed("uu") - feed("oa<esc>") - feed("ob<esc>") - feed("uu") - feed("oA<esc>") - feed("oB<esc>") + command('set inccommand=' .. split) + + insert('1') + feed('o2<esc>') + feed('o3<esc>') + feed('uu') + feed('oa<esc>') + feed('ob<esc>') + feed('uu') + feed('oA<esc>') + feed('oB<esc>') -- This is the undo tree (x-Axis is timeline), we're at B now -- ----------------A - B @@ -424,33 +455,45 @@ describe(":substitute, 'inccommand' preserves undo", function() -- |/ -- 1 - 2 - 3 - feed("2u") - feed(substring .. "<esc>") + feed('2u') + for _, s in pairs(substring) do + feed(s) + poke_eventloop() + end + feed('<esc>') expect([[ 1]]) - feed("g-") + feed('g-') expect([[ ]]) - feed("g+") + feed('g+') expect([[ 1]]) - feed("<c-r>") + feed('<c-r>') expect([[ 1 A]]) - feed("g-") -- go to b - feed("2u") - feed(substring .. "<esc>") - feed("<c-r>") + feed('g-') -- go to b + feed('2u') + for _, s in pairs(substring) do + feed(s) + poke_eventloop() + end + feed('<esc>') + feed('<c-r>') expect([[ 1 a]]) - feed("g-") -- go to 3 - feed("2u") - feed(substring .. "<esc>") - feed("<c-r>") + feed('g-') -- go to 3 + feed('2u') + for _, s in pairs(substring) do + feed(s) + poke_eventloop() + end + feed('<esc>') + feed('<c-r>') expect([[ 1 2]]) @@ -458,37 +501,37 @@ describe(":substitute, 'inccommand' preserves undo", function() before_each(clear) - it("at a non-leaf of the undo tree", function() - for _, case in pairs(cases) do - for _, str in pairs(substrings) do - for _, redoable in pairs({true}) do - test_sub(str, case, redoable) - end - end - end + it('at a non-leaf of the undo tree', function() + for _, case in pairs(cases) do + for _, str in pairs(substrings) do + for _, redoable in pairs({ true }) do + test_sub(str, case, redoable) + end + end + end end) - it("at a leaf of the undo tree", function() + it('at a leaf of the undo tree', function() for _, case in pairs(cases) do for _, str in pairs(substrings) do - for _, redoable in pairs({false}) do + for _, redoable in pairs({ false }) do test_sub(str, case, redoable) end end end end) - it("when interrupting substitution", function() + it('when interrupting substitution', function() for _, case in pairs(cases) do for _, str in pairs(substrings) do - for _, redoable in pairs({true,false}) do + for _, redoable in pairs({ true, false }) do test_notsub(str, case, redoable) end end end end) - it("in a complex undo scenario", function() + it('in a complex undo scenario', function() for _, case in pairs(cases) do for _, str in pairs(substrings) do test_threetree(str, case) @@ -500,28 +543,32 @@ describe(":substitute, 'inccommand' preserves undo", function() for _, case in pairs(cases) do clear() common_setup(nil, case, default_text) - feed_command("set undolevels=0") + command('set undolevels=0') - feed("1G0") - insert("X") - feed(":%s/tw/MO/<esc>") - feed_command("undo") + feed('1G0') + insert('X') + feed(':%s/tw/MO/') + poke_eventloop() + feed('<esc>') + command('undo') expect(default_text) - feed_command("undo") - expect(default_text:gsub("Inc", "XInc")) - feed_command("undo") + command('undo') + expect(default_text:gsub('Inc', 'XInc')) + command('undo') - feed_command("%s/tw/MO/g") - expect(default_text:gsub("tw", "MO")) - feed_command("undo") + feed(':%s/tw/MO/g') + poke_eventloop() + feed('<CR>') + expect(default_text:gsub('tw', 'MO')) + command('undo') expect(default_text) - feed_command("undo") - expect(default_text:gsub("tw", "MO")) + command('undo') + expect(default_text:gsub('tw', 'MO')) end end) it('with undolevels=1', function() - local screen = Screen.new(20,10) + local screen = Screen.new(20, 10) for _, case in pairs(cases) do clear() @@ -530,46 +577,43 @@ describe(":substitute, 'inccommand' preserves undo", function() Inc substitution on | two lines | ^ | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 | ]]) - feed_command("set undolevels=1") - - feed("1G0") - insert("X") - feed("IY<esc>") - feed(":%s/tw/MO/<esc>") - -- feed_command("undo") here would cause "Press ENTER". - feed("u") - expect(default_text:gsub("Inc", "XInc")) - feed("u") + command('set undolevels=1') + + feed('1G0') + insert('X') + feed('IY<esc>') + feed(':%s/tw/MO/') + poke_eventloop() + feed('<esc>') + feed('u') + expect(default_text:gsub('Inc', 'XInc')) + feed('u') expect(default_text) - feed(":%s/tw/MO/g<enter>") - feed(":%s/MO/GO/g<enter>") - feed(":%s/GO/NO/g<enter>") - feed("u") - expect(default_text:gsub("tw", "GO")) - feed("u") - expect(default_text:gsub("tw", "MO")) - feed("u") + feed(':%s/tw/MO/g') + poke_eventloop() + feed('<enter>') + feed(':%s/MO/GO/g') + poke_eventloop() + feed('<enter>') + feed(':%s/GO/NO/g') + poke_eventloop() + feed('<enter>') + feed('u') + expect(default_text:gsub('tw', 'GO')) + feed('u') + expect(default_text:gsub('tw', 'MO')) + feed('u') - if case == "split" then + if case == 'split' then screen:expect([[ Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) else @@ -577,12 +621,7 @@ describe(":substitute, 'inccommand' preserves undo", function() Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) end @@ -590,37 +629,33 @@ describe(":substitute, 'inccommand' preserves undo", function() end) it('with undolevels=2', function() - local screen = Screen.new(20,10) + local screen = Screen.new(20, 10) for _, case in pairs(cases) do clear() common_setup(screen, case, default_text) - feed_command("set undolevels=2") - - feed("2GAx<esc>") - feed("Ay<esc>") - feed("Az<esc>") - feed(":%s/tw/AR<esc>") - -- feed_command("undo") here would cause "Press ENTER". - feed("u") - expect(default_text:gsub("lines", "linesxy")) - feed("u") - expect(default_text:gsub("lines", "linesx")) - feed("u") + command('set undolevels=2') + + feed('2GAx<esc>') + feed('Ay<esc>') + feed('Az<esc>') + feed(':%s/tw/AR') + poke_eventloop() + feed('<esc>') + feed('u') + expect(default_text:gsub('lines', 'linesxy')) + feed('u') + expect(default_text:gsub('lines', 'linesx')) + feed('u') expect(default_text) - feed("u") + feed('u') - if case == "split" then + if case == 'split' then screen:expect([[ Inc substitution on | two line^s | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) else @@ -628,39 +663,37 @@ describe(":substitute, 'inccommand' preserves undo", function() Inc substitution on | two line^s | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) end - feed(":%s/tw/MO/g<enter>") - feed(":%s/MO/GO/g<enter>") - feed(":%s/GO/NO/g<enter>") - feed(":%s/NO/LO/g<enter>") - feed("u") - expect(default_text:gsub("tw", "NO")) - feed("u") - expect(default_text:gsub("tw", "GO")) - feed("u") - expect(default_text:gsub("tw", "MO")) - feed("u") - - if case == "split" then + feed(':%s/tw/MO/g') + poke_eventloop() + feed('<enter>') + feed(':%s/MO/GO/g') + poke_eventloop() + feed('<enter>') + feed(':%s/GO/NO/g') + poke_eventloop() + feed('<enter>') + feed(':%s/NO/LO/g') + poke_eventloop() + feed('<enter>') + feed('u') + expect(default_text:gsub('tw', 'NO')) + feed('u') + expect(default_text:gsub('tw', 'GO')) + feed('u') + expect(default_text:gsub('tw', 'MO')) + feed('u') + + if case == 'split' then screen:expect([[ Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) else @@ -668,12 +701,7 @@ describe(":substitute, 'inccommand' preserves undo", function() Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) end @@ -681,27 +709,23 @@ describe(":substitute, 'inccommand' preserves undo", function() end) it('with undolevels=-1', function() - local screen = Screen.new(20,10) + local screen = Screen.new(20, 10) for _, case in pairs(cases) do clear() common_setup(screen, case, default_text) - feed_command("set undolevels=-1") - feed(":%s/tw/MO/g<enter>") - -- feed_command("undo") here will result in a "Press ENTER" prompt - feed("u") - if case == "split" then + command('set undolevels=-1') + feed(':%s/tw/MO/g') + poke_eventloop() + feed('<enter>') + feed('u') + if case == 'split' then screen:expect([[ Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) else @@ -709,12 +733,7 @@ describe(":substitute, 'inccommand' preserves undo", function() Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) end @@ -723,41 +742,37 @@ describe(":substitute, 'inccommand' preserves undo", function() clear() common_setup(screen, case, default_text) - feed_command("set undolevels=-1") - feed("1G") - feed("IL<esc>") - feed(":%s/tw/MO/g<esc>") - feed("u") + command('set undolevels=-1') + feed('1G') + feed('IL<esc>') + feed(':%s/tw/MO/g') + poke_eventloop() + feed('<esc>') + feed('u') screen:expect([[ ^LInc substitution on| two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) end end) - end) -describe(":substitute, inccommand=split", function() +describe(':substitute, inccommand=split', function() local screen before_each(function() clear() - screen = Screen.new(30,15) - common_setup(screen, "split", default_text .. default_text) + screen = Screen.new(30, 15) + common_setup(screen, 'split', default_text .. default_text) end) it("preserves 'modified' buffer flag", function() - feed_command("set nomodified") - feed(":%s/tw") + command('set nomodified') + feed(':%s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | @@ -767,30 +782,26 @@ describe(":substitute, inccommand=split", function() {11:[No Name] }| |2| {12:tw}o lines | |4| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw^ | ]]) - feed([[<C-\><C-N>]]) -- Cancel the :substitute command. - eq(0, eval("&modified")) + feed([[<C-\><C-N>]]) -- Cancel the :substitute command. + eq(0, eval('&modified')) end) - it("shows preview when cmd modifiers are present", function() + it('shows preview when cmd modifiers are present', function() -- one modifier feed(':keeppatterns %s/tw/to') - screen:expect{any=[[{12:to}o lines]]} + screen:expect { any = [[{12:to}o lines]] } feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } -- multiple modifiers feed(':keeppatterns silent %s/tw/to') - screen:expect{any=[[{12:to}o lines]]} + screen:expect { any = [[{12:to}o lines]] } feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } -- non-modifier prefix feed(':silent tabedit %s/tw/to') @@ -800,27 +811,19 @@ describe(":substitute, inccommand=split", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :silent tabedit %s/tw/to^ | ]]) feed('<Esc>') -- leading colons feed(':::%s/tw/to') - screen:expect{any=[[{12:to}o lines]]} + screen:expect { any = [[{12:to}o lines]] } feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } end) - it("ignores new-window modifiers when splitting the preview window", function() + it('ignores new-window modifiers when splitting the preview window', function() -- one modifier feed(':topleft %s/tw/to') screen:expect([[ @@ -832,16 +835,12 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:to}o lines | |4| {12:to}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :topleft %s/tw/to^ | ]]) feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } -- multiple modifiers feed(':topleft vert %s/tw/to') @@ -854,20 +853,16 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:to}o lines | |4| {12:to}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :topleft vert %s/tw/to^ | ]]) feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } end) it('shows split window when typing the pattern', function() - feed(":%s/tw") + feed(':%s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | @@ -877,18 +872,14 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:tw}o lines | |4| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw^ | ]]) end) it('shows preview with empty replacement', function() - feed(":%s/tw/") + feed(':%s/tw/') screen:expect([[ Inc substitution on | o lines | @@ -898,16 +889,12 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| o lines | |4| o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw/^ | ]]) - feed("x") + feed('x') screen:expect([[ Inc substitution on | {12:x}o lines | @@ -917,16 +904,12 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:x}o lines | |4| {12:x}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw/x^ | ]]) - feed("<bs>") + feed('<bs>') screen:expect([[ Inc substitution on | o lines | @@ -936,19 +919,14 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| o lines | |4| o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw/^ | ]]) - end) it('shows split window when typing replacement', function() - feed(":%s/tw/XX") + feed(':%s/tw/XX') screen:expect([[ Inc substitution on | {12:XX}o lines | @@ -958,41 +936,29 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:XX}o lines | |4| {12:XX}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw/XX^ | ]]) end) it('does not show split window for :s/', function() - feed("2gg") - feed(":s/tw") + feed('2gg') + feed(':s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :s/tw^ | ]]) end) it("'hlsearch' is active, 'cursorline' is not", function() - feed_command("set hlsearch cursorline") - feed("gg") + command('set hlsearch cursorline') + feed('gg') -- Assert that 'cursorline' is active. screen:expect([[ @@ -1001,19 +967,11 @@ describe(":substitute, inccommand=split", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - :set hlsearch cursorline | + {15:~ }|*9 + | ]]) - feed(":%s/tw") + feed(':%s/tw') -- 'cursorline' is NOT active during preview. screen:expect([[ Inc substitution on | @@ -1024,11 +982,7 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:tw}o lines | |4| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw^ | ]]) @@ -1046,12 +1000,7 @@ describe(":substitute, inccommand=split", function() two lines | {11:[No Name] [+] }| |1| {12:123} {12:123} {12:123} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/M/123/g^ | ]]) @@ -1068,33 +1017,20 @@ describe(":substitute, inccommand=split", function() | {11:[No Name] [+] }| | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/Inx^ | ]]) end) it('previews correctly when previewhight is small', function() - feed_command('set cwh=3') - feed_command('set hls') + command('set cwh=3') + command('set hls') feed('ggdG') insert(string.rep('abc abc abc\n', 20)) feed(':%s/abc/MMM/g') screen:expect([[ - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | + {12:MMM} {12:MMM} {12:MMM} |*9 {11:[No Name] [+] }| | 1| {12:MMM} {12:MMM} {12:MMM} | | 2| {12:MMM} {12:MMM} {12:MMM} | @@ -1105,7 +1041,9 @@ describe(":substitute, inccommand=split", function() end) it('actually replaces text', function() - feed(":%s/tw/XX/g<Enter>") + feed(':%s/tw/XX/g') + poke_eventloop() + feed('<Enter>') screen:expect([[ Inc substitution on | @@ -1113,32 +1051,24 @@ describe(":substitute, inccommand=split", function() Inc substitution on | ^XXo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :%s/tw/XX/g | ]]) end) it('shows correct line numbers with many lines', function() - feed("gg") - feed("2yy") - feed("2000p") - feed_command("1,1000s/tw/BB/g") + feed('gg') + feed('2yy') + feed('2000p') + command('1,1000s/tw/BB/g') - feed(":%s/tw/X") + feed(':%s/tw/X') screen:expect([[ + Inc substitution on | BBo lines | Inc substitution on | {12:X}o lines | Inc substitution on | - {12:X}o lines | {11:[No Name] [+] }| |1001| {12:X}o lines | |1003| {12:X}o lines | @@ -1155,58 +1085,52 @@ describe(":substitute, inccommand=split", function() it('does not spam the buffer numbers', function() -- The preview buffer is re-used (unless user deleted it), so buffer numbers -- will not increase on each keystroke. - feed(":%s/tw/Xo/g") + feed(':%s/tw/Xo/g') -- Delete and re-type the g a few times. - feed("<BS>") + feed('<BS>') poke_eventloop() - feed("g") + feed('g') poke_eventloop() - feed("<BS>") + feed('<BS>') poke_eventloop() - feed("g") + feed('g') poke_eventloop() - feed("<CR>") + feed('<CR>') poke_eventloop() - feed(":vs tmp<enter>") - eq(3, helpers.call('bufnr', '$')) + feed(':vs tmp<enter>') + eq(3, fn.bufnr('$')) end) it('works with the n flag', function() - feed(":%s/tw/Mix/n<Enter>") + feed(':%s/tw/Mix/n') + poke_eventloop() + feed('<Enter>') screen:expect([[ Inc substitution on | two lines | Inc substitution on | two lines | ^ | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 2 matches on 2 lines | ]]) end) it("deactivates if 'redrawtime' is exceeded #5602", function() -- prevent redraws from 'incsearch' - meths.set_option_value('incsearch', false, {}) + api.nvim_set_option_value('incsearch', false, {}) -- Assert that 'inccommand' is ENABLED initially. - eq("split", eval("&inccommand")) + eq('split', eval('&inccommand')) -- Set 'redrawtime' to minimal value, to ensure timeout is triggered. - feed_command("set redrawtime=1 nowrap") + command('set redrawtime=1 nowrap') -- Load a big file. - feed_command("silent edit! test/functional/fixtures/bigfile_oneline.txt") + command('silent edit! test/functional/fixtures/bigfile_oneline.txt') -- Start :substitute with a slow pattern. feed([[:%s/B.*N/x]]) poke_eventloop() -- Assert that 'inccommand' is DISABLED in cmdline mode. - eq("", eval("&inccommand")) + eq('', eval('&inccommand')) -- Assert that preview cleared (or never manifested). screen:expect([[ 0000;<control>;Cc;0;BN;;;;;N;N| @@ -1228,7 +1152,7 @@ describe(":substitute, inccommand=split", function() -- Assert that 'inccommand' is again ENABLED after leaving cmdline mode. feed([[<C-\><C-N>]]) - eq("split", eval("&inccommand")) + eq('split', eval('&inccommand')) end) it("deactivates if 'foldexpr' is slow #9557", function() @@ -1264,12 +1188,12 @@ describe(":substitute, inccommand=split", function() end) end) - it("clears preview if non-previewable command is edited #5585", function() + it('clears preview if non-previewable command is edited #5585', function() feed('gg') -- Put a non-previewable command in history. - feed_command("echo 'foo'") + feed(":echo 'foo'<CR>") -- Start an incomplete :substitute command. - feed(":1,2s/t/X") + feed(':1,2s/t/X') screen:expect([[ Inc subs{12:X}itution on | @@ -1280,17 +1204,13 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |1| Inc subs{12:X}itution on | |2| {12:X}wo lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :1,2s/t/X^ | ]]) -- Select the previous command. - feed("<C-P>") + feed('<C-P>') -- Assert that preview was cleared. screen:expect([[ Inc substitution on | @@ -1298,22 +1218,14 @@ describe(":substitute, inccommand=split", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :echo 'foo'^ | ]]) end) it([[preview changes correctly with c_CTRL-R_= and c_CTRL-\_e]], function() feed('gg') - feed(":1,2s/t/X") + feed(':1,2s/t/X') screen:expect([[ Inc subs{12:X}itution on | {12:X}wo lines | @@ -1323,11 +1235,7 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |1| Inc subs{12:X}itution on | |2| {12:X}wo lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :1,2s/t/X^ | ]]) @@ -1343,11 +1251,7 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |1| Inc subs{12:X}itution on | |2| {12:X}wo lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| ={1:'Y'}^ | ]]) @@ -1363,11 +1267,7 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |1| Inc subs{12:XY}itution on | |2| {12:XY}wo lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :1,2s/t/XY^ | ]]) @@ -1383,11 +1283,7 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |1| Inc subs{12:XY}itution on | |2| {12:XY}wo lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| ={1:'echo'}^ | ]]) @@ -1400,76 +1296,61 @@ describe(":substitute, inccommand=split", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :echo^ | ]]) end) - end) -describe("inccommand=nosplit", function() +describe('inccommand=nosplit', function() local screen before_each(function() clear() - screen = Screen.new(20,10) - common_setup(screen, "nosplit", default_text .. default_text) + screen = Screen.new(20, 10) + common_setup(screen, 'nosplit', default_text .. default_text) end) - it("works with :smagic, :snomagic", function() - feed_command("set hlsearch") - insert("Line *.3.* here") + it('works with :smagic, :snomagic', function() + command('set hlsearch') + insert('Line *.3.* here') - feed(":%smagic/3.*/X") -- start :smagic command + feed(':%smagic/3.*/X') -- start :smagic command screen:expect([[ Inc substitution on | two lines | Inc substitution on | two lines | Line *.{12:X} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%smagic/3.*/X^ | ]]) - feed([[<C-\><C-N>]]) -- cancel - feed(":%snomagic/3.*/X") -- start :snomagic command + feed([[<C-\><C-N>]]) -- cancel + feed(':%snomagic/3.*/X') -- start :snomagic command screen:expect([[ Inc substitution on | two lines | Inc substitution on | two lines | Line *.{12:X} here | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%snomagic/3.*/X^ | ]]) end) - it("shows preview when cmd modifiers are present", function() + it('shows preview when cmd modifiers are present', function() -- one modifier feed(':keeppatterns %s/tw/to') - screen:expect{any=[[{12:to}o lines]]} + screen:expect { any = [[{12:to}o lines]] } feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } -- multiple modifiers feed(':keeppatterns silent %s/tw/to') - screen:expect{any=[[{12:to}o lines]]} + screen:expect { any = [[{12:to}o lines]] } feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } -- non-modifier prefix feed(':silent tabedit %s/tw/to') @@ -1479,22 +1360,21 @@ describe("inccommand=nosplit", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11: }| :silent tabedit %s/t| w/to^ | ]]) end) - it("does not show window after toggling :set inccommand", function() - feed(":%s/tw/OKOK") - feed("<Esc>") - command("set icm=split") - feed(":%s/tw/OKOK") - feed("<Esc>") - command("set icm=nosplit") - feed(":%s/tw/OKOK") + it('does not show window after toggling :set inccommand', function() + feed(':%s/tw/OKOK') + feed('<Esc>') + command('set icm=split') + feed(':%s/tw/OKOK') + feed('<Esc>') + command('set icm=nosplit') + feed(':%s/tw/OKOK') poke_eventloop() screen:expect([[ Inc substitution on | @@ -1502,79 +1382,64 @@ describe("inccommand=nosplit", function() Inc substitution on | {12:OKOK}o lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/tw/OKOK^ | ]]) end) it('never shows preview buffer', function() - feed_command("set hlsearch") + command('set hlsearch') - feed(":%s/tw") + feed(':%s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | Inc substitution on | {12:tw}o lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/tw^ | ]]) - feed("/BM") + feed('/BM') screen:expect([[ Inc substitution on | {12:BM}o lines | Inc substitution on | {12:BM}o lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/tw/BM^ | ]]) - feed("/") + feed('/') screen:expect([[ Inc substitution on | {12:BM}o lines | Inc substitution on | {12:BM}o lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/tw/BM/^ | ]]) - feed("<enter>") + feed('<enter>') screen:expect([[ Inc substitution on | BMo lines | Inc substitution on | ^BMo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/tw/BM/ | ]]) end) - it("clears preview if non-previewable command is edited", function() + it('clears preview if non-previewable command is edited', function() -- Put a non-previewable command in history. - feed_command("echo 'foo'") + feed(":echo 'foo'<CR>") -- Start an incomplete :substitute command. - feed(":1,2s/t/X") + feed(':1,2s/t/X') screen:expect([[ Inc subs{12:X}itution on | @@ -1582,15 +1447,12 @@ describe("inccommand=nosplit", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :1,2s/t/X^ | ]]) -- Select the previous command. - feed("<C-P>") + feed('<C-P>') -- Assert that preview was cleared. screen:expect([[ Inc substitution on | @@ -1598,15 +1460,12 @@ describe("inccommand=nosplit", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :echo 'foo'^ | ]]) end) - it("does not execute trailing bar-separated commands #7494", function() + it('does not execute trailing bar-separated commands #7494', function() feed(':%s/two/three/g|q!') screen:expect([[ Inc substitution on | @@ -1614,16 +1473,13 @@ describe("inccommand=nosplit", function() Inc substitution on | {12:three} lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/two/three/g|q!^ | ]]) eq(eval('v:null'), eval('v:exiting')) end) - it("does not break bar-separated command #8796", function() + it('does not break bar-separated command #8796', function() source([[ function! F() if v:false | return | endif @@ -1631,17 +1487,14 @@ describe("inccommand=nosplit", function() ]]) command('call timer_start(10, {-> F()}, {"repeat":-1})') feed(':%s/') - sleep(20) -- Allow some timer activity. + sleep(20) -- Allow some timer activity. screen:expect([[ Inc substitution on | two lines | Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/^ | ]]) end) @@ -1649,19 +1502,21 @@ end) describe(":substitute, 'inccommand' with a failing expression", function() local screen - local cases = { "", "split", "nosplit" } + local cases = { '', 'split', 'nosplit' } local function refresh(case) clear() - screen = Screen.new(20,10) + screen = Screen.new(20, 10) common_setup(screen, case, default_text) end it('in the pattern does nothing', function() for _, case in pairs(cases) do refresh(case) - feed_command("set inccommand=" .. case) - feed(":silent! %s/tw\\(/LARD/<enter>") + command('set inccommand=' .. case) + feed(':silent! %s/tw\\(/LARD/') + poke_eventloop() + feed('<enter>') expect(default_text) end end) @@ -1669,13 +1524,15 @@ describe(":substitute, 'inccommand' with a failing expression", function() it('in the replacement deletes the matches', function() for _, case in pairs(cases) do refresh(case) - local replacements = { "\\='LARD", "\\=xx_novar__xx" } + local replacements = { "\\='LARD", '\\=xx_novar__xx' } for _, repl in pairs(replacements) do - feed_command("set inccommand=" .. case) - feed(":silent! %s/tw/" .. repl .. "/<enter>") - expect(default_text:gsub("tw", "")) - feed_command("undo") + command('set inccommand=' .. case) + feed(':silent! %s/tw/' .. repl .. '/') + poke_eventloop() + feed('<enter>') + expect(default_text:gsub('tw', '')) + command('undo') end end end) @@ -1689,12 +1546,7 @@ describe(":substitute, 'inccommand' with a failing expression", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 :100s/^ | ]]) @@ -1703,88 +1555,101 @@ describe(":substitute, 'inccommand' with a failing expression", function() Inc substitution on | two lines | ^ | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {14:E16: Invalid range} | ]]) end end) - end) describe("'inccommand' and :cnoremap", function() - local cases = { "", "split", "nosplit" } + local cases = { '', 'split', 'nosplit' } local screen local function refresh(case, visual) clear() - screen = visual and Screen.new(80,10) or nil + screen = visual and Screen.new(80, 10) or nil common_setup(screen, case, default_text) end it('work with remapped characters', function() for _, case in pairs(cases) do refresh(case) - local cmd = "%s/lines/LINES/g" + local cmd = '%s/lines/LINES/g' for i = 1, string.len(cmd) do local c = string.sub(cmd, i, i) - feed_command("cnoremap ".. c .. " " .. c) + command('cnoremap ' .. c .. ' ' .. c) end - feed_command(cmd) + feed(':' .. cmd) + poke_eventloop() + feed('<CR>') expect([[ Inc substitution on two LINES ]]) - end + end end) it('work when mappings move the cursor', function() for _, case in pairs(cases) do refresh(case) - feed_command("cnoremap ,S LINES/<left><left><left><left><left><left>") + command('cnoremap ,S LINES/<left><left><left><left><left><left>') - feed(":%s/lines/,Sor three <enter>") + feed(':%s/lines/') + poke_eventloop() + feed(',S') + poke_eventloop() + feed('or three <enter>') + poke_eventloop() expect([[ Inc substitution on two or three LINES ]]) - feed_command("cnoremap ;S /X/<left><left><left>") - feed(":%s/;SI<enter>") + command('cnoremap ;S /X/<left><left><left>') + feed(':%s/') + poke_eventloop() + feed(';S') + poke_eventloop() + feed('I<enter>') expect([[ Xnc substitution on two or three LXNES ]]) - feed_command("cnoremap ,T //Y/<left><left><left>") - feed(":%s,TX<enter>") + command('cnoremap ,T //Y/<left><left><left>') + feed(':%s') + poke_eventloop() + feed(',T') + poke_eventloop() + feed('X<enter>') expect([[ Ync substitution on two or three LYNES ]]) - feed_command("cnoremap ;T s//Z/<left><left><left>") - feed(":%;TY<enter>") + command('cnoremap ;T s//Z/<left><left><left>') + feed(':%') + poke_eventloop() + feed(';T') + poke_eventloop() + feed('Y<enter>') expect([[ Znc substitution on two or three LZNES ]]) - end + end end) it('still works with a broken mapping', function() for _, case in pairs(cases) do refresh(case, true) - feed_command("cnoremap <expr> x execute('bwipeout!')[-1].'x'") + command("cnoremap <expr> x execute('bwipeout!')[-1].'x'") - feed(":%s/tw/tox<enter>") - screen:expect{any=[[{14:^E565:]]} + feed(':%s/tw/tox<enter>') + screen:expect { any = [[{14:^E565:]] } feed('<c-c>') -- error thrown b/c of the mapping @@ -1799,20 +1664,24 @@ describe("'inccommand' and :cnoremap", function() it('work when temporarily moving the cursor', function() for _, case in pairs(cases) do refresh(case) - feed_command("cnoremap <expr> x cursor(1, 1)[-1].'x'") + command("cnoremap <expr> x cursor(1, 1)[-1].'x'") - feed(":%s/tw/tox/g<enter>") - expect(default_text:gsub("tw", "tox")) + feed(':%s/tw/tox') + poke_eventloop() + feed('/g<enter>') + expect(default_text:gsub('tw', 'tox')) end end) it("work when a mapping disables 'inccommand'", function() for _, case in pairs(cases) do refresh(case) - feed_command("cnoremap <expr> x execute('set inccommand=')[-1]") + command("cnoremap <expr> x execute('set inccommand=')[-1]") - feed(":%s/tw/toxa/g<enter>") - expect(default_text:gsub("tw", "toa")) + feed(':%s/tw/tox') + poke_eventloop() + feed('a/g<enter>') + expect(default_text:gsub('tw', 'toa')) end end) @@ -1822,12 +1691,12 @@ describe("'inccommand' and :cnoremap", function() source([[cnoremap x <C-\>eextend(g:, {'fo': getcmdline()}) \.fo<CR><C-c>:new<CR>:bw!<CR>:<C-r>=remove(g:, 'fo')<CR>x]]) - feed(":%s/tw/tox") - feed("/<enter>") - expect(default_text:gsub("tw", "tox")) + feed(':%s/tw/tox') + poke_eventloop() + feed('/<enter>') + expect(default_text:gsub('tw', 'tox')) end end) - end) describe("'inccommand' autocommands", function() @@ -1868,9 +1737,9 @@ describe("'inccommand' autocommands", function() } local function bufferlist(t) - local s = "" + local s = '' for _, buffer in pairs(t) do - s = s .. ", " .. tostring(buffer) + s = s .. ', ' .. tostring(buffer) end return s end @@ -1882,12 +1751,12 @@ describe("'inccommand' autocommands", function() end local function register_autocmd(event) - meths.set_var(event .. "_fired", {}) - feed_command("autocmd " .. event .. " * call add(g:" .. event .. "_fired, expand('<abuf>'))") + api.nvim_set_var(event .. '_fired', {}) + command('autocmd ' .. event .. ' * call add(g:' .. event .. "_fired, expand('<abuf>'))") end it('are not fired when splitting', function() - common_setup(nil, "split", default_text) + common_setup(nil, 'split', default_text) local eventsObserved = {} for event, _ in pairs(eventsExpected) do @@ -1895,162 +1764,112 @@ describe("'inccommand' autocommands", function() register_autocmd(event) end - feed(":%s/tw") + feed(':%s/tw') for event, _ in pairs(eventsExpected) do - eventsObserved[event].open = meths.get_var(event .. "_fired") - meths.set_var(event .. "_fired", {}) + eventsObserved[event].open = api.nvim_get_var(event .. '_fired') + api.nvim_set_var(event .. '_fired', {}) end - feed("/<enter>") + feed('/<enter>') for event, _ in pairs(eventsExpected) do - eventsObserved[event].close = meths.get_var(event .. "_fired") + eventsObserved[event].close = api.nvim_get_var(event .. '_fired') end for event, _ in pairs(eventsExpected) do - eq(event .. bufferlist(eventsExpected[event].open), - event .. bufferlist(eventsObserved[event].open)) - eq(event .. bufferlist(eventsExpected[event].close), - event .. bufferlist(eventsObserved[event].close)) + eq( + event .. bufferlist(eventsExpected[event].open), + event .. bufferlist(eventsObserved[event].open) + ) + eq( + event .. bufferlist(eventsExpected[event].close), + event .. bufferlist(eventsObserved[event].close) + ) end end) - end) describe("'inccommand' split windows", function() local screen local function refresh() clear() - screen = Screen.new(40,30) - common_setup(screen, "split", default_text) + screen = Screen.new(40, 30) + common_setup(screen, 'split', default_text) end it('work after more splits', function() refresh() - feed("gg") - feed_command("vsplit") - feed_command("split") - feed(":%s/tw") + feed('gg') + command('vsplit') + command('split') + feed(':%s/tw') screen:expect([[ Inc substitution on │Inc substitution on| {12:tw}o lines │{12:tw}o lines | │ | - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| + {15:~ }│{15:~ }|*11 {11:[No Name] [+] }│{15:~ }| Inc substitution on │{15:~ }| {12:tw}o lines │{15:~ }| │{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| + {15:~ }│{15:~ }|*2 {10:[No Name] [+] [No Name] [+] }| |2| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/tw^ | ]]) - feed("<esc>") - feed_command("only") - feed_command("split") - feed_command("vsplit") + feed('<esc>') + command('only') + command('split') + command('vsplit') - feed(":%s/tw") + feed(':%s/tw') screen:expect([[ Inc substitution on │Inc substitution on| {12:tw}o lines │{12:tw}o lines | │ | - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| + {15:~ }│{15:~ }|*11 {11:[No Name] [+] }{10:[No Name] [+] }| Inc substitution on | {12:tw}o lines | | - {15:~ }| - {15:~ }| + {15:~ }|*2 {10:[No Name] [+] }| |2| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/tw^ | ]]) end) local settings = { - "splitbelow", - "splitright", - "noequalalways", - "equalalways eadirection=ver", - "equalalways eadirection=hor", - "equalalways eadirection=both", + 'splitbelow', + 'splitright', + 'noequalalways', + 'equalalways eadirection=ver', + 'equalalways eadirection=hor', + 'equalalways eadirection=both', } - it("are not affected by various settings", function() + it('are not affected by various settings', function() for _, setting in pairs(settings) do refresh() - feed_command("set " .. setting) + command('set ' .. setting) - feed(":%s/tw") + feed(':%s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*17 {11:[No Name] [+] }| |2| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/tw^ | ]]) @@ -2060,7 +1879,7 @@ describe("'inccommand' split windows", function() it("don't open if there's not enough room", function() refresh() screen:try_resize(40, 3) - feed("gg:%s/tw") + feed('gg:%s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | @@ -2074,43 +1893,43 @@ describe("'inccommand' with 'gdefault'", function() clear() end) - it("does not lock up #7244", function() - common_setup(nil, "nosplit", "{") - command("set gdefault") - feed(":s/{\\n") - eq({mode='c', blocking=false}, nvim("get_mode")) - feed("/A<Enter>") - expect("A") - eq({mode='n', blocking=false}, nvim("get_mode")) + it('does not lock up #7244', function() + common_setup(nil, 'nosplit', '{') + command('set gdefault') + feed(':s/{\\n') + eq({ mode = 'c', blocking = false }, api.nvim_get_mode()) + feed('/A<Enter>') + expect('A') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) - it("with multiline text and range, does not lock up #7244", function() - common_setup(nil, "nosplit", "{\n\n{") - command("set gdefault") - feed(":%s/{\\n") - eq({mode='c', blocking=false}, nvim("get_mode")) - feed("/A<Enter>") - expect("A\nA") - eq({mode='n', blocking=false}, nvim("get_mode")) + it('with multiline text and range, does not lock up #7244', function() + common_setup(nil, 'nosplit', '{\n\n{') + command('set gdefault') + feed(':%s/{\\n') + eq({ mode = 'c', blocking = false }, api.nvim_get_mode()) + feed('/A<Enter>') + expect('A\nA') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) - it("does not crash on zero-width matches #7485", function() - common_setup(nil, "split", default_text) - command("set gdefault") - feed("gg") - feed("Vj") - feed(":s/\\%V") - eq({mode='c', blocking=false}, nvim("get_mode")) - feed("<Esc>") - eq({mode='n', blocking=false}, nvim("get_mode")) + it('does not crash on zero-width matches #7485', function() + common_setup(nil, 'split', default_text) + command('set gdefault') + feed('gg') + feed('Vj') + feed(':s/\\%V') + eq({ mode = 'c', blocking = false }, api.nvim_get_mode()) + feed('<Esc>') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) - it("removes highlights after abort for a zero-width match", function() - local screen = Screen.new(30,5) - common_setup(screen, "nosplit", default_text) - command("set gdefault") + it('removes highlights after abort for a zero-width match', function() + local screen = Screen.new(30, 5) + common_setup(screen, 'nosplit', default_text) + command('set gdefault') - feed(":%s/\\%1c/a/") + feed(':%s/\\%1c/a/') screen:expect([[ {12:a}Inc substitution on | {12:a}two lines | @@ -2119,7 +1938,7 @@ describe("'inccommand' with 'gdefault'", function() :%s/\%1c/a/^ | ]]) - feed("<Esc>") + feed('<Esc>') screen:expect([[ Inc substitution on | two lines | @@ -2128,21 +1947,20 @@ describe("'inccommand' with 'gdefault'", function() | ]]) end) - end) -describe(":substitute", function() +describe(':substitute', function() local screen before_each(function() clear() - screen = Screen.new(30,15) + screen = Screen.new(30, 15) end) - it("inccommand=split, highlights multiline substitutions", function() - common_setup(screen, "split", multiline_text) - feed("gg") + it('inccommand=split, highlights multiline substitutions', function() + common_setup(screen, 'split', multiline_text) + feed('gg') - feed(":%s/2\\_.*X") + feed(':%s/2\\_.*X') screen:expect([[ 1 {12:2 3} | {12:A B C} | @@ -2154,33 +1972,25 @@ describe(":substitute", function() |2|{12: A B C} | |3|{12: 4 5 6} | |4|{12: X} Y Z | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {10:[Preview] }| :%s/2\_.*X^ | ]]) - feed("/MMM") + feed('/MMM') screen:expect([[ 1 {12:MMM} Y Z | 7 8 9 | | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |1| 1 {12:MMM} Y Z | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/2\_.*X/MMM^ | ]]) - feed("\\rK\\rLLL") + feed('\\rK\\rLLL') screen:expect([[ 1 {12:MMM} | {12:K} | @@ -2191,113 +2001,77 @@ describe(":substitute", function() |1| 1 {12:MMM} | |2|{12: K} | |3|{12: LLL} Y Z | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 {10:[Preview] }| :%s/2\_.*X/MMM\rK\rLLL^ | ]]) end) - it("inccommand=nosplit, highlights multiline substitutions", function() - common_setup(screen, "nosplit", multiline_text) - feed("gg") + it('inccommand=nosplit, highlights multiline substitutions', function() + common_setup(screen, 'nosplit', multiline_text) + feed('gg') - feed(":%s/2\\_.*X/MMM") + feed(':%s/2\\_.*X/MMM') screen:expect([[ 1 {12:MMM} Y Z | 7 8 9 | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*11 :%s/2\_.*X/MMM^ | ]]) - feed("\\rK\\rLLL") + feed('\\rK\\rLLL') screen:expect([[ 1 {12:MMM} | {12:K} | {12:LLL} Y Z | 7 8 9 | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :%s/2\_.*X/MMM\rK\rLLL^ | ]]) end) - it("inccommand=split, highlights multiple matches on a line", function() - common_setup(screen, "split", multimatch_text) - command("set gdefault") - feed("gg") + it('inccommand=split, highlights multiple matches on a line', function() + common_setup(screen, 'split', multimatch_text) + command('set gdefault') + feed('gg') - feed(":%s/a/XLK") + feed(':%s/a/XLK') screen:expect([[ {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:XLK} r| x | | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |1| {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:X}| {12:LK} r | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/a/XLK^ | ]]) end) - it("inccommand=nosplit, highlights multiple matches on a line", function() - common_setup(screen, "nosplit", multimatch_text) - command("set gdefault") - feed("gg") + it('inccommand=nosplit, highlights multiple matches on a line', function() + common_setup(screen, 'nosplit', multimatch_text) + command('set gdefault') + feed('gg') - feed(":%s/a/XLK") + feed(':%s/a/XLK') screen:expect([[ {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:XLK} r| x | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*11 :%s/a/XLK^ | ]]) end) - it("inccommand=split, with \\zs", function() - common_setup(screen, "split", multiline_text) - feed("gg") + it('inccommand=split, with \\zs', function() + common_setup(screen, 'split', multiline_text) + feed('gg') - feed(":%s/[0-9]\\n\\zs[A-Z]/OKO") + feed(':%s/[0-9]\\n\\zs[A-Z]/OKO') screen:expect([[ {12:OKO} B C | 4 5 6 | @@ -2309,19 +2083,17 @@ describe(":substitute", function() |2| {12:OKO} B C | |3| 4 5 6 | |4| {12:OKO} Y Z | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {10:[Preview] }| :%s/[0-9]\n\zs[A-Z]/OKO^ | ]]) end) - it("inccommand=nosplit, with \\zs", function() - common_setup(screen, "nosplit", multiline_text) - feed("gg") + it('inccommand=nosplit, with \\zs', function() + common_setup(screen, 'nosplit', multiline_text) + feed('gg') - feed(":%s/[0-9]\\n\\zs[A-Z]/OKO") + feed(':%s/[0-9]\\n\\zs[A-Z]/OKO') screen:expect([[ 1 2 3 | {12:OKO} B C | @@ -2329,65 +2101,41 @@ describe(":substitute", function() {12:OKO} Y Z | 7 8 9 | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*8 :%s/[0-9]\n\zs[A-Z]/OKO^ | ]]) end) - it("inccommand=split, substitutions of different length", function() - common_setup(screen, "split", "T T123 T2T TTT T090804\nx") + it('inccommand=split, substitutions of different length', function() + common_setup(screen, 'split', 'T T123 T2T TTT T090804\nx') - feed(":%s/T\\([0-9]\\+\\)/\\1\\1/g") + feed(':%s/T\\([0-9]\\+\\)/\\1\\1/g') screen:expect([[ T {12:123123} {12:22}T TTT {12:090804090804} | x | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {11:[No Name] [+] }| |1| T {12:123123} {12:22}T TTT {12:090804090}| {12:804} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/T\([0-9]\+\)/\1\1/g^ | ]]) end) - it("inccommand=nosplit, substitutions of different length", function() - common_setup(screen, "nosplit", "T T123 T2T TTT T090804\nx") + it('inccommand=nosplit, substitutions of different length', function() + common_setup(screen, 'nosplit', 'T T123 T2T TTT T090804\nx') - feed(":%s/T\\([0-9]\\+\\)/\\1\\1/g") + feed(':%s/T\\([0-9]\\+\\)/\\1\\1/g') screen:expect([[ T {12:123123} {12:22}T TTT {12:090804090804} | x | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*12 :%s/T\([0-9]\+\)/\1\1/g^ | ]]) end) - it("inccommand=split, contraction of lines", function() + it('inccommand=split, contraction of lines', function() local text = [[ T T123 T T123 T2T TT T23423424 x @@ -2396,8 +2144,8 @@ describe(":substitute", function() alx ]] - common_setup(screen, "split", text) - feed(":%s/[QR]\\n") + common_setup(screen, 'split', text) + feed(':%s/[QR]\\n') screen:expect([[ afa {12:Q} | adf la;lkd {12:R} | @@ -2408,15 +2156,12 @@ describe(":substitute", function() |3| afa {12:Q} | |4|{12: }adf la;lkd {12:R} | |5|{12: }alx | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 {10:[Preview] }| :%s/[QR]\n^ | ]]) - feed("/KKK") + feed('/KKK') screen:expect([[ T T123 T T123 T2T TT T23423424| x | @@ -2425,18 +2170,13 @@ describe(":substitute", function() {15:~ }| {11:[No Name] [+] }| |3| afa {12:KKK}adf la;lkd {12:KKK}alx | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/[QR]\n/KKK^ | ]]) end) - it("inccommand=nosplit, contraction of lines", function() + it('inccommand=nosplit, contraction of lines', function() local text = [[ T T123 T T123 T2T TT T23423424 x @@ -2445,28 +2185,19 @@ describe(":substitute", function() alx ]] - common_setup(screen, "nosplit", text) - feed(":%s/[QR]\\n/KKK") + common_setup(screen, 'nosplit', text) + feed(':%s/[QR]\\n/KKK') screen:expect([[ T T123 T T123 T2T TT T23423424| x | afa {12:KKK}adf la;lkd {12:KKK}alx | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*10 :%s/[QR]\n/KKK^ | ]]) end) - it("inccommand=split, contraction of two subsequent NL chars", function() + it('inccommand=split, contraction of two subsequent NL chars', function() local text = [[ AAA AA @@ -2478,9 +2209,10 @@ describe(":substitute", function() -- This used to crash, but more than 20 highlight entries are required -- to reproduce it (so that the marktree has multiple nodes) - common_setup(screen, "split", string.rep(text,10)) - feed(":%s/\\n\\n/<c-v><c-m>/g") - screen:expect{grid=[[ + common_setup(screen, 'split', string.rep(text, 10)) + feed(':%s/\\n\\n/<c-v><c-m>/g') + screen:expect { + grid = [[ CCC CC | AAA AA | BBB BB | @@ -2496,11 +2228,12 @@ describe(":substitute", function() | 7|{12: }AAA AA | {10:[Preview] }| :%s/\n\n/{17:^M}/g^ | - ]]} + ]], + } assert_alive() end) - it("inccommand=nosplit, contraction of two subsequent NL chars", function() + it('inccommand=nosplit, contraction of two subsequent NL chars', function() local text = [[ AAA AA @@ -2510,9 +2243,10 @@ describe(":substitute", function() ]] - common_setup(screen, "nosplit", string.rep(text,10)) - feed(":%s/\\n\\n/<c-v><c-m>/g") - screen:expect{grid=[[ + common_setup(screen, 'nosplit', string.rep(text, 10)) + feed(':%s/\\n\\n/<c-v><c-m>/g') + screen:expect { + grid = [[ CCC CC | AAA AA | BBB BB | @@ -2528,13 +2262,14 @@ describe(":substitute", function() CCC CC | | :%s/\n\n/{17:^M}/g^ | - ]]} + ]], + } assert_alive() end) - it("inccommand=split, multibyte text", function() - common_setup(screen, "split", multibyte_text) - feed(":%s/£.*ѫ/X¥¥") + it('inccommand=split, multibyte text', function() + common_setup(screen, 'split', multibyte_text) + feed(':%s/£.*ѫ/X¥¥') screen:expect([[ a{12:X¥¥}¥KOL | £ ¥ libm | @@ -2545,15 +2280,12 @@ describe(":substitute", function() |1| {12:X¥¥} PEPPERS | |2| {12:X¥¥} | |3| a{12:X¥¥}¥KOL | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 {10:[Preview] }| :%s/£.*ѫ/X¥¥^ | ]]) - feed("\\ra££ ¥") + feed('\\ra££ ¥') screen:expect([[ a{12:X¥¥} | {12:a££ ¥}¥KOL | @@ -2573,9 +2305,9 @@ describe(":substitute", function() ]]) end) - it("inccommand=nosplit, multibyte text", function() - common_setup(screen, "nosplit", multibyte_text) - feed(":%s/£.*ѫ/X¥¥") + it('inccommand=nosplit, multibyte text', function() + common_setup(screen, 'nosplit', multibyte_text) + feed(':%s/£.*ѫ/X¥¥') screen:expect([[ {12:X¥¥} PEPPERS | {12:X¥¥} | @@ -2583,18 +2315,11 @@ describe(":substitute", function() £ ¥ libm | £ ¥ | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*8 :%s/£.*ѫ/X¥¥^ | ]]) - feed("\\ra££ ¥") + feed('\\ra££ ¥') screen:expect([[ {12:X¥¥} | {12:a££ ¥} PEPPERS | @@ -2605,20 +2330,16 @@ describe(":substitute", function() £ ¥ libm | £ ¥ | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 :%s/£.*ѫ/X¥¥\ra££ ¥^ | ]]) end) - it("inccommand=split, small cmdwinheight", function() - common_setup(screen, "split", long_multiline_text) - command("set cmdwinheight=2") + it('inccommand=split, small cmdwinheight', function() + common_setup(screen, 'split', long_multiline_text) + command('set cmdwinheight=2') - feed(":%s/[a-z]") + feed(':%s/[a-z]') screen:expect([[ X Y Z | 7 8 9 | @@ -2637,7 +2358,7 @@ describe(":substitute", function() :%s/[a-z]^ | ]]) - feed("/JLKR £") + feed('/JLKR £') screen:expect([[ X Y Z | 7 8 9 | @@ -2656,7 +2377,7 @@ describe(":substitute", function() :%s/[a-z]/JLKR £^ | ]]) - feed("\\rѫ ab \\rXXXX") + feed('\\rѫ ab \\rXXXX') screen:expect([[ 7 8 9 | K L M | @@ -2676,11 +2397,11 @@ describe(":substitute", function() ]]) end) - it("inccommand=split, large cmdwinheight", function() - common_setup(screen, "split", long_multiline_text) - command("set cmdwinheight=11") + it('inccommand=split, large cmdwinheight', function() + common_setup(screen, 'split', long_multiline_text) + command('set cmdwinheight=11') - feed(":%s/. .$") + feed(':%s/. .$') screen:expect([[ t {12:œ ¥} | {11:[No Name] [+] }| @@ -2699,7 +2420,7 @@ describe(":substitute", function() :%s/. .$^ | ]]) - feed("/ YYY") + feed('/ YYY') screen:expect([[ t {12: YYY} | {11:[No Name] [+] }| @@ -2718,7 +2439,7 @@ describe(":substitute", function() :%s/. .$/ YYY^ | ]]) - feed("\\r KKK") + feed('\\r KKK') screen:expect([[ a {12: YYY} | {11:[No Name] [+] }| @@ -2738,28 +2459,22 @@ describe(":substitute", function() ]]) end) - it("inccommand=split, lookaround", function() - common_setup(screen, "split", "something\neverything\nsomeone") + it('inccommand=split, lookaround', function() + common_setup(screen, 'split', 'something\neverything\nsomeone') feed([[:%s/\(some\)\@<lt>=thing/one/]]) screen:expect([[ some{12:one} | everything | someone | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |1| some{12:one} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/\(some\)\@<=thing/one/^ | ]]) - feed("<C-c>") + feed('<C-c>') feed('gg') poke_eventloop() feed([[:%s/\(some\)\@<lt>!thing/one/]]) @@ -2767,16 +2482,10 @@ describe(":substitute", function() something | every{12:one} | someone | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |2| every{12:one} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/\(some\)\@<!thing/one/^ | ]]) @@ -2788,16 +2497,10 @@ describe(":substitute", function() {12:every}thing | everything | someone | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |1| {12:every}thing | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/some\(thing\)\@=/every/^ | ]]) @@ -2809,16 +2512,10 @@ describe(":substitute", function() something | everything | {12:every}one | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |3| {12:every}one | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/some\(thing\)\@!/every/^ | ]]) @@ -2826,7 +2523,7 @@ describe(":substitute", function() it("doesn't prompt to swap cmd range", function() screen = Screen.new(50, 8) -- wide to avoid hit-enter prompt - common_setup(screen, "split", default_text) + common_setup(screen, 'split', default_text) feed(':2,1s/tw/MO/g') -- substitution preview should have been made, without prompting @@ -2834,9 +2531,7 @@ describe(":substitute", function() {12:MO}o lines | {11:[No Name] [+] }| |2| {12:MO}o lines | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {10:[Preview] }| :2,1s/tw/MO/g^ | ]]) @@ -2847,9 +2542,7 @@ describe(":substitute", function() {12:MO}o lines | {11:[No Name] [+] }| |2| {12:MO}o lines | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {10:[Preview] }| {13:Backwards range given, OK to swap (y/n)?}^ | ]]) @@ -2859,10 +2552,7 @@ describe(":substitute", function() Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 {13:Backwards range given, OK to swap (y/n)?}y | ]]) end) @@ -2874,19 +2564,19 @@ it(':substitute with inccommand during :terminal activity', function() end retry(2, 40000, function() clear() - local screen = Screen.new(30,15) + local screen = Screen.new(30, 15) - command("set cmdwinheight=3") + command('set cmdwinheight=3') feed(([[:terminal "%s" REP 5000 xxx<cr>]]):format(testprg('shell-test'))) command('file term') - feed('G') -- Follow :terminal output. + feed('G') -- Follow :terminal output. command('new') common_setup(screen, 'split', 'foo bar baz\nbar baz fox\nbar foo baz') command('wincmd =') feed('gg') feed(':%s/foo/ZZZ') - sleep(20) -- Allow some terminal activity. + sleep(20) -- Allow some terminal activity. poke_eventloop() screen:sleep(0) screen:expect_unchanged() @@ -2895,7 +2585,7 @@ end) it(':substitute with inccommand, timer-induced :redraw #9777', function() clear() - local screen = Screen.new(30,12) + local screen = Screen.new(30, 12) command('set cmdwinheight=3') command('call timer_start(10, {-> execute("redraw")}, {"repeat":-1})') command('call timer_start(10, {-> execute("redrawstatus")}, {"repeat":-1})') @@ -2903,14 +2593,12 @@ it(':substitute with inccommand, timer-induced :redraw #9777', function() feed('gg') feed(':%s/foo/ZZZ') - sleep(20) -- Allow some timer activity. + sleep(20) -- Allow some timer activity. screen:expect([[ {12:ZZZ} bar baz | bar baz fox | bar {12:ZZZ} baz | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {11:[No Name] [+] }| |1| {12:ZZZ} bar baz | |3| bar {12:ZZZ} baz | @@ -2922,12 +2610,17 @@ end) it(':substitute with inccommand, allows :redraw before first separator is typed #18857', function() clear() - local screen = Screen.new(30,6) + local screen = Screen.new(30, 6) common_setup(screen, 'split', 'foo bar baz\nbar baz fox\nbar foo baz') command('hi! link NormalFloat CursorLine') - local float_buf = meths.create_buf(false, true) - meths.open_win(float_buf, false, { - relative = 'editor', height = 1, width = 5, row = 3, col = 0, focusable = false, + local float_buf = api.nvim_create_buf(false, true) + api.nvim_open_win(float_buf, false, { + relative = 'editor', + height = 1, + width = 5, + row = 3, + col = 0, + focusable = false, }) feed(':') screen:expect([[ @@ -2947,7 +2640,7 @@ it(':substitute with inccommand, allows :redraw before first separator is typed {15:~ }| :%s^ | ]]) - meths.buf_set_lines(float_buf, 0, -1, true, {'foo'}) + api.nvim_buf_set_lines(float_buf, 0, -1, true, { 'foo' }) command('redraw') screen:expect([[ foo bar baz | @@ -2966,10 +2659,7 @@ it(':substitute with inccommand, does not crash if range contains invalid marks' feed([[:'a,'bs]]) screen:expect([[ test | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :'a,'bs^ | ]]) -- v:errmsg shouldn't be set either before the first separator is typed @@ -2977,10 +2667,7 @@ it(':substitute with inccommand, does not crash if range contains invalid marks' feed('/') screen:expect([[ test | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :'a,'bs/^ | ]]) end) @@ -3030,17 +2717,14 @@ it(':substitute with inccommand, no unnecessary redraw if preview is not shown', -- now inccommand is shown, so screen is redrawn screen:expect([[ {12:test} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :s/test^ | ]]) end) it(":substitute doesn't crash with inccommand, if undo is empty #12932", function() clear() - local screen = Screen.new(10,5) + local screen = Screen.new(10, 5) command('set undolevels=-1') common_setup(screen, 'split', 'test') feed(':%s/test') @@ -3050,9 +2734,7 @@ it(":substitute doesn't crash with inccommand, if undo is empty #12932", functio feed('f') screen:expect([[ {12:f} | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 :%s/test/f^ | ]]) assert_alive() @@ -3062,7 +2744,7 @@ it(':substitute with inccommand works properly if undo is not synced #20029', fu clear() local screen = Screen.new(30, 6) common_setup(screen, 'nosplit', 'foo\nbar\nbaz') - meths.set_keymap('x', '<F2>', '<Esc>`<Oaaaaa asdf<Esc>`>obbbbb asdf<Esc>V`<k:s/asdf/', {}) + api.nvim_set_keymap('x', '<F2>', '<Esc>`<Oaaaaa asdf<Esc>`>obbbbb asdf<Esc>V`<k:s/asdf/', {}) feed('gg0<C-V>lljj<F2>') screen:expect([[ aaaaa | @@ -3127,10 +2809,31 @@ end) it('long :%s/ with inccommand does not collapse cmdline', function() clear() - local screen = Screen.new(10,5) + local screen = Screen.new(10, 5) common_setup(screen, 'nosplit') - feed(':%s/AAAAAAA', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', - 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A') + feed( + ':%s/AAAAAAA', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A' + ) screen:expect([[ | {11: }| @@ -3147,10 +2850,7 @@ it("with 'inccommand' typing invalid `={expr}` does not show error", function() feed(':edit `=`') screen:expect([[ | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :edit `=`^ | ]]) end) @@ -3195,3 +2895,54 @@ it("'inccommand' cannot be changed during preview #23136", function() feed(':%s/foo/bar<C-E><C-E><C-E>') assert_alive() end) + +it("'inccommand' value can be changed multiple times #27086", function() + clear() + local screen = Screen.new(30, 20) + common_setup(screen, 'split', 'foo1\nfoo2\nfoo3') + for _ = 1, 3 do + feed(':%s/foo/bar') + screen:expect([[ + {12:bar}1 | + {12:bar}2 | + {12:bar}3 | + {15:~ }|*7 + {11:[No Name] [+] }| + |1| {12:bar}1 | + |2| {12:bar}2 | + |3| {12:bar}3 | + {15:~ }|*4 + {10:[Preview] }| + :%s/foo/bar^ | + ]]) + feed('<Esc>') + command('set inccommand=nosplit') + feed(':%s/foo/bar') + screen:expect([[ + {12:bar}1 | + {12:bar}2 | + {12:bar}3 | + {15:~ }|*16 + :%s/foo/bar^ | + ]]) + feed('<Esc>') + command('set inccommand=split') + end +end) + +it("'inccommand' disables preview if preview buffer can't be created #27086", function() + clear() + api.nvim_buf_set_name(0, '[Preview]') + local screen = Screen.new(30, 20) + common_setup(screen, 'split', 'foo1\nfoo2\nfoo3') + eq('split', api.nvim_get_option_value('inccommand', {})) + feed(':%s/foo/bar') + screen:expect([[ + {12:bar}1 | + {12:bar}2 | + {12:bar}3 | + {15:~ }|*16 + :%s/foo/bar^ | + ]]) + eq('nosplit', api.nvim_get_option_value('inccommand', {})) +end) |