mirror of
https://github.com/neovim/neovim.git
synced 2026-06-15 16:23:48 +00:00
Problem: A vim.ui_attach() callback that redraws to show a 'verbose'
regex message during 'incsearch' results in recusive redrawing.
Solution: Check that curwin was redrawn instead of just any window when
determining if 'incsearch' highlighting was cleared.
(cherry picked from commit 61fb88992d)
311 lines
13 KiB
Lua
311 lines
13 KiB
Lua
-- Tests for (protocol-driven) ui2, intended to replace the legacy message grid UI.
|
|
|
|
local t = require('test.testutil')
|
|
local n = require('test.functional.testnvim')()
|
|
local Screen = require('test.functional.ui.screen')
|
|
|
|
local clear, exec, exec_lua, feed = n.clear, n.exec, n.exec_lua, n.feed
|
|
|
|
describe('cmdline2', function()
|
|
local screen
|
|
before_each(function()
|
|
clear()
|
|
screen = Screen.new()
|
|
screen:add_extra_attr_ids({
|
|
[100] = { foreground = Screen.colors.Magenta1, bold = true },
|
|
[101] = { background = Screen.colors.Yellow, foreground = Screen.colors.Grey0 },
|
|
})
|
|
exec_lua(function()
|
|
require('vim._core.ui2').enable({})
|
|
end)
|
|
end)
|
|
|
|
it("no crash for invalid grid after 'cmdheight' OptionSet", function()
|
|
exec('tabnew | tabprev')
|
|
feed(':set ch=0')
|
|
screen:expect([[
|
|
{5: [No Name] }{24: [No Name] }{2: }{24:X}|
|
|
|
|
|
{1:~ }|*11
|
|
{16::}{15:set} {16:ch}{15:=}0^ |
|
|
]])
|
|
feed('<CR>')
|
|
exec('tabnext')
|
|
screen:expect([[
|
|
{24: [No Name] }{5: [No Name] }{2: }{24:X}|
|
|
^ |
|
|
{1:~ }|*11
|
|
{16::}{15:set} {16:ch}{15:=}0 |
|
|
]])
|
|
exec('tabnext')
|
|
screen:expect([[
|
|
{5: [No Name] }{24: [No Name] }{2: }{24:X}|
|
|
^ |
|
|
{1:~ }|*12
|
|
]])
|
|
n.assert_alive()
|
|
end)
|
|
|
|
it("redraw does not clear 'incsearch' highlight with conceal", function()
|
|
exec('call setline(1, ["foo", "foobar"]) | set conceallevel=1 concealcursor=c')
|
|
feed('/foo')
|
|
screen:expect([[
|
|
{10:foo} |
|
|
{2:foo}bar |
|
|
{1:~ }|*11
|
|
/foo^ |
|
|
]])
|
|
end)
|
|
|
|
it('block mode', function()
|
|
feed(':if 1<CR>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*11
|
|
{16::}{15:if} {26:1} |
|
|
{16::} ^ |
|
|
]])
|
|
feed('echo "foo"')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*11
|
|
{16::}{15:if} {26:1} |
|
|
{16::} {15:echo} {26:"foo"}^ |
|
|
]])
|
|
feed('<CR>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*9
|
|
{16::}{15:if} {26:1} |
|
|
{16::} {15:echo} {26:"foo"} |
|
|
foo |
|
|
{16::} ^ |
|
|
]])
|
|
feed([[echo input("foo\nbar:")<CR>]])
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*7
|
|
{16::}{15:if} {26:1} |
|
|
{16::} {15:echo} {26:"foo"} |
|
|
foo |
|
|
{16::} {15:echo} {25:input}{16:(}{26:"foo\nbar:"}{16:)} |
|
|
foo |
|
|
bar:^ |
|
|
]])
|
|
feed('baz')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*7
|
|
{16::}{15:if} {26:1} |
|
|
{16::} {15:echo} {26:"foo"} |
|
|
foo |
|
|
{16::} {15:echo} {25:input}{16:(}{26:"foo\nbar:"}{16:)} |
|
|
foo |
|
|
bar:baz^ |
|
|
]])
|
|
feed('<CR>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*5
|
|
{16::}{15:if} {26:1} |
|
|
{16::} {15:echo} {26:"foo"} |
|
|
foo |
|
|
{16::} {15:echo} {25:input}{16:(}{26:"foo\nbar:"}{16:)} |
|
|
foo |
|
|
bar:baz |
|
|
baz |
|
|
{16::} ^ |
|
|
]])
|
|
feed('endif')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*5
|
|
{16::}{15:if} {26:1} |
|
|
{16::} {15:echo} {26:"foo"} |
|
|
foo |
|
|
{16::} {15:echo} {25:input}{16:(}{26:"foo\nbar:"}{16:)} |
|
|
foo |
|
|
bar:baz |
|
|
baz |
|
|
{16::} {15:endif}^ |
|
|
]])
|
|
feed('<CR>')
|
|
screen:expect([[
|
|
^ |
|
|
{1:~ }|*12
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('handles empty prompt', function()
|
|
feed(":call input('')<CR>")
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*12
|
|
^ |
|
|
]])
|
|
end)
|
|
|
|
it('highlights after deleting buffer', function()
|
|
feed(':sil %bw!<CR>:call foo()')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*12
|
|
{16::}{15:call} {25:foo}{16:()}^ |
|
|
]])
|
|
end)
|
|
|
|
it('can change cmdline buffer during textlock', function()
|
|
exec([[
|
|
func Foo(a, b)
|
|
redrawstatus!
|
|
endfunc
|
|
set wildoptions=pum findfunc=Foo wildmode=noselect:lastused,full
|
|
au CmdlineChanged * call wildtrigger()
|
|
]])
|
|
feed(':find ')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*12
|
|
{16::}{15:find} ^ |
|
|
]])
|
|
t.eq(n.eval('v:errmsg'), "E1514: 'findfunc' did not return a List type")
|
|
end)
|
|
|
|
it('substitution match, empty message does not clear active cmdline', function()
|
|
exec('call setline(1, "foo")')
|
|
feed(':s/f')
|
|
screen:expect([[
|
|
{10:f}oo |
|
|
{1:~ }|*12
|
|
{16::}{15:s}{16:/f^ } |
|
|
]])
|
|
feed('<Esc>:foo')
|
|
screen:expect([[
|
|
foo |
|
|
{1:~ }|*12
|
|
{16::}{15:foo}^ |
|
|
]])
|
|
exec('echo')
|
|
screen:expect_unchanged(true)
|
|
end)
|
|
|
|
it('dialog position is adjusted for toggled non-pum wildmenu', function()
|
|
exec([[
|
|
set wildmode=list:full,full wildoptions-=pum
|
|
func Foo()
|
|
endf
|
|
func Fooo()
|
|
endf
|
|
]])
|
|
feed(':call Fo<C-Z>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*9
|
|
{3: }|
|
|
Foo() Fooo() |
|
|
|
|
|
{16::}{15:call} Fo^ |
|
|
]])
|
|
feed('<C-Z>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*8
|
|
{3: }|
|
|
Foo() Fooo() |
|
|
|
|
|
{101:Foo()}{3: Fooo() }|
|
|
{16::}{15:call} {25:Foo}{16:()}^ |
|
|
]])
|
|
feed('<BS><BS>')
|
|
exec('set wildoptions+=pum laststatus=2')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*9
|
|
{3: }|
|
|
Foo() Fooo() |
|
|
|
|
|
{16::}{15:call} Foo^ |
|
|
]])
|
|
feed('<C-Z><C-Z>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*9
|
|
{3: }|
|
|
Foo(){12: Foo() } |
|
|
{4: Fooo() } |
|
|
{16::}{15:call} {25:Foo}{16:()}^ |
|
|
]])
|
|
end)
|
|
|
|
it('updated after setcmdline() #38764', function()
|
|
-- Also check that command-preview is updated.
|
|
exec('call setline(1, "foo")')
|
|
feed(':%s/foo')
|
|
screen:expect([[
|
|
{10:foo} |
|
|
{1:~ }|*12
|
|
{16::}%{15:s}{16:/foo^ } |
|
|
]])
|
|
exec_lua(function()
|
|
_G.events = {}
|
|
vim.api.nvim_create_autocmd({ 'CmdlineChanged', 'CursorMovedC' }, {
|
|
callback = function(ev)
|
|
_G.events[ev.event] = (_G.events[ev.event] or 0) + 1
|
|
end,
|
|
})
|
|
end)
|
|
exec('call setcmdline("%s/fo")')
|
|
screen:expect([[
|
|
{10:fo}o |
|
|
{1:~ }|*12
|
|
{16::}%{15:s}{16:/fo^ } |
|
|
]])
|
|
t.eq({ CmdlineChanged = 1, CursorMovedC = 1 }, exec_lua('return _G.events'))
|
|
end)
|
|
|
|
it("no 'incsearch' recursion with 'verbose' regex message", function()
|
|
exec('set verbose=1')
|
|
feed([[:%s/.\{//}]])
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*9
|
|
{3: }|
|
|
Switching to backtracking RE engine for pattern: .\{ |*2
|
|
{16::}%{15:s}{16:/.\{//}^ } |
|
|
]])
|
|
end)
|
|
end)
|
|
|
|
describe('cmdline2', function()
|
|
it('resizing during startup shows confirm prompt #36439', function()
|
|
clear({
|
|
args = {
|
|
'--clean',
|
|
'+lua require("vim._core.ui2").enable({})',
|
|
"+call feedkeys(':')",
|
|
},
|
|
})
|
|
local screen = Screen.new()
|
|
feed('call confirm("Ok?")<CR>')
|
|
screen:try_resize(screen._width + 1, screen._height)
|
|
screen:expect([[
|
|
|*10
|
|
{3: }|
|
|
|
|
|
{6:Ok?} |
|
|
{6:[O]k: }^ |
|
|
]])
|
|
-- And resizing the next event loop iteration also works.
|
|
feed('k')
|
|
screen:try_resize(screen._width, screen._height + 1)
|
|
screen:expect([[
|
|
|*11
|
|
{3: }|
|
|
|
|
|
{6:Ok?} |
|
|
{6:[O]k: }^ |
|
|
]])
|
|
end)
|
|
end)
|