aboutsummaryrefslogtreecommitdiff
path: root/test/functional/api/vim_spec.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/api/vim_spec.lua')
-rw-r--r--test/functional/api/vim_spec.lua441
1 files changed, 359 insertions, 82 deletions
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 9a4a457637..fd0535aa51 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -1,42 +1,43 @@
-local helpers = require('test.functional.helpers')(after_each)
+local t = require('test.testutil')
+local n = require('test.functional.testnvim')()
local Screen = require('test.functional.ui.screen')
local uv = vim.uv
local fmt = string.format
-local dedent = helpers.dedent
-local assert_alive = helpers.assert_alive
+local dedent = t.dedent
+local assert_alive = n.assert_alive
local NIL = vim.NIL
-local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq
-local command = helpers.command
-local command_output = helpers.api.nvim_command_output
-local exec = helpers.exec
-local exec_capture = helpers.exec_capture
-local eval = helpers.eval
-local expect = helpers.expect
-local fn = helpers.fn
-local api = helpers.api
-local matches = helpers.matches
+local clear, eq, neq = n.clear, t.eq, t.neq
+local command = n.command
+local command_output = n.api.nvim_command_output
+local exec = n.exec
+local exec_capture = n.exec_capture
+local eval = n.eval
+local expect = n.expect
+local fn = n.fn
+local api = n.api
+local matches = t.matches
local pesc = vim.pesc
-local mkdir_p = helpers.mkdir_p
-local ok, nvim_async, feed = helpers.ok, helpers.nvim_async, helpers.feed
-local async_meths = helpers.async_meths
-local is_os = helpers.is_os
-local parse_context = helpers.parse_context
-local request = helpers.request
-local rmdir = helpers.rmdir
-local source = helpers.source
-local next_msg = helpers.next_msg
-local tmpname = helpers.tmpname
-local write_file = helpers.write_file
-local exec_lua = helpers.exec_lua
-local exc_exec = helpers.exc_exec
-local insert = helpers.insert
-local skip = helpers.skip
-
-local pcall_err = helpers.pcall_err
+local mkdir_p = n.mkdir_p
+local ok, nvim_async, feed = t.ok, n.nvim_async, n.feed
+local async_meths = n.async_meths
+local is_os = t.is_os
+local parse_context = n.parse_context
+local request = n.request
+local rmdir = n.rmdir
+local source = n.source
+local next_msg = n.next_msg
+local tmpname = t.tmpname
+local write_file = t.write_file
+local exec_lua = n.exec_lua
+local exc_exec = n.exc_exec
+local insert = n.insert
+local skip = t.skip
+
+local pcall_err = t.pcall_err
local format_string = require('test.format_string').format_string
-local intchar2lua = helpers.intchar2lua
-local mergedicts_copy = helpers.mergedicts_copy
+local intchar2lua = t.intchar2lua
+local mergedicts_copy = t.mergedicts_copy
local endswith = vim.endswith
describe('API', function()
@@ -559,6 +560,16 @@ describe('API', function()
eq('Vim:E121: Undefined variable: bogus', pcall_err(request, 'nvim_eval', 'bogus expression'))
eq('', eval('v:errmsg')) -- v:errmsg was not updated.
end)
+
+ it('can return Lua function to Lua code', function()
+ eq(
+ [["a string with \"double quotes\" and 'single quotes'"]],
+ exec_lua([=[
+ local fun = vim.api.nvim_eval([[luaeval('string.format')]])
+ return fun('%q', [[a string with "double quotes" and 'single quotes']])
+ ]=])
+ )
+ end)
end)
describe('nvim_call_function', function()
@@ -624,6 +635,16 @@ describe('API', function()
pcall_err(request, 'nvim_call_function', 'Foo', too_many_args)
)
end)
+
+ it('can return Lua function to Lua code', function()
+ eq(
+ [["a string with \"double quotes\" and 'single quotes'"]],
+ exec_lua([=[
+ local fun = vim.api.nvim_call_function('luaeval', { 'string.format' })
+ return fun('%q', [[a string with "double quotes" and 'single quotes']])
+ ]=])
+ )
+ end)
end)
describe('nvim_call_dict_function', function()
@@ -702,18 +723,18 @@ describe('API', function()
end)
after_each(function()
- helpers.rmdir('Xtestdir')
+ n.rmdir('Xtestdir')
end)
it('works', function()
api.nvim_set_current_dir('Xtestdir')
- eq(fn.getcwd(), start_dir .. helpers.get_pathsep() .. 'Xtestdir')
+ eq(start_dir .. n.get_pathsep() .. 'Xtestdir', fn.getcwd())
end)
it('sets previous directory', function()
api.nvim_set_current_dir('Xtestdir')
command('cd -')
- eq(fn.getcwd(), start_dir)
+ eq(start_dir, fn.getcwd())
end)
end)
@@ -1269,7 +1290,7 @@ describe('API', function()
api.nvim_paste('', true, 3)
screen:expect([[
|
- ~ |*2
+ {1:~ }|*2
:Foo^ |
]])
end)
@@ -1280,8 +1301,8 @@ describe('API', function()
api.nvim_paste('normal! \023\022\006\027', true, -1)
screen:expect([[
|
- ~ |*2
- :normal! ^W^V^F^[^ |
+ {1:~ }|*2
+ :normal! {18:^W^V^F^[}^ |
]])
end)
it('crlf=false does not break lines at CR, CRLF', function()
@@ -1467,7 +1488,7 @@ describe('API', function()
eq(NIL, api.nvim_get_var('Unknown_script_func'))
-- Check if autoload works properly
- local pathsep = helpers.get_pathsep()
+ local pathsep = n.get_pathsep()
local xconfig = 'Xhome' .. pathsep .. 'Xconfig'
local xdata = 'Xhome' .. pathsep .. 'Xdata'
local autoload_folder = table.concat({ xconfig, 'nvim', 'autoload' }, pathsep)
@@ -1593,14 +1614,12 @@ describe('API', function()
api.nvim_set_option_value('equalalways', false, {})
local status, rv = pcall(command_output, 'verbose set equalalways?')
eq(true, status)
- ok(
- nil ~= string.find(rv, 'noequalalways\n' .. '\tLast set from API client %(channel id %d+%)')
- )
+ matches('noequalalways\n' .. '\tLast set from API client %(channel id %d+%)', rv)
api.nvim_exec_lua('vim.api.nvim_set_option_value("equalalways", true, {})', {})
status, rv = pcall(command_output, 'verbose set equalalways?')
eq(true, status)
- eq(' equalalways\n\tLast set from Lua', rv)
+ eq(' equalalways\n\tLast set from Lua (run Nvim with -V1 for more details)', rv)
end)
it('updates whether the option has ever been set #25025', function()
@@ -1953,7 +1972,7 @@ describe('API', function()
describe('RPC (K_EVENT)', function()
it('does not complete ("interrupt") normal-mode operator-pending #6166', function()
- helpers.insert([[
+ n.insert([[
FIRST LINE
SECOND LINE]])
api.nvim_input('gg')
@@ -1981,16 +2000,16 @@ describe('API', function()
-- Make any RPC request (can be non-async: op-pending does not block).
api.nvim_get_current_buf()
screen:expect([[
- ^a$ |
- b$ |
- c$ |
+ ^a{1:$} |
+ b{1:$} |
+ c{1:$} |
|
]])
end)
it('does not complete ("interrupt") normal-mode map-pending #6166', function()
command("nnoremap dd :let g:foo='it worked...'<CR>")
- helpers.insert([[
+ n.insert([[
FIRST LINE
SECOND LINE]])
api.nvim_input('gg')
@@ -2002,13 +2021,13 @@ describe('API', function()
expect([[
FIRST LINE
SECOND LINE]])
- eq('it worked...', helpers.eval('g:foo'))
+ eq('it worked...', n.eval('g:foo'))
end)
it('does not complete ("interrupt") insert-mode map-pending #6166', function()
command('inoremap xx foo')
command('set timeoutlen=9999')
- helpers.insert([[
+ n.insert([[
FIRST LINE
SECOND LINE]])
api.nvim_input('ix')
@@ -2155,35 +2174,32 @@ describe('API', function()
describe('nvim_replace_termcodes', function()
it('escapes K_SPECIAL as K_SPECIAL KS_SPECIAL KE_FILLER', function()
- eq('\128\254X', helpers.api.nvim_replace_termcodes('\128', true, true, true))
+ eq('\128\254X', n.api.nvim_replace_termcodes('\128', true, true, true))
end)
it('leaves non-K_SPECIAL string unchanged', function()
- eq('abc', helpers.api.nvim_replace_termcodes('abc', true, true, true))
+ eq('abc', n.api.nvim_replace_termcodes('abc', true, true, true))
end)
it('converts <expressions>', function()
- eq('\\', helpers.api.nvim_replace_termcodes('<Leader>', true, true, true))
+ eq('\\', n.api.nvim_replace_termcodes('<Leader>', true, true, true))
end)
it('converts <LeftMouse> to K_SPECIAL KS_EXTRA KE_LEFTMOUSE', function()
-- K_SPECIAL KS_EXTRA KE_LEFTMOUSE
-- 0x80 0xfd 0x2c
-- 128 253 44
- eq('\128\253\44', helpers.api.nvim_replace_termcodes('<LeftMouse>', true, true, true))
+ eq('\128\253\44', n.api.nvim_replace_termcodes('<LeftMouse>', true, true, true))
end)
it('converts keycodes', function()
- eq(
- '\nx\27x\rx<x',
- helpers.api.nvim_replace_termcodes('<NL>x<Esc>x<CR>x<lt>x', true, true, true)
- )
+ eq('\nx\27x\rx<x', n.api.nvim_replace_termcodes('<NL>x<Esc>x<CR>x<lt>x', true, true, true))
end)
it('does not convert keycodes if special=false', function()
eq(
'<NL>x<Esc>x<CR>x<lt>x',
- helpers.api.nvim_replace_termcodes('<NL>x<Esc>x<CR>x<lt>x', true, true, false)
+ n.api.nvim_replace_termcodes('<NL>x<Esc>x<CR>x<lt>x', true, true, false)
)
end)
@@ -2212,18 +2228,18 @@ describe('API', function()
api.nvim_feedkeys(':let x1="…"\n', '', true)
-- Both nvim_replace_termcodes and nvim_feedkeys escape \x80
- local inp = helpers.api.nvim_replace_termcodes(':let x2="…"<CR>', true, true, true)
+ local inp = n.api.nvim_replace_termcodes(':let x2="…"<CR>', true, true, true)
api.nvim_feedkeys(inp, '', true) -- escape_ks=true
-- nvim_feedkeys with K_SPECIAL escaping disabled
- inp = helpers.api.nvim_replace_termcodes(':let x3="…"<CR>', true, true, true)
+ inp = n.api.nvim_replace_termcodes(':let x3="…"<CR>', true, true, true)
api.nvim_feedkeys(inp, '', false) -- escape_ks=false
- helpers.stop()
+ n.stop()
end
-- spin the loop a bit
- helpers.run(nil, nil, on_setup)
+ n.run(nil, nil, on_setup)
eq('…', api.nvim_get_var('x1'))
-- Because of the double escaping this is neq
@@ -2366,7 +2382,7 @@ describe('API', function()
{0:~ }|*6
{1:very fail} |
]])
- helpers.poke_eventloop()
+ n.poke_eventloop()
-- shows up to &cmdheight lines
async_meths.nvim_err_write('more fail\ntoo fail\n')
@@ -2678,7 +2694,7 @@ describe('API', function()
describe('nvim_list_runtime_paths', function()
setup(function()
- local pathsep = helpers.get_pathsep()
+ local pathsep = n.get_pathsep()
mkdir_p('Xtest' .. pathsep .. 'a')
mkdir_p('Xtest' .. pathsep .. 'b')
end)
@@ -2723,7 +2739,7 @@ describe('API', function()
it('can throw exceptions', function()
local status, err = pcall(api.nvim_get_option_value, 'invalid-option', {})
eq(false, status)
- ok(err:match("Unknown option 'invalid%-option'") ~= nil)
+ matches("Unknown option 'invalid%-option'", err)
end)
it('does not truncate error message <1 MB #5984', function()
@@ -2736,10 +2752,7 @@ describe('API', function()
it('does not leak memory on incorrect argument types', function()
local status, err = pcall(api.nvim_set_current_dir, { 'not', 'a', 'dir' })
eq(false, status)
- ok(
- err:match(': Wrong type for argument 1 when calling nvim_set_current_dir, expecting String')
- ~= nil
- )
+ matches(': Wrong type for argument 1 when calling nvim_set_current_dir, expecting String', err)
end)
describe('nvim_parse_expression', function()
@@ -3135,10 +3148,60 @@ describe('API', function()
-- nowadays this works because we don't execute any spurious autocmds at all #24824
assert_alive()
end)
+
+ it('no memory leak when autocommands load the buffer immediately', function()
+ exec([[
+ autocmd BufNew * ++once call bufload(expand("<abuf>")->str2nr())
+ \| let loaded = bufloaded(expand("<abuf>")->str2nr())
+ ]])
+ api.nvim_create_buf(false, true)
+ eq(1, eval('g:loaded'))
+ end)
+
+ it('creating scratch buffer where autocommands set &swapfile works', function()
+ exec([[
+ autocmd BufNew * ++once execute expand("<abuf>") "buffer"
+ \| file foobar
+ \| setlocal swapfile
+ ]])
+ local new_buf = api.nvim_create_buf(false, true)
+ neq('', fn.swapname(new_buf))
+ end)
+
+ it('fires expected autocommands', function()
+ exec([=[
+ " Append the &buftype to check autocommands trigger *after* the buffer was configured to be
+ " scratch, if applicable.
+ autocmd BufNew * let fired += [["BufNew", expand("<abuf>")->str2nr(),
+ \ getbufvar(expand("<abuf>")->str2nr(), "&buftype")]]
+ autocmd BufAdd * let fired += [["BufAdd", expand("<abuf>")->str2nr(),
+ \ getbufvar(expand("<abuf>")->str2nr(), "&buftype")]]
+
+ " Don't want to see OptionSet; buffer options set from passing true for "scratch", etc.
+ " should be configured invisibly, and before autocommands.
+ autocmd OptionSet * let fired += [["OptionSet", expand("<amatch>")]]
+
+ let fired = []
+ ]=])
+ local new_buf = api.nvim_create_buf(false, false)
+ eq({ { 'BufNew', new_buf, '' } }, eval('g:fired'))
+
+ command('let fired = []')
+ new_buf = api.nvim_create_buf(false, true)
+ eq({ { 'BufNew', new_buf, 'nofile' } }, eval('g:fired'))
+
+ command('let fired = []')
+ new_buf = api.nvim_create_buf(true, false)
+ eq({ { 'BufNew', new_buf, '' }, { 'BufAdd', new_buf, '' } }, eval('g:fired'))
+
+ command('let fired = []')
+ new_buf = api.nvim_create_buf(true, true)
+ eq({ { 'BufNew', new_buf, 'nofile' }, { 'BufAdd', new_buf, 'nofile' } }, eval('g:fired'))
+ end)
end)
describe('nvim_get_runtime_file', function()
- local p = helpers.alter_slashes
+ local p = n.alter_slashes
it('can find files', function()
eq({}, api.nvim_get_runtime_file('bork.borkbork', false))
eq({}, api.nvim_get_runtime_file('bork.borkbork', true))
@@ -3365,13 +3428,13 @@ describe('API', function()
{desc="(global option, fallback requested) points to global", linenr=9, sid=1, args={'completeopt', {}}},
}
- for _, t in pairs(tests) do
- it(t.desc, function()
+ for _, test in pairs(tests) do
+ it(test.desc, function()
-- Switch to the target buffer/window so that curbuf/curwin are used.
api.nvim_set_current_win(wins[2])
- local info = api.nvim_get_option_info2(unpack(t.args))
- eq(t.linenr, info.last_set_linenr)
- eq(t.sid, info.last_set_sid)
+ local info = api.nvim_get_option_info2(unpack(test.args))
+ eq(test.linenr, info.last_set_linenr)
+ eq(test.sid, info.last_set_sid)
end)
end
@@ -3492,9 +3555,9 @@ describe('API', function()
false,
{ width = 79, height = 31, row = 1, col = 1, relative = 'editor' }
)
- local t = api.nvim_open_term(b, {})
+ local term = api.nvim_open_term(b, {})
- api.nvim_chan_send(t, io.open('test/functional/fixtures/smile2.cat', 'r'):read('*a'))
+ api.nvim_chan_send(term, io.open('test/functional/fixtures/smile2.cat', 'r'):read('*a'))
screen:expect {
grid = [[
^ |
@@ -3620,7 +3683,7 @@ describe('API', function()
api.nvim_buf_set_name(buf, 'mybuf')
local mark = api.nvim_get_mark('F', {})
-- Compare the path tail only
- assert(string.find(mark[4], 'mybuf$'))
+ matches('mybuf$', mark[4])
eq({ 2, 2, buf, mark[4] }, mark)
end)
it('validation', function()
@@ -3855,13 +3918,13 @@ describe('API', function()
norm 4G
]])
eq({
- str = '││aabb 4 ',
+ str = '││bbaa 4 ',
width = 9,
highlights = {
{ group = 'CursorLineFold', start = 0 },
{ group = 'Normal', start = 6 },
- { group = 'IncSearch', start = 6 },
- { group = 'ErrorMsg', start = 8 },
+ { group = 'ErrorMsg', start = 6 },
+ { group = 'IncSearch', start = 8 },
{ group = 'Normal', start = 10 },
},
}, api.nvim_eval_statusline(
@@ -4953,4 +5016,218 @@ describe('API', function()
eq(false, exec_lua('return _G.success'))
end)
end)
+
+ it('nvim__redraw', function()
+ local screen = Screen.new(60, 5)
+ screen:attach()
+ local win = api.nvim_get_current_win()
+ eq('at least one action required', pcall_err(api.nvim__redraw, {}))
+ eq('at least one action required', pcall_err(api.nvim__redraw, { buf = 0 }))
+ eq('at least one action required', pcall_err(api.nvim__redraw, { win = 0 }))
+ eq("cannot use both 'buf' and 'win'", pcall_err(api.nvim__redraw, { buf = 0, win = 0 }))
+ feed(':echo getchar()<CR>')
+ fn.setline(1, 'foobar')
+ command('vnew')
+ fn.setline(1, 'foobaz')
+ -- Can flush pending screen updates
+ api.nvim__redraw({ flush = true })
+ screen:expect({
+ grid = [[
+ foobaz │foobar |
+ {1:~ }│{1:~ }|*2
+ {3:[No Name] [+] }{2:[No Name] [+] }|
+ ^:echo getchar() |
+ ]],
+ })
+ -- Can update the grid cursor position #20793
+ api.nvim__redraw({ cursor = true })
+ screen:expect({
+ grid = [[
+ ^foobaz │foobar |
+ {1:~ }│{1:~ }|*2
+ {3:[No Name] [+] }{2:[No Name] [+] }|
+ :echo getchar() |
+ ]],
+ })
+ -- Also in non-current window
+ api.nvim__redraw({ cursor = true, win = win })
+ screen:expect({
+ grid = [[
+ foobaz │^foobar |
+ {1:~ }│{1:~ }|*2
+ {3:[No Name] [+] }{2:[No Name] [+] }|
+ :echo getchar() |
+ ]],
+ })
+ -- Can update the 'statusline' in a single window
+ api.nvim_set_option_value('statusline', 'statusline1', { win = 0 })
+ api.nvim_set_option_value('statusline', 'statusline2', { win = win })
+ api.nvim__redraw({ cursor = true, win = 0, statusline = true })
+ screen:expect({
+ grid = [[
+ ^foobaz │foobar |
+ {1:~ }│{1:~ }|*2
+ {3:statusline1 }{2:[No Name] [+] }|
+ :echo getchar() |
+ ]],
+ })
+ api.nvim__redraw({ win = win, statusline = true })
+ screen:expect({
+ grid = [[
+ ^foobaz │foobar |
+ {1:~ }│{1:~ }|*2
+ {3:statusline1 }{2:statusline2 }|
+ :echo getchar() |
+ ]],
+ })
+ -- Can update the 'statusline' in all windows
+ api.nvim_set_option_value('statusline', '', { win = win })
+ api.nvim_set_option_value('statusline', 'statusline3', {})
+ api.nvim__redraw({ statusline = true })
+ screen:expect({
+ grid = [[
+ ^foobaz │foobar |
+ {1:~ }│{1:~ }|*2
+ {3:statusline3 }{2:statusline3 }|
+ :echo getchar() |
+ ]],
+ })
+ -- Can update the 'statuscolumn'
+ api.nvim_set_option_value('statuscolumn', 'statuscolumn', { win = win })
+ api.nvim__redraw({ statuscolumn = true })
+ screen:expect({
+ grid = [[
+ ^foobaz │{8:statuscolumn}foobar |
+ {1:~ }│{1:~ }|*2
+ {3:statusline3 }{2:statusline3 }|
+ :echo getchar() |
+ ]],
+ })
+ -- Can update the 'winbar'
+ api.nvim_set_option_value('winbar', 'winbar', { win = 0 })
+ api.nvim__redraw({ win = 0, winbar = true })
+ screen:expect({
+ grid = [[
+ {5:^winbar }│{8:statuscolumn}foobar |
+ foobaz │{1:~ }|
+ {1:~ }│{1:~ }|
+ {3:statusline3 }{2:statusline3 }|
+ :echo getchar() |
+ ]],
+ })
+ -- Can update the 'tabline'
+ api.nvim_set_option_value('showtabline', 2, {})
+ api.nvim_set_option_value('tabline', 'tabline', {})
+ api.nvim__redraw({ tabline = true })
+ screen:expect({
+ grid = [[
+ {2:^tabline }|
+ {5:winbar }│{8:statuscolumn}foobar |
+ foobaz │{1:~ }|
+ {3:statusline3 }{2:statusline3 }|
+ :echo getchar() |
+ ]],
+ })
+ -- Can update multiple status widgets
+ api.nvim_set_option_value('tabline', 'tabline2', {})
+ api.nvim_set_option_value('statusline', 'statusline4', {})
+ api.nvim__redraw({ statusline = true, tabline = true })
+ screen:expect({
+ grid = [[
+ {2:^tabline2 }|
+ {5:winbar }│{8:statuscolumn}foobar |
+ foobaz │{1:~ }|
+ {3:statusline4 }{2:statusline4 }|
+ :echo getchar() |
+ ]],
+ })
+ -- Can update all status widgets
+ api.nvim_set_option_value('tabline', 'tabline3', {})
+ api.nvim_set_option_value('statusline', 'statusline5', {})
+ api.nvim_set_option_value('statuscolumn', 'statuscolumn2', {})
+ api.nvim_set_option_value('winbar', 'winbar2', {})
+ api.nvim__redraw({ statuscolumn = true, statusline = true, tabline = true, winbar = true })
+ screen:expect({
+ grid = [[
+ {2:^tabline3 }|
+ {5:winbar2 }│{5:winbar2 }|
+ {8:statuscolumn2}foobaz │{8:statuscolumn}foobar |
+ {3:statusline5 }{2:statusline5 }|
+ :echo getchar() |
+ ]],
+ })
+ -- Can update status widget for a specific window
+ feed('<CR><CR>')
+ command('let g:status=0')
+ api.nvim_set_option_value('statusline', '%{%g:status%}', { win = 0 })
+ command('vsplit')
+ screen:expect({
+ grid = [[
+ {2:tabline3 }|
+ {5:winbar2 }│{5:winbar2 }│{5:winbar2 }|
+ {8:statuscolumn2}^foobaz │{8:statuscolumn2}foobaz│{8:statuscolumn}foobar |
+ {3:0 }{2:0 statusline5 }|
+ 13 |
+ ]],
+ })
+ command('let g:status=1')
+ api.nvim__redraw({ win = 0, statusline = true })
+ screen:expect({
+ grid = [[
+ {2:tabline3 }|
+ {5:winbar2 }│{5:winbar2 }│{5:winbar2 }|
+ {8:statuscolumn2}^foobaz │{8:statuscolumn2}foobaz│{8:statuscolumn}foobar |
+ {3:1 }{2:0 statusline5 }|
+ 13 |
+ ]],
+ })
+ -- Can update status widget for a specific buffer
+ command('let g:status=2')
+ api.nvim__redraw({ buf = 0, statusline = true })
+ screen:expect({
+ grid = [[
+ {2:tabline3 }|
+ {5:winbar2 }│{5:winbar2 }│{5:winbar2 }|
+ {8:statuscolumn2}^foobaz │{8:statuscolumn2}foobaz│{8:statuscolumn}foobar |
+ {3:2 }{2:2 statusline5 }|
+ 13 |
+ ]],
+ })
+ -- valid = true does not draw any lines on its own
+ exec_lua([[
+ _G.lines = 0
+ ns = vim.api.nvim_create_namespace('')
+ vim.api.nvim_set_decoration_provider(ns, {
+ on_win = function()
+ if _G.do_win then
+ vim.api.nvim_buf_set_extmark(0, ns, 0, 0, { hl_group = 'IncSearch', end_col = 6 })
+ end
+ end,
+ on_line = function()
+ _G.lines = _G.lines + 1
+ end,
+ })
+ ]])
+ local lines = exec_lua('return lines')
+ api.nvim__redraw({ buf = 0, valid = true, flush = true })
+ eq(lines, exec_lua('return _G.lines'))
+ -- valid = false does
+ api.nvim__redraw({ buf = 0, valid = false, flush = true })
+ neq(lines, exec_lua('return _G.lines'))
+ -- valid = true does redraw lines if affected by on_win callback
+ exec_lua('_G.do_win = true')
+ api.nvim__redraw({ buf = 0, valid = true, flush = true })
+ screen:expect({
+ grid = [[
+ {2:tabline3 }|
+ {5:winbar2 }│{5:winbar2 }│{5:winbar2 }|
+ {8:statuscolumn2}{2:^foobaz} │{8:statuscolumn2}{2:foobaz}│{8:statuscolumn}foobar |
+ {3:2 }{2:2 statusline5 }|
+ 13 |
+ ]],
+ })
+ -- takes buffer line count from correct buffer with "win" and {0, -1} "range"
+ api.nvim__redraw({ win = 0, range = { 0, -1 } })
+ n.assert_alive()
+ end)
end)