mirror of
https://github.com/neovim/neovim.git
synced 2025-09-15 15:58:17 +00:00

... that does not have that superflous last line. Also, remove some indeterminism for the freebsd64 tests. Partially, those were suggested by the tests themselves, while successfull. Some of them were added after some testing because the lookaround test would fail on freebsd64 only.
2382 lines
71 KiB
Lua
2382 lines
71 KiB
Lua
local helpers = require('test.functional.helpers')(after_each)
|
||
local Screen = require('test.functional.ui.screen')
|
||
local clear = helpers.clear
|
||
local command = helpers.command
|
||
local curbufmeths = helpers.curbufmeths
|
||
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 neq = helpers.neq
|
||
local ok = helpers.ok
|
||
local source = helpers.source
|
||
local wait = helpers.wait
|
||
local nvim = helpers.nvim
|
||
|
||
local default_text = [[
|
||
Inc substitution on
|
||
two lines
|
||
]]
|
||
|
||
local multiline_text = [[
|
||
1 2 3
|
||
A B C
|
||
4 5 6
|
||
X Y Z
|
||
7 8 9
|
||
]]
|
||
|
||
local multimatch_text = [[
|
||
a bdc eae a fgl lzia r
|
||
x
|
||
]]
|
||
|
||
local multibyte_text = [[
|
||
£ ¥ ѫѫ PEPPERS
|
||
£ ¥ ѫfѫ
|
||
a£ ѫ¥KOL
|
||
£ ¥ libm
|
||
£ ¥
|
||
]]
|
||
|
||
local long_multiline_text = [[
|
||
1 2 3
|
||
A B C
|
||
4 5 6
|
||
X Y Z
|
||
7 8 9
|
||
K L M
|
||
a b c
|
||
d e f
|
||
q r s
|
||
x y z
|
||
£ m n
|
||
t œ ¥
|
||
]]
|
||
|
||
local function common_setup(screen, inccommand, text)
|
||
if screen then
|
||
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
|
||
vis = {background=Screen.colors.LightGrey}
|
||
})
|
||
end
|
||
|
||
command("set inccommand=" .. (inccommand and inccommand or ""))
|
||
|
||
if text then
|
||
insert(text)
|
||
end
|
||
end
|
||
|
||
describe(":substitute, inccommand=split does not trigger preview", function()
|
||
before_each(function()
|
||
clear()
|
||
common_setup(nil, "split", default_text)
|
||
end)
|
||
|
||
it("if invoked by a script ", function()
|
||
source('%s/tw/MO/g')
|
||
wait()
|
||
eq(1, eval("bufnr('$')"))
|
||
|
||
-- sanity check: assert the buffer state
|
||
expect(default_text:gsub("tw", "MO"))
|
||
end)
|
||
|
||
it("if invoked by feedkeys()", function()
|
||
-- in a script...
|
||
source([[:call feedkeys(":%s/tw/MO/g\<CR>")]])
|
||
wait()
|
||
-- or interactively...
|
||
feed([[:call feedkeys(":%s/tw/MO/g\<CR>")<CR>]])
|
||
wait()
|
||
eq(1, eval("bufnr('$')"))
|
||
|
||
-- sanity check: assert the buffer state
|
||
expect(default_text:gsub("tw", "MO"))
|
||
end)
|
||
end)
|
||
|
||
describe(":substitute, 'inccommand' preserves", function()
|
||
if helpers.pending_win32(pending) then return end
|
||
|
||
before_each(clear)
|
||
|
||
it('listed buffers (:ls)', function()
|
||
local screen = Screen.new(30,10)
|
||
common_setup(screen, "split", "ABC")
|
||
|
||
feed_command("%s/AB/BA/")
|
||
feed_command("ls")
|
||
|
||
screen:expect([[
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:ls |
|
||
1 %a + "[No Name]" |
|
||
line 1 |
|
||
{13:Press ENTER or type command to}|
|
||
{13: continue}^ |
|
||
]])
|
||
end)
|
||
|
||
for _, case in pairs{"", "split", "nosplit"} do
|
||
it("various delimiters (inccommand="..case..")", function()
|
||
insert(default_text)
|
||
feed_command("set inccommand=" .. case)
|
||
|
||
local delims = { '/', '#', ';', '%', ',', '@', '!', ''}
|
||
for _,delim in pairs(delims) do
|
||
feed_command("%s"..delim.."lines"..delim.."LINES"..delim.."g")
|
||
expect([[
|
||
Inc substitution on
|
||
two LINES
|
||
]])
|
||
feed_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("set inccommand=" .. case)
|
||
insert("as")
|
||
feed(":%s/as/glork/<enter>")
|
||
eq(meths.get_option('undolevels'), 139)
|
||
eq(curbufmeths.get_option('undolevels'), 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()")
|
||
|
||
-- Start typing an incomplete :substitute command.
|
||
feed([[:%s/e/YYYY/g]])
|
||
wait()
|
||
-- Cancel the :substitute.
|
||
feed([[<C-\><C-N>]])
|
||
|
||
-- The undo tree should be unchanged.
|
||
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)
|
||
-- Make some changes.
|
||
feed([[isome text 1<C-\><C-N>]])
|
||
feed([[osome text 2<C-\><C-N>]])
|
||
-- Add an undo branch.
|
||
feed([[u]])
|
||
-- More changes, more undo branches.
|
||
feed([[osome text 3<C-\><C-N>]])
|
||
feed([[AX<C-\><C-N>]])
|
||
feed([[...]])
|
||
feed([[uu]])
|
||
feed([[osome text 4<C-\><C-N>]])
|
||
feed([[u<C-R>u]])
|
||
feed([[osome text 5<C-\><C-N>]])
|
||
expect([[
|
||
some text 1
|
||
some text 3XX
|
||
some text 5]])
|
||
local expected_undotree = eval("undotree()")
|
||
eq(5, #expected_undotree["entries"]) -- sanity
|
||
|
||
-- Start typing an incomplete :substitute command.
|
||
feed([[:%s/e/YYYY/g]])
|
||
wait()
|
||
-- Cancel the :substitute.
|
||
feed([[<C-\><C-N>]])
|
||
|
||
-- The undo tree should be unchanged.
|
||
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)
|
||
feed([[isome text 1<C-\><C-N>]])
|
||
feed([[osome text 2<C-\><C-N>]])
|
||
local expected_tick = eval("b:changedtick")
|
||
ok(expected_tick > 0)
|
||
|
||
expect([[
|
||
some text 1
|
||
some text 2]])
|
||
feed(":%s/e/XXX/")
|
||
wait()
|
||
|
||
eq(expected_tick, eval("b:changedtick"))
|
||
end)
|
||
end
|
||
|
||
for _, case in pairs{"", "split", "nosplit"} do
|
||
it("visual selection for non-previewable command (inccommand="..case..") #5888", function()
|
||
local screen = Screen.new(30,10)
|
||
common_setup(screen, case, default_text)
|
||
feed('1G2V')
|
||
|
||
feed(':s')
|
||
screen:expect([[
|
||
{vis:Inc substitution on} |
|
||
t{vis:wo lines} |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:'<,'>s^ |
|
||
]])
|
||
|
||
feed('o')
|
||
screen:expect([[
|
||
{vis:Inc substitution on} |
|
||
t{vis:wo lines} |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:'<,'>so^ |
|
||
]])
|
||
end)
|
||
end
|
||
|
||
end)
|
||
|
||
describe(":substitute, 'inccommand' preserves undo", function()
|
||
if helpers.pending_win32(pending) then return end
|
||
|
||
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>"
|
||
}
|
||
|
||
local function test_sub(substring, split, redoable)
|
||
clear()
|
||
feed_command("set inccommand=" .. split)
|
||
|
||
insert("1")
|
||
feed("o2<esc>")
|
||
feed_command("undo")
|
||
feed("o3<esc>")
|
||
if redoable then
|
||
feed("o4<esc>")
|
||
feed_command("undo")
|
||
end
|
||
feed(substring.. "<enter>")
|
||
feed_command("undo")
|
||
|
||
feed("g-")
|
||
expect([[
|
||
1
|
||
2]])
|
||
|
||
feed("g+")
|
||
expect([[
|
||
1
|
||
3]])
|
||
end
|
||
|
||
local function test_notsub(substring, split, redoable)
|
||
clear()
|
||
feed_command("set inccommand=" .. split)
|
||
|
||
insert("1")
|
||
feed("o2<esc>")
|
||
feed_command("undo")
|
||
feed("o3<esc>")
|
||
if redoable then
|
||
feed("o4<esc>")
|
||
feed_command("undo")
|
||
end
|
||
feed(substring .. "<esc>")
|
||
|
||
feed("g-")
|
||
expect([[
|
||
1
|
||
2]])
|
||
|
||
feed("g+")
|
||
expect([[
|
||
1
|
||
3]])
|
||
|
||
if redoable then
|
||
feed("<c-r>")
|
||
expect([[
|
||
1
|
||
3
|
||
4]])
|
||
end
|
||
end
|
||
|
||
|
||
local function test_threetree(substring, split)
|
||
clear()
|
||
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>")
|
||
|
||
-- This is the undo tree (x-Axis is timeline), we're at B now
|
||
-- ----------------A - B
|
||
-- /
|
||
-- | --------a - b
|
||
-- |/
|
||
-- 1 - 2 - 3
|
||
|
||
feed("2u")
|
||
feed(substring .. "<esc>")
|
||
expect([[
|
||
1]])
|
||
feed("g-")
|
||
expect([[
|
||
]])
|
||
feed("g+")
|
||
expect([[
|
||
1]])
|
||
feed("<c-r>")
|
||
expect([[
|
||
1
|
||
A]])
|
||
|
||
feed("g-") -- go to b
|
||
feed("2u")
|
||
feed(substring .. "<esc>")
|
||
feed("<c-r>")
|
||
expect([[
|
||
1
|
||
a]])
|
||
|
||
feed("g-") -- go to 3
|
||
feed("2u")
|
||
feed(substring .. "<esc>")
|
||
feed("<c-r>")
|
||
expect([[
|
||
1
|
||
2]])
|
||
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()
|
||
for _, case in pairs(cases) do
|
||
for _, str in pairs(substrings) do
|
||
for _, redoable in pairs({false}) do
|
||
test_sub(str, case, redoable)
|
||
end
|
||
end
|
||
end
|
||
end)
|
||
|
||
it("when interrupting substitution", function()
|
||
for _, case in pairs(cases) do
|
||
for _, str in pairs(substrings) do
|
||
for _, redoable in pairs({true,false}) do
|
||
test_notsub(str, case, redoable)
|
||
end
|
||
end
|
||
end
|
||
end)
|
||
|
||
it("in a complex undo scenario", function()
|
||
for _, case in pairs(cases) do
|
||
for _, str in pairs(substrings) do
|
||
test_threetree(str, case)
|
||
end
|
||
end
|
||
end)
|
||
|
||
it('with undolevels=0', function()
|
||
for _, case in pairs(cases) do
|
||
clear()
|
||
common_setup(nil, case, default_text)
|
||
feed_command("set undolevels=0")
|
||
|
||
feed("1G0")
|
||
insert("X")
|
||
feed(":%s/tw/MO/<esc>")
|
||
feed_command("undo")
|
||
expect(default_text)
|
||
feed_command("undo")
|
||
expect(default_text:gsub("Inc", "XInc"))
|
||
feed_command("undo")
|
||
|
||
feed_command("%s/tw/MO/g")
|
||
expect(default_text:gsub("tw", "MO"))
|
||
feed_command("undo")
|
||
expect(default_text)
|
||
feed_command("undo")
|
||
expect(default_text:gsub("tw", "MO"))
|
||
end
|
||
end)
|
||
|
||
it('with undolevels=1', function()
|
||
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("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")
|
||
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")
|
||
|
||
if case == "split" then
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
^MOo lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
Already ...t change |
|
||
]])
|
||
else
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
^MOo lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
Already ...t change |
|
||
]])
|
||
end
|
||
end
|
||
screen:detach()
|
||
end)
|
||
|
||
it('with undolevels=2', function()
|
||
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")
|
||
expect(default_text)
|
||
feed("u")
|
||
|
||
if case == "split" then
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
two line^s |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
Already ...t change |
|
||
]])
|
||
else
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
two line^s |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
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
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
^MOo lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
Already ...t change |
|
||
]])
|
||
else
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
^MOo lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
Already ...t change |
|
||
]])
|
||
end
|
||
screen:detach()
|
||
end
|
||
end)
|
||
|
||
it('with undolevels=-1', function()
|
||
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
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
^MOo lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
Already ...t change |
|
||
]])
|
||
else
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
^MOo lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
Already ...t change |
|
||
]])
|
||
end
|
||
|
||
-- repeat with an interrupted substitution
|
||
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")
|
||
|
||
screen:expect([[
|
||
^LInc substitution on|
|
||
two lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
Already ...t change |
|
||
]])
|
||
end
|
||
screen:detach()
|
||
end)
|
||
|
||
end)
|
||
|
||
describe(":substitute, inccommand=split", function()
|
||
if helpers.pending_win32(pending) then return end
|
||
|
||
local screen = Screen.new(30,15)
|
||
|
||
before_each(function()
|
||
clear()
|
||
common_setup(screen, "split", default_text .. default_text)
|
||
end)
|
||
|
||
after_each(function()
|
||
screen:detach()
|
||
end)
|
||
|
||
it("preserves 'modified' buffer flag", function()
|
||
feed_command("set nomodified")
|
||
feed(":%s/tw")
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
two lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] }|
|
||
|2| two lines |
|
||
|4| two lines |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/tw^ |
|
||
]])
|
||
feed([[<C-\><C-N>]]) -- Cancel the :substitute command.
|
||
eq(0, eval("&modified"))
|
||
end)
|
||
|
||
it("shows preview when cmd modifiers are present", function()
|
||
-- one modifier
|
||
feed(':keeppatterns %s/tw/to')
|
||
screen:expect([[too lines]], nil, nil, nil, true)
|
||
feed('<Esc>')
|
||
screen:expect([[two lines]], nil, nil, nil, true)
|
||
|
||
-- multiple modifiers
|
||
feed(':keeppatterns silent %s/tw/to')
|
||
screen:expect([[too lines]], nil, nil, nil, true)
|
||
feed('<Esc>')
|
||
screen:expect([[two lines]], nil, nil, nil, true)
|
||
|
||
-- non-modifier prefix
|
||
feed(':silent tabedit %s/tw/to')
|
||
screen:expect([[two lines]], nil, nil, nil, true)
|
||
feed('<Esc>')
|
||
end)
|
||
|
||
it('shows split window when typing the pattern', function()
|
||
feed(":%s/tw")
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
two lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|2| two lines |
|
||
|4| two lines |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/tw^ |
|
||
]])
|
||
end)
|
||
|
||
it('shows preview with empty replacement', function()
|
||
feed(":%s/tw/")
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
o lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|2| o lines |
|
||
|4| o lines |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/tw/^ |
|
||
]])
|
||
|
||
feed("x")
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
{12:x}o lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|2| {12:x}o lines |
|
||
|4| {12:x}o lines |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/tw/x^ |
|
||
]])
|
||
|
||
feed("<bs>")
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
o lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|2| o lines |
|
||
|4| o lines |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/tw/^ |
|
||
]])
|
||
|
||
end)
|
||
|
||
it('shows split window when typing replacement', function()
|
||
feed(":%s/tw/XX")
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
{12:XX}o lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|2| {12:XX}o lines |
|
||
|4| {12:XX}o lines |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/tw/XX^ |
|
||
]])
|
||
end)
|
||
|
||
it('does not show split window for :s/', function()
|
||
feed("2gg")
|
||
feed(":s/tw")
|
||
screen:sleep(1)
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
two lines |
|
||
Inc substitution on |
|
||
two lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:s/tw^ |
|
||
]])
|
||
end)
|
||
|
||
it("'hlsearch' is active, 'cursorline' is not", function()
|
||
feed_command("set hlsearch cursorline")
|
||
feed("gg")
|
||
|
||
-- Assert that 'cursorline' is active.
|
||
screen:expect([[
|
||
{16:^Inc substitution on }|
|
||
two lines |
|
||
Inc substitution on |
|
||
two lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:set hlsearch cursorline |
|
||
]])
|
||
|
||
feed(":%s/tw")
|
||
-- 'cursorline' is NOT active during preview.
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
{9:tw}o lines |
|
||
Inc substitution on |
|
||
{9:tw}o lines |
|
||
|
|
||
{11:[No Name] [+] }|
|
||
|2| {9:tw}o lines |
|
||
|4| {9:tw}o lines |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/tw^ |
|
||
]])
|
||
end)
|
||
|
||
it('highlights the replacement text', function()
|
||
feed('ggO')
|
||
feed('M M M<esc>')
|
||
feed(':%s/M/123/g')
|
||
screen:expect([[
|
||
{12:123} {12:123} {12:123} |
|
||
Inc substitution on |
|
||
two lines |
|
||
Inc substitution on |
|
||
two lines |
|
||
{11:[No Name] [+] }|
|
||
|1| {12:123} {12:123} {12:123} |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/M/123/g^ |
|
||
]])
|
||
end)
|
||
|
||
it('previews correctly when previewhight is small', function()
|
||
feed_command('set cwh=3')
|
||
feed_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} |
|
||
{11:[No Name] [+] }|
|
||
| 1| {12:MMM} {12:MMM} {12:MMM} |
|
||
| 2| {12:MMM} {12:MMM} {12:MMM} |
|
||
| 3| {12:MMM} {12:MMM} {12:MMM} |
|
||
{10:[Preview] }|
|
||
:%s/abc/MMM/g^ |
|
||
]])
|
||
end)
|
||
|
||
it('actually replaces text', function()
|
||
feed(":%s/tw/XX/g<Enter>")
|
||
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
XXo lines |
|
||
Inc substitution on |
|
||
^XXo lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:%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(":%s/tw/X")
|
||
screen:expect([[
|
||
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 |
|
||
|1005| {12:X}o lines |
|
||
|1007| {12:X}o lines |
|
||
|1009| {12:X}o lines |
|
||
|1011| {12:X}o lines |
|
||
|1013| {12:X}o lines |
|
||
{10:[Preview] }|
|
||
:%s/tw/X^ |
|
||
]])
|
||
end)
|
||
|
||
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")
|
||
-- Delete and re-type the g a few times.
|
||
feed("<BS>")
|
||
wait()
|
||
feed("g")
|
||
wait()
|
||
feed("<BS>")
|
||
wait()
|
||
feed("g")
|
||
wait()
|
||
feed("<CR>")
|
||
wait()
|
||
feed(":vs tmp<enter>")
|
||
eq(3, helpers.call('bufnr', '$'))
|
||
end)
|
||
|
||
it('works with the n flag', function()
|
||
feed(":%s/tw/Mix/n<Enter>")
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
two lines |
|
||
Inc substitution on |
|
||
two lines |
|
||
^ |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
2 matches on 2 lines |
|
||
]])
|
||
end)
|
||
|
||
it("deactivates if 'redrawtime' is exceeded #5602", function()
|
||
-- Assert that 'inccommand' is ENABLED initially.
|
||
eq("split", eval("&inccommand"))
|
||
-- Set 'redrawtime' to minimal value, to ensure timeout is triggered.
|
||
feed_command("set redrawtime=1 nowrap")
|
||
-- Load a big file.
|
||
feed_command("silent edit! test/functional/fixtures/bigfile_oneline.txt")
|
||
-- Start :substitute with a slow pattern.
|
||
feed([[:%s/B.*N/x]])
|
||
wait()
|
||
|
||
-- Assert that 'inccommand' is DISABLED in cmdline mode.
|
||
eq("", eval("&inccommand"))
|
||
-- Assert that preview cleared (or never manifested).
|
||
screen:expect([[
|
||
0000;<control>;Cc;0;BN;;;;;N;N|
|
||
2F923;CJK COMPATIBILITY IDEOGR|
|
||
2F924;CJK COMPATIBILITY IDEOGR|
|
||
2F925;CJK COMPATIBILITY IDEOGR|
|
||
2F926;CJK COMPATIBILITY IDEOGR|
|
||
2F927;CJK COMPATIBILITY IDEOGR|
|
||
2F928;CJK COMPATIBILITY IDEOGR|
|
||
2F929;CJK COMPATIBILITY IDEOGR|
|
||
2F92A;CJK COMPATIBILITY IDEOGR|
|
||
2F92B;CJK COMPATIBILITY IDEOGR|
|
||
2F92C;CJK COMPATIBILITY IDEOGR|
|
||
2F92D;CJK COMPATIBILITY IDEOGR|
|
||
2F92E;CJK COMPATIBILITY IDEOGR|
|
||
2F92F;CJK COMPATIBILITY IDEOGR|
|
||
:%s/B.*N/x^ |
|
||
]])
|
||
|
||
-- Assert that 'inccommand' is again ENABLED after leaving cmdline mode.
|
||
feed([[<C-\><C-N>]])
|
||
eq("split", eval("&inccommand"))
|
||
end)
|
||
|
||
it("clears preview if non-previewable command is edited #5585", function()
|
||
-- Put a non-previewable command in history.
|
||
feed_command("echo 'foo'")
|
||
-- Start an incomplete :substitute command.
|
||
feed(":1,2s/t/X")
|
||
|
||
screen:expect([[
|
||
Inc subs{12:X}itution on |
|
||
{12:X}wo lines |
|
||
Inc substitution on |
|
||
two lines |
|
||
|
|
||
{11:[No Name] [+] }|
|
||
|1| Inc subs{12:X}itution on |
|
||
|2| {12:X}wo lines |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:1,2s/t/X^ |
|
||
]])
|
||
|
||
-- Select the previous command.
|
||
feed("<C-P>")
|
||
-- Assert that preview was cleared.
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
two lines |
|
||
Inc substitution on |
|
||
two lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:echo 'foo'^ |
|
||
]])
|
||
end)
|
||
|
||
end)
|
||
|
||
describe("inccommand=nosplit", function()
|
||
if helpers.pending_win32(pending) then return end
|
||
|
||
local screen = Screen.new(20,10)
|
||
|
||
before_each(function()
|
||
clear()
|
||
common_setup(screen, "nosplit", default_text .. default_text)
|
||
end)
|
||
|
||
after_each(function()
|
||
if screen then screen:detach() end
|
||
end)
|
||
|
||
it("works with :smagic, :snomagic", function()
|
||
feed_command("set hlsearch")
|
||
insert("Line *.3.* here")
|
||
|
||
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:~ }|
|
||
:%smagic/3.*/X^ |
|
||
]])
|
||
|
||
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:~ }|
|
||
:%snomagic/3.*/X^ |
|
||
]])
|
||
end)
|
||
|
||
it("shows preview when cmd modifiers are present", function()
|
||
-- one modifier
|
||
feed(':keeppatterns %s/tw/to')
|
||
screen:expect([[too lines]], nil, nil, nil, true)
|
||
feed('<Esc>')
|
||
screen:expect([[two lines]], nil, nil, nil, true)
|
||
|
||
-- multiple modifiers
|
||
feed(':keeppatterns silent %s/tw/to')
|
||
screen:expect([[too lines]], nil, nil, nil, true)
|
||
feed('<Esc>')
|
||
screen:expect([[two lines]], nil, nil, nil, true)
|
||
|
||
-- non-modifier prefix
|
||
feed(':silent tabedit %s/tw/to')
|
||
screen:expect([[two lines]], nil, nil, nil, true)
|
||
feed('<Esc>')
|
||
end)
|
||
|
||
it("does not show window after toggling :set inccomand", 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")
|
||
wait()
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
{12:OKOK}o lines |
|
||
Inc substitution on |
|
||
{12:OKOK}o lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:%s/tw/OKOK^ |
|
||
]])
|
||
end)
|
||
|
||
it('never shows preview buffer', function()
|
||
feed_command("set hlsearch")
|
||
|
||
feed(":%s/tw")
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
{9:tw}o lines |
|
||
Inc substitution on |
|
||
{9:tw}o lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:%s/tw^ |
|
||
]])
|
||
|
||
feed("/BM")
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
{12:BM}o lines |
|
||
Inc substitution on |
|
||
{12:BM}o lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:%s/tw/BM^ |
|
||
]])
|
||
|
||
feed("/")
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
{12:BM}o lines |
|
||
Inc substitution on |
|
||
{12:BM}o lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:%s/tw/BM/^ |
|
||
]])
|
||
|
||
feed("<enter>")
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
BMo lines |
|
||
Inc substitution on |
|
||
^BMo lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:%s/tw/BM/ |
|
||
]])
|
||
end)
|
||
|
||
it("clears preview if non-previewable command is edited", function()
|
||
-- Put a non-previewable command in history.
|
||
feed_command("echo 'foo'")
|
||
-- Start an incomplete :substitute command.
|
||
feed(":1,2s/t/X")
|
||
|
||
screen:expect([[
|
||
Inc subs{12:X}itution on |
|
||
{12:X}wo lines |
|
||
Inc substitution on |
|
||
two lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:1,2s/t/X^ |
|
||
]])
|
||
|
||
-- Select the previous command.
|
||
feed("<C-P>")
|
||
-- Assert that preview was cleared.
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
two lines |
|
||
Inc substitution on |
|
||
two lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:echo 'foo'^ |
|
||
]])
|
||
end)
|
||
end)
|
||
|
||
describe(":substitute, 'inccommand' with a failing expression", function()
|
||
if helpers.pending_win32(pending) then return end
|
||
|
||
local screen = Screen.new(20,10)
|
||
local cases = { "", "split", "nosplit" }
|
||
|
||
local function refresh(case)
|
||
clear()
|
||
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>")
|
||
expect(default_text)
|
||
end
|
||
end)
|
||
|
||
it('in the replacement deletes the matches', function()
|
||
for _, case in pairs(cases) do
|
||
refresh(case)
|
||
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")
|
||
end
|
||
end
|
||
end)
|
||
|
||
it('in the range does not error #5912', function()
|
||
for _, case in pairs(cases) do
|
||
refresh(case)
|
||
feed(':100s/')
|
||
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
two lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:100s/^ |
|
||
]])
|
||
|
||
feed('<enter>')
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
two lines |
|
||
^ |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{14:E16: Invalid range} |
|
||
]])
|
||
end
|
||
end)
|
||
|
||
end)
|
||
|
||
describe("'inccommand' and :cnoremap", function()
|
||
local cases = { "", "split", "nosplit" }
|
||
|
||
local function refresh(case)
|
||
clear()
|
||
common_setup(nil, case, default_text)
|
||
end
|
||
|
||
it('work with remapped characters', function()
|
||
for _, case in pairs(cases) do
|
||
refresh(case)
|
||
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)
|
||
end
|
||
|
||
feed_command(cmd)
|
||
expect([[
|
||
Inc substitution on
|
||
two LINES
|
||
]])
|
||
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>")
|
||
|
||
feed(":%s/lines/,Sor three <enter>")
|
||
expect([[
|
||
Inc substitution on
|
||
two or three LINES
|
||
]])
|
||
|
||
feed_command("cnoremap ;S /X/<left><left><left>")
|
||
feed(":%s/;SI<enter>")
|
||
expect([[
|
||
Xnc substitution on
|
||
two or three LXNES
|
||
]])
|
||
|
||
feed_command("cnoremap ,T //Y/<left><left><left>")
|
||
feed(":%s,TX<enter>")
|
||
expect([[
|
||
Ync substitution on
|
||
two or three LYNES
|
||
]])
|
||
|
||
feed_command("cnoremap ;T s//Z/<left><left><left>")
|
||
feed(":%;TY<enter>")
|
||
expect([[
|
||
Znc substitution on
|
||
two or three LZNES
|
||
]])
|
||
end
|
||
end)
|
||
|
||
it('does not work with a failing mapping', function()
|
||
for _, case in pairs(cases) do
|
||
refresh(case)
|
||
feed_command("cnoremap <expr> x execute('bwipeout!')[-1].'x'")
|
||
|
||
feed(":%s/tw/tox<enter>")
|
||
|
||
-- error thrown b/c of the mapping
|
||
neq(nil, eval('v:errmsg'):find('^E523:'))
|
||
expect(default_text)
|
||
end
|
||
end)
|
||
|
||
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'")
|
||
|
||
feed(":%s/tw/tox/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]")
|
||
|
||
feed(":%s/tw/toxa/g<enter>")
|
||
expect(default_text:gsub("tw", "toa"))
|
||
end
|
||
end)
|
||
|
||
it('work with a complex mapping', function()
|
||
for _, case in pairs(cases) do
|
||
refresh(case)
|
||
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"))
|
||
end
|
||
end)
|
||
|
||
end)
|
||
|
||
describe("'inccommand' autocommands", function()
|
||
before_each(clear)
|
||
|
||
-- keys are events to be tested
|
||
-- values are arrays like
|
||
-- { open = { 1 }, close = { 2, 3} }
|
||
-- which would mean that during the test below the event fires for
|
||
-- buffer 1 when opening the preview window, and for buffers 2 and 3
|
||
-- when closing the preview window
|
||
local eventsExpected = {
|
||
BufAdd = {},
|
||
BufDelete = {},
|
||
BufEnter = {},
|
||
BufFilePost = {},
|
||
BufFilePre = {},
|
||
BufHidden = {},
|
||
BufLeave = {},
|
||
BufNew = {},
|
||
BufNewFile = {},
|
||
BufRead = {},
|
||
BufReadCmd = {},
|
||
BufReadPre = {},
|
||
BufUnload = {},
|
||
BufWinEnter = {},
|
||
BufWinLeave = {},
|
||
BufWipeout = {},
|
||
BufWrite = {},
|
||
BufWriteCmd = {},
|
||
BufWritePost = {},
|
||
Syntax = {},
|
||
FileType = {},
|
||
WinEnter = {},
|
||
WinLeave = {},
|
||
CmdwinEnter = {},
|
||
CmdwinLeave = {},
|
||
}
|
||
|
||
local function bufferlist(t)
|
||
local s = ""
|
||
for _, buffer in pairs(t) do
|
||
s = s .. ", " .. tostring(buffer)
|
||
end
|
||
return s
|
||
end
|
||
|
||
-- fill the table with default values
|
||
for event, _ in pairs(eventsExpected) do
|
||
eventsExpected[event].open = eventsExpected[event].open or {}
|
||
eventsExpected[event].close = eventsExpected[event].close or {}
|
||
end
|
||
|
||
local function register_autocmd(event)
|
||
meths.set_var(event .. "_fired", {})
|
||
feed_command("autocmd " .. event .. " * call add(g:" .. event .. "_fired, expand('<abuf>'))")
|
||
end
|
||
|
||
it('are not fired when splitting', function()
|
||
common_setup(nil, "split", default_text)
|
||
|
||
local eventsObserved = {}
|
||
for event, _ in pairs(eventsExpected) do
|
||
eventsObserved[event] = {}
|
||
register_autocmd(event)
|
||
end
|
||
|
||
feed(":%s/tw")
|
||
|
||
for event, _ in pairs(eventsExpected) do
|
||
eventsObserved[event].open = meths.get_var(event .. "_fired")
|
||
meths.set_var(event .. "_fired", {})
|
||
end
|
||
|
||
feed("/<enter>")
|
||
|
||
for event, _ in pairs(eventsExpected) do
|
||
eventsObserved[event].close = meths.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))
|
||
end
|
||
end)
|
||
|
||
end)
|
||
|
||
describe("'inccommand' split windows", function()
|
||
if helpers.pending_win32(pending) then return end
|
||
|
||
local screen
|
||
local function refresh()
|
||
clear()
|
||
screen = Screen.new(40,30)
|
||
common_setup(screen, "split", default_text)
|
||
end
|
||
|
||
after_each(function()
|
||
screen:detach()
|
||
end)
|
||
|
||
it('work after more splits', function()
|
||
refresh()
|
||
|
||
feed("gg")
|
||
feed_command("vsplit")
|
||
feed_command("split")
|
||
feed(":%s/tw")
|
||
screen:expect([[
|
||
Inc substitution on {10:|}Inc substitution on|
|
||
two lines {10:|}two lines |
|
||
{10:|} |
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{11:[No Name] [+] }{10:|}{15:~ }|
|
||
Inc substitution on {10:|}{15:~ }|
|
||
two lines {10:|}{15:~ }|
|
||
{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{10:[No Name] [+] [No Name] [+] }|
|
||
|2| two lines |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/tw^ |
|
||
]])
|
||
|
||
feed("<esc>")
|
||
feed_command("only")
|
||
feed_command("split")
|
||
feed_command("vsplit")
|
||
|
||
feed(":%s/tw")
|
||
screen:expect([[
|
||
Inc substitution on {10:|}Inc substitution on|
|
||
two lines {10:|}two lines |
|
||
{10:|} |
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{15:~ }{10:|}{15:~ }|
|
||
{11:[No Name] [+] }{10:[No Name] [+] }|
|
||
Inc substitution on |
|
||
two lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[No Name] [+] }|
|
||
|2| two lines |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/tw^ |
|
||
]])
|
||
end)
|
||
|
||
local settings = {
|
||
"splitbelow",
|
||
"splitright",
|
||
"noequalalways",
|
||
"equalalways eadirection=ver",
|
||
"equalalways eadirection=hor",
|
||
"equalalways eadirection=both",
|
||
}
|
||
|
||
it("are not affected by various settings", function()
|
||
for _, setting in pairs(settings) do
|
||
refresh()
|
||
feed_command("set " .. setting)
|
||
|
||
feed(":%s/tw")
|
||
|
||
screen:expect([[
|
||
Inc substitution on |
|
||
two lines |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|2| two lines |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/tw^ |
|
||
]])
|
||
end
|
||
end)
|
||
|
||
end)
|
||
|
||
describe("'inccommand' with 'gdefault'", function()
|
||
before_each(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"))
|
||
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"))
|
||
end)
|
||
end)
|
||
|
||
describe(":substitute", function()
|
||
local screen = Screen.new(30,15)
|
||
|
||
before_each(function()
|
||
clear()
|
||
end)
|
||
|
||
it(", inccomand=split, highlights multiline substitutions", function()
|
||
common_setup(screen, "split", multiline_text)
|
||
feed("gg")
|
||
|
||
feed(":%s/2\\_.*X/MMM")
|
||
screen:expect([[
|
||
1 {12:MMM} Y Z |
|
||
7 8 9 |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|1| 1 {12:MMM} Y Z |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/2\_.*X/MMM^ |
|
||
]])
|
||
|
||
feed("\\rK\\rLLL")
|
||
screen:expect([[
|
||
1 {12:MMM} |
|
||
{12:K} |
|
||
{12:LLL} Y Z |
|
||
7 8 9 |
|
||
|
|
||
{11:[No Name] [+] }|
|
||
|1| 1 {12:MMM} |
|
||
|2|{12: K} |
|
||
|3|{12: LLL} Y Z |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/2\_.*X/MMM\rK\rLLL^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=nosplit, highlights multiline substitutions", function()
|
||
common_setup(screen, "nosplit", multiline_text)
|
||
feed("gg")
|
||
|
||
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:~ }|
|
||
:%s/2\_.*X/MMM^ |
|
||
]])
|
||
|
||
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:~ }|
|
||
:%s/2\_.*X/MMM\rK\rLLL^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=split, highlights multiple matches on a line", function()
|
||
common_setup(screen, "split", multimatch_text)
|
||
command("set gdefault")
|
||
feed("gg")
|
||
|
||
feed(":%s/a/XLK")
|
||
screen:expect([[
|
||
{12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:XLK} r|
|
||
x |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{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:~ }|
|
||
{10:[Preview] }|
|
||
:%s/a/XLK^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=nosplit, highlights multiple matches on a line", function()
|
||
common_setup(screen, "nosplit", multimatch_text)
|
||
command("set gdefault")
|
||
feed("gg")
|
||
|
||
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:~ }|
|
||
:%s/a/XLK^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=split, with \\zs", function()
|
||
common_setup(screen, "split", multiline_text)
|
||
feed("gg")
|
||
|
||
feed(":%s/[0-9]\\n\\zs[A-Z]/OKO")
|
||
screen:expect([[
|
||
1 2 3 |
|
||
{12:OKO} B C |
|
||
4 5 6 |
|
||
{12:OKO} Y Z |
|
||
7 8 9 |
|
||
{11:[No Name] [+] }|
|
||
|1| 1 2 3 |
|
||
|2| {12:OKO} B C |
|
||
|3| 4 5 6 |
|
||
|4| {12:OKO} Y Z |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/[0-9]\n\zs[A-Z]/OKO^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=nosplit, with \\zs", function()
|
||
common_setup(screen, "nosplit", multiline_text)
|
||
feed("gg")
|
||
|
||
feed(":%s/[0-9]\\n\\zs[A-Z]/OKO")
|
||
screen:expect([[
|
||
1 2 3 |
|
||
{12:OKO} B C |
|
||
4 5 6 |
|
||
{12:OKO} Y Z |
|
||
7 8 9 |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:%s/[0-9]\n\zs[A-Z]/OKO^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=split, substitutions of different length",
|
||
function()
|
||
common_setup(screen, "split", "T T123 T2T TTT T090804\nx")
|
||
|
||
feed(":%s/T\\([0-9]\\+\\)/\\1\\1/g")
|
||
screen:expect([[
|
||
T {12:123123} {12:22}T TTT {12:090804090804} |
|
||
x |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|1| T {12:123123} {12:22}T TTT {12:090804090}|
|
||
{12:804} |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/T\([0-9]\+\)/\1\1/g^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=nosplit, substitutions of different length", function()
|
||
common_setup(screen, "nosplit", "T T123 T2T TTT T090804\nx")
|
||
|
||
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:~ }|
|
||
:%s/T\([0-9]\+\)/\1\1/g^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=split, contraction of lines", function()
|
||
local text = [[
|
||
T T123 T T123 T2T TT T23423424
|
||
x
|
||
afa Q
|
||
adf la;lkd R
|
||
alx
|
||
]]
|
||
|
||
common_setup(screen, "split", text)
|
||
feed(":%s/[QR]\\n")
|
||
screen:expect([[
|
||
afa Q |
|
||
adf la;lkd R |
|
||
alx |
|
||
|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|3| afa Q |
|
||
|4| adf la;lkd R |
|
||
|5| alx |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/[QR]\n^ |
|
||
]])
|
||
|
||
feed("/KKK")
|
||
screen:expect([[
|
||
x |
|
||
afa {12:KKK}adf la;lkd {12:KKK}alx |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|3| afa {12:KKK}adf la;lkd {12:KKK}alx |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/[QR]\n/KKK^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=nosplit, contraction of lines", function()
|
||
local text = [[
|
||
T T123 T T123 T2T TT T23423424
|
||
x
|
||
afa Q
|
||
adf la;lkd R
|
||
alx
|
||
]]
|
||
|
||
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:~ }|
|
||
:%s/[QR]\n/KKK^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccommand=split, multibyte text", function()
|
||
common_setup(screen, "split", multibyte_text)
|
||
feed(":%s/£.*ѫ/X¥¥")
|
||
screen:expect([[
|
||
{12:X¥¥} |
|
||
a{12:X¥¥}¥KOL |
|
||
£ ¥ libm |
|
||
£ ¥ |
|
||
|
|
||
{11:[No Name] [+] }|
|
||
|1| {12:X¥¥} PEPPERS |
|
||
|2| {12:X¥¥} |
|
||
|3| a{12:X¥¥}¥KOL |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/£.*ѫ/X¥¥^ |
|
||
]])
|
||
|
||
feed("\\ra££ ¥")
|
||
screen:expect([[
|
||
{12:a££ ¥} |
|
||
a{12:X¥¥} |
|
||
{12:a££ ¥}¥KOL |
|
||
£ ¥ libm |
|
||
£ ¥ |
|
||
{11:[No Name] [+] }|
|
||
|1| {12:X¥¥} |
|
||
|2|{12: a££ ¥} PEPPERS |
|
||
|3| {12:X¥¥} |
|
||
|4|{12: a££ ¥} |
|
||
|5| a{12:X¥¥} |
|
||
|6|{12: a££ ¥}¥KOL |
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/£.*ѫ/X¥¥\ra££ ¥^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccommand=nosplit, multibyte text", function()
|
||
common_setup(screen, "nosplit", multibyte_text)
|
||
feed(":%s/£.*ѫ/X¥¥")
|
||
screen:expect([[
|
||
{12:X¥¥} PEPPERS |
|
||
{12:X¥¥} |
|
||
a{12:X¥¥}¥KOL |
|
||
£ ¥ libm |
|
||
£ ¥ |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:%s/£.*ѫ/X¥¥^ |
|
||
]])
|
||
|
||
feed("\\ra££ ¥")
|
||
screen:expect([[
|
||
{12:X¥¥} |
|
||
{12:a££ ¥} PEPPERS |
|
||
{12:X¥¥} |
|
||
{12:a££ ¥} |
|
||
a{12:X¥¥} |
|
||
{12:a££ ¥}¥KOL |
|
||
£ ¥ libm |
|
||
£ ¥ |
|
||
|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
:%s/£.*ѫ/X¥¥\ra££ ¥^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=split, small cmdwinheight", function()
|
||
common_setup(screen, "split", long_multiline_text)
|
||
command("set cmdwinheight=2")
|
||
|
||
feed(":%s/[a-z]")
|
||
screen:expect([[
|
||
X Y Z |
|
||
7 8 9 |
|
||
K L M |
|
||
a b c |
|
||
d e f |
|
||
q r s |
|
||
x y z |
|
||
£ m n |
|
||
t œ ¥ |
|
||
|
|
||
{11:[No Name] [+] }|
|
||
| 7| a b c |
|
||
| 8| d e f |
|
||
{10:[Preview] }|
|
||
:%s/[a-z]^ |
|
||
]])
|
||
|
||
feed("/JLKR £")
|
||
screen:expect([[
|
||
X Y Z |
|
||
7 8 9 |
|
||
K L M |
|
||
{12:JLKR £} b c |
|
||
{12:JLKR £} e f |
|
||
{12:JLKR £} r s |
|
||
{12:JLKR £} y z |
|
||
£ {12:JLKR £} n |
|
||
{12:JLKR £} œ ¥ |
|
||
|
|
||
{11:[No Name] [+] }|
|
||
| 7| {12:JLKR £} b c |
|
||
| 8| {12:JLKR £} e f |
|
||
{10:[Preview] }|
|
||
:%s/[a-z]/JLKR £^ |
|
||
]])
|
||
|
||
feed("\\rѫ ab \\rXXXX")
|
||
screen:expect([[
|
||
7 8 9 |
|
||
K L M |
|
||
{12:JLKR £} |
|
||
{12:ѫ ab } |
|
||
{12:XXXX} b c |
|
||
{12:JLKR £} |
|
||
{12:ѫ ab } |
|
||
{12:XXXX} e f |
|
||
{12:JLKR £} |
|
||
{11:[No Name] [+] }|
|
||
| 7| {12:JLKR £} |
|
||
| 8|{12: ѫ ab } |
|
||
{10:[Preview] }|
|
||
:%s/[a-z]/JLKR £\rѫ ab \rXXX|
|
||
X^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=split, large cmdwinheight", function()
|
||
common_setup(screen, "split", long_multiline_text)
|
||
command("set cmdwinheight=11")
|
||
|
||
feed(":%s/. .$")
|
||
screen:expect([[
|
||
t œ ¥ |
|
||
{11:[No Name] [+] }|
|
||
| 1| 1 2 3 |
|
||
| 2| A B C |
|
||
| 3| 4 5 6 |
|
||
| 4| X Y Z |
|
||
| 5| 7 8 9 |
|
||
| 6| K L M |
|
||
| 7| a b c |
|
||
| 8| d e f |
|
||
| 9| q r s |
|
||
|10| x y z |
|
||
|11| £ m n |
|
||
{10:[Preview] }|
|
||
:%s/. .$^ |
|
||
]])
|
||
|
||
feed("/ YYY")
|
||
screen:expect([[
|
||
t {12: YYY} |
|
||
{11:[No Name] [+] }|
|
||
| 1| 1 {12: YYY} |
|
||
| 2| A {12: YYY} |
|
||
| 3| 4 {12: YYY} |
|
||
| 4| X {12: YYY} |
|
||
| 5| 7 {12: YYY} |
|
||
| 6| K {12: YYY} |
|
||
| 7| a {12: YYY} |
|
||
| 8| d {12: YYY} |
|
||
| 9| q {12: YYY} |
|
||
|10| x {12: YYY} |
|
||
|11| £ {12: YYY} |
|
||
{10:[Preview] }|
|
||
:%s/. .$/ YYY^ |
|
||
]])
|
||
|
||
feed("\\r KKK")
|
||
screen:expect([[
|
||
a {12: YYY} |
|
||
{11:[No Name] [+] }|
|
||
| 1| 1 {12: YYY} |
|
||
| 2|{12: KKK} |
|
||
| 3| A {12: YYY} |
|
||
| 4|{12: KKK} |
|
||
| 5| 4 {12: YYY} |
|
||
| 6|{12: KKK} |
|
||
| 7| X {12: YYY} |
|
||
| 8|{12: KKK} |
|
||
| 9| 7 {12: YYY} |
|
||
|10|{12: KKK} |
|
||
|11| K {12: YYY} |
|
||
{10:[Preview] }|
|
||
:%s/. .$/ YYY\r KKK^ |
|
||
]])
|
||
end)
|
||
|
||
it(", inccomand=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:~ }|
|
||
{11:[No Name] [+] }|
|
||
|1| some{12:one} |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/\(some\)\@<=thing/one/^ |
|
||
]])
|
||
|
||
feed("<C-c>")
|
||
wait()
|
||
feed([[:%s/\(some\)\@<lt>!thing/one/]])
|
||
screen:expect([[
|
||
something |
|
||
every{12:one} |
|
||
someone |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|2| every{12:one} |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/\(some\)\@<!thing/one/^ |
|
||
]])
|
||
|
||
feed([[<C-c>]])
|
||
wait()
|
||
feed([[:%s/some\(thing\)\@=/every/]])
|
||
screen:expect([[
|
||
{12:every}thing |
|
||
everything |
|
||
someone |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|1| {12:every}thing |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/some\(thing\)\@=/every/^ |
|
||
]])
|
||
|
||
feed([[<C-c>]])
|
||
wait()
|
||
feed([[:%s/some\(thing\)\@!/every/]])
|
||
screen:expect([[
|
||
everything |
|
||
{12:every}one |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{11:[No Name] [+] }|
|
||
|3| {12:every}one |
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{15:~ }|
|
||
{10:[Preview] }|
|
||
:%s/some\(thing\)\@!/every/^ |
|
||
]])
|
||
end)
|
||
end)
|