aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/api/highlight_spec.lua95
-rw-r--r--test/functional/api/vim_spec.lua4
-rw-r--r--test/functional/api/window_spec.lua14
-rw-r--r--test/functional/core/job_spec.lua26
-rw-r--r--test/functional/eval/null_spec.lua5
-rw-r--r--test/functional/fixtures/streams-test.c17
-rw-r--r--test/functional/legacy/011_autocommands_spec.lua2
-rw-r--r--test/functional/legacy/delete_spec.lua78
-rw-r--r--test/functional/legacy/mksession_spec.lua42
-rw-r--r--test/functional/legacy/packadd_spec.lua3
-rw-r--r--test/functional/lua/buffer_updates_spec.lua51
-rw-r--r--test/functional/lua/vim_spec.lua474
-rw-r--r--test/functional/plugin/lsp/diagnostic_spec.lua33
-rw-r--r--test/functional/plugin/lsp_spec.lua151
-rw-r--r--test/functional/treesitter/parser_spec.lua96
-rw-r--r--test/functional/ui/float_spec.lua88
-rw-r--r--test/functional/ui/messages_spec.lua4
-rw-r--r--test/functional/ui/screen.lua29
18 files changed, 1052 insertions, 160 deletions
diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua
index 058706718a..21e3094f8e 100644
--- a/test/functional/api/highlight_spec.lua
+++ b/test/functional/api/highlight_spec.lua
@@ -158,3 +158,98 @@ describe('API: highlight',function()
assert_alive()
end)
end)
+
+describe("API: set highlight", function()
+ local highlight_color = {
+ fg = tonumber('0xff0000'),
+ bg = tonumber('0x0032aa'),
+ ctermfg = 8,
+ ctermbg = 15,
+ }
+ local highlight1 = {
+ background = highlight_color.bg,
+ foreground = highlight_color.fg,
+ bold = true,
+ italic = true,
+ }
+ local highlight2_config = {
+ ctermbg = highlight_color.ctermbg,
+ ctermfg = highlight_color.ctermfg,
+ underline = true,
+ reverse = true,
+ }
+ local highlight2_result = {
+ background = highlight_color.ctermbg,
+ foreground = highlight_color.ctermfg,
+ underline = true,
+ reverse = true,
+ }
+ local highlight3_config = {
+ background = highlight_color.bg,
+ foreground = highlight_color.fg,
+ ctermbg = highlight_color.ctermbg,
+ ctermfg = highlight_color.ctermfg,
+ bold = true,
+ italic = true,
+ reverse = true,
+ undercurl = true,
+ underline = true,
+ cterm = {
+ italic = true,
+ reverse = true,
+ undercurl = true,
+ }
+ }
+ local highlight3_result_gui = {
+ background = highlight_color.bg,
+ foreground = highlight_color.fg,
+ bold = true,
+ italic = true,
+ reverse = true,
+ undercurl = true,
+ underline = true,
+ }
+ local highlight3_result_cterm = {
+ background = highlight_color.ctermbg,
+ foreground = highlight_color.ctermfg,
+ italic = true,
+ reverse = true,
+ undercurl = true,
+ }
+
+ local function get_ns()
+ local ns = meths.create_namespace('Test_set_hl')
+ meths._set_hl_ns(ns)
+ return ns
+ end
+
+ before_each(clear)
+
+ it ("can set gui highlight", function()
+ local ns = get_ns()
+ meths.set_hl(ns, 'Test_hl', highlight1)
+ eq(highlight1, meths.get_hl_by_name('Test_hl', true))
+ end)
+
+ it ("can set cterm highlight", function()
+ local ns = get_ns()
+ meths.set_hl(ns, 'Test_hl', highlight2_config)
+ eq(highlight2_result, meths.get_hl_by_name('Test_hl', false))
+ end)
+
+ it ("cterm attr defaults to gui attr", function()
+ local ns = get_ns()
+ meths.set_hl(ns, 'Test_hl', highlight1)
+ eq({
+ bold = true,
+ italic = true,
+ }, meths.get_hl_by_name('Test_hl', false))
+ end)
+
+ it ("can overwrite attr for cterm", function()
+ local ns = get_ns()
+ meths.set_hl(ns, 'Test_hl', highlight3_config)
+ eq(highlight3_result_gui, meths.get_hl_by_name('Test_hl', true))
+ eq(highlight3_result_cterm, meths.get_hl_by_name('Test_hl', false))
+ end)
+end)
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 6926022ee3..0c0f610401 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -1986,6 +1986,10 @@ describe('API', function()
eq(meths.get_option_info'winhighlight', options_info.winhighlight)
end)
+
+ it('should not crash when echoed', function()
+ meths.exec("echo nvim_get_all_options_info()", true)
+ end)
end)
describe('nvim_get_option_info', function()
diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua
index ceeb84cec9..a57826f7e7 100644
--- a/test/functional/api/window_spec.lua
+++ b/test/functional/api/window_spec.lua
@@ -387,4 +387,18 @@ describe('API/win', function()
eq({oldbuf}, meths.list_bufs())
end)
end)
+
+ describe('open_win', function()
+ it('noautocmd option works', function()
+ command('autocmd BufEnter,BufLeave,BufWinEnter * let g:fired = 1')
+ meths.open_win(meths.create_buf(true, true), true, {
+ relative='win', row=3, col=3, width=12, height=3, noautocmd=true
+ })
+ eq(0, funcs.exists('g:fired'))
+ meths.open_win(meths.create_buf(true, true), true, {
+ relative='win', row=3, col=3, width=12, height=3
+ })
+ eq(1, funcs.exists('g:fired'))
+ end)
+ end)
end)
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index 9de0d08e79..34ab90d760 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -118,6 +118,32 @@ describe('jobs', function()
end
end)
+ it('handles case-insensitively matching #env vars', function()
+ nvim('command', "let $TOTO = 'abc'")
+ -- Since $Toto is being set in the job, it should take precedence over the
+ -- global $TOTO on Windows
+ nvim('command', "let g:job_opts = {'env': {'Toto': 'def'}, 'stdout_buffered': v:true}")
+ if iswin() then
+ nvim('command', [[let j = jobstart('set | find /I "toto="', g:job_opts)]])
+ else
+ nvim('command', [[let j = jobstart('env | grep -i toto=', g:job_opts)]])
+ end
+ nvim('command', "call jobwait([j])")
+ nvim('command', "let g:output = Normalize(g:job_opts.stdout)")
+ local actual = eval('g:output')
+ local expected
+ if iswin() then
+ -- Toto is normalized to TOTO so we can detect duplicates, and because
+ -- Windows doesn't care about case
+ expected = {'TOTO=def', ''}
+ else
+ expected = {'TOTO=abc', 'Toto=def', ''}
+ end
+ table.sort(actual)
+ table.sort(expected)
+ eq(expected, actual)
+ end)
+
it('uses &shell and &shellcmdflag if passed a string', function()
nvim('command', "let $VAR = 'abc'")
if iswin() then
diff --git a/test/functional/eval/null_spec.lua b/test/functional/eval/null_spec.lua
index d403fbc878..b1ceff9115 100644
--- a/test/functional/eval/null_spec.lua
+++ b/test/functional/eval/null_spec.lua
@@ -73,6 +73,7 @@ describe('NULL', function()
null_expr_test('does not crash col()', 'col(L)', 0, 0)
null_expr_test('does not crash virtcol()', 'virtcol(L)', 0, 0)
null_expr_test('does not crash line()', 'line(L)', 0, 0)
+ null_expr_test('does not crash line() with window id', 'line(L, 1000)', 0, 0)
null_expr_test('does not crash count()', 'count(L, 1)', 0, 0)
null_expr_test('does not crash cursor()', 'cursor(L)', 'E474: Invalid argument', -1)
null_expr_test('does not crash map()', 'map(L, "v:val")', 0, {})
@@ -96,7 +97,7 @@ describe('NULL', function()
null_expr_test('makes filter() return v:_null_list', 'filter(L, "1") is# L', 0, 1)
null_test('is treated by :let as empty list', ':let [l] = L', 'Vim(let):E688: More targets than List items')
null_expr_test('is accepted as an empty list by inputlist()', '[feedkeys("\\n"), inputlist(L)]',
- 'Type number and <Enter> or click with mouse (empty cancels): ', {0, 0})
+ 'Type number and <Enter> or click with the mouse (q or empty cancels): ', {0, 0})
null_expr_test('is accepted as an empty list by writefile()',
('[writefile(L, "%s"), readfile("%s")]'):format(tmpfname, tmpfname),
0, {0, {}})
@@ -149,6 +150,7 @@ describe('NULL', function()
null_test('does not crash :execute', 'execute S', 0)
null_expr_test('does not crash execute()', 'execute(S)', 0, '')
null_expr_test('makes executable() error out', 'executable(S)', 'E928: String required', 0)
+ null_expr_test('makes timer_start() error out', 'timer_start(0, S)', 'E921: Invalid callback argument', -1)
null_expr_test('does not crash filereadable()', 'filereadable(S)', 0, 0)
null_expr_test('does not crash filewritable()', 'filewritable(S)', 0, 0)
null_expr_test('does not crash fnamemodify()', 'fnamemodify(S, S)', 0, '')
@@ -161,7 +163,6 @@ describe('NULL', function()
null_expr_test('does not crash mkdir()', 'mkdir(S)', 0, 0)
null_expr_test('does not crash sort()', 'sort(["b", S, "a"])', 0, {'', 'a', 'b'})
null_expr_test('does not crash split()', 'split(S)', 0, {})
-
null_test('can be used to set an option', 'let &grepprg = S', 0)
null_expr_test('is equal to non-existent variable', 'S == V', 0, 1)
diff --git a/test/functional/fixtures/streams-test.c b/test/functional/fixtures/streams-test.c
index eec447153c..be40edfe7e 100644
--- a/test/functional/fixtures/streams-test.c
+++ b/test/functional/fixtures/streams-test.c
@@ -6,23 +6,22 @@
#include <uv.h>
-uv_loop_t *loop;
-uv_process_t child_req;
-uv_process_options_t options;
-
int main(int argc, char **argv)
{
- loop = uv_default_loop();
+ uv_loop_t *loop = uv_default_loop();
+ uv_process_t child_req;
char * args[3];
args[0] = "sleep";
args[1] = "10";
args[2] = NULL;
- options.exit_cb = NULL;
- options.file = "sleep";
- options.args = args;
- options.flags = UV_PROCESS_DETACHED;
+ uv_process_options_t options = {
+ .exit_cb = NULL,
+ .file = "sleep",
+ .args = args,
+ .flags = UV_PROCESS_DETACHED,
+ };
int r;
if ((r = uv_spawn(loop, &child_req, &options))) {
diff --git a/test/functional/legacy/011_autocommands_spec.lua b/test/functional/legacy/011_autocommands_spec.lua
index c9c004eec1..7cc31dc787 100644
--- a/test/functional/legacy/011_autocommands_spec.lua
+++ b/test/functional/legacy/011_autocommands_spec.lua
@@ -70,7 +70,7 @@ describe('file reading, writing and bufnew and filter autocommands', function()
feed_command('let $GZIP = ""')
--execute('au FileChangedShell * echo "caught FileChangedShell"')
feed_command('set bin')
- feed_command("au FileReadPost *.gz '[,']!GZIP= gzip -d")
+ feed_command("au FileReadPost *.gz '[,']!gzip -d")
-- Read and decompress the testfile.
feed_command('$r Xtestfile.gz')
expect('\n'..text1)
diff --git a/test/functional/legacy/delete_spec.lua b/test/functional/legacy/delete_spec.lua
index 3d2c4a7d91..f2ced8942d 100644
--- a/test/functional/legacy/delete_spec.lua
+++ b/test/functional/legacy/delete_spec.lua
@@ -17,6 +17,33 @@ describe('Test for delete()', function()
eq(-1, eval("delete('Xfile')"))
end)
+ it('directory delete', function()
+ command("call mkdir('Xdir1')")
+ eq(1, eval("isdirectory('Xdir1')"))
+ eq(0, eval("delete('Xdir1', 'd')"))
+ eq(0, eval("isdirectory('Xdir1')"))
+ eq(-1, eval("delete('Xdir1', 'd')"))
+ end)
+ it('recursive delete', function()
+ command("call mkdir('Xdir1')")
+ command("call mkdir('Xdir1/subdir')")
+ command("call mkdir('Xdir1/empty')")
+ command('split Xdir1/Xfile')
+ command("call setline(1, ['a', 'b'])")
+ command('w')
+ command('w Xdir1/subdir/Xfile')
+ command('close')
+
+ eq(1, eval("isdirectory('Xdir1')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir1/Xfile')"))
+ eq(1, eval("isdirectory('Xdir1/subdir')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir1/subdir/Xfile')"))
+ eq(1, eval("isdirectory('Xdir1/empty')"))
+ eq(0, eval("delete('Xdir1', 'rf')"))
+ eq(0, eval("isdirectory('Xdir1')"))
+ eq(-1, eval("delete('Xdir1', 'd')"))
+ end)
+
it('symlink delete', function()
source([[
split Xfile
@@ -36,4 +63,55 @@ describe('Test for delete()', function()
eq(-1, eval("delete('Xlink')"))
eq(0, eval("delete('Xfile')"))
end)
+
+ it('symlink directory delete', function()
+ command("call mkdir('Xdir1')")
+ if helpers.iswin() then
+ command("silent !mklink /j Xlink Xdir1")
+ else
+ command("silent !ln -s Xdir1 Xlink")
+ end
+ eq(1, eval("isdirectory('Xdir1')"))
+ eq(1, eval("isdirectory('Xlink')"))
+ -- Delete the link, not the directory
+ eq(0, eval("delete('Xlink')"))
+ eq(-1, eval("delete('Xlink')"))
+ eq(0, eval("delete('Xdir1', 'd')"))
+ end)
+
+ it('symlink recursive delete', function()
+ source([[
+ call mkdir('Xdir3')
+ call mkdir('Xdir3/subdir')
+ call mkdir('Xdir4')
+ split Xdir3/Xfile
+ call setline(1, ['a', 'b'])
+ w
+ w Xdir3/subdir/Xfile
+ w Xdir4/Xfile
+ close
+ if has('win32')
+ silent !mklink /j Xdir3\Xlink Xdir4
+ else
+ silent !ln -s ../Xdir4 Xdir3/Xlink
+ endif
+ ]])
+
+ eq(1, eval("isdirectory('Xdir3')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir3/Xfile')"))
+ eq(1, eval("isdirectory('Xdir3/subdir')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir3/subdir/Xfile')"))
+ eq(1, eval("isdirectory('Xdir4')"))
+ eq(1, eval("isdirectory('Xdir3/Xlink')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir4/Xfile')"))
+
+ eq(0, eval("delete('Xdir3', 'rf')"))
+ eq(0, eval("isdirectory('Xdir3')"))
+ eq(-1, eval("delete('Xdir3', 'd')"))
+ -- symlink is deleted, not the directory it points to
+ eq(1, eval("isdirectory('Xdir4')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir4/Xfile')"))
+ eq(0, eval("delete('Xdir4/Xfile')"))
+ eq(0, eval("delete('Xdir4', 'd')"))
+ end)
end)
diff --git a/test/functional/legacy/mksession_spec.lua b/test/functional/legacy/mksession_spec.lua
new file mode 100644
index 0000000000..a2af891107
--- /dev/null
+++ b/test/functional/legacy/mksession_spec.lua
@@ -0,0 +1,42 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear = helpers.clear
+local command = helpers.command
+local funcs = helpers.funcs
+local eq = helpers.eq
+
+describe('mksession', function()
+ before_each(clear)
+
+ after_each(function()
+ os.remove('Xtest_mks.out')
+ end)
+
+ it('supports "skiprtp" value', function()
+ command('set sessionoptions&vi')
+ command('set rtp+=$HOME')
+ command('set pp+=$HOME')
+ command('mksession! Xtest_mks.out')
+ local found_rtp = 0
+ local found_pp = 0
+ for _, line in pairs(funcs.readfile('Xtest_mks.out', 'b')) do
+ if line:find('set runtimepath') then
+ found_rtp = found_rtp + 1
+ end
+ if line:find('set packpath') then
+ found_pp = found_pp + 1
+ end
+ end
+ eq(1, found_rtp)
+ eq(1, found_pp)
+
+ command('set sessionoptions+=skiprtp')
+ command('mksession! Xtest_mks.out')
+ local found_rtp_or_pp = 0
+ for _, line in pairs(funcs.readfile('Xtest_mks.out', 'b')) do
+ if line:find('set runtimepath') or line:find('set packpath') then
+ found_rtp_or_pp = found_rtp_or_pp + 1
+ end
+ end
+ eq(0, found_rtp_or_pp)
+ end)
+end)
diff --git a/test/functional/legacy/packadd_spec.lua b/test/functional/legacy/packadd_spec.lua
index 3c84105c6b..486a1fe471 100644
--- a/test/functional/legacy/packadd_spec.lua
+++ b/test/functional/legacy/packadd_spec.lua
@@ -20,7 +20,6 @@ describe('packadd', function()
func SetUp()
let s:topdir = expand(getcwd() . '/Xdir')
- call delete(s:topdir, 'rf')
exe 'set packpath=' . s:topdir
let s:plugdir = expand(s:topdir . '/pack/mine/opt/mytest')
endfunc
@@ -268,6 +267,8 @@ describe('packadd', function()
call assert_match('look-here', tags1[0])
let tags2 = readfile(docdir2 . '/tags')
call assert_match('look-away', tags2[0])
+
+ call assert_fails('helptags abcxyz', 'E150:')
endfunc
func Test_colorscheme()
diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua
index d4c65eae5b..1b2c21783e 100644
--- a/test/functional/lua/buffer_updates_spec.lua
+++ b/test/functional/lua/buffer_updates_spec.lua
@@ -401,8 +401,8 @@ describe('lua: nvim_buf_attach on_bytes', function()
}
feed '<cr>'
check_events {
- { "test1", "bytes", 1, 4, 8, 0, 115, 0, 4, 4, 0, 0, 0 };
- { "test1", "bytes", 1, 5, 7, 4, 118, 0, 0, 0, 1, 4, 5 };
+ { "test1", "bytes", 1, 4, 7, 0, 114, 0, 4, 4, 0, 0, 0 };
+ { "test1", "bytes", 1, 5, 7, 0, 114, 0, 0, 0, 1, 4, 5 };
}
end)
@@ -447,8 +447,8 @@ describe('lua: nvim_buf_attach on_bytes', function()
feed '<CR>'
check_events {
- { "test1", "bytes", 1, 6, 2, 2, 16, 0, 1, 1, 0, 0, 0 };
- { "test1", "bytes", 1, 7, 1, 3, 14, 0, 0, 0, 1, 3, 4 };
+ { "test1", "bytes", 1, 6, 1, 2, 13, 0, 1, 1, 0, 0, 0 };
+ { "test1", "bytes", 1, 7, 1, 2, 13, 0, 0, 0, 1, 3, 4 };
}
end)
@@ -936,6 +936,26 @@ describe('lua: nvim_buf_attach on_bytes', function()
}
end)
+ it("virtual edit", function ()
+ local check_events = setup_eventcheck(verify, { "", " " })
+
+ meths.set_option("virtualedit", "all")
+
+ feed [[<Right><Right>iab<ESC>]]
+
+ check_events {
+ { "test1", "bytes", 1, 3, 0, 0, 0, 0, 0, 0, 0, 2, 2 };
+ { "test1", "bytes", 1, 4, 0, 2, 2, 0, 0, 0, 0, 2, 2 };
+ }
+
+ feed [[j<Right><Right>iab<ESC>]]
+
+ check_events {
+ { "test1", "bytes", 1, 5, 1, 0, 5, 0, 1, 1, 0, 8, 8 };
+ { "test1", "bytes", 1, 6, 1, 5, 10, 0, 0, 0, 0, 2, 2 };
+ }
+ end)
+
it("block visual paste", function()
local check_events = setup_eventcheck(verify, {"AAA",
"BBB",
@@ -958,6 +978,29 @@ describe('lua: nvim_buf_attach on_bytes', function()
}
end)
+ it("nvim_buf_set_lines", function()
+ local check_events = setup_eventcheck(verify, {"AAA", "BBB"})
+
+ -- delete
+ meths.buf_set_lines(0, 0, 1, true, {})
+
+ check_events {
+ { "test1", "bytes", 1, 3, 0, 0, 0, 1, 0, 4, 0, 0, 0 };
+ }
+
+ -- add
+ meths.buf_set_lines(0, 0, 0, true, {'asdf'})
+ check_events {
+ { "test1", "bytes", 1, 4, 0, 0, 0, 0, 0, 0, 1, 0, 5 };
+ }
+
+ -- replace
+ meths.buf_set_lines(0, 0, 1, true, {'asdf', 'fdsa'})
+ check_events {
+ { "test1", "bytes", 1, 5, 0, 0, 0, 1, 0, 5, 2, 0, 10 };
+ }
+ end)
+
teardown(function()
os.remove "Xtest-reload"
os.remove "Xtest-undofile"
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 9bf00b594b..08a0552a38 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -945,12 +945,20 @@ describe('lua stdlib', function()
exec_lua [[
vim.api.nvim_set_var("testing", "hi")
vim.api.nvim_set_var("other", 123)
+ vim.api.nvim_set_var("floaty", 5120.1)
+ vim.api.nvim_set_var("nullvar", vim.NIL)
vim.api.nvim_set_var("to_delete", {hello="world"})
]]
eq('hi', funcs.luaeval "vim.g.testing")
eq(123, funcs.luaeval "vim.g.other")
+ eq(5120.1, funcs.luaeval "vim.g.floaty")
eq(NIL, funcs.luaeval "vim.g.nonexistant")
+ eq(NIL, funcs.luaeval "vim.g.nullvar")
+ -- lost over RPC, so test locally:
+ eq({false, true}, exec_lua [[
+ return {vim.g.nonexistant == vim.NIL, vim.g.nullvar == vim.NIL}
+ ]])
eq({hello="world"}, funcs.luaeval "vim.g.to_delete")
exec_lua [[
@@ -963,12 +971,20 @@ describe('lua stdlib', function()
exec_lua [[
vim.api.nvim_buf_set_var(0, "testing", "hi")
vim.api.nvim_buf_set_var(0, "other", 123)
+ vim.api.nvim_buf_set_var(0, "floaty", 5120.1)
+ vim.api.nvim_buf_set_var(0, "nullvar", vim.NIL)
vim.api.nvim_buf_set_var(0, "to_delete", {hello="world"})
]]
eq('hi', funcs.luaeval "vim.b.testing")
eq(123, funcs.luaeval "vim.b.other")
+ eq(5120.1, funcs.luaeval "vim.b.floaty")
eq(NIL, funcs.luaeval "vim.b.nonexistant")
+ eq(NIL, funcs.luaeval "vim.b.nullvar")
+ -- lost over RPC, so test locally:
+ eq({false, true}, exec_lua [[
+ return {vim.b.nonexistant == vim.NIL, vim.b.nullvar == vim.NIL}
+ ]])
eq({hello="world"}, funcs.luaeval "vim.b.to_delete")
exec_lua [[
@@ -1097,6 +1113,464 @@ describe('lua stdlib', function()
eq(0, funcs.luaeval "vim.wo[1000].cole")
end)
+ describe('vim.opt', function()
+ -- TODO: We still need to write some tests for optlocal, opt and then getting the options
+ -- Probably could also do some stuff with getting things from viml side as well to confirm behavior is the same.
+
+ it('should allow setting number values', function()
+ local scrolloff = exec_lua [[
+ vim.opt.scrolloff = 10
+ return vim.o.scrolloff
+ ]]
+ eq(scrolloff, 10)
+ end)
+
+ pending('should handle STUPID window things', function()
+ local result = exec_lua [[
+ local result = {}
+
+ table.insert(result, vim.api.nvim_get_option('scrolloff'))
+ table.insert(result, vim.api.nvim_win_get_option(0, 'scrolloff'))
+
+ return result
+ ]]
+
+ eq({}, result)
+ end)
+
+ it('should allow setting tables', function()
+ local wildignore = exec_lua [[
+ vim.opt.wildignore = { 'hello', 'world' }
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, "hello,world")
+ end)
+
+ it('should allow setting tables with shortnames', function()
+ local wildignore = exec_lua [[
+ vim.opt.wig = { 'hello', 'world' }
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, "hello,world")
+ end)
+
+ it('should error when you attempt to set string values to numeric options', function()
+ local result = exec_lua [[
+ return {
+ pcall(function() vim.opt.textwidth = 'hello world' end)
+ }
+ ]]
+
+ eq(false, result[1])
+ end)
+
+ it('should error when you attempt to setlocal a global value', function()
+ local result = exec_lua [[
+ return pcall(function() vim.opt_local.clipboard = "hello" end)
+ ]]
+
+ eq(false, result)
+ end)
+
+ it('should allow you to set boolean values', function()
+ eq({true, false, true}, exec_lua [[
+ local results = {}
+
+ vim.opt.autoindent = true
+ table.insert(results, vim.bo.autoindent)
+
+ vim.opt.autoindent = false
+ table.insert(results, vim.bo.autoindent)
+
+ vim.opt.autoindent = not vim.opt.autoindent:get()
+ table.insert(results, vim.bo.autoindent)
+
+ return results
+ ]])
+ end)
+
+ it('should change current buffer values and defaults for global local values', function()
+ local result = exec_lua [[
+ local result = {}
+
+ vim.opt.makeprg = "global-local"
+ table.insert(result, vim.api.nvim_get_option('makeprg'))
+ table.insert(result, (pcall(vim.api.nvim_buf_get_option, 0, 'makeprg')))
+
+ vim.opt_local.mp = "only-local"
+ table.insert(result, vim.api.nvim_get_option('makeprg'))
+ table.insert(result, vim.api.nvim_buf_get_option(0, 'makeprg'))
+
+ vim.opt_global.makeprg = "only-global"
+ table.insert(result, vim.api.nvim_get_option('makeprg'))
+ table.insert(result, vim.api.nvim_buf_get_option(0, 'makeprg'))
+
+ vim.opt.makeprg = "global-local"
+ table.insert(result, vim.api.nvim_get_option('makeprg'))
+ table.insert(result, vim.api.nvim_buf_get_option(0, 'makeprg'))
+ return result
+ ]]
+
+ -- Set -> global & local
+ eq("global-local", result[1])
+ eq(false, result[2])
+
+ -- Setlocal -> only local
+ eq("global-local", result[3])
+ eq("only-local", result[4])
+
+ -- Setglobal -> only global
+ eq("only-global", result[5])
+ eq("only-local", result[6])
+
+ -- set -> doesn't override previously set value
+ eq("global-local", result[7])
+ eq("only-local", result[8])
+ end)
+
+ it('should allow all sorts of string manipulation', function()
+ eq({'hello', 'hello world', 'start hello world'}, exec_lua [[
+ local results = {}
+
+ vim.opt.makeprg = "hello"
+ table.insert(results, vim.o.makeprg)
+
+ vim.opt.makeprg = vim.opt.makeprg + " world"
+ table.insert(results, vim.o.makeprg)
+
+ vim.opt.makeprg = vim.opt.makeprg ^ "start "
+ table.insert(results, vim.o.makeprg)
+
+ return results
+ ]])
+ end)
+
+ describe('option:get()', function()
+ it('should work for boolean values', function()
+ eq(false, exec_lua [[
+ vim.opt.number = false
+ return vim.opt.number:get()
+ ]])
+ end)
+
+ it('should work for number values', function()
+ local tabstop = exec_lua[[
+ vim.opt.tabstop = 10
+ return vim.opt.tabstop:get()
+ ]]
+
+ eq(10, tabstop)
+ end)
+
+ it('should work for string values', function()
+ eq("hello world", exec_lua [[
+ vim.opt.makeprg = "hello world"
+ return vim.opt.makeprg:get()
+ ]])
+ end)
+
+ it('should work for set type flaglists', function()
+ local formatoptions = exec_lua [[
+ vim.opt.formatoptions = 'tcro'
+ return vim.opt.formatoptions:get()
+ ]]
+
+ eq(true, formatoptions.t)
+ eq(true, not formatoptions.q)
+ end)
+
+ it('should work for set type flaglists', function()
+ local formatoptions = exec_lua [[
+ vim.opt.formatoptions = { t = true, c = true, r = true, o = true }
+ return vim.opt.formatoptions:get()
+ ]]
+
+ eq(true, formatoptions.t)
+ eq(true, not formatoptions.q)
+ end)
+
+ it('should work for array list type options', function()
+ local wildignore = exec_lua [[
+ vim.opt.wildignore = "*.c,*.o,__pycache__"
+ return vim.opt.wildignore:get()
+ ]]
+
+ eq(3, #wildignore)
+ eq("*.c", wildignore[1])
+ end)
+
+ it('should work for key-value pair options', function()
+ local listchars = exec_lua [[
+ vim.opt.listchars = "tab:>~,space:_"
+ return vim.opt.listchars:get()
+ ]]
+
+ eq({
+ tab = ">~",
+ space = "_",
+ }, listchars)
+ end)
+
+ it('should allow you to add numeric options', function()
+ eq(16, exec_lua [[
+ vim.opt.tabstop = 12
+ vim.opt.tabstop = vim.opt.tabstop + 4
+ return vim.bo.tabstop
+ ]])
+ end)
+
+ it('should allow you to subtract numeric options', function()
+ eq(2, exec_lua [[
+ vim.opt.tabstop = 4
+ vim.opt.tabstop = vim.opt.tabstop - 2
+ return vim.bo.tabstop
+ ]])
+ end)
+ end)
+
+ describe('key:value style options', function()
+ it('should handle dictionary style', function()
+ local listchars = exec_lua [[
+ vim.opt.listchars = {
+ eol = "~",
+ space = ".",
+ }
+
+ return vim.o.listchars
+ ]]
+ eq("eol:~,space:.", listchars)
+ end)
+
+ it('should allow adding dictionary style', function()
+ local listchars = exec_lua [[
+ vim.opt.listchars = {
+ eol = "~",
+ space = ".",
+ }
+
+ vim.opt.listchars = vim.opt.listchars + { space = "-" }
+
+ return vim.o.listchars
+ ]]
+
+ eq("eol:~,space:-", listchars)
+ end)
+
+ it('should allow adding dictionary style', function()
+ local listchars = exec_lua [[
+ vim.opt.listchars = {
+ eol = "~",
+ space = ".",
+ }
+ vim.opt.listchars = vim.opt.listchars + { space = "-" } + { space = "_" }
+
+ return vim.o.listchars
+ ]]
+
+ eq("eol:~,space:_", listchars)
+ end)
+
+ it('should allow completely new keys', function()
+ local listchars = exec_lua [[
+ vim.opt.listchars = {
+ eol = "~",
+ space = ".",
+ }
+ vim.opt.listchars = vim.opt.listchars + { tab = ">>>" }
+
+ return vim.o.listchars
+ ]]
+
+ eq("eol:~,space:.,tab:>>>", listchars)
+ end)
+
+ it('should allow subtracting dictionary style', function()
+ local listchars = exec_lua [[
+ vim.opt.listchars = {
+ eol = "~",
+ space = ".",
+ }
+ vim.opt.listchars = vim.opt.listchars - "space"
+
+ return vim.o.listchars
+ ]]
+
+ eq("eol:~", listchars)
+ end)
+
+ it('should allow subtracting dictionary style', function()
+ local listchars = exec_lua [[
+ vim.opt.listchars = {
+ eol = "~",
+ space = ".",
+ }
+ vim.opt.listchars = vim.opt.listchars - "space" - "eol"
+
+ return vim.o.listchars
+ ]]
+
+ eq("", listchars)
+ end)
+
+ it('should allow subtracting dictionary style multiple times', function()
+ local listchars = exec_lua [[
+ vim.opt.listchars = {
+ eol = "~",
+ space = ".",
+ }
+ vim.opt.listchars = vim.opt.listchars - "space" - "space"
+
+ return vim.o.listchars
+ ]]
+
+ eq("eol:~", listchars)
+ end)
+
+ it('should allow adding a key:value string to a listchars', function()
+ local listchars = exec_lua [[
+ vim.opt.listchars = {
+ eol = "~",
+ space = ".",
+ }
+ vim.opt.listchars = vim.opt.listchars + "tab:>~"
+
+ return vim.o.listchars
+ ]]
+
+ eq("eol:~,space:.,tab:>~", listchars)
+ end)
+
+ it('should allow prepending a key:value string to a listchars', function()
+ local listchars = exec_lua [[
+ vim.opt.listchars = {
+ eol = "~",
+ space = ".",
+ }
+ vim.opt.listchars = vim.opt.listchars ^ "tab:>~"
+
+ return vim.o.listchars
+ ]]
+
+ eq("eol:~,space:.,tab:>~", listchars)
+ end)
+ end)
+
+ it('should automatically set when calling remove', function()
+ eq("foo,baz", exec_lua [[
+ vim.opt.wildignore = "foo,bar,baz"
+ vim.opt.wildignore:remove("bar")
+
+ return vim.o.wildignore
+ ]])
+ end)
+
+ it('should automatically set when calling remove with a table', function()
+ eq("foo", exec_lua [[
+ vim.opt.wildignore = "foo,bar,baz"
+ vim.opt.wildignore:remove { "bar", "baz" }
+
+ return vim.o.wildignore
+ ]])
+ end)
+
+ it('should automatically set when calling append', function()
+ eq("foo,bar,baz,bing", exec_lua [[
+ vim.opt.wildignore = "foo,bar,baz"
+ vim.opt.wildignore:append("bing")
+
+ return vim.o.wildignore
+ ]])
+ end)
+
+ it('should automatically set when calling append with a table', function()
+ eq("foo,bar,baz,bing,zap", exec_lua [[
+ vim.opt.wildignore = "foo,bar,baz"
+ vim.opt.wildignore:append { "bing", "zap" }
+
+ return vim.o.wildignore
+ ]])
+ end)
+
+ it('should allow adding tables', function()
+ local wildignore = exec_lua [[
+ vim.opt.wildignore = 'foo'
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, 'foo')
+
+ wildignore = exec_lua [[
+ vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, 'foo,bar,baz')
+ end)
+
+ it('should handle adding duplicates', function()
+ local wildignore = exec_lua [[
+ vim.opt.wildignore = 'foo'
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, 'foo')
+
+ wildignore = exec_lua [[
+ vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, 'foo,bar,baz')
+
+ wildignore = exec_lua [[
+ vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, 'foo,bar,baz')
+ end)
+
+ it('should allow adding multiple times', function()
+ local wildignore = exec_lua [[
+ vim.opt.wildignore = 'foo'
+ vim.opt.wildignore = vim.opt.wildignore + 'bar' + 'baz'
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, 'foo,bar,baz')
+ end)
+
+ it('should remove values when you use minus', function()
+ local wildignore = exec_lua [[
+ vim.opt.wildignore = 'foo'
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, 'foo')
+
+ wildignore = exec_lua [[
+ vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, 'foo,bar,baz')
+
+ wildignore = exec_lua [[
+ vim.opt.wildignore = vim.opt.wildignore - 'bar'
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, 'foo,baz')
+ end)
+
+ it('should prepend values when using ^', function()
+ local wildignore = exec_lua [[
+ vim.opt.wildignore = 'foo'
+ vim.opt.wildignore = vim.opt.wildignore ^ 'first'
+ return vim.o.wildignore
+ ]]
+ eq('first,foo', wildignore)
+
+ wildignore = exec_lua [[
+ vim.opt.wildignore = vim.opt.wildignore ^ 'super_first'
+ return vim.o.wildignore
+ ]]
+ eq(wildignore, 'super_first,first,foo')
+ end)
+
+ end)
+
it('vim.cmd', function()
exec_lua [[
vim.cmd "autocmd BufNew * ++once lua BUF = vim.fn.expand('<abuf>')"
diff --git a/test/functional/plugin/lsp/diagnostic_spec.lua b/test/functional/plugin/lsp/diagnostic_spec.lua
index 8c91c4ab2c..962028e7e1 100644
--- a/test/functional/plugin/lsp/diagnostic_spec.lua
+++ b/test/functional/plugin/lsp/diagnostic_spec.lua
@@ -86,6 +86,39 @@ describe('vim.lsp.diagnostic', function()
eq(2, #result[1])
eq('Diagnostic #1', result[1][1].message)
end)
+ it('Can convert diagnostic to quickfix items format', function()
+ local bufnr = exec_lua([[
+ local fake_uri = ...
+ return vim.uri_to_bufnr(fake_uri)
+ ]], fake_uri)
+ local result = exec_lua([[
+ local bufnr = ...
+ vim.lsp.diagnostic.save(
+ {
+ make_error('Diagnostic #1', 1, 1, 1, 1),
+ make_error('Diagnostic #2', 2, 1, 2, 1),
+ }, bufnr, 1
+ )
+ return vim.lsp.util.diagnostics_to_items(vim.lsp.diagnostic.get_all())
+ ]], bufnr)
+ local expected = {
+ {
+ bufnr = bufnr,
+ col = 2,
+ lnum = 2,
+ text = 'Diagnostic #1',
+ type = 'E'
+ },
+ {
+ bufnr = bufnr,
+ col = 2,
+ lnum = 3,
+ text = 'Diagnostic #2',
+ type = 'E'
+ },
+ }
+ eq(expected, result)
+ end)
it('should be able to save and count a single client error', function()
eq(1, exec_lua [[
vim.lsp.diagnostic.save(
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index 2b7198bf63..663271deab 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -9,6 +9,7 @@ local eq = helpers.eq
local pcall_err = helpers.pcall_err
local pesc = helpers.pesc
local insert = helpers.insert
+local funcs = helpers.funcs
local retry = helpers.retry
local NIL = helpers.NIL
local read_file = require('test.helpers').read_file
@@ -1392,10 +1393,10 @@ describe('LSP', function()
{ label='foocar', sortText="e", insertText='foodar', textEdit={newText='foobar'} },
{ label='foocar', sortText="f", textEdit={newText='foobar'} },
-- real-world snippet text
- { label='foocar', sortText="g", insertText='foodar', textEdit={newText='foobar(${1:place holder}, ${2:more ...holder{\\}})'} },
- { label='foocar', sortText="h", insertText='foodar(${1:var1} typ1, ${2:var2} *typ2) {$0\\}', textEdit={} },
+ { label='foocar', sortText="g", insertText='foodar', insertTextFormat=2, textEdit={newText='foobar(${1:place holder}, ${2:more ...holder{\\}})'} },
+ { label='foocar', sortText="h", insertText='foodar(${1:var1} typ1, ${2:var2} *typ2) {$0\\}', insertTextFormat=2, textEdit={} },
-- nested snippet tokens
- { label='foocar', sortText="i", insertText='foodar(${1:var1 ${2|typ2,typ3|} ${3:tail}}) {$0\\}', textEdit={} },
+ { label='foocar', sortText="i", insertText='foodar(${1:var1 ${2|typ2,typ3|} ${3:tail}}) {$0\\}', insertTextFormat=2, textEdit={} },
-- plain text
{ label='foocar', sortText="j", insertText='foodar(${1:var1})', insertTextFormat=1, textEdit={} },
}
@@ -1407,9 +1408,9 @@ describe('LSP', function()
{ abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foobar', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="d", insertText='foobar', textEdit={} } } } } },
{ abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foobar', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="e", insertText='foodar', textEdit={newText='foobar'} } } } } },
{ abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foobar', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="f", textEdit={newText='foobar'} } } } } },
- { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foobar(place holder, more ...holder{})', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="g", insertText='foodar', textEdit={newText='foobar(${1:place holder}, ${2:more ...holder{\\}})'} } } } } },
- { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foodar(var1 typ1, var2 *typ2) {}', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="h", insertText='foodar(${1:var1} typ1, ${2:var2} *typ2) {$0\\}', textEdit={} } } } } },
- { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foodar(var1 typ2,typ3 tail) {}', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="i", insertText='foodar(${1:var1 ${2|typ2,typ3|} ${3:tail}}) {$0\\}', textEdit={} } } } } },
+ { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foobar(place holder, more ...holder{})', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="g", insertText='foodar', insertTextFormat=2, textEdit={newText='foobar(${1:place holder}, ${2:more ...holder{\\}})'} } } } } },
+ { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foodar(var1 typ1, var2 *typ2) {}', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="h", insertText='foodar(${1:var1} typ1, ${2:var2} *typ2) {$0\\}', insertTextFormat=2, textEdit={} } } } } },
+ { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foodar(var1 typ2,typ3 tail) {}', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="i", insertText='foodar(${1:var1 ${2|typ2,typ3|} ${3:tail}}) {$0\\}', insertTextFormat=2, textEdit={} } } } } },
{ abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foodar(${1:var1})', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="j", insertText='foodar(${1:var1})', insertTextFormat=1, textEdit={} } } } } },
}
@@ -1820,36 +1821,20 @@ describe('LSP', function()
end)
describe('lsp.util.jump_to_location', function()
- local default_target_bufnr
- local default_target_uri = 'file://fake/uri'
-
- local create_buf = function(uri, lines)
- for i, line in ipairs(lines) do
- lines[i] = '"' .. line .. '"'
- end
- lines = table.concat(lines, ", ")
-
- -- Let's set "hidden" to true in order to avoid errors when switching
- -- between buffers in test.
- local code = string.format([[
- vim.api.nvim_set_option('hidden', true)
+ local target_bufnr
- local bufnr = vim.uri_to_bufnr("%s")
- local lines = {%s}
+ before_each(function()
+ target_bufnr = exec_lua [[
+ local bufnr = vim.uri_to_bufnr("file://fake/uri")
+ local lines = {"1st line of text", "å å ɧ 汉语 ↥ 🤦 🦄"}
vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
return bufnr
- ]], uri, lines)
-
- return exec_lua(code)
- end
-
- before_each(function()
- default_target_bufnr = create_buf(default_target_uri, {'1st line of text', 'å å ɧ 汉语 ↥ 🤦 🦄'})
+ ]]
end)
- local location = function(uri, start_line, start_char, end_line, end_char)
+ local location = function(start_line, start_char, end_line, end_char)
return {
- uri = uri,
+ uri = "file://fake/uri",
range = {
start = { line = start_line, character = start_char },
["end"] = { line = end_line, character = end_char },
@@ -1857,9 +1842,9 @@ describe('LSP', function()
}
end
- local jump = function(bufnr, msg)
+ local jump = function(msg)
eq(true, exec_lua('return vim.lsp.util.jump_to_location(...)', msg))
- eq(bufnr, exec_lua[[return vim.fn.bufnr('%')]])
+ eq(target_bufnr, exec_lua[[return vim.fn.bufnr('%')]])
return {
line = exec_lua[[return vim.fn.line('.')]],
col = exec_lua[[return vim.fn.col('.')]],
@@ -1867,13 +1852,13 @@ describe('LSP', function()
end
it('jumps to a Location', function()
- local pos = jump(default_target_bufnr, location(default_target_uri, 0, 9, 0, 9))
+ local pos = jump(location(0, 9, 0, 9))
eq(1, pos.line)
eq(10, pos.col)
end)
it('jumps to a LocationLink', function()
- local pos = jump(default_target_bufnr, {
+ local pos = jump({
targetUri = "file://fake/uri",
targetSelectionRange = {
start = { line = 0, character = 4 },
@@ -1889,104 +1874,22 @@ describe('LSP', function()
end)
it('jumps to the correct multibyte column', function()
- local pos = jump(default_target_bufnr, location(default_target_uri, 1, 2, 1, 2))
+ local pos = jump(location(1, 2, 1, 2))
eq(2, pos.line)
eq(4, pos.col)
eq('å', exec_lua[[return vim.fn.expand('<cword>')]])
end)
it('adds current position to jumplist before jumping', function()
- exec_lua([[
- vim.api.nvim_win_set_buf(0, ...)
- vim.api.nvim_win_set_cursor(0, {2, 0})
- ]], default_target_bufnr)
- jump(default_target_bufnr, location(default_target_uri, 0, 9, 0, 9))
-
- local mark = exec_lua([[return vim.inspect(vim.api.nvim_buf_get_mark(..., "'"))]], default_target_bufnr)
- eq('{ 2, 0 }', mark)
- end)
-
- it('should not push item to tagstack if destination is the same as source', function()
- -- Set cursor at the 2nd line, 1st character. This is the source position
- -- for the test, and will also be the destination one, making the cursor
- -- "motionless", thus not triggering a push to the tagstack.
- exec_lua(string.format([[
- vim.api.nvim_win_set_buf(0, %d)
- vim.api.nvim_win_set_cursor(0, {2, 0})
- ]], default_target_bufnr))
-
- -- Jump to 'f' in 'foobar', at the 2nd line.
- jump(default_target_bufnr, location(default_target_uri, 1, 0, 1, 0))
+ funcs.nvim_win_set_buf(0, target_bufnr)
+ local mark = funcs.nvim_buf_get_mark(target_bufnr, "'")
+ eq({ 1, 0 }, mark)
- local stack = exec_lua[[return vim.fn.gettagstack()]]
- eq(0, stack.length)
- end)
-
- it('should not push the same item from same buffer twice to tagstack', function()
- -- Set cursor at the 2nd line, 5th character.
- exec_lua(string.format([[
- vim.api.nvim_win_set_buf(0, %d)
- vim.api.nvim_win_set_cursor(0, {2, 4})
- ]], default_target_bufnr))
-
- local stack
-
- -- Jump to 1st line, 1st column.
- jump(default_target_bufnr, location(default_target_uri, 0, 0, 0, 0))
-
- stack = exec_lua[[return vim.fn.gettagstack()]]
- eq({default_target_bufnr, 2, 5, 0}, stack.items[1].from)
-
- -- Go back to 5th character at 2nd line, which is currently at the top of
- -- the tagstack.
- exec_lua(string.format([[
- vim.api.nvim_win_set_cursor(0, {2, 4})
- ]], default_target_bufnr))
-
- -- Jump again to 1st line, 1st column. Since we're jumping from the same
- -- position we have just jumped from, this jump shouldn't be pushed to
- -- the tagstack.
- jump(default_target_bufnr, location(default_target_uri, 0, 0, 0, 0))
+ funcs.nvim_win_set_cursor(0, {2, 3})
+ jump(location(0, 9, 0, 9))
- stack = exec_lua[[return vim.fn.gettagstack()]]
- eq({default_target_bufnr, 2, 5, 0}, stack.items[1].from)
- eq(1, stack.length)
- end)
-
- it('should not push the same item from another buffer twice to tagstack', function()
- local target_uri = 'file://foo/bar'
- local target_bufnr = create_buf(target_uri, {'this is a line', 'foobar'})
-
- -- Set cursor at the 1st line, 3rd character of the default test buffer.
- exec_lua(string.format([[
- vim.api.nvim_win_set_buf(0, %d)
- vim.api.nvim_win_set_cursor(0, {1, 2})
- ]], default_target_bufnr))
-
- local stack
-
- -- Jump to 1st line, 1st column of a different buffer from the source
- -- position.
- jump(target_bufnr, location(target_uri, 0, 0, 0, 0))
-
- stack = exec_lua[[return vim.fn.gettagstack()]]
- eq({default_target_bufnr, 1, 3, 0}, stack.items[1].from)
-
- -- Go back to 3rd character at 1st line of the default test buffer, which
- -- is currently at the top of the tagstack.
- exec_lua(string.format([[
- vim.api.nvim_win_set_buf(0, %d)
- vim.api.nvim_win_set_cursor(0, {1, 2})
- ]], default_target_bufnr))
-
- -- Jump again to 1st line, 1st column of the different buffer. Since
- -- we're jumping from the same position we have just jumped from, this
- -- jump shouldn't be pushed to the tagstack.
- jump(target_bufnr, location(target_uri, 0, 0, 0, 0))
-
- stack = exec_lua[[return vim.fn.gettagstack()]]
- eq({default_target_bufnr, 1, 3, 0}, stack.items[1].from)
- eq(1, stack.length)
+ mark = funcs.nvim_buf_get_mark(target_bufnr, "'")
+ eq({ 2, 3 }, mark)
end)
end)
diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua
index f267f9fb5d..d2f9148e8f 100644
--- a/test/functional/treesitter/parser_spec.lua
+++ b/test/functional/treesitter/parser_spec.lua
@@ -235,6 +235,100 @@ void ui_refresh(void)
}, res)
end)
+ it('can match special regex characters like \\ * + ( with `vim-match?`', function()
+ if pending_c_parser(pending) then return end
+
+ insert('char* astring = "\\n"; (1 + 1) * 2 != 2;')
+
+ local res = exec_lua([[
+ cquery = vim.treesitter.parse_query("c", '((_) @plus (vim-match? @plus "^\\\\+$"))'..
+ '((_) @times (vim-match? @times "^\\\\*$"))'..
+ '((_) @paren (vim-match? @paren "^\\\\($"))'..
+ '((_) @escape (vim-match? @escape "^\\\\\\\\n$"))'..
+ '((_) @string (vim-match? @string "^\\"\\\\\\\\n\\"$"))')
+ parser = vim.treesitter.get_parser(0, "c")
+ tree = parser:parse()[1]
+ res = {}
+ for pattern, match in cquery:iter_matches(tree:root(), 0) do
+ -- can't transmit node over RPC. just check the name and range
+ local mrepr = {}
+ for cid,node in pairs(match) do
+ table.insert(mrepr, {cquery.captures[cid], node:type(), node:range()})
+ end
+ table.insert(res, {pattern, mrepr})
+ end
+ return res
+ ]])
+
+ eq({
+ { 2, { { "times", '*', 0, 4, 0, 5 } } },
+ { 5, { { "string", 'string_literal', 0, 16, 0, 20 } } },
+ { 4, { { "escape", 'escape_sequence', 0, 17, 0, 19 } } },
+ { 3, { { "paren", '(', 0, 22, 0, 23 } } },
+ { 1, { { "plus", '+', 0, 25, 0, 26 } } },
+ { 2, { { "times", '*', 0, 30, 0, 31 } } },
+ }, res)
+ end)
+
+ it('supports builtin query predicate any-of?', function()
+ if pending_c_parser(pending) then return end
+
+ insert([[
+ #include <stdio.h>
+
+ int main(void) {
+ int i;
+ for(i=1; i<=100; i++) {
+ if(((i%3)||(i%5))== 0)
+ printf("number= %d FizzBuzz\n", i);
+ else if((i%3)==0)
+ printf("number= %d Fizz\n", i);
+ else if((i%5)==0)
+ printf("number= %d Buzz\n", i);
+ else
+ printf("number= %d\n",i);
+ }
+ return 0;
+ }
+ ]])
+ exec_lua([[
+ function get_query_result(query_text)
+ cquery = vim.treesitter.parse_query("c", query_text)
+ parser = vim.treesitter.get_parser(0, "c")
+ tree = parser:parse()[1]
+ res = {}
+ for cid, node in cquery:iter_captures(tree:root(), 0) do
+ -- can't transmit node over RPC. just check the name, range, and text
+ local text = vim.treesitter.get_node_text(node, 0)
+ local range = {node:range()}
+ table.insert(res, {cquery.captures[cid], node:type(), range, text})
+ end
+ return res
+ end
+ ]])
+
+ local res0 = exec_lua([[return get_query_result(...)]],
+ [[((primitive_type) @c-keyword (#any-of? @c-keyword "int" "float"))]])
+ eq({
+ { "c-keyword", "primitive_type", { 2, 2, 2, 5 }, "int" },
+ { "c-keyword", "primitive_type", { 3, 4, 3, 7 }, "int" },
+ }, res0)
+
+ local res1 = exec_lua([[return get_query_result(...)]],
+ [[
+ ((string_literal) @fizzbuzz-strings (#any-of? @fizzbuzz-strings
+ "\"number= %d FizzBuzz\\n\""
+ "\"number= %d Fizz\\n\""
+ "\"number= %d Buzz\\n\""
+ ))
+ ]])
+ eq({
+ { "fizzbuzz-strings", "string_literal", { 6, 15, 6, 38 }, "\"number= %d FizzBuzz\\n\""},
+ { "fizzbuzz-strings", "string_literal", { 8, 15, 8, 34 }, "\"number= %d Fizz\\n\""},
+ { "fizzbuzz-strings", "string_literal", { 10, 15, 10, 34 }, "\"number= %d Buzz\\n\""},
+ }, res1)
+ end)
+
it('allow loading query with escaped quotes and capture them with `lua-match?` and `vim-match?`', function()
if pending_c_parser(pending) then return end
@@ -308,7 +402,7 @@ void ui_refresh(void)
return list
]]
- eq({ 'contains?', 'eq?', 'is-main?', 'lua-match?', 'match?', 'vim-match?' }, res_list)
+ eq({ 'any-of?', 'contains?', 'eq?', 'is-main?', 'lua-match?', 'match?', 'vim-match?' }, res_list)
end)
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index 66aaf0c941..f3b840da21 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -64,10 +64,13 @@ describe('float window', function()
it('win_execute() should work' , function()
local buf = meths.create_buf(false, false)
- meths.buf_set_lines(buf, 0, -1, true, {'the floatwin'})
+ meths.buf_set_lines(buf, 0, -1, true, {'the floatwin', 'abc', 'def'})
local win = meths.open_win(buf, false, {relative='win', width=16, height=1, row=0, col=10})
local line = funcs.win_execute(win, 'echo getline(1)')
eq('\nthe floatwin', line)
+ eq('\n1', funcs.win_execute(win, 'echo line(".",'..win.id..')'))
+ eq('\n3', funcs.win_execute(win, 'echo line("$",'..win.id..')'))
+ eq('\n0', funcs.win_execute(win, 'echo line("$", 123456)'))
funcs.win_execute(win, 'bwipe!')
end)
@@ -1077,8 +1080,8 @@ describe('float window', function()
{1: abb }|
{13: acc }|
]], float_pos={
- [5] = { { id = 1002 }, "NW", 1, 0, 5, true },
- [6] = { { id = -1 }, "NW", 5, 4, 0, false }
+ [5] = { { id = 1002 }, "NW", 1, 0, 5, true, 50 },
+ [6] = { { id = -1 }, "NW", 5, 4, 0, false, 100 }
}, win_viewport={
[2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0};
[5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 2, curcol = 3};
@@ -2755,8 +2758,8 @@ describe('float window', function()
{1: word }|
{1: longtext }|
]], float_pos={
- [4] = {{ id = 1001 }, "NW", 1, 2, 5, true},
- [5] = {{ id = -1 }, "NW", 4, 1, 1, false}
+ [4] = {{ id = 1001 }, "NW", 1, 2, 5, true, 50},
+ [5] = {{ id = -1 }, "NW", 4, 1, 1, false, 100}
}}
else
screen:expect([[
@@ -2842,8 +2845,8 @@ describe('float window', function()
{1:yy }|
{1:zz }|
]], float_pos={
- [4] = {{ id = 1001 }, "NW", 1, 2, 5, true},
- [5] = {{ id = -1 }, "NW", 2, 1, 0, false}
+ [4] = {{ id = 1001 }, "NW", 1, 2, 5, true, 50},
+ [5] = {{ id = -1 }, "NW", 2, 1, 0, false, 100}
}}
else
screen:expect([[
@@ -3104,7 +3107,7 @@ describe('float window', function()
{1:word }|
{1:longtext }|
]], float_pos={
- [4] = {{id = -1}, "NW", 2, 1, 0, false}}
+ [4] = {{id = -1}, "NW", 2, 1, 0, false, 100}}
}
else
screen:expect([[
@@ -3148,8 +3151,8 @@ describe('float window', function()
{15:some info }|
{15:about item }|
]], float_pos={
- [4] = {{id = -1}, "NW", 2, 1, 0, false},
- [6] = {{id = 1002}, "NW", 2, 1, 12, true},
+ [4] = {{id = -1}, "NW", 2, 1, 0, false, 100},
+ [6] = {{id = 1002}, "NW", 2, 1, 12, true, 50},
}}
else
screen:expect([[
@@ -3263,7 +3266,7 @@ describe('float window', function()
{1:word }|
{1:longtext }|
]], float_pos={
- [4] = {{id = -1}, "NW", 2, 1, 0, false},
+ [4] = {{id = -1}, "NW", 2, 1, 0, false, 100},
}}
else
screen:expect([[
@@ -6296,6 +6299,69 @@ describe('float window', function()
]]}
end
end)
+
+ it('can use z-index', function()
+ local buf = meths.create_buf(false,false)
+ local win1 = meths.open_win(buf, false, {relative='editor', width=20, height=3, row=1, col=5, zindex=30})
+ meths.win_set_option(win1, "winhl", "Normal:ErrorMsg,EndOfBuffer:ErrorMsg")
+ local win2 = meths.open_win(buf, false, {relative='editor', width=20, height=3, row=2, col=6, zindex=50})
+ meths.win_set_option(win2, "winhl", "Normal:Search,EndOfBuffer:Search")
+ local win3 = meths.open_win(buf, false, {relative='editor', width=20, height=3, row=3, col=7, zindex=40})
+ meths.win_set_option(win3, "winhl", "Normal:Question,EndOfBuffer:Question")
+
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ {7: }|
+ {7:~ }|
+ {7:~ }|
+ ## grid 5
+ {17: }|
+ {17:~ }|
+ {17:~ }|
+ ## grid 6
+ {8: }|
+ {8:~ }|
+ {8:~ }|
+ ]], float_pos={
+ [4] = {{id = 1001}, "NW", 1, 1, 5, true, 30};
+ [5] = {{id = 1002}, "NW", 1, 2, 6, true, 50};
+ [6] = {{id = 1003}, "NW", 1, 3, 7, true, 40};
+ }, win_viewport={
+ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0};
+ [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0};
+ [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0};
+ [6] = {win = {id = 1003}, topline = 0, botline = 2, curline = 0, curcol = 0};
+ }}
+ else
+ screen:expect{grid=[[
+ ^ |
+ {0:~ }{7: }{0: }|
+ {0:~ }{7:~}{17: }{0: }|
+ {0:~ }{7:~}{17:~ }{8: }{0: }|
+ {0:~ }{17:~ }{8: }{0: }|
+ {0:~ }{8:~ }{0: }|
+ |
+ ]]}
+ end
+ end)
end
describe('with ext_multigrid', function()
diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua
index 9d7719a7c0..72468392ee 100644
--- a/test/functional/ui/messages_spec.lua
+++ b/test/functional/ui/messages_spec.lua
@@ -811,7 +811,7 @@ describe('ui/ext_messages', function()
{1:~ }|
{1:^~ }|
]], messages={
- {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Helli"\nType number and <Enter> or click with mouse (empty cancels): ' } }, kind = ""}
+ {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Helli"\nType number and <Enter> or click with the mouse (q or empty cancels): ' } }, kind = ""}
}}
feed('1')
@@ -822,7 +822,7 @@ describe('ui/ext_messages', function()
{1:~ }|
{1:^~ }|
]], messages={
- {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Helli"\nType number and <Enter> or click with mouse (empty cancels): ' } }, kind = ""},
+ {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Helli"\nType number and <Enter> or click with the mouse (q or empty cancels): ' } }, kind = ""},
{ content = { { "1" } }, kind = "" }
}}
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index fcf6926433..f73d051857 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -429,6 +429,15 @@ screen:redraw_debug() to show all intermediate screen states. ]])
extstate.win_viewport = nil
end
+ if expected.float_pos then
+ expected.float_pos = deepcopy(expected.float_pos)
+ for _, v in pairs(expected.float_pos) do
+ if not v.external and v[7] == nil then
+ v[7] = 50
+ end
+ end
+ end
+
-- Convert assertion errors into invalid screen state descriptions.
for _, k in ipairs(concat_tables(ext_keys, {'mode', 'mouse_enabled'})) do
-- Empty states are considered the default and need not be mentioned.
@@ -1287,6 +1296,11 @@ function Screen:get_snapshot(attrs, ignore)
end
local function fmt_ext_state(name, state)
+ local function remove_all_metatables(item, path)
+ if path[#path] ~= inspect.METATABLE then
+ return item
+ end
+ end
if name == "win_viewport" then
local str = "{\n"
for k,v in pairs(state) do
@@ -1295,13 +1309,18 @@ local function fmt_ext_state(name, state)
..", curcol = "..v.curcol.."};\n")
end
return str .. "}"
- else
- -- TODO(bfredl): improve formatting of more states
- local function remove_all_metatables(item, path)
- if path[#path] ~= inspect.METATABLE then
- return item
+ elseif name == "float_pos" then
+ local str = "{\n"
+ for k,v in pairs(state) do
+ str = str.." ["..k.."] = {{id = "..v[1].id.."}"
+ for i = 2, #v do
+ str = str..", "..inspect(v[i])
end
+ str = str .. "};\n"
end
+ return str .. "}"
+ else
+ -- TODO(bfredl): improve formatting of more states
return inspect(state,{process=remove_all_metatables})
end
end