From 4df38ec9df4764d4b2ae0b12c1b62c34889f1aa5 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Mon, 16 Sep 2019 19:16:39 +0200 Subject: server_requests_spec: fix assertion, pass Lua paths via args (#10875) This makes it pick up the nvim Luarocks module properly when not installed via third-party. --- test/functional/api/rpc_fixture.lua | 14 +++++--------- test/functional/api/server_requests_spec.lua | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/rpc_fixture.lua b/test/functional/api/rpc_fixture.lua index 87f5a91115..94df751363 100644 --- a/test/functional/api/rpc_fixture.lua +++ b/test/functional/api/rpc_fixture.lua @@ -1,12 +1,8 @@ -local deps_prefix = (os.getenv('DEPS_PREFIX') and os.getenv('DEPS_PREFIX') - or './.deps/usr') - -package.path = deps_prefix .. '/share/lua/5.1/?.lua;' .. - deps_prefix .. '/share/lua/5.1/?/init.lua;' .. - package.path - -package.cpath = deps_prefix .. '/lib/lua/5.1/?.so;' .. - package.cpath +--- RPC server fixture. +-- +-- Lua's paths are passed as arguments to reflect the path in the test itself. +package.path = arg[1] +package.cpath = arg[2] local mpack = require('mpack') local StdioStream = require('nvim.stdio_stream') diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index e275d8cd35..5a9ef7dd40 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -241,10 +241,14 @@ describe('server -> client', function() \ 'rpc': v:true \ } ]]) - meths.set_var("args", {helpers.test_lua_prg, - 'test/functional/api/rpc_fixture.lua'}) + meths.set_var("args", { + helpers.test_lua_prg, + 'test/functional/api/rpc_fixture.lua', + package.path, + package.cpath, + }) jobid = eval("jobstart(g:args, g:job_opts)") - neq(0, 'jobid') + neq(0, jobid) end) after_each(function() @@ -254,7 +258,11 @@ describe('server -> client', function() if helpers.pending_win32(pending) then return end it('rpc and text stderr can be combined', function() - eq("ok",funcs.rpcrequest(jobid, "poll")) + local status, rv = pcall(funcs.rpcrequest, jobid, 'poll') + if not status then + error(string.format('missing nvim Lua module? (%s)', rv)) + end + eq('ok', rv) funcs.rpcnotify(jobid, "ping") eq({'notification', 'pong', {}}, next_msg()) eq("done!",funcs.rpcrequest(jobid, "write_stderr", "fluff\n")) -- cgit From 4987311fb5b8f4a11d26995f71f5f402a9e2ace4 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 13 Oct 2019 20:18:22 +0200 Subject: tests/ui: remove unnecessary screen:detach() It is perfectly fine and expected to detach from the screen just by the UI disconnecting from nvim or exiting nvim. Just keep detach() in screen_basic_spec, to get some coverage of the detach method itself. This avoids hang on failure in many situations (though one could argue that detach() should be "fast", or at least "as fast as resize", which works in press-return already). Never use detach() just to change the size of the screen, try_resize() method exists for that specifically. --- test/functional/api/menu_spec.lua | 4 ---- 1 file changed, 4 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/menu_spec.lua b/test/functional/api/menu_spec.lua index 2cfa0e3e47..34a92477f3 100644 --- a/test/functional/api/menu_spec.lua +++ b/test/functional/api/menu_spec.lua @@ -15,10 +15,6 @@ describe("update_menu notification", function() screen:attach() end) - after_each(function() - screen:detach() - end) - local function expect_sent(expected) screen:expect{condition=function() if screen.update_menu ~= expected then -- cgit From 4bbad5481773ac2a273a41a9fe8035ca57e03cd8 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 18 Oct 2019 04:46:30 +0200 Subject: tests: fix non-controversial misuse of `pending` (#11247) Ref: https://github.com/neovim/neovim/pull/11184 --- test/functional/api/server_requests_spec.lua | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index 5a9ef7dd40..61184d2c59 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -317,8 +317,7 @@ describe('server -> client', function() set_session(server) local status, address = pcall(funcs.serverstart, "127.0.0.1:") if not status then - pending('no ipv4 stack', function() end) - return + pending('no ipv4 stack') end eq('127.0.0.1:', string.sub(address,1,10)) connect_test(server, 'tcp', address) @@ -329,8 +328,7 @@ describe('server -> client', function() set_session(server) local status, address = pcall(funcs.serverstart, '::1:') if not status then - pending('no ipv6 stack', function() end) - return + pending('no ipv6 stack') end eq('::1:', string.sub(address,1,4)) connect_test(server, 'tcp', address) @@ -349,8 +347,7 @@ describe('server -> client', function() it('does not deadlock', function() if not helpers.isCI('travis') and helpers.is_os('mac') then -- It does, in fact, deadlock on QuickBuild. #6851 - pending("deadlocks on QuickBuild", function() end) - return + pending("deadlocks on QuickBuild") end local address = funcs.serverlist()[1] local first = string.sub(address,1,1) -- cgit From 019c8d13dd7056725c0715dc15e451118b767b7d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 19 Oct 2019 18:04:08 -0700 Subject: build/doc/CI: remove/update quickbuild references #11258 --- test/functional/api/server_requests_spec.lua | 4 ---- 1 file changed, 4 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index 61184d2c59..237a4b01e4 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -345,10 +345,6 @@ describe('server -> client', function() describe('connecting to its own pipe address', function() it('does not deadlock', function() - if not helpers.isCI('travis') and helpers.is_os('mac') then - -- It does, in fact, deadlock on QuickBuild. #6851 - pending("deadlocks on QuickBuild") - end local address = funcs.serverlist()[1] local first = string.sub(address,1,1) ok(first == '/' or first == '\\') -- cgit From a9065a50518ef59351f9d0d32041a991a751653f Mon Sep 17 00:00:00 2001 From: timeyyy Date: Wed, 18 Jan 2017 13:20:07 +0100 Subject: nsmarks: initial commit --- test/functional/api/mark_extended_spec.lua | 1365 ++++++++++++++++++++++++++++ 1 file changed, 1365 insertions(+) create mode 100644 test/functional/api/mark_extended_spec.lua (limited to 'test/functional/api') diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua new file mode 100644 index 0000000000..6bf0e59133 --- /dev/null +++ b/test/functional/api/mark_extended_spec.lua @@ -0,0 +1,1365 @@ +-- TODO(timeyyy): go through todo's lol +-- change representation of stored marks to have location start at 0 +-- check with memsan, asan etc + +local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') + +local request = helpers.request +local eq = helpers.eq +local ok = helpers.ok +local curbufmeths = helpers.curbufmeths +local meth_pcall = helpers.meth_pcall +local insert = helpers.insert +local feed = helpers.feed +local clear = helpers.clear + +local ALL = -1 + +local rv = nil + +local function check_undo_redo(ns, mark, sr, sc, er, ec) --s = start, e = end + rv = curbufmeths.get_extmark_by_id(ns, mark) + eq({er, ec}, rv) + feed("u") + rv = curbufmeths.get_extmark_by_id(ns, mark) + eq({sr, sc}, rv) + feed("") + rv = curbufmeths.get_extmark_by_id(ns, mark) + eq({er, ec}, rv) +end + +describe('Extmarks buffer api', function() + local screen + local marks, positions, ns_string2, ns_string, init_text, row, col + local ns, ns2 + + before_each(function() + -- Initialize some namespaces and insert 12345 into a buffer + marks = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} + positions = {{0, 0,}, {0, 2}, {0, 3}} + + ns_string = "my-fancy-plugin" + ns_string2 = "my-fancy-plugin2" + init_text = "12345" + row = 0 + col = 2 + + clear() + screen = Screen.new(15, 10) + screen:attach() + + insert(init_text) + ns = request('nvim_create_namespace', ns_string) + ns2 = request('nvim_create_namespace', ns_string2) + end) + + it('adds, updates and deletes marks #extmarks', function() + rv = curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + eq(marks[1], rv) + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({positions[1][1], positions[1][2]}, rv) + -- Test adding a second mark on same row works + rv = curbufmeths.set_extmark(ns, marks[2], positions[2][1], positions[2][2]) + eq(marks[2], rv) + + -- Test an update, (same pos) + rv = curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + eq(0, rv) + rv = curbufmeths.get_extmark_by_id(ns, marks[2]) + eq({positions[2][1], positions[2][2]}, rv) + -- Test an update, (new pos) + row = positions[1][1] + col = positions[1][2] + 1 + rv = curbufmeths.set_extmark(ns, marks[1], row, col) + eq(0, rv) + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({row, col}, rv) + + -- remove the test marks + eq(true, curbufmeths.del_extmark(ns, marks[1])) + eq(false, curbufmeths.del_extmark(ns, marks[1])) + eq(true, curbufmeths.del_extmark(ns, marks[2])) + eq(false, curbufmeths.del_extmark(ns, marks[3])) + eq(false, curbufmeths.del_extmark(ns, 1000)) + end) + + it('can clear a specific namespace range #extmarks', function() + curbufmeths.set_extmark(ns, 1, 0, 1) + curbufmeths.set_extmark(ns2, 1, 0, 1) + -- force a new undo buffer + feed('o') + curbufmeths.clear_namespace(ns2, 0, -1) + eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) + eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + feed('u') + eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) + eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + feed('') + eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) + eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + end) + + it('can clear a namespace range using ALL #extmarks', function() + curbufmeths.set_extmark(ns, 1, 0, 1) + curbufmeths.set_extmark(ns2, 1, 0, 1) + -- force a new undo buffer + feed('o') + curbufmeths.clear_namespace(-1, 0, -1) + eq({}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) + eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + feed('u') + eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) + eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + feed('') + eq({}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) + eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + end) + + it('querying for information and ranges #extmarks', function() + -- add some more marks + for i, m in ipairs(marks) do + if positions[i] ~= nil then + rv = curbufmeths.set_extmark(ns, m, positions[i][1], positions[i][2]) + eq(m, rv) + end + end + + -- {0, 0} and {-1, -1} work as extreme values + eq({{1, 0, 0}}, curbufmeths.get_extmarks(ns, {0, 0}, {0, 0}, ALL)) + eq({}, curbufmeths.get_extmarks(ns, {-1, -1}, {-1, -1}, ALL)) + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + for i, m in ipairs(marks) do + if positions[i] ~= nil then + eq({m, positions[i][1], positions[i][2]}, rv[i]) + end + end + + -- 0 and -1 works as short hand extreme values + eq({{1, 0, 0}}, curbufmeths.get_extmarks(ns, 0, 0, ALL)) + eq({}, curbufmeths.get_extmarks(ns, -1, -1, ALL)) + rv = curbufmeths.get_extmarks(ns, 0, -1, ALL) + for i, m in ipairs(marks) do + if positions[i] ~= nil then + eq({m, positions[i][1], positions[i][2]}, rv[i]) + end + end + + -- next with mark id + rv = curbufmeths.get_extmarks(ns, marks[1], {-1, -1}, 1) + eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + rv = curbufmeths.get_extmarks(ns, marks[2], {-1, -1}, 1) + eq({{marks[2], positions[2][1], positions[2][2]}}, rv) + -- next with positional when mark exists at position + rv = curbufmeths.get_extmarks(ns, positions[1], {-1, -1}, 1) + eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + -- next with positional index (no mark at position) + rv = curbufmeths.get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, 1) + eq({{marks[2], positions[2][1], positions[2][2]}}, rv) + -- next with Extremity index + rv = curbufmeths.get_extmarks(ns, {0,0}, {-1, -1}, 1) + eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + + -- nextrange with mark id + rv = curbufmeths.get_extmarks(ns, marks[1], marks[3], ALL) + eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) + eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) + -- nextrange with amount + rv = curbufmeths.get_extmarks(ns, marks[1], marks[3], 2) + eq(2, table.getn(rv)) + -- nextrange with positional when mark exists at position + rv = curbufmeths.get_extmarks(ns, positions[1], positions[3], ALL) + eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) + eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) + rv = curbufmeths.get_extmarks(ns, positions[2], positions[3], ALL) + eq(2, table.getn(rv)) + -- nextrange with positional index (no mark at position) + local lower = {positions[1][1], positions[2][2] -1} + local upper = {positions[2][1], positions[3][2] - 1} + rv = curbufmeths.get_extmarks(ns, lower, upper, ALL) + eq({{marks[2], positions[2][1], positions[2][2]}}, rv) + lower = {positions[3][1], positions[3][2] + 1} + upper = {positions[3][1], positions[3][2] + 2} + rv = curbufmeths.get_extmarks(ns, lower, upper, ALL) + eq({}, rv) + -- nextrange with extremity index + lower = {positions[2][1], positions[2][2]+1} + upper = {-1, -1} + rv = curbufmeths.get_extmarks(ns, lower, upper, ALL) + eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + + -- prev with mark id + rv = curbufmeths.get_extmarks(ns, marks[3], {0, 0}, 1) + eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + rv = curbufmeths.get_extmarks(ns, marks[2], {0, 0}, 1) + eq({{marks[2], positions[2][1], positions[2][2]}}, rv) + -- prev with positional when mark exists at position + rv = curbufmeths.get_extmarks(ns, positions[3], {0, 0}, 1) + eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + -- prev with positional index (no mark at position) + rv = curbufmeths.get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, 1) + eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + -- prev with Extremity index + rv = curbufmeths.get_extmarks(ns, {-1,-1}, {0,0}, 1) + eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + + -- prevrange with mark id + rv = curbufmeths.get_extmarks(ns, marks[3], marks[1], ALL) + eq({marks[3], positions[3][1], positions[3][2]}, rv[1]) + eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) + eq({marks[1], positions[1][1], positions[1][2]}, rv[3]) + -- prevrange with amount + rv = curbufmeths.get_extmarks(ns, marks[3], marks[1], 2) + eq(2, table.getn(rv)) + -- prevrange with positional when mark exists at position + rv = curbufmeths.get_extmarks(ns, positions[3], positions[1], ALL) + eq({{marks[3], positions[3][1], positions[3][2]}, + {marks[2], positions[2][1], positions[2][2]}, + {marks[1], positions[1][1], positions[1][2]}}, rv) + rv = curbufmeths.get_extmarks(ns, positions[2], positions[1], ALL) + eq(2, table.getn(rv)) + -- prevrange with positional index (no mark at position) + lower = {positions[2][1], positions[2][2] + 1} + upper = {positions[3][1], positions[3][2] + 1} + rv = curbufmeths.get_extmarks(ns, upper, lower, ALL) + eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + lower = {positions[3][1], positions[3][2] + 1} + upper = {positions[3][1], positions[3][2] + 2} + rv = curbufmeths.get_extmarks(ns, upper, lower, ALL) + eq({}, rv) + -- prevrange with extremity index + lower = {0,0} + upper = {positions[2][1], positions[2][2] - 1} + rv = curbufmeths.get_extmarks(ns, upper, lower, ALL) + eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + end) + + it('querying for information with amount #extmarks', function() + -- add some more marks + for i, m in ipairs(marks) do + if positions[i] ~= nil then + rv = curbufmeths.set_extmark(ns, m, positions[i][1], positions[i][2]) + eq(m, rv) + end + end + + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 1) + eq(1, table.getn(rv)) + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 2) + eq(2, table.getn(rv)) + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 3) + eq(3, table.getn(rv)) + + -- now in reverse + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 1) + eq(1, table.getn(rv)) + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 2) + eq(2, table.getn(rv)) + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 3) + eq(3, table.getn(rv)) + end) + + it('get_marks works when mark col > upper col #extmarks', function() + feed('A12345') + feed('A12345') + curbufmeths.set_extmark(ns, 10, 0, 2) -- this shouldn't be found + curbufmeths.set_extmark(ns, 11, 2, 1) -- this shouldn't be found + curbufmeths.set_extmark(ns, marks[1], 0, 4) -- check col > our upper bound + curbufmeths.set_extmark(ns, marks[2], 1, 1) -- check col < lower bound + curbufmeths.set_extmark(ns, marks[3], 2, 0) -- check is inclusive + eq({{marks[1], 0, 4}, + {marks[2], 1, 1}, + {marks[3], 2, 0}}, + curbufmeths.get_extmarks(ns, {0, 3}, {2, 0}, -1)) + end) + + it('get_marks works in reverse when mark col < lower col #extmarks', function() + feed('A12345') + feed('A12345') + curbufmeths.set_extmark(ns, 10, 0, 1) -- this shouldn't be found + curbufmeths.set_extmark(ns, 11, 2, 4) -- this shouldn't be found + curbufmeths.set_extmark(ns, marks[1], 2, 1) -- check col < our lower bound + curbufmeths.set_extmark(ns, marks[2], 1, 4) -- check col > upper bound + curbufmeths.set_extmark(ns, marks[3], 0, 2) -- check is inclusive + rv = curbufmeths.get_extmarks(ns, {2, 3}, {0, 2}, -1) + eq({{marks[1], 2, 1}, + {marks[2], 1, 4}, + {marks[3], 0, 2}}, + rv) + end) + + it('get_marks amount 0 returns nothing #extmarks', function() + curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + rv = curbufmeths.get_extmarks(ns, {-1, -1}, {-1, -1}, 0) + eq({}, rv) + end) + + + it('marks move with line insertations #extmarks', function() + curbufmeths.set_extmark(ns, marks[1], 0, 0) + feed("yyP") + check_undo_redo(ns, marks[1], 0, 0, 1, 0) + end) + + it('marks move with multiline insertations #extmarks', function() + feed("a2233") + curbufmeths.set_extmark(ns, marks[1], 1, 1) + feed('ggVGyP') + check_undo_redo(ns, marks[1], 1, 1, 4, 1) + end) + + it('marks move with line join #extmarks', function() + -- do_join in ops.c + feed("a222") + curbufmeths.set_extmark(ns, marks[1], 1, 0) + feed('ggJ') + check_undo_redo(ns, marks[1], 1, 0, 0, 6) + end) + + it('join works when no marks are present #extmarks', function() + feed("a1") + feed('kJ') + -- This shouldn't seg fault + screen:expect([[ + 12345^ 1 | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + | + ]]) + end) + + it('marks move with multiline join #extmarks', function() + -- do_join in ops.c + feed("a222333444") + curbufmeths.set_extmark(ns, marks[1], 3, 0) + feed('2GVGJ') + check_undo_redo(ns, marks[1], 3, 0, 1, 8) + end) + + it('marks move with line deletes #extmarks', function() + feed("a222333444") + curbufmeths.set_extmark(ns, marks[1], 2, 1) + feed('ggjdd') + check_undo_redo(ns, marks[1], 2, 1, 1, 1) + end) + + it('marks move with multiline deletes #extmarks', function() + feed("a222333444") + curbufmeths.set_extmark(ns, marks[1], 3, 0) + feed('gg2dd') + check_undo_redo(ns, marks[1], 3, 0, 1, 0) + -- regression test, undoing multiline delete when mark is on row 1 + feed('ugg3dd') + check_undo_redo(ns, marks[1], 3, 0, 0, 0) + end) + + it('marks move with open line #extmarks', function() + -- open_line in misc1.c + -- testing marks below are also moved + feed("yyP") + curbufmeths.set_extmark(ns, marks[1], 0, 4) + curbufmeths.set_extmark(ns, marks[2], 1, 4) + feed('1G') + check_undo_redo(ns, marks[1], 0, 4, 1, 4) + check_undo_redo(ns, marks[2], 1, 4, 2, 4) + feed('2Go') + check_undo_redo(ns, marks[1], 1, 4, 1, 4) + check_undo_redo(ns, marks[2], 2, 4, 3, 4) + end) + + -- NO idea why this doesn't work... works in program. + pending('marks move with char inserts #extmarks', function() + -- insertchar in edit.c (the ins_str branch) + curbufmeths.set_extmark(ns, marks[1], 1, 3) + feed('0') + insert('abc') + screen:expect([[ + ab^c12345 | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + | + ]]) + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq(1, rv[2]) + eq(6, rv[3]) + -- check_undo_redo(ns, marks[1], 0, 2, 0, 5) + end) + + -- gravity right as definted in tk library + it('marks have gravity right #extmarks', function() + -- insertchar in edit.c (the ins_str branch) + curbufmeths.set_extmark(ns, marks[1], 0, 2) + feed('03l') + insert("X") + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + + -- check multibyte chars + feed('03l') + insert("~~") + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + end) + + it('we can insert multibyte chars #extmarks', function() + -- insertchar in edit.c + feed('a12345') + curbufmeths.set_extmark(ns, marks[1], 1, 2) + -- Insert a fullwidth (two col) tilde, NICE + feed('0i~') + check_undo_redo(ns, marks[1], 1, 2, 1, 3) + end) + + it('marks move with blockwise inserts #extmarks', function() + -- op_insert in ops.c + feed('a12345') + curbufmeths.set_extmark(ns, marks[1], 1, 2) + feed('0lkI9') + check_undo_redo(ns, marks[1], 1, 2, 1, 3) + end) + + it('marks move with line splits (using enter) #extmarks', function() + -- open_line in misc1.c + -- testing marks below are also moved + feed("yyP") + curbufmeths.set_extmark(ns, marks[1], 0, 4) + curbufmeths.set_extmark(ns, marks[2], 1, 4) + feed('1Gla') + check_undo_redo(ns, marks[1], 0, 4, 1, 2) + check_undo_redo(ns, marks[2], 1, 4, 2, 4) + end) + + -- TODO mark_col_adjust for normal marks fails in vim/neovim + -- because flags is 9 in: if (flags & OPENLINE_MARKFIX) { + it('marks at last line move on insert new line #extmarks', function() + -- open_line in misc1.c + curbufmeths.set_extmark(ns, marks[1], 0, 4) + feed('0i') + check_undo_redo(ns, marks[1], 0, 4, 1, 4) + end) + + it('yet again marks move with line splits #extmarks', function() + -- the first test above wasn't catching all errors.. + feed("A67890") + curbufmeths.set_extmark(ns, marks[1], 0, 4) + feed("04li") + check_undo_redo(ns, marks[1], 0, 4, 1, 0) + end) + + it('and one last time line splits... #extmarks', function() + curbufmeths.set_extmark(ns, marks[1], 0, 1) + curbufmeths.set_extmark(ns, marks[2], 0, 2) + feed("02li") + check_undo_redo(ns, marks[1], 0, 1, 0, 1) + check_undo_redo(ns, marks[2], 0, 2, 1, 0) + end) + + it('multiple marks move with mark splits #extmarks', function() + curbufmeths.set_extmark(ns, marks[1], 0, 1) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + feed("0li") + check_undo_redo(ns, marks[1], 0, 1, 1, 0) + check_undo_redo(ns, marks[2], 0, 3, 1, 2) + end) + + it('deleting on a mark works #extmarks', function() + -- op_delete in ops.c + curbufmeths.set_extmark(ns, marks[1], 0, 2) + feed('02lx') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + end) + + it('marks move with char deletes #extmarks', function() + -- op_delete in ops.c + curbufmeths.set_extmark(ns, marks[1], 0, 2) + feed('02dl') + check_undo_redo(ns, marks[1], 0, 2, 0, 0) + -- from the other side (nothing should happen) + feed('$x') + check_undo_redo(ns, marks[1], 0, 0, 0, 0) + end) + + it('marks move with char deletes over a range #extmarks', function() + -- op_delete in ops.c + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + feed('0l3dl') + check_undo_redo(ns, marks[1], 0, 2, 0, 1) + check_undo_redo(ns, marks[2], 0, 3, 0, 1) + -- delete 1, nothing should happend to our marks + feed('u') + feed('$x') + -- TODO do we need to test marks[1] ??? + check_undo_redo(ns, marks[2], 0, 3, 0, 3) + end) + + it('deleting marks at end of line works #extmarks', function() + -- mark_extended.c/extmark_col_adjust_delete + curbufmeths.set_extmark(ns, marks[1], 0, 4) + feed('$x') + check_undo_redo(ns, marks[1], 0, 4, 0, 4) + -- check the copy happened correctly on delete at eol + feed('$x') + check_undo_redo(ns, marks[1], 0, 4, 0, 3) + feed('u') + check_undo_redo(ns, marks[1], 0, 4, 0, 4) + end) + + it('marks move with blockwise deletes #extmarks', function() + -- op_delete in ops.c + feed('a12345') + curbufmeths.set_extmark(ns, marks[1], 1, 4) + feed('hhhkd') + check_undo_redo(ns, marks[1], 1, 4, 1, 1) + end) + + it('marks move with blockwise deletes over a range #extmarks', function() + -- op_delete in ops.c + feed('a12345') + curbufmeths.set_extmark(ns, marks[1], 0, 1) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + curbufmeths.set_extmark(ns, marks[3], 1, 2) + feed('0k3lx') + check_undo_redo(ns, marks[1], 0, 1, 0, 0) + check_undo_redo(ns, marks[2], 0, 3, 0, 0) + check_undo_redo(ns, marks[3], 1, 2, 1, 0) + -- delete 1, nothing should happend to our marks + feed('u') + feed('$jx') + -- TODO do we need to test marks[1] ??? + check_undo_redo(ns, marks[2], 0, 3, 0, 3) + check_undo_redo(ns, marks[3], 1, 2, 1, 2) + end) + + it('works with char deletes over multilines #extmarks', function() + feed('a12345test-me') + curbufmeths.set_extmark(ns, marks[1], 2, 5) + feed('gg') + feed('dv?-m?') + check_undo_redo(ns, marks[1], 2, 5, 0, 0) + end) + + it('marks outside of deleted range move with visual char deletes #extmarks', function() + -- op_delete in ops.c + curbufmeths.set_extmark(ns, marks[1], 0, 3) + feed('0vx') + check_undo_redo(ns, marks[1], 0, 3, 0, 2) + + feed("u") + feed('0vlx') + check_undo_redo(ns, marks[1], 0, 3, 0, 1) + + feed("u") + feed('0v2lx') + check_undo_redo(ns, marks[1], 0, 3, 0, 0) + + -- from the other side (nothing should happen) + feed('$vx') + check_undo_redo(ns, marks[1], 0, 0, 0, 0) + end) + + it('marks outside of deleted range move with char deletes #extmarks', function() + -- op_delete in ops.c + curbufmeths.set_extmark(ns, marks[1], 0, 3) + feed('0x') + check_undo_redo(ns, marks[1], 0, 3, 0, 2) + + feed("u") + feed('02x') + check_undo_redo(ns, marks[1], 0, 3, 0, 1) + + feed("u") + feed('0v3lx') + check_undo_redo(ns, marks[1], 0, 3, 0, 0) + + -- from the other side (nothing should happen) + feed("u") + feed('$vx') + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + end) + + it('marks move with P(backward) paste #extmarks', function() + -- do_put in ops.c + feed('0iabc') + curbufmeths.set_extmark(ns, marks[1], 0, 7) + feed('0veyP') + check_undo_redo(ns, marks[1], 0, 7, 0, 15) + end) + + it('marks move with p(forward) paste #extmarks', function() + -- do_put in ops.c + feed('0iabc') + curbufmeths.set_extmark(ns, marks[1], 0, 7) + feed('0veyp') + check_undo_redo(ns, marks[1], 0, 7, 0, 14) + end) + + it('marks move with blockwise P(backward) paste #extmarks', function() + -- do_put in ops.c + feed('a12345') + curbufmeths.set_extmark(ns, marks[1], 1, 4) + feed('hhkyP') + check_undo_redo(ns, marks[1], 1, 4, 1, 7) + end) + + it('marks move with blockwise p(forward) paste #extmarks', function() + -- do_put in ops.c + feed('a12345') + curbufmeths.set_extmark(ns, marks[1], 1, 4) + feed('hhkyp') + check_undo_redo(ns, marks[1], 1, 4, 1, 6) + end) + + it('replace works #extmarks', function() + curbufmeths.set_extmark(ns, marks[1], 0, 2) + feed('0r2') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + end) + + it('blockwise replace works #extmarks', function() + feed('a12345') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + feed('0llkr1') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + end) + + it('shift line #extmarks', function() + -- shift_line in ops.c + feed(':set shiftwidth=4') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + feed('0>>') + check_undo_redo(ns, marks[1], 0, 2, 0, 6) + + feed('>>') + check_undo_redo(ns, marks[1], 0, 6, 0, 10) + + feed('') -- have to escape, same as << + check_undo_redo(ns, marks[1], 0, 10, 0, 6) + end) + + it('blockwise shift #extmarks', function() + -- shift_block in ops.c + feed(':set shiftwidth=4') + feed('a12345') + curbufmeths.set_extmark(ns, marks[1], 1, 2) + feed('0k>') + check_undo_redo(ns, marks[1], 1, 2, 1, 6) + feed('j>') + check_undo_redo(ns, marks[1], 1, 6, 1, 10) + + feed('j') + check_undo_redo(ns, marks[1], 1, 10, 1, 6) + end) + + it('tab works with expandtab #extmarks', function() + -- ins_tab in edit.c + feed(':set expandtab') + feed(':set shiftwidth=2') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + feed('0i') + check_undo_redo(ns, marks[1], 0, 2, 0, 6) + end) + + it('tabs work #extmarks', function() + -- ins_tab in edit.c + feed(':set noexpandtab') + feed(':set shiftwidth=2') + feed(':set softtabstop=2') + feed(':set tabstop=8') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + feed('0i') + check_undo_redo(ns, marks[1], 0, 2, 0, 4) + feed('0iX') + check_undo_redo(ns, marks[1], 0, 4, 0, 6) + end) + + it('marks move when using :move #extmarks', function() + curbufmeths.set_extmark(ns, marks[1], 0, 0) + feed('A2:1move 2') + check_undo_redo(ns, marks[1], 0, 0, 1, 0) + -- test codepath when moving lines up + feed(':2move 0') + check_undo_redo(ns, marks[1], 1, 0, 0, 0) + end) + + it('marks move when using :move part 2 #extmarks', function() + -- make sure we didn't get lucky with the math... + feed('A23456') + curbufmeths.set_extmark(ns, marks[1], 1, 0) + feed(':2,3move 5') + check_undo_redo(ns, marks[1], 1, 0, 3, 0) + -- test codepath when moving lines up + feed(':4,5move 1') + check_undo_redo(ns, marks[1], 3, 0, 1, 0) + end) + + it('undo and redo of set and unset marks #extmarks', function() + -- Force a new undo head + feed('o') + curbufmeths.set_extmark(ns, marks[1], 0, 1) + feed('o') + curbufmeths.set_extmark(ns, marks[2], 0, -1) + curbufmeths.set_extmark(ns, marks[3], 0, -1) + + feed("u") + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + eq(1, table.getn(rv)) + + feed("") + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + eq(3, table.getn(rv)) + + -- Test updates + feed('o') + curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + rv = curbufmeths.get_extmarks(ns, marks[1], marks[1], 1) + feed("u") + feed("") + check_undo_redo(ns, marks[1], 0, 1, positions[1][1], positions[1][2]) + + -- Test unset + feed('o') + curbufmeths.del_extmark(ns, marks[3]) + feed("u") + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + eq(3, table.getn(rv)) + feed("") + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + eq(2, table.getn(rv)) + end) + + it('undo and redo of marks deleted during edits #extmarks', function() + -- test extmark_adjust + feed('A12345') + curbufmeths.set_extmark(ns, marks[1], 1, 2) + feed('dd') + check_undo_redo(ns, marks[1], 1, 2, 1, 0) + end) + + it('namespaces work properly #extmarks', function() + rv = curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + eq(1, rv) + rv = curbufmeths.set_extmark(ns2, marks[1], positions[1][1], positions[1][2]) + eq(1, rv) + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + eq(1, table.getn(rv)) + rv = curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL) + eq(1, table.getn(rv)) + + -- Set more marks for testing the ranges + rv = curbufmeths.set_extmark(ns, marks[2], positions[2][1], positions[2][2]) + rv = curbufmeths.set_extmark(ns, marks[3], positions[3][1], positions[3][2]) + rv = curbufmeths.set_extmark(ns2, marks[2], positions[2][1], positions[2][2]) + rv = curbufmeths.set_extmark(ns2, marks[3], positions[3][1], positions[3][2]) + + -- get_next (amount set) + rv = curbufmeths.get_extmarks(ns, {0, 0}, positions[2], 1) + eq(1, table.getn(rv)) + rv = curbufmeths.get_extmarks(ns2, {0, 0}, positions[2], 1) + eq(1, table.getn(rv)) + -- get_prev (amount set) + rv = curbufmeths.get_extmarks(ns, positions[1], {0, 0}, 1) + eq(1, table.getn(rv)) + rv = curbufmeths.get_extmarks(ns2, positions[1], {0, 0}, 1) + eq(1, table.getn(rv)) + + -- get_next (amount not set) + rv = curbufmeths.get_extmarks(ns, positions[1], positions[2], ALL) + eq(2, table.getn(rv)) + rv = curbufmeths.get_extmarks(ns2, positions[1], positions[2], ALL) + eq(2, table.getn(rv)) + -- get_prev (amount not set) + rv = curbufmeths.get_extmarks(ns, positions[2], positions[1], ALL) + eq(2, table.getn(rv)) + rv = curbufmeths.get_extmarks(ns2, positions[2], positions[1], ALL) + eq(2, table.getn(rv)) + + curbufmeths.del_extmark(ns, marks[1]) + rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + eq(2, table.getn(rv)) + curbufmeths.del_extmark(ns2, marks[1]) + rv = curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL) + eq(2, table.getn(rv)) + end) + + it('mark set can create unique identifiers #extmarks', function() + -- create mark with id 1 + eq(1, curbufmeths.set_extmark(ns, 1, positions[1][1], positions[1][2])) + -- ask for unique id, it should be the next one, i e 2 + eq(2, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(3, curbufmeths.set_extmark(ns, 3, positions[2][1], positions[2][2])) + eq(4, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) + + -- mixing manual and allocated id:s are not recommened, but it should + -- do something reasonable + eq(6, curbufmeths.set_extmark(ns, 6, positions[2][1], positions[2][2])) + eq(7, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(8, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) + end) + + it('auto indenting with enter works #extmarks', function() + -- op_reindent in ops.c + feed(':set cindent') + feed(':set autoindent') + feed(':set shiftwidth=2') + feed("0iint A {1M1b") + -- Set the mark on the M, should move.. + curbufmeths.set_extmark(ns, marks[1], 0, 12) + -- Set the mark before the cursor, should stay there + curbufmeths.set_extmark(ns, marks[2], 0, 10) + feed("i") + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({1, 3}, rv) + rv = curbufmeths.get_extmark_by_id(ns, marks[2]) + eq({0, 10}, rv) + check_undo_redo(ns, marks[1], 0, 12, 1, 3) + end) + + it('auto indenting entire line works #extmarks', function() + feed(':set cindent') + feed(':set autoindent') + feed(':set shiftwidth=2') + -- will force an indent of 2 + feed("0iint A {0i1M1") + curbufmeths.set_extmark(ns, marks[1], 1, 1) + feed("0i") + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({1, 3}, rv) + check_undo_redo(ns, marks[1], 1, 1, 1, 3) + -- now check when cursor at eol + feed("uA") + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({1, 3}, rv) + end) + + it('removing auto indenting with works #extmarks', function() + feed(':set cindent') + feed(':set autoindent') + feed(':set shiftwidth=2') + feed("0i") + curbufmeths.set_extmark(ns, marks[1], 0, 3) + feed("bi") + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({0, 1}, rv) + check_undo_redo(ns, marks[1], 0, 3, 0, 1) + -- check when cursor at eol + feed("uA") + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({0, 1}, rv) + end) + + it('indenting multiple lines with = works #extmarks', function() + feed(':set cindent') + feed(':set autoindent') + feed(':set shiftwidth=2') + feed("0iint A {1M12M2") + curbufmeths.set_extmark(ns, marks[1], 1, 1) + curbufmeths.set_extmark(ns, marks[2], 2, 1) + feed('=gg') + check_undo_redo(ns, marks[1], 1, 1, 1, 3) + check_undo_redo(ns, marks[2], 2, 1, 2, 5) + end) + + it('substitutes by deleting inside the replace matches #extmarks_sub', function() + -- do_sub in ex_cmds.c + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + feed(':s/34/xx') + check_undo_redo(ns, marks[1], 0, 2, 0, 4) + check_undo_redo(ns, marks[2], 0, 3, 0, 4) + end) + + it('substitutes when insert text > deleted #extmarks_sub', function() + -- do_sub in ex_cmds.c + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + feed(':s/34/xxx') + check_undo_redo(ns, marks[1], 0, 2, 0, 5) + check_undo_redo(ns, marks[2], 0, 3, 0, 5) + end) + + it('substitutes when marks around eol #extmarks_sub', function() + -- do_sub in ex_cmds.c + curbufmeths.set_extmark(ns, marks[1], 0, 4) + curbufmeths.set_extmark(ns, marks[2], 0, 5) + feed(':s/5/xxx') + check_undo_redo(ns, marks[1], 0, 4, 0, 7) + check_undo_redo(ns, marks[2], 0, 5, 0, 7) + end) + + it('substitutes over range insert text > deleted #extmarks_sub', function() + -- do_sub in ex_cmds.c + feed('Ax34xx') + feed('Axxx34') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 1, 1) + curbufmeths.set_extmark(ns, marks[3], 2, 4) + feed(':1,3s/34/xxx') + check_undo_redo(ns, marks[1], 0, 2, 0, 5) + check_undo_redo(ns, marks[2], 1, 1, 1, 4) + check_undo_redo(ns, marks[3], 2, 4, 2, 6) + end) + + it('substitutes multiple matches in a line #extmarks_sub', function() + -- do_sub in ex_cmds.c + feed('ddi3x3x3') + curbufmeths.set_extmark(ns, marks[1], 0, 0) + curbufmeths.set_extmark(ns, marks[2], 0, 2) + curbufmeths.set_extmark(ns, marks[3], 0, 4) + feed(':s/3/yy/g') + check_undo_redo(ns, marks[1], 0, 0, 0, 2) + check_undo_redo(ns, marks[2], 0, 2, 0, 5) + check_undo_redo(ns, marks[3], 0, 4, 0, 8) + end) + + it('substitions over multiple lines with newline in pattern #extmarks_sub', function() + feed('A67890xx') + curbufmeths.set_extmark(ns, marks[1], 0, 3) + curbufmeths.set_extmark(ns, marks[2], 0, 4) + curbufmeths.set_extmark(ns, marks[3], 1, 0) + curbufmeths.set_extmark(ns, marks[4], 1, 5) + curbufmeths.set_extmark(ns, marks[5], 2, 0) + feed([[:1,2s:5\n:5 ]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 0, 6) + check_undo_redo(ns, marks[3], 1, 0, 0, 6) + check_undo_redo(ns, marks[4], 1, 5, 0, 11) + check_undo_redo(ns, marks[5], 2, 0, 1, 0) + end) + + it('inserting #extmarks_sub', function() + feed('A67890xx') + curbufmeths.set_extmark(ns, marks[1], 0, 3) + curbufmeths.set_extmark(ns, marks[2], 0, 4) + curbufmeths.set_extmark(ns, marks[3], 1, 0) + curbufmeths.set_extmark(ns, marks[4], 1, 5) + curbufmeths.set_extmark(ns, marks[5], 2, 0) + curbufmeths.set_extmark(ns, marks[6], 1, 2) + feed([[:1,2s:5\n67:X]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 0, 5) + check_undo_redo(ns, marks[3], 1, 0, 0, 5) + check_undo_redo(ns, marks[4], 1, 5, 0, 8) + check_undo_redo(ns, marks[5], 2, 0, 1, 0) + check_undo_redo(ns, marks[6], 1, 2, 0, 5) + end) + + it('substitions with multiple newlines in pattern #extmarks_sub', function() + feed('A67890xx') + curbufmeths.set_extmark(ns, marks[1], 0, 4) + curbufmeths.set_extmark(ns, marks[2], 0, 5) + curbufmeths.set_extmark(ns, marks[3], 1, 0) + curbufmeths.set_extmark(ns, marks[4], 1, 5) + curbufmeths.set_extmark(ns, marks[5], 2, 0) + feed([[:1,2s:\n.*\n:X]]) + check_undo_redo(ns, marks[1], 0, 4, 0, 4) + check_undo_redo(ns, marks[2], 0, 5, 0, 6) + check_undo_redo(ns, marks[3], 1, 0, 0, 6) + check_undo_redo(ns, marks[4], 1, 5, 0, 6) + check_undo_redo(ns, marks[5], 2, 0, 0, 6) + end) + + it('substitions over multiple lines with replace in substition #extmarks_sub', function() + feed('A67890xx') + curbufmeths.set_extmark(ns, marks[1], 0, 1) + curbufmeths.set_extmark(ns, marks[2], 0, 2) + curbufmeths.set_extmark(ns, marks[3], 0, 4) + curbufmeths.set_extmark(ns, marks[4], 1, 0) + curbufmeths.set_extmark(ns, marks[5], 2, 0) + feed([[:1,2s:3:\r]]) + check_undo_redo(ns, marks[1], 0, 1, 0, 1) + check_undo_redo(ns, marks[2], 0, 2, 1, 0) + check_undo_redo(ns, marks[3], 0, 4, 1, 1) + check_undo_redo(ns, marks[4], 1, 0, 2, 0) + check_undo_redo(ns, marks[5], 2, 0, 3, 0) + feed('u') + feed([[:1,2s:3:\rxx]]) + eq({1, 3}, curbufmeths.get_extmark_by_id(ns, marks[3])) + end) + + it('substitions over multiple lines with replace in substition #extmarks_sub', function() + feed('Ax3xx') + curbufmeths.set_extmark(ns, marks[1], 1, 0) + curbufmeths.set_extmark(ns, marks[2], 1, 1) + curbufmeths.set_extmark(ns, marks[3], 1, 2) + feed([[:2,2s:3:\r]]) + check_undo_redo(ns, marks[1], 1, 0, 1, 0) + check_undo_redo(ns, marks[2], 1, 1, 2, 0) + check_undo_redo(ns, marks[3], 1, 2, 2, 0) + end) + + it('substitions over multiple lines with replace in substition #extmarks_sub', function() + feed('Ax3xx') + curbufmeths.set_extmark(ns, marks[1], 0, 1) + curbufmeths.set_extmark(ns, marks[2], 0, 2) + curbufmeths.set_extmark(ns, marks[3], 0, 4) + curbufmeths.set_extmark(ns, marks[4], 1, 1) + curbufmeths.set_extmark(ns, marks[5], 2, 0) + feed([[:1,2s:3:\r]]) + check_undo_redo(ns, marks[1], 0, 1, 0, 1) + check_undo_redo(ns, marks[2], 0, 2, 1, 0) + check_undo_redo(ns, marks[3], 0, 4, 1, 1) + check_undo_redo(ns, marks[4], 1, 1, 3, 0) + check_undo_redo(ns, marks[5], 2, 0, 4, 0) + feed('u') + feed([[:1,2s:3:\rxx]]) + check_undo_redo(ns, marks[3], 0, 4, 1, 3) + end) + + it('substitions with newline in match and sub, delta is 0 #extmarks_sub', function() + feed('A67890xx') + curbufmeths.set_extmark(ns, marks[1], 0, 3) + curbufmeths.set_extmark(ns, marks[2], 0, 4) + curbufmeths.set_extmark(ns, marks[3], 0, 5) + curbufmeths.set_extmark(ns, marks[4], 1, 0) + curbufmeths.set_extmark(ns, marks[5], 1, 5) + curbufmeths.set_extmark(ns, marks[6], 2, 0) + feed([[:1,1s:5\n:\r]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 1, 0) + check_undo_redo(ns, marks[3], 0, 5, 1, 0) + check_undo_redo(ns, marks[4], 1, 0, 1, 0) + check_undo_redo(ns, marks[5], 1, 5, 1, 5) + check_undo_redo(ns, marks[6], 2, 0, 2, 0) + end) + + it('substitions with newline in match and sub, delta > 0 #extmarks_sub', function() + feed('A67890xx') + curbufmeths.set_extmark(ns, marks[1], 0, 3) + curbufmeths.set_extmark(ns, marks[2], 0, 4) + curbufmeths.set_extmark(ns, marks[3], 0, 5) + curbufmeths.set_extmark(ns, marks[4], 1, 0) + curbufmeths.set_extmark(ns, marks[5], 1, 5) + curbufmeths.set_extmark(ns, marks[6], 2, 0) + feed([[:1,1s:5\n:\r\r]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 2, 0) + check_undo_redo(ns, marks[3], 0, 5, 2, 0) + check_undo_redo(ns, marks[4], 1, 0, 2, 0) + check_undo_redo(ns, marks[5], 1, 5, 2, 5) + check_undo_redo(ns, marks[6], 2, 0, 3, 0) + end) + + it('substitions with newline in match and sub, delta < 0 #extmarks_sub', function() + feed('A67890xxxx') + curbufmeths.set_extmark(ns, marks[1], 0, 3) + curbufmeths.set_extmark(ns, marks[2], 0, 4) + curbufmeths.set_extmark(ns, marks[3], 0, 5) + curbufmeths.set_extmark(ns, marks[4], 1, 0) + curbufmeths.set_extmark(ns, marks[5], 1, 5) + curbufmeths.set_extmark(ns, marks[6], 2, 1) + curbufmeths.set_extmark(ns, marks[7], 3, 0) + feed([[:1,2s:5\n.*\n:\r]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 1, 0) + check_undo_redo(ns, marks[3], 0, 5, 1, 0) + check_undo_redo(ns, marks[4], 1, 0, 1, 0) + check_undo_redo(ns, marks[5], 1, 5, 1, 0) + check_undo_redo(ns, marks[6], 2, 1, 1, 1) + check_undo_redo(ns, marks[7], 3, 0, 2, 0) + end) + + it('substitions with backrefs, newline inserted into sub #extmarks_sub', function() + feed('A67890xxxx') + curbufmeths.set_extmark(ns, marks[1], 0, 3) + curbufmeths.set_extmark(ns, marks[2], 0, 4) + curbufmeths.set_extmark(ns, marks[3], 0, 5) + curbufmeths.set_extmark(ns, marks[4], 1, 0) + curbufmeths.set_extmark(ns, marks[5], 1, 5) + curbufmeths.set_extmark(ns, marks[6], 2, 0) + feed([[:1,1s:5\(\n\):\0\1]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 2, 0) + check_undo_redo(ns, marks[3], 0, 5, 2, 0) + check_undo_redo(ns, marks[4], 1, 0, 2, 0) + check_undo_redo(ns, marks[5], 1, 5, 2, 5) + check_undo_redo(ns, marks[6], 2, 0, 3, 0) + end) + + it('substitions a ^ #extmarks_sub', function() + curbufmeths.set_extmark(ns, marks[1], 0, 0) + curbufmeths.set_extmark(ns, marks[2], 0, 1) + feed([[:s:^:x]]) + check_undo_redo(ns, marks[1], 0, 0, 0, 1) + check_undo_redo(ns, marks[2], 0, 1, 0, 2) + end) + + it('using without increase in order of magnitude #extmarks_inc_dec', function() + -- do_addsub in ops.c + feed('ddiabc998xxxTc') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + curbufmeths.set_extmark(ns, marks[3], 0, 5) + curbufmeths.set_extmark(ns, marks[4], 0, 6) + curbufmeths.set_extmark(ns, marks[5], 0, 7) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 6) + check_undo_redo(ns, marks[3], 0, 5, 0, 6) + check_undo_redo(ns, marks[4], 0, 6, 0, 6) + check_undo_redo(ns, marks[5], 0, 7, 0, 7) + end) + + it('using when increase in order of magnitude #extmarks_inc_dec', function() + -- do_addsub in ops.c + feed('ddiabc999xxxTc') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + curbufmeths.set_extmark(ns, marks[3], 0, 5) + curbufmeths.set_extmark(ns, marks[4], 0, 6) + curbufmeths.set_extmark(ns, marks[5], 0, 7) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 7) + check_undo_redo(ns, marks[3], 0, 5, 0, 7) + check_undo_redo(ns, marks[4], 0, 6, 0, 7) + check_undo_redo(ns, marks[5], 0, 7, 0, 8) + end) + + it('using when negative and without decrease in order of magnitude #extmarks_inc_dec', function() + feed('ddiabc-999xxxT-') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + curbufmeths.set_extmark(ns, marks[3], 0, 6) + curbufmeths.set_extmark(ns, marks[4], 0, 7) + curbufmeths.set_extmark(ns, marks[5], 0, 8) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 7) + check_undo_redo(ns, marks[3], 0, 6, 0, 7) + check_undo_redo(ns, marks[4], 0, 7, 0, 7) + check_undo_redo(ns, marks[5], 0, 8, 0, 8) + end) + + it('using when negative and decrease in order of magnitude #extmarks_inc_dec', function() + feed('ddiabc-1000xxxT-') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + curbufmeths.set_extmark(ns, marks[3], 0, 7) + curbufmeths.set_extmark(ns, marks[4], 0, 8) + curbufmeths.set_extmark(ns, marks[5], 0, 9) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 7) + check_undo_redo(ns, marks[3], 0, 7, 0, 7) + check_undo_redo(ns, marks[4], 0, 8, 0, 7) + check_undo_redo(ns, marks[5], 0, 9, 0, 8) + end) + + it('using without decrease in order of magnitude #extmarks_inc_dec', function() + -- do_addsub in ops.c + feed('ddiabc999xxxTc') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + curbufmeths.set_extmark(ns, marks[3], 0, 5) + curbufmeths.set_extmark(ns, marks[4], 0, 6) + curbufmeths.set_extmark(ns, marks[5], 0, 7) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 6) + check_undo_redo(ns, marks[3], 0, 5, 0, 6) + check_undo_redo(ns, marks[4], 0, 6, 0, 6) + check_undo_redo(ns, marks[5], 0, 7, 0, 7) + end) + + it('using when decrease in order of magnitude #extmarks_inc_dec', function() + -- do_addsub in ops.c + feed('ddiabc1000xxxTc') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + curbufmeths.set_extmark(ns, marks[3], 0, 6) + curbufmeths.set_extmark(ns, marks[4], 0, 7) + curbufmeths.set_extmark(ns, marks[5], 0, 8) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 6) + check_undo_redo(ns, marks[3], 0, 6, 0, 6) + check_undo_redo(ns, marks[4], 0, 7, 0, 6) + check_undo_redo(ns, marks[5], 0, 8, 0, 7) + end) + + it('using when negative and without increase in order of magnitude #extmarks_inc_dec', function() + feed('ddiabc-998xxxT-') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + curbufmeths.set_extmark(ns, marks[3], 0, 6) + curbufmeths.set_extmark(ns, marks[4], 0, 7) + curbufmeths.set_extmark(ns, marks[5], 0, 8) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 7) + check_undo_redo(ns, marks[3], 0, 6, 0, 7) + check_undo_redo(ns, marks[4], 0, 7, 0, 7) + check_undo_redo(ns, marks[5], 0, 8, 0, 8) + end) + + it('using when negative and increase in order of magnitude #extmarks_inc_dec', function() + feed('ddiabc-999xxxT-') + curbufmeths.set_extmark(ns, marks[1], 0, 2) + curbufmeths.set_extmark(ns, marks[2], 0, 3) + curbufmeths.set_extmark(ns, marks[3], 0, 6) + curbufmeths.set_extmark(ns, marks[4], 0, 7) + curbufmeths.set_extmark(ns, marks[5], 0, 8) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 8) + check_undo_redo(ns, marks[3], 0, 6, 0, 8) + check_undo_redo(ns, marks[4], 0, 7, 0, 8) + check_undo_redo(ns, marks[5], 0, 8, 0, 9) + end) + + -- TODO catch exceptions + pending('throws consistent error codes #todo', function() + local ns_invalid = ns2 + 1 + rv = curbufmeths.set_extmark(ns_invalid, marks[1], positions[1][1], positions[1][2]) + rv = curbufmeths.del_extmark(ns_invalid, marks[1]) + rv = curbufmeths.get_extmarks(ns_invalid, positions[1], positions[2], ALL) + rv = curbufmeths.get_extmark_by_id(ns_invalid, marks[1]) + + end) + + it('when col = line-length, set the mark on eol #extmarks', function() + curbufmeths.set_extmark(ns, marks[1], 0, -1) + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({0, init_text:len()}, rv) + -- Test another + curbufmeths.set_extmark(ns, marks[1], 0, -1) + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({0, init_text:len()}, rv) + end) + + it('when col = line-length, set the mark on eol #extmarks', function() + local invalid_col = init_text:len() + 1 + eq({false, "col value outside range"}, meth_pcall(curbufmeths.set_extmark, ns, marks[1], 0, invalid_col)) + end) + + -- TODO(bfredl): decide what to do with this + pending('when line > line, set the mark on end of buffer #extmarks', function() + local invalid_col = init_text:len() + 1 + local invalid_lnum = 3 -- line1 ends in an eol. so line 2 contains a valid position (eol)? + curbufmeths.set_extmark(ns, marks[1], invalid_lnum, invalid_col) + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({2, 1}, rv) + end) + + it('bug from check_col in extmark_set #extmarks_sub', function() + -- This bug was caused by extmark_set always using + -- check_col. check_col always uses the current buffer. + -- This wasn't working during undo so we now use + -- check_col and check_lnum only when they are required. + feed('A67890xx') + feed('A1234567890xx') + curbufmeths.set_extmark(ns, marks[1], 3, 4) + feed([[:1,5s:5\n:5 ]]) + check_undo_redo(ns, marks[1], 3, 4, 2, 6) + end) + +end) + +describe('Extmarks buffer api with many marks', function() + local ns1 + local ns2 + local ns_marks = {} + before_each(function() + clear() + ns1 = request('nvim_create_namespace', "ns1") + ns2 = request('nvim_create_namespace', "ns2") + ns_marks = {[ns1]={}, [ns2]={}} + local lines = {} + for i = 1,30 do + lines[#lines+1] = string.rep("x ",i) + end + curbufmeths.set_lines(0, -1, true, lines) + local ns = ns1 + local q = 0 + for i = 0,29 do + for j = 0,i do + local id = curbufmeths.set_extmark(ns,0, i,j) + eq(nil, ns_marks[ns][id]) + ok(id > 0) + ns_marks[ns][id] = {i,j} + ns = ns1+ns2-ns + q = q + 1 + end + end + eq(233, #ns_marks[ns1]) + eq(232, #ns_marks[ns2]) + + end) + + local function get_marks(ns) + local mark_list = curbufmeths.get_extmarks(ns, 0, -1, -1) + local marks = {} + for _, mark in ipairs(mark_list) do + local id, row, col = unpack(mark) + eq(nil, marks[id], "duplicate mark") + marks[id] = {row,col} + end + return marks + end + + it("can get marks #extmarks", function() + eq(ns_marks[ns1], get_marks(ns1)) + eq(ns_marks[ns2], get_marks(ns2)) + end) + + it("can clear all marks in ns #extmarks", function() + curbufmeths.clear_namespace(ns1, 0, -1) + eq({}, get_marks(ns1)) + eq(ns_marks[ns2], get_marks(ns2)) + curbufmeths.clear_namespace(ns2, 0, -1) + eq({}, get_marks(ns1)) + eq({}, get_marks(ns2)) + end) + + it("can clear line range #extmarks", function() + curbufmeths.clear_namespace(ns1, 10, 20) + for id, mark in pairs(ns_marks[ns1]) do + if 10 <= mark[1] and mark[1] < 20 then + ns_marks[ns1][id] = nil + end + end + eq(ns_marks[ns1], get_marks(ns1)) + eq(ns_marks[ns2], get_marks(ns2)) + end) + + it("can delete line #extmarks", function() + feed('10Gdd') + for _, marks in pairs(ns_marks) do + for id, mark in pairs(marks) do + if mark[1] == 9 then + marks[id] = {9,0} + elseif mark[1] >= 10 then + mark[1] = mark[1] - 1 + end + end + end + eq(ns_marks[ns1], get_marks(ns1)) + eq(ns_marks[ns2], get_marks(ns2)) + end) + + it("can delete lines #extmarks", function() + feed('10G10dd') + for _, marks in pairs(ns_marks) do + for id, mark in pairs(marks) do + if 9 <= mark[1] and mark[1] < 19 then + marks[id] = {9,0} + elseif mark[1] >= 19 then + mark[1] = mark[1] - 10 + end + end + end + eq(ns_marks[ns1], get_marks(ns1)) + eq(ns_marks[ns2], get_marks(ns2)) + end) +end) -- cgit From 18a8b702c0ce7a8bacd84f6c95e440ae23a3299e Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 9 Nov 2019 12:41:50 +0100 Subject: extmark: review changes --- test/functional/api/mark_extended_spec.lua | 624 +++++++++++++++-------------- 1 file changed, 314 insertions(+), 310 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua index 6bf0e59133..a5d68c6b9f 100644 --- a/test/functional/api/mark_extended_spec.lua +++ b/test/functional/api/mark_extended_spec.lua @@ -1,7 +1,3 @@ --- TODO(timeyyy): go through todo's lol --- change representation of stored marks to have location start at 0 --- check with memsan, asan etc - local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') @@ -9,17 +5,14 @@ local request = helpers.request local eq = helpers.eq local ok = helpers.ok local curbufmeths = helpers.curbufmeths -local meth_pcall = helpers.meth_pcall +local pcall_err = helpers.pcall_err local insert = helpers.insert local feed = helpers.feed local clear = helpers.clear - -local ALL = -1 - -local rv = nil +local command = helpers.command local function check_undo_redo(ns, mark, sr, sc, er, ec) --s = start, e = end - rv = curbufmeths.get_extmark_by_id(ns, mark) + local rv = curbufmeths.get_extmark_by_id(ns, mark) eq({er, ec}, rv) feed("u") rv = curbufmeths.get_extmark_by_id(ns, mark) @@ -29,6 +22,20 @@ local function check_undo_redo(ns, mark, sr, sc, er, ec) --s = start, e = end eq({er, ec}, rv) end +local function set_extmark(ns_id, id, line, col, opts) + if opts == nil then + opts = {} + end + return curbufmeths.set_extmark(ns_id, id, line, col, opts) +end + +local function get_extmarks(ns_id, start, end_, opts) + if opts == nil then + opts = {} + end + return curbufmeths.get_extmarks(ns_id, start, end_, opts) +end + describe('Extmarks buffer api', function() local screen local marks, positions, ns_string2, ns_string, init_text, row, col @@ -55,24 +62,24 @@ describe('Extmarks buffer api', function() end) it('adds, updates and deletes marks #extmarks', function() - rv = curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + local rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) eq(marks[1], rv) rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({positions[1][1], positions[1][2]}, rv) -- Test adding a second mark on same row works - rv = curbufmeths.set_extmark(ns, marks[2], positions[2][1], positions[2][2]) + rv = set_extmark(ns, marks[2], positions[2][1], positions[2][2]) eq(marks[2], rv) -- Test an update, (same pos) - rv = curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - eq(0, rv) + rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + eq(marks[1], rv) rv = curbufmeths.get_extmark_by_id(ns, marks[2]) eq({positions[2][1], positions[2][2]}, rv) -- Test an update, (new pos) row = positions[1][1] col = positions[1][2] + 1 - rv = curbufmeths.set_extmark(ns, marks[1], row, col) - eq(0, rv) + rv = set_extmark(ns, marks[1], row, col) + eq(marks[1], rv) rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({row, col}, rv) @@ -85,50 +92,50 @@ describe('Extmarks buffer api', function() end) it('can clear a specific namespace range #extmarks', function() - curbufmeths.set_extmark(ns, 1, 0, 1) - curbufmeths.set_extmark(ns2, 1, 0, 1) + set_extmark(ns, 1, 0, 1) + set_extmark(ns2, 1, 0, 1) -- force a new undo buffer feed('o') curbufmeths.clear_namespace(ns2, 0, -1) - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('u') - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({{1, 0, 1}}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('') - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) end) - it('can clear a namespace range using ALL #extmarks', function() - curbufmeths.set_extmark(ns, 1, 0, 1) - curbufmeths.set_extmark(ns2, 1, 0, 1) + it('can clear a namespace range using 0,-1 #extmarks', function() + set_extmark(ns, 1, 0, 1) + set_extmark(ns2, 1, 0, 1) -- force a new undo buffer feed('o') curbufmeths.clear_namespace(-1, 0, -1) - eq({}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('u') - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({{1, 0, 1}}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('') - eq({}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) end) it('querying for information and ranges #extmarks', function() -- add some more marks for i, m in ipairs(marks) do if positions[i] ~= nil then - rv = curbufmeths.set_extmark(ns, m, positions[i][1], positions[i][2]) + local rv = set_extmark(ns, m, positions[i][1], positions[i][2]) eq(m, rv) end end -- {0, 0} and {-1, -1} work as extreme values - eq({{1, 0, 0}}, curbufmeths.get_extmarks(ns, {0, 0}, {0, 0}, ALL)) - eq({}, curbufmeths.get_extmarks(ns, {-1, -1}, {-1, -1}, ALL)) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + eq({{1, 0, 0}}, get_extmarks(ns, {0, 0}, {0, 0})) + eq({}, get_extmarks(ns, {-1, -1}, {-1, -1})) + local rv = get_extmarks(ns, {0, 0}, {-1, -1}) for i, m in ipairs(marks) do if positions[i] ~= nil then eq({m, positions[i][1], positions[i][2]}, rv[i]) @@ -136,9 +143,9 @@ describe('Extmarks buffer api', function() end -- 0 and -1 works as short hand extreme values - eq({{1, 0, 0}}, curbufmeths.get_extmarks(ns, 0, 0, ALL)) - eq({}, curbufmeths.get_extmarks(ns, -1, -1, ALL)) - rv = curbufmeths.get_extmarks(ns, 0, -1, ALL) + eq({{1, 0, 0}}, get_extmarks(ns, 0, 0)) + eq({}, get_extmarks(ns, -1, -1)) + rv = get_extmarks(ns, 0, -1) for i, m in ipairs(marks) do if positions[i] ~= nil then eq({m, positions[i][1], positions[i][2]}, rv[i]) @@ -146,91 +153,91 @@ describe('Extmarks buffer api', function() end -- next with mark id - rv = curbufmeths.get_extmarks(ns, marks[1], {-1, -1}, 1) + rv = get_extmarks(ns, marks[1], {-1, -1}, {amount=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) - rv = curbufmeths.get_extmarks(ns, marks[2], {-1, -1}, 1) + rv = get_extmarks(ns, marks[2], {-1, -1}, {amount=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- next with positional when mark exists at position - rv = curbufmeths.get_extmarks(ns, positions[1], {-1, -1}, 1) + rv = get_extmarks(ns, positions[1], {-1, -1}, {amount=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- next with positional index (no mark at position) - rv = curbufmeths.get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, 1) + rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, {amount=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- next with Extremity index - rv = curbufmeths.get_extmarks(ns, {0,0}, {-1, -1}, 1) + rv = get_extmarks(ns, {0,0}, {-1, -1}, {amount=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- nextrange with mark id - rv = curbufmeths.get_extmarks(ns, marks[1], marks[3], ALL) + rv = get_extmarks(ns, marks[1], marks[3]) eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) -- nextrange with amount - rv = curbufmeths.get_extmarks(ns, marks[1], marks[3], 2) + rv = get_extmarks(ns, marks[1], marks[3], {amount=2}) eq(2, table.getn(rv)) -- nextrange with positional when mark exists at position - rv = curbufmeths.get_extmarks(ns, positions[1], positions[3], ALL) + rv = get_extmarks(ns, positions[1], positions[3]) eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) - rv = curbufmeths.get_extmarks(ns, positions[2], positions[3], ALL) + rv = get_extmarks(ns, positions[2], positions[3]) eq(2, table.getn(rv)) -- nextrange with positional index (no mark at position) local lower = {positions[1][1], positions[2][2] -1} local upper = {positions[2][1], positions[3][2] - 1} - rv = curbufmeths.get_extmarks(ns, lower, upper, ALL) + rv = get_extmarks(ns, lower, upper) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) lower = {positions[3][1], positions[3][2] + 1} upper = {positions[3][1], positions[3][2] + 2} - rv = curbufmeths.get_extmarks(ns, lower, upper, ALL) + rv = get_extmarks(ns, lower, upper) eq({}, rv) -- nextrange with extremity index lower = {positions[2][1], positions[2][2]+1} upper = {-1, -1} - rv = curbufmeths.get_extmarks(ns, lower, upper, ALL) + rv = get_extmarks(ns, lower, upper) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prev with mark id - rv = curbufmeths.get_extmarks(ns, marks[3], {0, 0}, 1) + rv = get_extmarks(ns, marks[3], {0, 0}, {amount=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) - rv = curbufmeths.get_extmarks(ns, marks[2], {0, 0}, 1) + rv = get_extmarks(ns, marks[2], {0, 0}, {amount=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- prev with positional when mark exists at position - rv = curbufmeths.get_extmarks(ns, positions[3], {0, 0}, 1) + rv = get_extmarks(ns, positions[3], {0, 0}, {amount=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prev with positional index (no mark at position) - rv = curbufmeths.get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, 1) + rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, {amount=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- prev with Extremity index - rv = curbufmeths.get_extmarks(ns, {-1,-1}, {0,0}, 1) + rv = get_extmarks(ns, {-1,-1}, {0,0}, {amount=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prevrange with mark id - rv = curbufmeths.get_extmarks(ns, marks[3], marks[1], ALL) + rv = get_extmarks(ns, marks[3], marks[1]) eq({marks[3], positions[3][1], positions[3][2]}, rv[1]) eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) eq({marks[1], positions[1][1], positions[1][2]}, rv[3]) -- prevrange with amount - rv = curbufmeths.get_extmarks(ns, marks[3], marks[1], 2) + rv = get_extmarks(ns, marks[3], marks[1], {amount=2}) eq(2, table.getn(rv)) -- prevrange with positional when mark exists at position - rv = curbufmeths.get_extmarks(ns, positions[3], positions[1], ALL) + rv = get_extmarks(ns, positions[3], positions[1]) eq({{marks[3], positions[3][1], positions[3][2]}, {marks[2], positions[2][1], positions[2][2]}, {marks[1], positions[1][1], positions[1][2]}}, rv) - rv = curbufmeths.get_extmarks(ns, positions[2], positions[1], ALL) + rv = get_extmarks(ns, positions[2], positions[1]) eq(2, table.getn(rv)) -- prevrange with positional index (no mark at position) lower = {positions[2][1], positions[2][2] + 1} upper = {positions[3][1], positions[3][2] + 1} - rv = curbufmeths.get_extmarks(ns, upper, lower, ALL) + rv = get_extmarks(ns, upper, lower) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) lower = {positions[3][1], positions[3][2] + 1} upper = {positions[3][1], positions[3][2] + 2} - rv = curbufmeths.get_extmarks(ns, upper, lower, ALL) + rv = get_extmarks(ns, upper, lower) eq({}, rv) -- prevrange with extremity index lower = {0,0} upper = {positions[2][1], positions[2][2] - 1} - rv = curbufmeths.get_extmarks(ns, upper, lower, ALL) + rv = get_extmarks(ns, upper, lower) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) end) @@ -238,50 +245,50 @@ describe('Extmarks buffer api', function() -- add some more marks for i, m in ipairs(marks) do if positions[i] ~= nil then - rv = curbufmeths.set_extmark(ns, m, positions[i][1], positions[i][2]) + local rv = set_extmark(ns, m, positions[i][1], positions[i][2]) eq(m, rv) end end - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 1) + local rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=1}) eq(1, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 2) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=2}) eq(2, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 3) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=3}) eq(3, table.getn(rv)) -- now in reverse - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 1) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=1}) eq(1, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 2) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=2}) eq(2, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 3) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=3}) eq(3, table.getn(rv)) end) it('get_marks works when mark col > upper col #extmarks', function() feed('A12345') feed('A12345') - curbufmeths.set_extmark(ns, 10, 0, 2) -- this shouldn't be found - curbufmeths.set_extmark(ns, 11, 2, 1) -- this shouldn't be found - curbufmeths.set_extmark(ns, marks[1], 0, 4) -- check col > our upper bound - curbufmeths.set_extmark(ns, marks[2], 1, 1) -- check col < lower bound - curbufmeths.set_extmark(ns, marks[3], 2, 0) -- check is inclusive + set_extmark(ns, 10, 0, 2) -- this shouldn't be found + set_extmark(ns, 11, 2, 1) -- this shouldn't be found + set_extmark(ns, marks[1], 0, 4) -- check col > our upper bound + set_extmark(ns, marks[2], 1, 1) -- check col < lower bound + set_extmark(ns, marks[3], 2, 0) -- check is inclusive eq({{marks[1], 0, 4}, {marks[2], 1, 1}, {marks[3], 2, 0}}, - curbufmeths.get_extmarks(ns, {0, 3}, {2, 0}, -1)) + get_extmarks(ns, {0, 3}, {2, 0})) end) it('get_marks works in reverse when mark col < lower col #extmarks', function() feed('A12345') feed('A12345') - curbufmeths.set_extmark(ns, 10, 0, 1) -- this shouldn't be found - curbufmeths.set_extmark(ns, 11, 2, 4) -- this shouldn't be found - curbufmeths.set_extmark(ns, marks[1], 2, 1) -- check col < our lower bound - curbufmeths.set_extmark(ns, marks[2], 1, 4) -- check col > upper bound - curbufmeths.set_extmark(ns, marks[3], 0, 2) -- check is inclusive - rv = curbufmeths.get_extmarks(ns, {2, 3}, {0, 2}, -1) + set_extmark(ns, 10, 0, 1) -- this shouldn't be found + set_extmark(ns, 11, 2, 4) -- this shouldn't be found + set_extmark(ns, marks[1], 2, 1) -- check col < our lower bound + set_extmark(ns, marks[2], 1, 4) -- check col > upper bound + set_extmark(ns, marks[3], 0, 2) -- check is inclusive + local rv = get_extmarks(ns, {2, 3}, {0, 2}) eq({{marks[1], 2, 1}, {marks[2], 1, 4}, {marks[3], 0, 2}}, @@ -289,21 +296,21 @@ describe('Extmarks buffer api', function() end) it('get_marks amount 0 returns nothing #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - rv = curbufmeths.get_extmarks(ns, {-1, -1}, {-1, -1}, 0) + set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + local rv = get_extmarks(ns, {-1, -1}, {-1, -1}, {amount=0}) eq({}, rv) end) it('marks move with line insertations #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, 0) + set_extmark(ns, marks[1], 0, 0) feed("yyP") check_undo_redo(ns, marks[1], 0, 0, 1, 0) end) it('marks move with multiline insertations #extmarks', function() feed("a2233") - curbufmeths.set_extmark(ns, marks[1], 1, 1) + set_extmark(ns, marks[1], 1, 1) feed('ggVGyP') check_undo_redo(ns, marks[1], 1, 1, 4, 1) end) @@ -311,7 +318,7 @@ describe('Extmarks buffer api', function() it('marks move with line join #extmarks', function() -- do_join in ops.c feed("a222") - curbufmeths.set_extmark(ns, marks[1], 1, 0) + set_extmark(ns, marks[1], 1, 0) feed('ggJ') check_undo_redo(ns, marks[1], 1, 0, 0, 6) end) @@ -337,21 +344,21 @@ describe('Extmarks buffer api', function() it('marks move with multiline join #extmarks', function() -- do_join in ops.c feed("a222333444") - curbufmeths.set_extmark(ns, marks[1], 3, 0) + set_extmark(ns, marks[1], 3, 0) feed('2GVGJ') check_undo_redo(ns, marks[1], 3, 0, 1, 8) end) it('marks move with line deletes #extmarks', function() feed("a222333444") - curbufmeths.set_extmark(ns, marks[1], 2, 1) + set_extmark(ns, marks[1], 2, 1) feed('ggjdd') check_undo_redo(ns, marks[1], 2, 1, 1, 1) end) it('marks move with multiline deletes #extmarks', function() feed("a222333444") - curbufmeths.set_extmark(ns, marks[1], 3, 0) + set_extmark(ns, marks[1], 3, 0) feed('gg2dd') check_undo_redo(ns, marks[1], 3, 0, 1, 0) -- regression test, undoing multiline delete when mark is on row 1 @@ -363,8 +370,8 @@ describe('Extmarks buffer api', function() -- open_line in misc1.c -- testing marks below are also moved feed("yyP") - curbufmeths.set_extmark(ns, marks[1], 0, 4) - curbufmeths.set_extmark(ns, marks[2], 1, 4) + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 1, 4) feed('1G') check_undo_redo(ns, marks[1], 0, 4, 1, 4) check_undo_redo(ns, marks[2], 1, 4, 2, 4) @@ -373,10 +380,9 @@ describe('Extmarks buffer api', function() check_undo_redo(ns, marks[2], 2, 4, 3, 4) end) - -- NO idea why this doesn't work... works in program. - pending('marks move with char inserts #extmarks', function() + it('marks move with char inserts #extmarks', function() -- insertchar in edit.c (the ins_str branch) - curbufmeths.set_extmark(ns, marks[1], 1, 3) + set_extmark(ns, marks[1], 0, 3) feed('0') insert('abc') screen:expect([[ @@ -391,16 +397,15 @@ describe('Extmarks buffer api', function() ~ | | ]]) - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq(1, rv[2]) - eq(6, rv[3]) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({0, 6}, rv) -- check_undo_redo(ns, marks[1], 0, 2, 0, 5) end) -- gravity right as definted in tk library it('marks have gravity right #extmarks', function() -- insertchar in edit.c (the ins_str branch) - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('03l') insert("X") check_undo_redo(ns, marks[1], 0, 2, 0, 2) @@ -414,7 +419,7 @@ describe('Extmarks buffer api', function() it('we can insert multibyte chars #extmarks', function() -- insertchar in edit.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 2) + set_extmark(ns, marks[1], 1, 2) -- Insert a fullwidth (two col) tilde, NICE feed('0i~') check_undo_redo(ns, marks[1], 1, 2, 1, 3) @@ -423,7 +428,7 @@ describe('Extmarks buffer api', function() it('marks move with blockwise inserts #extmarks', function() -- op_insert in ops.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 2) + set_extmark(ns, marks[1], 1, 2) feed('0lkI9') check_undo_redo(ns, marks[1], 1, 2, 1, 3) end) @@ -432,18 +437,16 @@ describe('Extmarks buffer api', function() -- open_line in misc1.c -- testing marks below are also moved feed("yyP") - curbufmeths.set_extmark(ns, marks[1], 0, 4) - curbufmeths.set_extmark(ns, marks[2], 1, 4) + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 1, 4) feed('1Gla') check_undo_redo(ns, marks[1], 0, 4, 1, 2) check_undo_redo(ns, marks[2], 1, 4, 2, 4) end) - -- TODO mark_col_adjust for normal marks fails in vim/neovim - -- because flags is 9 in: if (flags & OPENLINE_MARKFIX) { it('marks at last line move on insert new line #extmarks', function() -- open_line in misc1.c - curbufmeths.set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[1], 0, 4) feed('0i') check_undo_redo(ns, marks[1], 0, 4, 1, 4) end) @@ -451,22 +454,22 @@ describe('Extmarks buffer api', function() it('yet again marks move with line splits #extmarks', function() -- the first test above wasn't catching all errors.. feed("A67890") - curbufmeths.set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[1], 0, 4) feed("04li") check_undo_redo(ns, marks[1], 0, 4, 1, 0) end) it('and one last time line splits... #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, 1) - curbufmeths.set_extmark(ns, marks[2], 0, 2) + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 2) feed("02li") check_undo_redo(ns, marks[1], 0, 1, 0, 1) check_undo_redo(ns, marks[2], 0, 2, 1, 0) end) it('multiple marks move with mark splits #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, 1) - curbufmeths.set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 3) feed("0li") check_undo_redo(ns, marks[1], 0, 1, 1, 0) check_undo_redo(ns, marks[2], 0, 3, 1, 2) @@ -474,14 +477,14 @@ describe('Extmarks buffer api', function() it('deleting on a mark works #extmarks', function() -- op_delete in ops.c - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('02lx') check_undo_redo(ns, marks[1], 0, 2, 0, 2) end) it('marks move with char deletes #extmarks', function() -- op_delete in ops.c - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('02dl') check_undo_redo(ns, marks[1], 0, 2, 0, 0) -- from the other side (nothing should happen) @@ -491,21 +494,20 @@ describe('Extmarks buffer api', function() it('marks move with char deletes over a range #extmarks', function() -- op_delete in ops.c - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) feed('0l3dl') check_undo_redo(ns, marks[1], 0, 2, 0, 1) check_undo_redo(ns, marks[2], 0, 3, 0, 1) -- delete 1, nothing should happend to our marks feed('u') feed('$x') - -- TODO do we need to test marks[1] ??? check_undo_redo(ns, marks[2], 0, 3, 0, 3) end) it('deleting marks at end of line works #extmarks', function() -- mark_extended.c/extmark_col_adjust_delete - curbufmeths.set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[1], 0, 4) feed('$x') check_undo_redo(ns, marks[1], 0, 4, 0, 4) -- check the copy happened correctly on delete at eol @@ -518,7 +520,7 @@ describe('Extmarks buffer api', function() it('marks move with blockwise deletes #extmarks', function() -- op_delete in ops.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 4) + set_extmark(ns, marks[1], 1, 4) feed('hhhkd') check_undo_redo(ns, marks[1], 1, 4, 1, 1) end) @@ -526,9 +528,9 @@ describe('Extmarks buffer api', function() it('marks move with blockwise deletes over a range #extmarks', function() -- op_delete in ops.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 0, 1) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 1, 2) + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 1, 2) feed('0k3lx') check_undo_redo(ns, marks[1], 0, 1, 0, 0) check_undo_redo(ns, marks[2], 0, 3, 0, 0) @@ -536,14 +538,13 @@ describe('Extmarks buffer api', function() -- delete 1, nothing should happend to our marks feed('u') feed('$jx') - -- TODO do we need to test marks[1] ??? check_undo_redo(ns, marks[2], 0, 3, 0, 3) check_undo_redo(ns, marks[3], 1, 2, 1, 2) end) it('works with char deletes over multilines #extmarks', function() feed('a12345test-me') - curbufmeths.set_extmark(ns, marks[1], 2, 5) + set_extmark(ns, marks[1], 2, 5) feed('gg') feed('dv?-m?') check_undo_redo(ns, marks[1], 2, 5, 0, 0) @@ -551,7 +552,7 @@ describe('Extmarks buffer api', function() it('marks outside of deleted range move with visual char deletes #extmarks', function() -- op_delete in ops.c - curbufmeths.set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[1], 0, 3) feed('0vx') check_undo_redo(ns, marks[1], 0, 3, 0, 2) @@ -570,7 +571,7 @@ describe('Extmarks buffer api', function() it('marks outside of deleted range move with char deletes #extmarks', function() -- op_delete in ops.c - curbufmeths.set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[1], 0, 3) feed('0x') check_undo_redo(ns, marks[1], 0, 3, 0, 2) @@ -591,7 +592,7 @@ describe('Extmarks buffer api', function() it('marks move with P(backward) paste #extmarks', function() -- do_put in ops.c feed('0iabc') - curbufmeths.set_extmark(ns, marks[1], 0, 7) + set_extmark(ns, marks[1], 0, 7) feed('0veyP') check_undo_redo(ns, marks[1], 0, 7, 0, 15) end) @@ -599,7 +600,7 @@ describe('Extmarks buffer api', function() it('marks move with p(forward) paste #extmarks', function() -- do_put in ops.c feed('0iabc') - curbufmeths.set_extmark(ns, marks[1], 0, 7) + set_extmark(ns, marks[1], 0, 7) feed('0veyp') check_undo_redo(ns, marks[1], 0, 7, 0, 14) end) @@ -607,7 +608,7 @@ describe('Extmarks buffer api', function() it('marks move with blockwise P(backward) paste #extmarks', function() -- do_put in ops.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 4) + set_extmark(ns, marks[1], 1, 4) feed('hhkyP') check_undo_redo(ns, marks[1], 1, 4, 1, 7) end) @@ -615,20 +616,20 @@ describe('Extmarks buffer api', function() it('marks move with blockwise p(forward) paste #extmarks', function() -- do_put in ops.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 4) + set_extmark(ns, marks[1], 1, 4) feed('hhkyp') check_undo_redo(ns, marks[1], 1, 4, 1, 6) end) it('replace works #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('0r2') check_undo_redo(ns, marks[1], 0, 2, 0, 2) end) it('blockwise replace works #extmarks', function() feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('0llkr1') check_undo_redo(ns, marks[1], 0, 2, 0, 2) end) @@ -636,7 +637,7 @@ describe('Extmarks buffer api', function() it('shift line #extmarks', function() -- shift_line in ops.c feed(':set shiftwidth=4') - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('0>>') check_undo_redo(ns, marks[1], 0, 2, 0, 6) @@ -651,7 +652,7 @@ describe('Extmarks buffer api', function() -- shift_block in ops.c feed(':set shiftwidth=4') feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 2) + set_extmark(ns, marks[1], 1, 2) feed('0k>') check_undo_redo(ns, marks[1], 1, 2, 1, 6) feed('j>') @@ -665,7 +666,7 @@ describe('Extmarks buffer api', function() -- ins_tab in edit.c feed(':set expandtab') feed(':set shiftwidth=2') - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('0i') check_undo_redo(ns, marks[1], 0, 2, 0, 6) end) @@ -676,7 +677,7 @@ describe('Extmarks buffer api', function() feed(':set shiftwidth=2') feed(':set softtabstop=2') feed(':set tabstop=8') - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('0i') check_undo_redo(ns, marks[1], 0, 2, 0, 4) feed('0iX') @@ -684,7 +685,7 @@ describe('Extmarks buffer api', function() end) it('marks move when using :move #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, 0) + set_extmark(ns, marks[1], 0, 0) feed('A2:1move 2') check_undo_redo(ns, marks[1], 0, 0, 1, 0) -- test codepath when moving lines up @@ -695,7 +696,7 @@ describe('Extmarks buffer api', function() it('marks move when using :move part 2 #extmarks', function() -- make sure we didn't get lucky with the math... feed('A23456') - curbufmeths.set_extmark(ns, marks[1], 1, 0) + set_extmark(ns, marks[1], 1, 0) feed(':2,3move 5') check_undo_redo(ns, marks[1], 1, 0, 3, 0) -- test codepath when moving lines up @@ -706,23 +707,24 @@ describe('Extmarks buffer api', function() it('undo and redo of set and unset marks #extmarks', function() -- Force a new undo head feed('o') - curbufmeths.set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[1], 0, 1) feed('o') - curbufmeths.set_extmark(ns, marks[2], 0, -1) - curbufmeths.set_extmark(ns, marks[3], 0, -1) + set_extmark(ns, marks[2], 0, -1) + set_extmark(ns, marks[3], 0, -1) feed("u") - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + local rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(1, table.getn(rv)) feed("") - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(3, table.getn(rv)) -- Test updates feed('o') - curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - rv = curbufmeths.get_extmarks(ns, marks[1], marks[1], 1) + set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + rv = get_extmarks(ns, marks[1], marks[1], {amount=1}) + eq(1, table.getn(rv)) feed("u") feed("") check_undo_redo(ns, marks[1], 0, 1, positions[1][1], positions[1][2]) @@ -731,80 +733,80 @@ describe('Extmarks buffer api', function() feed('o') curbufmeths.del_extmark(ns, marks[3]) feed("u") - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(3, table.getn(rv)) feed("") - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(2, table.getn(rv)) end) it('undo and redo of marks deleted during edits #extmarks', function() -- test extmark_adjust feed('A12345') - curbufmeths.set_extmark(ns, marks[1], 1, 2) + set_extmark(ns, marks[1], 1, 2) feed('dd') check_undo_redo(ns, marks[1], 1, 2, 1, 0) end) it('namespaces work properly #extmarks', function() - rv = curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + local rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) eq(1, rv) - rv = curbufmeths.set_extmark(ns2, marks[1], positions[1][1], positions[1][2]) + rv = set_extmark(ns2, marks[1], positions[1][1], positions[1][2]) eq(1, rv) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(1, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns2, {0, 0}, {-1, -1}) eq(1, table.getn(rv)) -- Set more marks for testing the ranges - rv = curbufmeths.set_extmark(ns, marks[2], positions[2][1], positions[2][2]) - rv = curbufmeths.set_extmark(ns, marks[3], positions[3][1], positions[3][2]) - rv = curbufmeths.set_extmark(ns2, marks[2], positions[2][1], positions[2][2]) - rv = curbufmeths.set_extmark(ns2, marks[3], positions[3][1], positions[3][2]) + set_extmark(ns, marks[2], positions[2][1], positions[2][2]) + set_extmark(ns, marks[3], positions[3][1], positions[3][2]) + set_extmark(ns2, marks[2], positions[2][1], positions[2][2]) + set_extmark(ns2, marks[3], positions[3][1], positions[3][2]) -- get_next (amount set) - rv = curbufmeths.get_extmarks(ns, {0, 0}, positions[2], 1) + rv = get_extmarks(ns, {0, 0}, positions[2], {amount=1}) eq(1, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns2, {0, 0}, positions[2], 1) + rv = get_extmarks(ns2, {0, 0}, positions[2], {amount=1}) eq(1, table.getn(rv)) -- get_prev (amount set) - rv = curbufmeths.get_extmarks(ns, positions[1], {0, 0}, 1) + rv = get_extmarks(ns, positions[1], {0, 0}, {amount=1}) eq(1, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns2, positions[1], {0, 0}, 1) + rv = get_extmarks(ns2, positions[1], {0, 0}, {amount=1}) eq(1, table.getn(rv)) -- get_next (amount not set) - rv = curbufmeths.get_extmarks(ns, positions[1], positions[2], ALL) + rv = get_extmarks(ns, positions[1], positions[2]) eq(2, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns2, positions[1], positions[2], ALL) + rv = get_extmarks(ns2, positions[1], positions[2]) eq(2, table.getn(rv)) -- get_prev (amount not set) - rv = curbufmeths.get_extmarks(ns, positions[2], positions[1], ALL) + rv = get_extmarks(ns, positions[2], positions[1]) eq(2, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns2, positions[2], positions[1], ALL) + rv = get_extmarks(ns2, positions[2], positions[1]) eq(2, table.getn(rv)) curbufmeths.del_extmark(ns, marks[1]) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(2, table.getn(rv)) curbufmeths.del_extmark(ns2, marks[1]) - rv = curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns2, {0, 0}, {-1, -1}) eq(2, table.getn(rv)) end) it('mark set can create unique identifiers #extmarks', function() -- create mark with id 1 - eq(1, curbufmeths.set_extmark(ns, 1, positions[1][1], positions[1][2])) + eq(1, set_extmark(ns, 1, positions[1][1], positions[1][2])) -- ask for unique id, it should be the next one, i e 2 - eq(2, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) - eq(3, curbufmeths.set_extmark(ns, 3, positions[2][1], positions[2][2])) - eq(4, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(2, set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(3, set_extmark(ns, 3, positions[2][1], positions[2][2])) + eq(4, set_extmark(ns, 0, positions[1][1], positions[1][2])) -- mixing manual and allocated id:s are not recommened, but it should -- do something reasonable - eq(6, curbufmeths.set_extmark(ns, 6, positions[2][1], positions[2][2])) - eq(7, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) - eq(8, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(6, set_extmark(ns, 6, positions[2][1], positions[2][2])) + eq(7, set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(8, set_extmark(ns, 0, positions[1][1], positions[1][2])) end) it('auto indenting with enter works #extmarks', function() @@ -814,11 +816,11 @@ describe('Extmarks buffer api', function() feed(':set shiftwidth=2') feed("0iint A {1M1b") -- Set the mark on the M, should move.. - curbufmeths.set_extmark(ns, marks[1], 0, 12) + set_extmark(ns, marks[1], 0, 12) -- Set the mark before the cursor, should stay there - curbufmeths.set_extmark(ns, marks[2], 0, 10) + set_extmark(ns, marks[2], 0, 10) feed("i") - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({1, 3}, rv) rv = curbufmeths.get_extmark_by_id(ns, marks[2]) eq({0, 10}, rv) @@ -831,9 +833,9 @@ describe('Extmarks buffer api', function() feed(':set shiftwidth=2') -- will force an indent of 2 feed("0iint A {0i1M1") - curbufmeths.set_extmark(ns, marks[1], 1, 1) + set_extmark(ns, marks[1], 1, 1) feed("0i") - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({1, 3}, rv) check_undo_redo(ns, marks[1], 1, 1, 1, 3) -- now check when cursor at eol @@ -847,9 +849,9 @@ describe('Extmarks buffer api', function() feed(':set autoindent') feed(':set shiftwidth=2') feed("0i") - curbufmeths.set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[1], 0, 3) feed("bi") - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({0, 1}, rv) check_undo_redo(ns, marks[1], 0, 3, 0, 1) -- check when cursor at eol @@ -863,8 +865,8 @@ describe('Extmarks buffer api', function() feed(':set autoindent') feed(':set shiftwidth=2') feed("0iint A {1M12M2") - curbufmeths.set_extmark(ns, marks[1], 1, 1) - curbufmeths.set_extmark(ns, marks[2], 2, 1) + set_extmark(ns, marks[1], 1, 1) + set_extmark(ns, marks[2], 2, 1) feed('=gg') check_undo_redo(ns, marks[1], 1, 1, 1, 3) check_undo_redo(ns, marks[2], 2, 1, 2, 5) @@ -872,8 +874,8 @@ describe('Extmarks buffer api', function() it('substitutes by deleting inside the replace matches #extmarks_sub', function() -- do_sub in ex_cmds.c - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) feed(':s/34/xx') check_undo_redo(ns, marks[1], 0, 2, 0, 4) check_undo_redo(ns, marks[2], 0, 3, 0, 4) @@ -881,8 +883,8 @@ describe('Extmarks buffer api', function() it('substitutes when insert text > deleted #extmarks_sub', function() -- do_sub in ex_cmds.c - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) feed(':s/34/xxx') check_undo_redo(ns, marks[1], 0, 2, 0, 5) check_undo_redo(ns, marks[2], 0, 3, 0, 5) @@ -890,8 +892,8 @@ describe('Extmarks buffer api', function() it('substitutes when marks around eol #extmarks_sub', function() -- do_sub in ex_cmds.c - curbufmeths.set_extmark(ns, marks[1], 0, 4) - curbufmeths.set_extmark(ns, marks[2], 0, 5) + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 0, 5) feed(':s/5/xxx') check_undo_redo(ns, marks[1], 0, 4, 0, 7) check_undo_redo(ns, marks[2], 0, 5, 0, 7) @@ -901,9 +903,9 @@ describe('Extmarks buffer api', function() -- do_sub in ex_cmds.c feed('Ax34xx') feed('Axxx34') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 1, 1) - curbufmeths.set_extmark(ns, marks[3], 2, 4) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 1, 1) + set_extmark(ns, marks[3], 2, 4) feed(':1,3s/34/xxx') check_undo_redo(ns, marks[1], 0, 2, 0, 5) check_undo_redo(ns, marks[2], 1, 1, 1, 4) @@ -913,9 +915,9 @@ describe('Extmarks buffer api', function() it('substitutes multiple matches in a line #extmarks_sub', function() -- do_sub in ex_cmds.c feed('ddi3x3x3') - curbufmeths.set_extmark(ns, marks[1], 0, 0) - curbufmeths.set_extmark(ns, marks[2], 0, 2) - curbufmeths.set_extmark(ns, marks[3], 0, 4) + set_extmark(ns, marks[1], 0, 0) + set_extmark(ns, marks[2], 0, 2) + set_extmark(ns, marks[3], 0, 4) feed(':s/3/yy/g') check_undo_redo(ns, marks[1], 0, 0, 0, 2) check_undo_redo(ns, marks[2], 0, 2, 0, 5) @@ -924,11 +926,11 @@ describe('Extmarks buffer api', function() it('substitions over multiple lines with newline in pattern #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 1, 0) - curbufmeths.set_extmark(ns, marks[4], 1, 5) - curbufmeths.set_extmark(ns, marks[5], 2, 0) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 1, 0) + set_extmark(ns, marks[4], 1, 5) + set_extmark(ns, marks[5], 2, 0) feed([[:1,2s:5\n:5 ]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 0, 6) @@ -939,12 +941,12 @@ describe('Extmarks buffer api', function() it('inserting #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 1, 0) - curbufmeths.set_extmark(ns, marks[4], 1, 5) - curbufmeths.set_extmark(ns, marks[5], 2, 0) - curbufmeths.set_extmark(ns, marks[6], 1, 2) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 1, 0) + set_extmark(ns, marks[4], 1, 5) + set_extmark(ns, marks[5], 2, 0) + set_extmark(ns, marks[6], 1, 2) feed([[:1,2s:5\n67:X]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 0, 5) @@ -956,11 +958,11 @@ describe('Extmarks buffer api', function() it('substitions with multiple newlines in pattern #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 4) - curbufmeths.set_extmark(ns, marks[2], 0, 5) - curbufmeths.set_extmark(ns, marks[3], 1, 0) - curbufmeths.set_extmark(ns, marks[4], 1, 5) - curbufmeths.set_extmark(ns, marks[5], 2, 0) + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 0, 5) + set_extmark(ns, marks[3], 1, 0) + set_extmark(ns, marks[4], 1, 5) + set_extmark(ns, marks[5], 2, 0) feed([[:1,2s:\n.*\n:X]]) check_undo_redo(ns, marks[1], 0, 4, 0, 4) check_undo_redo(ns, marks[2], 0, 5, 0, 6) @@ -971,11 +973,11 @@ describe('Extmarks buffer api', function() it('substitions over multiple lines with replace in substition #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 1) - curbufmeths.set_extmark(ns, marks[2], 0, 2) - curbufmeths.set_extmark(ns, marks[3], 0, 4) - curbufmeths.set_extmark(ns, marks[4], 1, 0) - curbufmeths.set_extmark(ns, marks[5], 2, 0) + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 2) + set_extmark(ns, marks[3], 0, 4) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 2, 0) feed([[:1,2s:3:\r]]) check_undo_redo(ns, marks[1], 0, 1, 0, 1) check_undo_redo(ns, marks[2], 0, 2, 1, 0) @@ -989,9 +991,9 @@ describe('Extmarks buffer api', function() it('substitions over multiple lines with replace in substition #extmarks_sub', function() feed('Ax3xx') - curbufmeths.set_extmark(ns, marks[1], 1, 0) - curbufmeths.set_extmark(ns, marks[2], 1, 1) - curbufmeths.set_extmark(ns, marks[3], 1, 2) + set_extmark(ns, marks[1], 1, 0) + set_extmark(ns, marks[2], 1, 1) + set_extmark(ns, marks[3], 1, 2) feed([[:2,2s:3:\r]]) check_undo_redo(ns, marks[1], 1, 0, 1, 0) check_undo_redo(ns, marks[2], 1, 1, 2, 0) @@ -1000,11 +1002,11 @@ describe('Extmarks buffer api', function() it('substitions over multiple lines with replace in substition #extmarks_sub', function() feed('Ax3xx') - curbufmeths.set_extmark(ns, marks[1], 0, 1) - curbufmeths.set_extmark(ns, marks[2], 0, 2) - curbufmeths.set_extmark(ns, marks[3], 0, 4) - curbufmeths.set_extmark(ns, marks[4], 1, 1) - curbufmeths.set_extmark(ns, marks[5], 2, 0) + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 2) + set_extmark(ns, marks[3], 0, 4) + set_extmark(ns, marks[4], 1, 1) + set_extmark(ns, marks[5], 2, 0) feed([[:1,2s:3:\r]]) check_undo_redo(ns, marks[1], 0, 1, 0, 1) check_undo_redo(ns, marks[2], 0, 2, 1, 0) @@ -1018,12 +1020,12 @@ describe('Extmarks buffer api', function() it('substitions with newline in match and sub, delta is 0 #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 1, 0) - curbufmeths.set_extmark(ns, marks[5], 1, 5) - curbufmeths.set_extmark(ns, marks[6], 2, 0) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 0) feed([[:1,1s:5\n:\r]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 1, 0) @@ -1035,12 +1037,12 @@ describe('Extmarks buffer api', function() it('substitions with newline in match and sub, delta > 0 #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 1, 0) - curbufmeths.set_extmark(ns, marks[5], 1, 5) - curbufmeths.set_extmark(ns, marks[6], 2, 0) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 0) feed([[:1,1s:5\n:\r\r]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 2, 0) @@ -1052,13 +1054,13 @@ describe('Extmarks buffer api', function() it('substitions with newline in match and sub, delta < 0 #extmarks_sub', function() feed('A67890xxxx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 1, 0) - curbufmeths.set_extmark(ns, marks[5], 1, 5) - curbufmeths.set_extmark(ns, marks[6], 2, 1) - curbufmeths.set_extmark(ns, marks[7], 3, 0) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 1) + set_extmark(ns, marks[7], 3, 0) feed([[:1,2s:5\n.*\n:\r]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 1, 0) @@ -1071,12 +1073,12 @@ describe('Extmarks buffer api', function() it('substitions with backrefs, newline inserted into sub #extmarks_sub', function() feed('A67890xxxx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 1, 0) - curbufmeths.set_extmark(ns, marks[5], 1, 5) - curbufmeths.set_extmark(ns, marks[6], 2, 0) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 0) feed([[:1,1s:5\(\n\):\0\1]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 2, 0) @@ -1087,8 +1089,8 @@ describe('Extmarks buffer api', function() end) it('substitions a ^ #extmarks_sub', function() - curbufmeths.set_extmark(ns, marks[1], 0, 0) - curbufmeths.set_extmark(ns, marks[2], 0, 1) + set_extmark(ns, marks[1], 0, 0) + set_extmark(ns, marks[2], 0, 1) feed([[:s:^:x]]) check_undo_redo(ns, marks[1], 0, 0, 0, 1) check_undo_redo(ns, marks[2], 0, 1, 0, 2) @@ -1097,11 +1099,11 @@ describe('Extmarks buffer api', function() it('using without increase in order of magnitude #extmarks_inc_dec', function() -- do_addsub in ops.c feed('ddiabc998xxxTc') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 0, 6) - curbufmeths.set_extmark(ns, marks[5], 0, 7) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 0, 6) + set_extmark(ns, marks[5], 0, 7) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 6) @@ -1113,11 +1115,11 @@ describe('Extmarks buffer api', function() it('using when increase in order of magnitude #extmarks_inc_dec', function() -- do_addsub in ops.c feed('ddiabc999xxxTc') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 0, 6) - curbufmeths.set_extmark(ns, marks[5], 0, 7) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 0, 6) + set_extmark(ns, marks[5], 0, 7) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 7) @@ -1128,11 +1130,11 @@ describe('Extmarks buffer api', function() it('using when negative and without decrease in order of magnitude #extmarks_inc_dec', function() feed('ddiabc-999xxxT-') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 6) - curbufmeths.set_extmark(ns, marks[4], 0, 7) - curbufmeths.set_extmark(ns, marks[5], 0, 8) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 7) @@ -1143,11 +1145,11 @@ describe('Extmarks buffer api', function() it('using when negative and decrease in order of magnitude #extmarks_inc_dec', function() feed('ddiabc-1000xxxT-') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 7) - curbufmeths.set_extmark(ns, marks[4], 0, 8) - curbufmeths.set_extmark(ns, marks[5], 0, 9) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 7) + set_extmark(ns, marks[4], 0, 8) + set_extmark(ns, marks[5], 0, 9) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 7) @@ -1159,11 +1161,11 @@ describe('Extmarks buffer api', function() it('using without decrease in order of magnitude #extmarks_inc_dec', function() -- do_addsub in ops.c feed('ddiabc999xxxTc') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 0, 6) - curbufmeths.set_extmark(ns, marks[5], 0, 7) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 0, 6) + set_extmark(ns, marks[5], 0, 7) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 6) @@ -1175,11 +1177,11 @@ describe('Extmarks buffer api', function() it('using when decrease in order of magnitude #extmarks_inc_dec', function() -- do_addsub in ops.c feed('ddiabc1000xxxTc') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 6) - curbufmeths.set_extmark(ns, marks[4], 0, 7) - curbufmeths.set_extmark(ns, marks[5], 0, 8) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 6) @@ -1190,11 +1192,11 @@ describe('Extmarks buffer api', function() it('using when negative and without increase in order of magnitude #extmarks_inc_dec', function() feed('ddiabc-998xxxT-') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 6) - curbufmeths.set_extmark(ns, marks[4], 0, 7) - curbufmeths.set_extmark(ns, marks[5], 0, 8) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 7) @@ -1205,11 +1207,11 @@ describe('Extmarks buffer api', function() it('using when negative and increase in order of magnitude #extmarks_inc_dec', function() feed('ddiabc-999xxxT-') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 6) - curbufmeths.set_extmark(ns, marks[4], 0, 7) - curbufmeths.set_extmark(ns, marks[5], 0, 8) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 8) @@ -1218,38 +1220,34 @@ describe('Extmarks buffer api', function() check_undo_redo(ns, marks[5], 0, 8, 0, 9) end) - -- TODO catch exceptions - pending('throws consistent error codes #todo', function() + it('throws consistent error codes', function() local ns_invalid = ns2 + 1 - rv = curbufmeths.set_extmark(ns_invalid, marks[1], positions[1][1], positions[1][2]) - rv = curbufmeths.del_extmark(ns_invalid, marks[1]) - rv = curbufmeths.get_extmarks(ns_invalid, positions[1], positions[2], ALL) - rv = curbufmeths.get_extmark_by_id(ns_invalid, marks[1]) - + eq("Invalid ns_id", pcall_err(set_extmark, ns_invalid, marks[1], positions[1][1], positions[1][2])) + eq("Invalid ns_id", pcall_err(curbufmeths.del_extmark, ns_invalid, marks[1])) + eq("Invalid ns_id", pcall_err(get_extmarks, ns_invalid, positions[1], positions[2])) + eq("Invalid ns_id", pcall_err(curbufmeths.get_extmark_by_id, ns_invalid, marks[1])) end) it('when col = line-length, set the mark on eol #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, -1) - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + set_extmark(ns, marks[1], 0, -1) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({0, init_text:len()}, rv) -- Test another - curbufmeths.set_extmark(ns, marks[1], 0, -1) + set_extmark(ns, marks[1], 0, -1) rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({0, init_text:len()}, rv) end) it('when col = line-length, set the mark on eol #extmarks', function() local invalid_col = init_text:len() + 1 - eq({false, "col value outside range"}, meth_pcall(curbufmeths.set_extmark, ns, marks[1], 0, invalid_col)) + eq("col value outside range", pcall_err(set_extmark, ns, marks[1], 0, invalid_col)) end) - -- TODO(bfredl): decide what to do with this - pending('when line > line, set the mark on end of buffer #extmarks', function() + it('when line > line_count, throw error #extmarks', function() local invalid_col = init_text:len() + 1 - local invalid_lnum = 3 -- line1 ends in an eol. so line 2 contains a valid position (eol)? - curbufmeths.set_extmark(ns, marks[1], invalid_lnum, invalid_col) - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({2, 1}, rv) + local invalid_lnum = 3 + eq('line value outside range', pcall_err(set_extmark, ns, marks[1], invalid_lnum, invalid_col)) + eq({}, curbufmeths.get_extmark_by_id(ns, marks[1])) end) it('bug from check_col in extmark_set #extmarks_sub', function() @@ -1259,7 +1257,7 @@ describe('Extmarks buffer api', function() -- check_col and check_lnum only when they are required. feed('A67890xx') feed('A1234567890xx') - curbufmeths.set_extmark(ns, marks[1], 3, 4) + set_extmark(ns, marks[1], 3, 4) feed([[:1,5s:5\n:5 ]]) check_undo_redo(ns, marks[1], 3, 4, 2, 6) end) @@ -1284,7 +1282,7 @@ describe('Extmarks buffer api with many marks', function() local q = 0 for i = 0,29 do for j = 0,i do - local id = curbufmeths.set_extmark(ns,0, i,j) + local id = set_extmark(ns,0, i,j) eq(nil, ns_marks[ns][id]) ok(id > 0) ns_marks[ns][id] = {i,j} @@ -1298,7 +1296,7 @@ describe('Extmarks buffer api with many marks', function() end) local function get_marks(ns) - local mark_list = curbufmeths.get_extmarks(ns, 0, -1, -1) + local mark_list = get_extmarks(ns, 0, -1) local marks = {} for _, mark in ipairs(mark_list) do local id, row, col = unpack(mark) @@ -1362,4 +1360,10 @@ describe('Extmarks buffer api with many marks', function() eq(ns_marks[ns1], get_marks(ns1)) eq(ns_marks[ns2], get_marks(ns2)) end) + + it("can wipe buffer #extmarks", function() + command('bwipe!') + eq({}, get_marks(ns1)) + eq({}, get_marks(ns2)) + end) end) -- cgit From ebdf90e7d7c97b4355f42e06769e9424c279d695 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 16 Nov 2019 11:05:56 +0100 Subject: extmark: don't crash in RO buffer. --- test/functional/api/mark_extended_spec.lua | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'test/functional/api') diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua index a5d68c6b9f..76db9f9d81 100644 --- a/test/functional/api/mark_extended_spec.lua +++ b/test/functional/api/mark_extended_spec.lua @@ -1262,6 +1262,12 @@ describe('Extmarks buffer api', function() check_undo_redo(ns, marks[1], 3, 4, 2, 6) end) + it('in read-only buffer', function() + command("view! runtime/doc/help.txt") + eq(true, curbufmeths.get_option('ro')) + local id = set_extmark(ns, 0, 0, 2) + eq({{id, 0, 2}}, get_extmarks(ns,0, -1)) + end) end) describe('Extmarks buffer api with many marks', function() -- cgit From 2cc83c961c0533222890adec51ac56041fb2a6b4 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Thu, 14 Nov 2019 20:06:13 +0100 Subject: refactor: use inserted_bytes pattern from vim This covers all "small" inserts and deletes in insert mode, as well as a few more cases like small normal mode deletes vim-patch:8.1.0678: text properties as not adjusted for inserted text --- test/functional/api/mark_extended_spec.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'test/functional/api') diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua index 76db9f9d81..04b2b3bcc5 100644 --- a/test/functional/api/mark_extended_spec.lua +++ b/test/functional/api/mark_extended_spec.lua @@ -475,6 +475,13 @@ describe('Extmarks buffer api', function() check_undo_redo(ns, marks[2], 0, 3, 1, 2) end) + it('deleting right before a mark works #extmarks', function() + -- op_delete in ops.c + set_extmark(ns, marks[1], 0, 2) + feed('0lx') + check_undo_redo(ns, marks[1], 0, 2, 0, 1) + end) + it('deleting on a mark works #extmarks', function() -- op_delete in ops.c set_extmark(ns, marks[1], 0, 2) -- cgit From ddf509c2ba18048c97b5669710fb96a3bce60341 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Thu, 14 Nov 2019 20:24:17 +0100 Subject: test was wrong --- test/functional/api/mark_extended_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/api') diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua index 04b2b3bcc5..1f6c00b7d2 100644 --- a/test/functional/api/mark_extended_spec.lua +++ b/test/functional/api/mark_extended_spec.lua @@ -422,7 +422,7 @@ describe('Extmarks buffer api', function() set_extmark(ns, marks[1], 1, 2) -- Insert a fullwidth (two col) tilde, NICE feed('0i~') - check_undo_redo(ns, marks[1], 1, 2, 1, 3) + check_undo_redo(ns, marks[1], 1, 2, 1, 5) end) it('marks move with blockwise inserts #extmarks', function() -- cgit From fd5710ae9a3bcbc0f9cbb71de9e39253350ff09c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 25 Nov 2019 01:08:02 -0800 Subject: doc + extmarks tweaks #11421 - nvim_buf_get_extmarks: rename "amount" => "limit" - rename `set_extmark_index_from_obj` --- test/functional/api/mark_extended_spec.lua | 75 +++++++++++++++--------------- test/functional/api/proc_spec.lua | 2 +- 2 files changed, 38 insertions(+), 39 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua index 1f6c00b7d2..6735b8c0f5 100644 --- a/test/functional/api/mark_extended_spec.lua +++ b/test/functional/api/mark_extended_spec.lua @@ -36,7 +36,7 @@ local function get_extmarks(ns_id, start, end_, opts) return curbufmeths.get_extmarks(ns_id, start, end_, opts) end -describe('Extmarks buffer api', function() +describe('API/extmarks', function() local screen local marks, positions, ns_string2, ns_string, init_text, row, col local ns, ns2 @@ -153,26 +153,26 @@ describe('Extmarks buffer api', function() end -- next with mark id - rv = get_extmarks(ns, marks[1], {-1, -1}, {amount=1}) + rv = get_extmarks(ns, marks[1], {-1, -1}, {limit=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) - rv = get_extmarks(ns, marks[2], {-1, -1}, {amount=1}) + rv = get_extmarks(ns, marks[2], {-1, -1}, {limit=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- next with positional when mark exists at position - rv = get_extmarks(ns, positions[1], {-1, -1}, {amount=1}) + rv = get_extmarks(ns, positions[1], {-1, -1}, {limit=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- next with positional index (no mark at position) - rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, {amount=1}) + rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, {limit=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- next with Extremity index - rv = get_extmarks(ns, {0,0}, {-1, -1}, {amount=1}) + rv = get_extmarks(ns, {0,0}, {-1, -1}, {limit=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- nextrange with mark id rv = get_extmarks(ns, marks[1], marks[3]) eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) - -- nextrange with amount - rv = get_extmarks(ns, marks[1], marks[3], {amount=2}) + -- nextrange with `limit` + rv = get_extmarks(ns, marks[1], marks[3], {limit=2}) eq(2, table.getn(rv)) -- nextrange with positional when mark exists at position rv = get_extmarks(ns, positions[1], positions[3]) @@ -196,18 +196,18 @@ describe('Extmarks buffer api', function() eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prev with mark id - rv = get_extmarks(ns, marks[3], {0, 0}, {amount=1}) + rv = get_extmarks(ns, marks[3], {0, 0}, {limit=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) - rv = get_extmarks(ns, marks[2], {0, 0}, {amount=1}) + rv = get_extmarks(ns, marks[2], {0, 0}, {limit=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- prev with positional when mark exists at position - rv = get_extmarks(ns, positions[3], {0, 0}, {amount=1}) + rv = get_extmarks(ns, positions[3], {0, 0}, {limit=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prev with positional index (no mark at position) - rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, {amount=1}) + rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, {limit=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- prev with Extremity index - rv = get_extmarks(ns, {-1,-1}, {0,0}, {amount=1}) + rv = get_extmarks(ns, {-1,-1}, {0,0}, {limit=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prevrange with mark id @@ -215,8 +215,8 @@ describe('Extmarks buffer api', function() eq({marks[3], positions[3][1], positions[3][2]}, rv[1]) eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) eq({marks[1], positions[1][1], positions[1][2]}, rv[3]) - -- prevrange with amount - rv = get_extmarks(ns, marks[3], marks[1], {amount=2}) + -- prevrange with limit + rv = get_extmarks(ns, marks[3], marks[1], {limit=2}) eq(2, table.getn(rv)) -- prevrange with positional when mark exists at position rv = get_extmarks(ns, positions[3], positions[1]) @@ -241,7 +241,7 @@ describe('Extmarks buffer api', function() eq({{marks[1], positions[1][1], positions[1][2]}}, rv) end) - it('querying for information with amount #extmarks', function() + it('querying for information with limit #extmarks', function() -- add some more marks for i, m in ipairs(marks) do if positions[i] ~= nil then @@ -250,19 +250,19 @@ describe('Extmarks buffer api', function() end end - local rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=1}) + local rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=1}) eq(1, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=2}) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=2}) eq(2, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=3}) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=3}) eq(3, table.getn(rv)) -- now in reverse - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=1}) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=1}) eq(1, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=2}) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=2}) eq(2, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=3}) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=3}) eq(3, table.getn(rv)) end) @@ -295,9 +295,9 @@ describe('Extmarks buffer api', function() rv) end) - it('get_marks amount 0 returns nothing #extmarks', function() + it('get_marks limit=0 returns nothing #extmarks', function() set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - local rv = get_extmarks(ns, {-1, -1}, {-1, -1}, {amount=0}) + local rv = get_extmarks(ns, {-1, -1}, {-1, -1}, {limit=0}) eq({}, rv) end) @@ -730,7 +730,7 @@ describe('Extmarks buffer api', function() -- Test updates feed('o') set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - rv = get_extmarks(ns, marks[1], marks[1], {amount=1}) + rv = get_extmarks(ns, marks[1], marks[1], {limit=1}) eq(1, table.getn(rv)) feed("u") feed("") @@ -771,23 +771,23 @@ describe('Extmarks buffer api', function() set_extmark(ns2, marks[2], positions[2][1], positions[2][2]) set_extmark(ns2, marks[3], positions[3][1], positions[3][2]) - -- get_next (amount set) - rv = get_extmarks(ns, {0, 0}, positions[2], {amount=1}) + -- get_next (limit set) + rv = get_extmarks(ns, {0, 0}, positions[2], {limit=1}) eq(1, table.getn(rv)) - rv = get_extmarks(ns2, {0, 0}, positions[2], {amount=1}) + rv = get_extmarks(ns2, {0, 0}, positions[2], {limit=1}) eq(1, table.getn(rv)) - -- get_prev (amount set) - rv = get_extmarks(ns, positions[1], {0, 0}, {amount=1}) + -- get_prev (limit set) + rv = get_extmarks(ns, positions[1], {0, 0}, {limit=1}) eq(1, table.getn(rv)) - rv = get_extmarks(ns2, positions[1], {0, 0}, {amount=1}) + rv = get_extmarks(ns2, positions[1], {0, 0}, {limit=1}) eq(1, table.getn(rv)) - -- get_next (amount not set) + -- get_next (no limit) rv = get_extmarks(ns, positions[1], positions[2]) eq(2, table.getn(rv)) rv = get_extmarks(ns2, positions[1], positions[2]) eq(2, table.getn(rv)) - -- get_prev (amount not set) + -- get_prev (no limit) rv = get_extmarks(ns, positions[2], positions[1]) eq(2, table.getn(rv)) rv = get_extmarks(ns2, positions[2], positions[1]) @@ -1250,7 +1250,7 @@ describe('Extmarks buffer api', function() eq("col value outside range", pcall_err(set_extmark, ns, marks[1], 0, invalid_col)) end) - it('when line > line_count, throw error #extmarks', function() + it('fails when line > line_count #extmarks', function() local invalid_col = init_text:len() + 1 local invalid_lnum = 3 eq('line value outside range', pcall_err(set_extmark, ns, marks[1], invalid_lnum, invalid_col)) @@ -1258,10 +1258,9 @@ describe('Extmarks buffer api', function() end) it('bug from check_col in extmark_set #extmarks_sub', function() - -- This bug was caused by extmark_set always using - -- check_col. check_col always uses the current buffer. - -- This wasn't working during undo so we now use - -- check_col and check_lnum only when they are required. + -- This bug was caused by extmark_set always using check_col. check_col + -- always uses the current buffer. This wasn't working during undo so we + -- now use check_col and check_lnum only when they are required. feed('A67890xx') feed('A1234567890xx') set_extmark(ns, marks[1], 3, 4) diff --git a/test/functional/api/proc_spec.lua b/test/functional/api/proc_spec.lua index 063d382790..d828bdf948 100644 --- a/test/functional/api/proc_spec.lua +++ b/test/functional/api/proc_spec.lua @@ -10,7 +10,7 @@ local request = helpers.request local retry = helpers.retry local NIL = helpers.NIL -describe('api', function() +describe('API', function() before_each(clear) describe('nvim_get_proc_children', function() -- cgit From 4a77df2e518a51ffd5a5fe311424b4b5305009a7 Mon Sep 17 00:00:00 2001 From: notomo Date: Tue, 26 Nov 2019 00:50:30 +0900 Subject: [RFC] extmark: fix E315 in nvim_buf_set_extmark (#11449) extmark: need to use buf instead of curbuf --- test/functional/api/mark_extended_spec.lua | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'test/functional/api') diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua index 6735b8c0f5..edb0f8ac2b 100644 --- a/test/functional/api/mark_extended_spec.lua +++ b/test/functional/api/mark_extended_spec.lua @@ -5,6 +5,7 @@ local request = helpers.request local eq = helpers.eq local ok = helpers.ok local curbufmeths = helpers.curbufmeths +local bufmeths = helpers.bufmeths local pcall_err = helpers.pcall_err local insert = helpers.insert local feed = helpers.feed @@ -1274,6 +1275,13 @@ describe('API/extmarks', function() local id = set_extmark(ns, 0, 0, 2) eq({{id, 0, 2}}, get_extmarks(ns,0, -1)) end) + + it('can set a mark to other buffer', function() + local buf = request('nvim_create_buf', 0, 1) + request('nvim_buf_set_lines', buf, 0, -1, 1, {"", ""}) + local id = bufmeths.set_extmark(buf, ns, 0, 1, 0, {}) + eq({{id, 1, 0}}, bufmeths.get_extmarks(buf, ns, 0, -1, {})) + end) end) describe('Extmarks buffer api with many marks', function() -- cgit From 001e69cd4602e84219fd7cfd8ade62f0cb24097c Mon Sep 17 00:00:00 2001 From: Brian Wignall Date: Tue, 26 Nov 2019 07:15:14 -0500 Subject: doc: fix typos close #11459 --- test/functional/api/mark_extended_spec.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua index edb0f8ac2b..bf910568b1 100644 --- a/test/functional/api/mark_extended_spec.lua +++ b/test/functional/api/mark_extended_spec.lua @@ -507,7 +507,7 @@ describe('API/extmarks', function() feed('0l3dl') check_undo_redo(ns, marks[1], 0, 2, 0, 1) check_undo_redo(ns, marks[2], 0, 3, 0, 1) - -- delete 1, nothing should happend to our marks + -- delete 1, nothing should happen to our marks feed('u') feed('$x') check_undo_redo(ns, marks[2], 0, 3, 0, 3) @@ -543,7 +543,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 0, 1, 0, 0) check_undo_redo(ns, marks[2], 0, 3, 0, 0) check_undo_redo(ns, marks[3], 1, 2, 1, 0) - -- delete 1, nothing should happend to our marks + -- delete 1, nothing should happen to our marks feed('u') feed('$jx') check_undo_redo(ns, marks[2], 0, 3, 0, 3) -- cgit From 6aa03e86da041284b5f27a59f73cef0991fc577e Mon Sep 17 00:00:00 2001 From: Siddhant Gupta Date: Sun, 6 Oct 2019 13:37:54 -0700 Subject: API: nvim_source --- test/functional/api/vim_spec.lua | 78 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'test/functional/api') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 8b77dbcaa6..14ed474eb1 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -74,6 +74,84 @@ describe('API', function() eq({mode='i', blocking=false}, nvim("get_mode")) end) + describe('nvim_source', function() + it('works with a one-liner', function() + nvim('source', "let x1 = 'a'") + eq(nvim('get_var', 'x1'), 'a') + end) + + it('works with stray newline character', function() + nvim('source', "let x2 = 'a'\n") + eq(nvim('get_var', 'x2'),'a') + end) + + it('works with multiline command', function() + nvim('source', 'lua < Date: Sun, 6 Oct 2019 19:40:36 -0700 Subject: API: nvim_source: fix multiline input - DOCMD_REPEAT is needed to source all lines of input. - Fix ":verbose set {option}?" by handling SID_STR in get_scriptname(). closes #8722 --- test/functional/api/vim_spec.lua | 131 ++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 58 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 14ed474eb1..a01ef2d6dd 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -16,6 +16,7 @@ local parse_context = helpers.parse_context local request = helpers.request local source = helpers.source local next_msg = helpers.next_msg +local write_file = helpers.write_file local pcall_err = helpers.pcall_err local format_string = helpers.format_string @@ -75,80 +76,94 @@ describe('API', function() end) describe('nvim_source', function() - it('works with a one-liner', function() + it('one-line input', function() nvim('source', "let x1 = 'a'") - eq(nvim('get_var', 'x1'), 'a') + eq('a', nvim('get_var', 'x1')) end) - it('works with stray newline character', function() - nvim('source', "let x2 = 'a'\n") - eq(nvim('get_var', 'x2'),'a') - end) - - it('works with multiline command', function() - nvim('source', 'lua < Date: Wed, 9 Oct 2019 18:34:37 +0530 Subject: API: nvim_source_output - Similar to nvim_source but will capture the output - Add meaningful VimL tracebacks for nvim_source - Handle got_int - Add error reporting --- test/functional/api/vim_spec.lua | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'test/functional/api') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index a01ef2d6dd..9a7744142a 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -84,7 +84,7 @@ describe('API', function() it(':verbose set {option}?', function() nvim('source', 'set nowrap') eq('nowrap\n\tLast set from :source (no file)', - nvim('command_output', 'verbose set wrap?')) + nvim('source_output', 'verbose set wrap?')) end) it('multiline input', function() @@ -165,6 +165,36 @@ describe('API', function() eq('overwritten', request('nvim_get_var', 'x5')) os.remove(fname) end) + + it('traceback', function() + local fname = helpers.tmpname() + write_file(fname, 'echo "hello"\n') + local sourcing_fname = helpers.tmpname() + write_file(sourcing_fname, 'call nvim_source("source '..fname..'")\n') + meths.source('set verbose=2') + print() + local traceback_output = 'line 0: sourcing "'..sourcing_fname..'"\n'.. + 'line 0: sourcing "'..fname..'"\n'.. + 'hello\n'.. + 'finished sourcing '..fname..'\n'.. + 'continuing in nvim_source(..) called at '..sourcing_fname..':1\n'.. + 'finished sourcing '..sourcing_fname..'\n'.. + 'continuing in nvim_source(..) called at nvim_source_output(..):0' + eq(traceback_output, meths.source_output('call nvim_source("source '..sourcing_fname..'")')) + os.remove(fname) + os.remove(sourcing_fname) + end) + end) + + describe('nvim_source_output', function() + it('multiline input', function() + eq('this is spinal tap', + nvim('source_output', 'lua < Date: Sun, 1 Dec 2019 22:26:36 -0800 Subject: API: rename nvim_source => nvim_exec - Eliminate nvim_source_output(): add boolean `output` param to nvim_exec() instead. --- test/functional/api/vim_spec.lua | 79 +++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 41 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 9a7744142a..d7baf68a5b 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -16,6 +16,7 @@ local parse_context = helpers.parse_context local request = helpers.request local source = helpers.source local next_msg = helpers.next_msg +local tmpname = helpers.tmpname local write_file = helpers.write_file local pcall_err = helpers.pcall_err @@ -75,131 +76,127 @@ describe('API', function() eq({mode='i', blocking=false}, nvim("get_mode")) end) - describe('nvim_source', function() + describe('nvim_exec', function() it('one-line input', function() - nvim('source', "let x1 = 'a'") + nvim('exec', "let x1 = 'a'", false) eq('a', nvim('get_var', 'x1')) end) it(':verbose set {option}?', function() - nvim('source', 'set nowrap') + nvim('exec', 'set nowrap', false) eq('nowrap\n\tLast set from :source (no file)', - nvim('source_output', 'verbose set wrap?')) + nvim('exec', 'verbose set wrap?', true)) end) it('multiline input', function() -- Heredoc + empty lines. - nvim('source', "let x2 = 'a'\n") + nvim('exec', "let x2 = 'a'\n", false) eq('a', nvim('get_var', 'x2')) - nvim('source','lua < Date: Sun, 1 Dec 2019 22:43:16 -0800 Subject: API: deprecate nvim_command_output --- test/functional/api/keymap_spec.lua | 4 ++-- test/functional/api/vim_spec.lua | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua index 773207d360..210394c83f 100644 --- a/test/functional/api/keymap_spec.lua +++ b/test/functional/api/keymap_spec.lua @@ -585,13 +585,13 @@ describe('nvim_set_keymap, nvim_del_keymap', function() end) it('can set mappings whose RHS change dynamically', function() - meths.command_output([[ + meths.exec([[ function! FlipFlop() abort if !exists('g:flip') | let g:flip = 0 | endif let g:flip = !g:flip return g:flip endfunction - ]]) + ]], true) eq(1, meths.call_function('FlipFlop', {})) eq(0, meths.call_function('FlipFlop', {})) eq(1, meths.call_function('FlipFlop', {})) diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index d7baf68a5b..4f3279c80e 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -84,7 +84,7 @@ describe('API', function() it(':verbose set {option}?', function() nvim('exec', 'set nowrap', false) - eq('nowrap\n\tLast set from :source (no file)', + eq('nowrap\n\tLast set from anonymous :source', nvim('exec', 'verbose set wrap?', true)) end) @@ -1800,7 +1800,7 @@ describe('API', function() eq(' 1 %a "[No Name]" line 1\n'.. ' 3 h "[Scratch]" line 0\n'.. ' 4 h "[Scratch]" line 0', - meths.command_output("ls")) + meths.exec('ls', true)) -- current buffer didn't change eq({id=1}, meths.get_current_buf()) -- cgit From a3b6c2a3dc5576db45fe4e893cfb8482af591c92 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 2 Dec 2019 00:46:46 -0800 Subject: API: rename nvim_execute_lua => nvim_exec_lua - We already find ourselves renaming nvim_execute_lua in tests and scripts, which suggests "exec" is the verb we actually want. - Add "exec" verb to `:help dev-api`. --- test/functional/api/vim_spec.lua | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 4f3279c80e..d901a5e2eb 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -433,41 +433,44 @@ describe('API', function() end) end) - describe('nvim_execute_lua', function() + describe('nvim_exec_lua', function() it('works', function() - meths.execute_lua('vim.api.nvim_set_var("test", 3)', {}) + meths.exec_lua('vim.api.nvim_set_var("test", 3)', {}) eq(3, meths.get_var('test')) - eq(17, meths.execute_lua('a, b = ...\nreturn a + b', {10,7})) + eq(17, meths.exec_lua('a, b = ...\nreturn a + b', {10,7})) - eq(NIL, meths.execute_lua('function xx(a,b)\nreturn a..b\nend',{})) + eq(NIL, meths.exec_lua('function xx(a,b)\nreturn a..b\nend',{})) + eq("xy", meths.exec_lua('return xx(...)', {'x','y'})) + + -- Deprecated name: nvim_execute_lua. eq("xy", meths.execute_lua('return xx(...)', {'x','y'})) end) it('reports errors', function() eq([[Error loading lua: [string ""]:1: '=' expected near '+']], - pcall_err(meths.execute_lua, 'a+*b', {})) + pcall_err(meths.exec_lua, 'a+*b', {})) eq([[Error loading lua: [string ""]:1: unexpected symbol near '1']], - pcall_err(meths.execute_lua, '1+2', {})) + pcall_err(meths.exec_lua, '1+2', {})) eq([[Error loading lua: [string ""]:1: unexpected symbol]], - pcall_err(meths.execute_lua, 'aa=bb\0', {})) + pcall_err(meths.exec_lua, 'aa=bb\0', {})) eq([[Error executing lua: [string ""]:1: attempt to call global 'bork' (a nil value)]], - pcall_err(meths.execute_lua, 'bork()', {})) + pcall_err(meths.exec_lua, 'bork()', {})) eq('Error executing lua: [string ""]:1: did\nthe\nfail', - pcall_err(meths.execute_lua, 'error("did\\nthe\\nfail")', {})) + pcall_err(meths.exec_lua, 'error("did\\nthe\\nfail")', {})) end) it('uses native float values', function() - eq(2.5, meths.execute_lua("return select(1, ...)", {2.5})) - eq("2.5", meths.execute_lua("return vim.inspect(...)", {2.5})) + eq(2.5, meths.exec_lua("return select(1, ...)", {2.5})) + eq("2.5", meths.exec_lua("return vim.inspect(...)", {2.5})) -- "special" float values are still accepted as return values. - eq(2.5, meths.execute_lua("return vim.api.nvim_eval('2.5')", {})) - eq("{\n [false] = 2.5,\n [true] = 3\n}", meths.execute_lua("return vim.inspect(vim.api.nvim_eval('2.5'))", {})) + eq(2.5, meths.exec_lua("return vim.api.nvim_eval('2.5')", {})) + eq("{\n [false] = 2.5,\n [true] = 3\n}", meths.exec_lua("return vim.inspect(vim.api.nvim_eval('2.5'))", {})) end) end) @@ -573,7 +576,7 @@ describe('API', function() eq({0,3,14,0}, funcs.getpos('.')) end) it('vim.paste() failure', function() - nvim('execute_lua', 'vim.paste = (function(lines, phase) error("fake fail") end)', {}) + nvim('exec_lua', 'vim.paste = (function(lines, phase) error("fake fail") end)', {}) eq([[Error executing lua: [string ""]:1: fake fail]], pcall_err(request, 'nvim_paste', 'line 1\nline 2\nline 3', false, 1)) end) @@ -797,7 +800,7 @@ describe('API', function() ok(nil ~= string.find(rv, 'noequalalways\n'.. '\tLast set from API client %(channel id %d+%)')) - nvim('execute_lua', 'vim.api.nvim_set_option("equalalways", true)', {}) + nvim('exec_lua', 'vim.api.nvim_set_option("equalalways", true)', {}) status, rv = pcall(nvim, 'command_output', 'verbose set equalalways?') eq(true, status) -- cgit From 440695c29696f261337227e5c419aa1cf313c2dd Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 28 Sep 2019 14:27:20 +0200 Subject: tree-sitter: implement query functionality and highlighting prototype [skip.lint] --- test/functional/api/highlight_spec.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'test/functional/api') diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua index 5297c6454e..b6514a105c 100644 --- a/test/functional/api/highlight_spec.lua +++ b/test/functional/api/highlight_spec.lua @@ -4,6 +4,9 @@ local Screen = require('test.functional.ui.screen') local eq, eval = helpers.eq, helpers.eval local command = helpers.command local meths = helpers.meths +local funcs = helpers.funcs +local pcall_err = helpers.pcall_err +local ok = helpers.ok describe('API: highlight',function() local expected_rgb = { @@ -110,4 +113,20 @@ describe('API: highlight',function() meths.get_hl_by_name('cursorline', 0)); end) + + it('nvim_get_hl_id_by_name', function() + -- precondition: use a hl group that does not yet exist + eq('Invalid highlight name: Shrubbery', pcall_err(meths.get_hl_by_name, "Shrubbery", true)) + eq(0, funcs.hlID("Shrubbery")) + + local hl_id = meths.get_hl_id_by_name("Shrubbery") + ok(hl_id > 0) + eq(hl_id, funcs.hlID("Shrubbery")) + + command('hi Shrubbery guifg=#888888 guibg=#888888') + eq({foreground=tonumber("0x888888"), background=tonumber("0x888888")}, + meths.get_hl_by_id(hl_id, true)) + eq({foreground=tonumber("0x888888"), background=tonumber("0x888888")}, + meths.get_hl_by_name("Shrubbery", true)) + end) end) -- cgit From 831fa45ad84e2f41730db3350289e660006139d6 Mon Sep 17 00:00:00 2001 From: kevinhwang91 Date: Wed, 8 Jan 2020 22:19:23 +0800 Subject: API: nvim_get_hl_by_id: omit hl instead of returning -1 #11685 Problem: When Normal highlight group defines ctermfg/bg, but other highlight group lacks ctermfg/bg, nvim_get_hl_by_id(hl_id, v:false) returns -1 for the missing ctermfg/bg instead of just omitting it. Solution: checking for -1 in hlattrs2dict() fix #11680 --- test/functional/api/highlight_spec.lua | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'test/functional/api') diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua index b6514a105c..a9d4c72d31 100644 --- a/test/functional/api/highlight_spec.lua +++ b/test/functional/api/highlight_spec.lua @@ -70,6 +70,22 @@ describe('API: highlight',function() eq(false, err) eq('Invalid highlight id: -1', string.match(emsg, 'Invalid.*')) + + -- Test highlight group without ctermbg value. + command('hi Normal ctermfg=red ctermbg=yellow') + command('hi NewConstant ctermfg=green guifg=white guibg=blue') + hl_id = eval("hlID('NewConstant')") + eq({foreground = 10,}, meths.get_hl_by_id(hl_id, false)) + + -- Test highlight group without ctermfg value. + command('hi clear NewConstant') + command('hi NewConstant ctermbg=Magenta guifg=white guibg=blue') + eq({background = 13,}, meths.get_hl_by_id(hl_id, false)) + + -- Test highlight group with ctermfg and ctermbg values. + command('hi clear NewConstant') + command('hi NewConstant ctermfg=green ctermbg=Magenta guifg=white guibg=blue') + eq({foreground = 10, background = 13,}, meths.get_hl_by_id(hl_id, false)) end) it("nvim_get_hl_by_name", function() -- cgit From 3d1531aee5d92375b69098de8f8c788ea407b066 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 14 Jan 2020 09:21:10 +0100 Subject: API: include invalid buffer/window/tabpage in error message (#11712) --- test/functional/api/tabpage_spec.lua | 4 ++++ test/functional/api/window_spec.lua | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/tabpage_spec.lua b/test/functional/api/tabpage_spec.lua index ed7ce72597..20b3163d95 100644 --- a/test/functional/api/tabpage_spec.lua +++ b/test/functional/api/tabpage_spec.lua @@ -24,6 +24,10 @@ describe('api/tabpage', function() nvim('set_current_win', win3) eq(win3, tabpage('get_win', tab2)) end) + + it('validates args', function() + eq('Invalid tabpage id: 23', pcall_err(tabpage, 'list_wins', 23)) + end) end) describe('{get,set,del}_var', function() diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index 17e0d3235c..8c7c3208c0 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -55,8 +55,8 @@ describe('API/win', function() end) it('validates args', function() - eq('Invalid buffer id', pcall_err(window, 'set_buf', nvim('get_current_win'), 23)) - eq('Invalid window id', pcall_err(window, 'set_buf', 23, nvim('get_current_buf'))) + eq('Invalid buffer id: 23', pcall_err(window, 'set_buf', nvim('get_current_win'), 23)) + eq('Invalid window id: 23', pcall_err(window, 'set_buf', 23, nvim('get_current_buf'))) end) end) @@ -73,7 +73,7 @@ describe('API/win', function() it('does not leak memory when using invalid window ID with invalid pos', function() - eq('Invalid window id', pcall_err(meths.win_set_cursor, 1, {"b\na"})) + eq('Invalid window id: 1', pcall_err(meths.win_set_cursor, 1, {"b\na"})) end) it('updates the screen, and also when the window is unfocused', function() -- cgit From ca1a00edd6d6345b848a28d077d6a192528f811e Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Tue, 14 Jan 2020 12:45:09 +0100 Subject: extmarks/bufhl: reimplement using new marktree data structure Add new "splice" interface for tracking buffer changes at the byte level. This will later be reused for byte-resolution buffer updates. (Implementation has been started, but using undocumented "_on_bytes" option now as interface hasn't been finalized). Use this interface to improve many edge cases of extmark adjustment. Changed tests indicate previously incorrect behavior. Adding tests for more edge cases will be follow-up work (overlaps on_bytes tests) Don't consider creation/deletion of marks an undoable event by itself. This behavior was never documented, and imposes complexity for little gain. Add nvim__buf_add_decoration temporary API for direct access to the new implementation. This should be refactored into a proper API for decorations, probably involving a huge dict. fixes #11598 --- test/functional/api/mark_extended_spec.lua | 309 +++++++++++++++++++---------- 1 file changed, 199 insertions(+), 110 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua index bf910568b1..8aa8ed07c5 100644 --- a/test/functional/api/mark_extended_spec.lua +++ b/test/functional/api/mark_extended_spec.lua @@ -11,6 +11,11 @@ local insert = helpers.insert local feed = helpers.feed local clear = helpers.clear local command = helpers.command +local meths = helpers.meths + +local function expect(contents) + return eq(contents, helpers.curbuf_contents()) +end local function check_undo_redo(ns, mark, sr, sc, er, ec) --s = start, e = end local rv = curbufmeths.get_extmark_by_id(ns, mark) @@ -37,9 +42,36 @@ local function get_extmarks(ns_id, start, end_, opts) return curbufmeths.get_extmarks(ns_id, start, end_, opts) end +local function batch_set(ns_id, positions) + local ids = {} + for _, pos in ipairs(positions) do + table.insert(ids, set_extmark(ns_id, 0, pos[1], pos[2])) + end + return ids +end + +local function batch_check(ns_id, ids, positions) + local actual, expected = {}, {} + for i,id in ipairs(ids) do + expected[id] = positions[i] + end + for _, mark in pairs(get_extmarks(ns_id, 0, -1, {})) do + actual[mark[1]] = {mark[2], mark[3]} + end + eq(expected, actual) +end + +local function batch_check_undo_redo(ns_id, ids, before, after) + batch_check(ns_id, ids, after) + feed("u") + batch_check(ns_id, ids, before) + feed("") + batch_check(ns_id, ids, after) +end + describe('API/extmarks', function() local screen - local marks, positions, ns_string2, ns_string, init_text, row, col + local marks, positions, init_text, row, col local ns, ns2 before_each(function() @@ -47,22 +79,18 @@ describe('API/extmarks', function() marks = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} positions = {{0, 0,}, {0, 2}, {0, 3}} - ns_string = "my-fancy-plugin" - ns_string2 = "my-fancy-plugin2" init_text = "12345" row = 0 col = 2 clear() - screen = Screen.new(15, 10) - screen:attach() insert(init_text) - ns = request('nvim_create_namespace', ns_string) - ns2 = request('nvim_create_namespace', ns_string2) + ns = request('nvim_create_namespace', "my-fancy-plugin") + ns2 = request('nvim_create_namespace', "my-fancy-plugin2") end) - it('adds, updates and deletes marks #extmarks', function() + it('adds, updates and deletes marks', function() local rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) eq(marks[1], rv) rv = curbufmeths.get_extmark_by_id(ns, marks[1]) @@ -92,7 +120,7 @@ describe('API/extmarks', function() eq(false, curbufmeths.del_extmark(ns, 1000)) end) - it('can clear a specific namespace range #extmarks', function() + it('can clear a specific namespace range', function() set_extmark(ns, 1, 0, 1) set_extmark(ns2, 1, 0, 1) -- force a new undo buffer @@ -102,13 +130,13 @@ describe('API/extmarks', function() eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('u') eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({{1, 0, 1}}, get_extmarks(ns2, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('') eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) end) - it('can clear a namespace range using 0,-1 #extmarks', function() + it('can clear a namespace range using 0,-1', function() set_extmark(ns, 1, 0, 1) set_extmark(ns2, 1, 0, 1) -- force a new undo buffer @@ -117,14 +145,16 @@ describe('API/extmarks', function() eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('u') - eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({{1, 0, 1}}, get_extmarks(ns2, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('') eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) end) - it('querying for information and ranges #extmarks', function() + it('querying for information and ranges', function() + --marks = {1, 2, 3} + --positions = {{0, 0,}, {0, 2}, {0, 3}} -- add some more marks for i, m in ipairs(marks) do if positions[i] ~= nil then @@ -242,7 +272,7 @@ describe('API/extmarks', function() eq({{marks[1], positions[1][1], positions[1][2]}}, rv) end) - it('querying for information with limit #extmarks', function() + it('querying for information with limit', function() -- add some more marks for i, m in ipairs(marks) do if positions[i] ~= nil then @@ -267,7 +297,7 @@ describe('API/extmarks', function() eq(3, table.getn(rv)) end) - it('get_marks works when mark col > upper col #extmarks', function() + it('get_marks works when mark col > upper col', function() feed('A12345') feed('A12345') set_extmark(ns, 10, 0, 2) -- this shouldn't be found @@ -281,7 +311,7 @@ describe('API/extmarks', function() get_extmarks(ns, {0, 3}, {2, 0})) end) - it('get_marks works in reverse when mark col < lower col #extmarks', function() + it('get_marks works in reverse when mark col < lower col', function() feed('A12345') feed('A12345') set_extmark(ns, 10, 0, 1) -- this shouldn't be found @@ -296,27 +326,27 @@ describe('API/extmarks', function() rv) end) - it('get_marks limit=0 returns nothing #extmarks', function() + it('get_marks limit=0 returns nothing', function() set_extmark(ns, marks[1], positions[1][1], positions[1][2]) local rv = get_extmarks(ns, {-1, -1}, {-1, -1}, {limit=0}) eq({}, rv) end) - it('marks move with line insertations #extmarks', function() + it('marks move with line insertations', function() set_extmark(ns, marks[1], 0, 0) feed("yyP") check_undo_redo(ns, marks[1], 0, 0, 1, 0) end) - it('marks move with multiline insertations #extmarks', function() + it('marks move with multiline insertations', function() feed("a2233") set_extmark(ns, marks[1], 1, 1) feed('ggVGyP') check_undo_redo(ns, marks[1], 1, 1, 4, 1) end) - it('marks move with line join #extmarks', function() + it('marks move with line join', function() -- do_join in ops.c feed("a222") set_extmark(ns, marks[1], 1, 0) @@ -324,7 +354,9 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 1, 0, 0, 6) end) - it('join works when no marks are present #extmarks', function() + it('join works when no marks are present', function() + screen = Screen.new(15, 10) + screen:attach() feed("a1") feed('kJ') -- This shouldn't seg fault @@ -342,7 +374,7 @@ describe('API/extmarks', function() ]]) end) - it('marks move with multiline join #extmarks', function() + it('marks move with multiline join', function() -- do_join in ops.c feed("a222333444") set_extmark(ns, marks[1], 3, 0) @@ -350,14 +382,14 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 3, 0, 1, 8) end) - it('marks move with line deletes #extmarks', function() + it('marks move with line deletes', function() feed("a222333444") set_extmark(ns, marks[1], 2, 1) feed('ggjdd') check_undo_redo(ns, marks[1], 2, 1, 1, 1) end) - it('marks move with multiline deletes #extmarks', function() + it('marks move with multiline deletes', function() feed("a222333444") set_extmark(ns, marks[1], 3, 0) feed('gg2dd') @@ -367,7 +399,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 3, 0, 0, 0) end) - it('marks move with open line #extmarks', function() + it('marks move with open line', function() -- open_line in misc1.c -- testing marks below are also moved feed("yyP") @@ -381,8 +413,10 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[2], 2, 4, 3, 4) end) - it('marks move with char inserts #extmarks', function() + it('marks move with char inserts', function() -- insertchar in edit.c (the ins_str branch) + screen = Screen.new(15, 10) + screen:attach() set_extmark(ns, marks[1], 0, 3) feed('0') insert('abc') @@ -400,11 +434,11 @@ describe('API/extmarks', function() ]]) local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({0, 6}, rv) - -- check_undo_redo(ns, marks[1], 0, 2, 0, 5) + check_undo_redo(ns, marks[1], 0, 3, 0, 6) end) -- gravity right as definted in tk library - it('marks have gravity right #extmarks', function() + it('marks have gravity right', function() -- insertchar in edit.c (the ins_str branch) set_extmark(ns, marks[1], 0, 2) feed('03l') @@ -417,7 +451,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 0, 2, 0, 2) end) - it('we can insert multibyte chars #extmarks', function() + it('we can insert multibyte chars', function() -- insertchar in edit.c feed('a12345') set_extmark(ns, marks[1], 1, 2) @@ -426,7 +460,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 1, 2, 1, 5) end) - it('marks move with blockwise inserts #extmarks', function() + it('marks move with blockwise inserts', function() -- op_insert in ops.c feed('a12345') set_extmark(ns, marks[1], 1, 2) @@ -434,7 +468,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 1, 2, 1, 3) end) - it('marks move with line splits (using enter) #extmarks', function() + it('marks move with line splits (using enter)', function() -- open_line in misc1.c -- testing marks below are also moved feed("yyP") @@ -445,14 +479,14 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[2], 1, 4, 2, 4) end) - it('marks at last line move on insert new line #extmarks', function() + it('marks at last line move on insert new line', function() -- open_line in misc1.c set_extmark(ns, marks[1], 0, 4) feed('0i') check_undo_redo(ns, marks[1], 0, 4, 1, 4) end) - it('yet again marks move with line splits #extmarks', function() + it('yet again marks move with line splits', function() -- the first test above wasn't catching all errors.. feed("A67890") set_extmark(ns, marks[1], 0, 4) @@ -460,7 +494,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 0, 4, 1, 0) end) - it('and one last time line splits... #extmarks', function() + it('and one last time line splits...', function() set_extmark(ns, marks[1], 0, 1) set_extmark(ns, marks[2], 0, 2) feed("02li") @@ -468,7 +502,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[2], 0, 2, 1, 0) end) - it('multiple marks move with mark splits #extmarks', function() + it('multiple marks move with mark splits', function() set_extmark(ns, marks[1], 0, 1) set_extmark(ns, marks[2], 0, 3) feed("0li") @@ -476,21 +510,21 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[2], 0, 3, 1, 2) end) - it('deleting right before a mark works #extmarks', function() + it('deleting right before a mark works', function() -- op_delete in ops.c set_extmark(ns, marks[1], 0, 2) feed('0lx') check_undo_redo(ns, marks[1], 0, 2, 0, 1) end) - it('deleting on a mark works #extmarks', function() + it('deleting right after a mark works', function() -- op_delete in ops.c set_extmark(ns, marks[1], 0, 2) feed('02lx') check_undo_redo(ns, marks[1], 0, 2, 0, 2) end) - it('marks move with char deletes #extmarks', function() + it('marks move with char deletes', function() -- op_delete in ops.c set_extmark(ns, marks[1], 0, 2) feed('02dl') @@ -500,7 +534,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 0, 0, 0, 0) end) - it('marks move with char deletes over a range #extmarks', function() + it('marks move with char deletes over a range', function() -- op_delete in ops.c set_extmark(ns, marks[1], 0, 2) set_extmark(ns, marks[2], 0, 3) @@ -513,7 +547,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[2], 0, 3, 0, 3) end) - it('deleting marks at end of line works #extmarks', function() + it('deleting marks at end of line works', function() -- mark_extended.c/extmark_col_adjust_delete set_extmark(ns, marks[1], 0, 4) feed('$x') @@ -525,7 +559,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 0, 4, 0, 4) end) - it('marks move with blockwise deletes #extmarks', function() + it('marks move with blockwise deletes', function() -- op_delete in ops.c feed('a12345') set_extmark(ns, marks[1], 1, 4) @@ -533,7 +567,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 1, 4, 1, 1) end) - it('marks move with blockwise deletes over a range #extmarks', function() + it('marks move with blockwise deletes over a range', function() -- op_delete in ops.c feed('a12345') set_extmark(ns, marks[1], 0, 1) @@ -550,7 +584,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[3], 1, 2, 1, 2) end) - it('works with char deletes over multilines #extmarks', function() + it('works with char deletes over multilines', function() feed('a12345test-me') set_extmark(ns, marks[1], 2, 5) feed('gg') @@ -558,7 +592,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 2, 5, 0, 0) end) - it('marks outside of deleted range move with visual char deletes #extmarks', function() + it('marks outside of deleted range move with visual char deletes', function() -- op_delete in ops.c set_extmark(ns, marks[1], 0, 3) feed('0vx') @@ -577,7 +611,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 0, 0, 0, 0) end) - it('marks outside of deleted range move with char deletes #extmarks', function() + it('marks outside of deleted range move with char deletes', function() -- op_delete in ops.c set_extmark(ns, marks[1], 0, 3) feed('0x') @@ -597,7 +631,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 0, 3, 0, 3) end) - it('marks move with P(backward) paste #extmarks', function() + it('marks move with P(backward) paste', function() -- do_put in ops.c feed('0iabc') set_extmark(ns, marks[1], 0, 7) @@ -605,15 +639,15 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 0, 7, 0, 15) end) - it('marks move with p(forward) paste #extmarks', function() + it('marks move with p(forward) paste', function() -- do_put in ops.c feed('0iabc') set_extmark(ns, marks[1], 0, 7) feed('0veyp') - check_undo_redo(ns, marks[1], 0, 7, 0, 14) + check_undo_redo(ns, marks[1], 0, 7, 0, 15) end) - it('marks move with blockwise P(backward) paste #extmarks', function() + it('marks move with blockwise P(backward) paste', function() -- do_put in ops.c feed('a12345') set_extmark(ns, marks[1], 1, 4) @@ -621,42 +655,84 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 1, 4, 1, 7) end) - it('marks move with blockwise p(forward) paste #extmarks', function() + it('marks move with blockwise p(forward) paste', function() -- do_put in ops.c feed('a12345') set_extmark(ns, marks[1], 1, 4) feed('hhkyp') - check_undo_redo(ns, marks[1], 1, 4, 1, 6) + check_undo_redo(ns, marks[1], 1, 4, 1, 7) end) - it('replace works #extmarks', function() + describe('multiline regions', function() + before_each(function() + feed('dd') + -- Achtung: code has been spiced with some unicode, + -- to make life more interesting. + -- luacheck whines about TABs inside strings for whatever reason. + -- luacheck: push ignore 621 + insert([[ + static int nlua_rpcrequest(lua_State *lstate) + { + Ïf (!nlua_is_deferred_safe(lstate)) { + // strictly not allowed + Яetörn luaL_error(lstate, e_luv_api_disabled, "rpcrequest"); + } + return nlua_rpc(lstate, true); + }]]) + -- luacheck: pop + end) + + it('delete', function() + local pos1 = { + {2, 4}, {2, 12}, {2, 13}, {2, 14}, {2, 25}, + {4, 8}, {4, 10}, {4, 20}, + {5, 3}, {6, 10} + } + local ids = batch_set(ns, pos1) + batch_check(ns, ids, pos1) + feed('3Gfiv2+ftd') + batch_check_undo_redo(ns, ids, pos1, { + {2, 4}, {2, 12}, {2, 13}, {2, 13}, {2, 13}, + {2, 13}, {2, 15}, {2, 25}, + {3, 3}, {4, 10} + }) + end) + + -- TODO(bfredl): add more tests! + end) + + it('replace works', function() set_extmark(ns, marks[1], 0, 2) feed('0r2') check_undo_redo(ns, marks[1], 0, 2, 0, 2) end) - it('blockwise replace works #extmarks', function() + it('blockwise replace works', function() feed('a12345') set_extmark(ns, marks[1], 0, 2) feed('0llkr1') - check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[1], 0, 2, 0, 3) end) - it('shift line #extmarks', function() + it('shift line', function() -- shift_line in ops.c feed(':set shiftwidth=4') set_extmark(ns, marks[1], 0, 2) feed('0>>') check_undo_redo(ns, marks[1], 0, 2, 0, 6) + expect(' 12345') feed('>>') - check_undo_redo(ns, marks[1], 0, 6, 0, 10) + -- this is counter-intuitive. But what happens + -- is that 4 spaces gets extended to one tab (== 8 spaces) + check_undo_redo(ns, marks[1], 0, 6, 0, 3) + expect('\t12345') feed('') -- have to escape, same as << - check_undo_redo(ns, marks[1], 0, 10, 0, 6) + check_undo_redo(ns, marks[1], 0, 3, 0, 6) end) - it('blockwise shift #extmarks', function() + it('blockwise shift', function() -- shift_block in ops.c feed(':set shiftwidth=4') feed('a12345') @@ -664,13 +740,14 @@ describe('API/extmarks', function() feed('0k>') check_undo_redo(ns, marks[1], 1, 2, 1, 6) feed('j>') - check_undo_redo(ns, marks[1], 1, 6, 1, 10) + expect('\t12345\n\t12345') + check_undo_redo(ns, marks[1], 1, 6, 1, 3) feed('j') - check_undo_redo(ns, marks[1], 1, 10, 1, 6) + check_undo_redo(ns, marks[1], 1, 3, 1, 6) end) - it('tab works with expandtab #extmarks', function() + it('tab works with expandtab', function() -- ins_tab in edit.c feed(':set expandtab') feed(':set shiftwidth=2') @@ -679,7 +756,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 0, 2, 0, 6) end) - it('tabs work #extmarks', function() + it('tabs work', function() -- ins_tab in edit.c feed(':set noexpandtab') feed(':set shiftwidth=2') @@ -692,7 +769,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 0, 4, 0, 6) end) - it('marks move when using :move #extmarks', function() + it('marks move when using :move', function() set_extmark(ns, marks[1], 0, 0) feed('A2:1move 2') check_undo_redo(ns, marks[1], 0, 0, 1, 0) @@ -701,7 +778,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 1, 0, 0, 0) end) - it('marks move when using :move part 2 #extmarks', function() + it('marks move when using :move part 2', function() -- make sure we didn't get lucky with the math... feed('A23456') set_extmark(ns, marks[1], 1, 0) @@ -712,7 +789,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 3, 0, 1, 0) end) - it('undo and redo of set and unset marks #extmarks', function() + it('undo and redo of set and unset marks', function() -- Force a new undo head feed('o') set_extmark(ns, marks[1], 0, 1) @@ -722,7 +799,7 @@ describe('API/extmarks', function() feed("u") local rv = get_extmarks(ns, {0, 0}, {-1, -1}) - eq(1, table.getn(rv)) + eq(3, table.getn(rv)) feed("") rv = get_extmarks(ns, {0, 0}, {-1, -1}) @@ -735,20 +812,22 @@ describe('API/extmarks', function() eq(1, table.getn(rv)) feed("u") feed("") - check_undo_redo(ns, marks[1], 0, 1, positions[1][1], positions[1][2]) + -- old value is NOT kept in history + check_undo_redo(ns, marks[1], positions[1][1], positions[1][2], positions[1][1], positions[1][2]) -- Test unset feed('o') curbufmeths.del_extmark(ns, marks[3]) feed("u") rv = get_extmarks(ns, {0, 0}, {-1, -1}) - eq(3, table.getn(rv)) + -- undo does NOT restore deleted marks + eq(2, table.getn(rv)) feed("") rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(2, table.getn(rv)) end) - it('undo and redo of marks deleted during edits #extmarks', function() + it('undo and redo of marks deleted during edits', function() -- test extmark_adjust feed('A12345') set_extmark(ns, marks[1], 1, 2) @@ -756,7 +835,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 1, 2, 1, 0) end) - it('namespaces work properly #extmarks', function() + it('namespaces work properly', function() local rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) eq(1, rv) rv = set_extmark(ns2, marks[1], positions[1][1], positions[1][2]) @@ -802,7 +881,7 @@ describe('API/extmarks', function() eq(2, table.getn(rv)) end) - it('mark set can create unique identifiers #extmarks', function() + it('mark set can create unique identifiers', function() -- create mark with id 1 eq(1, set_extmark(ns, 1, positions[1][1], positions[1][2])) -- ask for unique id, it should be the next one, i e 2 @@ -817,7 +896,7 @@ describe('API/extmarks', function() eq(8, set_extmark(ns, 0, positions[1][1], positions[1][2])) end) - it('auto indenting with enter works #extmarks', function() + it('auto indenting with enter works', function() -- op_reindent in ops.c feed(':set cindent') feed(':set autoindent') @@ -835,7 +914,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[1], 0, 12, 1, 3) end) - it('auto indenting entire line works #extmarks', function() + it('auto indenting entire line works', function() feed(':set cindent') feed(':set autoindent') feed(':set shiftwidth=2') @@ -852,7 +931,7 @@ describe('API/extmarks', function() eq({1, 3}, rv) end) - it('removing auto indenting with works #extmarks', function() + it('removing auto indenting with works', function() feed(':set cindent') feed(':set autoindent') feed(':set shiftwidth=2') @@ -868,7 +947,7 @@ describe('API/extmarks', function() eq({0, 1}, rv) end) - it('indenting multiple lines with = works #extmarks', function() + it('indenting multiple lines with = works', function() feed(':set cindent') feed(':set autoindent') feed(':set shiftwidth=2') @@ -880,7 +959,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[2], 2, 1, 2, 5) end) - it('substitutes by deleting inside the replace matches #extmarks_sub', function() + it('substitutes by deleting inside the replace matches', function() -- do_sub in ex_cmds.c set_extmark(ns, marks[1], 0, 2) set_extmark(ns, marks[2], 0, 3) @@ -889,7 +968,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[2], 0, 3, 0, 4) end) - it('substitutes when insert text > deleted #extmarks_sub', function() + it('substitutes when insert text > deleted', function() -- do_sub in ex_cmds.c set_extmark(ns, marks[1], 0, 2) set_extmark(ns, marks[2], 0, 3) @@ -898,7 +977,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[2], 0, 3, 0, 5) end) - it('substitutes when marks around eol #extmarks_sub', function() + it('substitutes when marks around eol', function() -- do_sub in ex_cmds.c set_extmark(ns, marks[1], 0, 4) set_extmark(ns, marks[2], 0, 5) @@ -907,7 +986,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[2], 0, 5, 0, 7) end) - it('substitutes over range insert text > deleted #extmarks_sub', function() + it('substitutes over range insert text > deleted', function() -- do_sub in ex_cmds.c feed('Ax34xx') feed('Axxx34') @@ -920,7 +999,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[3], 2, 4, 2, 6) end) - it('substitutes multiple matches in a line #extmarks_sub', function() + it('substitutes multiple matches in a line', function() -- do_sub in ex_cmds.c feed('ddi3x3x3') set_extmark(ns, marks[1], 0, 0) @@ -932,7 +1011,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[3], 0, 4, 0, 8) end) - it('substitions over multiple lines with newline in pattern #extmarks_sub', function() + it('substitions over multiple lines with newline in pattern', function() feed('A67890xx') set_extmark(ns, marks[1], 0, 3) set_extmark(ns, marks[2], 0, 4) @@ -947,7 +1026,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[5], 2, 0, 1, 0) end) - it('inserting #extmarks_sub', function() + it('inserting', function() feed('A67890xx') set_extmark(ns, marks[1], 0, 3) set_extmark(ns, marks[2], 0, 4) @@ -964,7 +1043,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[6], 1, 2, 0, 5) end) - it('substitions with multiple newlines in pattern #extmarks_sub', function() + it('substitions with multiple newlines in pattern', function() feed('A67890xx') set_extmark(ns, marks[1], 0, 4) set_extmark(ns, marks[2], 0, 5) @@ -979,7 +1058,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[5], 2, 0, 0, 6) end) - it('substitions over multiple lines with replace in substition #extmarks_sub', function() + it('substitions over multiple lines with replace in substition', function() feed('A67890xx') set_extmark(ns, marks[1], 0, 1) set_extmark(ns, marks[2], 0, 2) @@ -997,7 +1076,7 @@ describe('API/extmarks', function() eq({1, 3}, curbufmeths.get_extmark_by_id(ns, marks[3])) end) - it('substitions over multiple lines with replace in substition #extmarks_sub', function() + it('substitions over multiple lines with replace in substition', function() feed('Ax3xx') set_extmark(ns, marks[1], 1, 0) set_extmark(ns, marks[2], 1, 1) @@ -1008,7 +1087,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[3], 1, 2, 2, 0) end) - it('substitions over multiple lines with replace in substition #extmarks_sub', function() + it('substitions over multiple lines with replace in substition', function() feed('Ax3xx') set_extmark(ns, marks[1], 0, 1) set_extmark(ns, marks[2], 0, 2) @@ -1026,7 +1105,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[3], 0, 4, 1, 3) end) - it('substitions with newline in match and sub, delta is 0 #extmarks_sub', function() + it('substitions with newline in match and sub, delta is 0', function() feed('A67890xx') set_extmark(ns, marks[1], 0, 3) set_extmark(ns, marks[2], 0, 4) @@ -1043,7 +1122,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[6], 2, 0, 2, 0) end) - it('substitions with newline in match and sub, delta > 0 #extmarks_sub', function() + it('substitions with newline in match and sub, delta > 0', function() feed('A67890xx') set_extmark(ns, marks[1], 0, 3) set_extmark(ns, marks[2], 0, 4) @@ -1060,7 +1139,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[6], 2, 0, 3, 0) end) - it('substitions with newline in match and sub, delta < 0 #extmarks_sub', function() + it('substitions with newline in match and sub, delta < 0', function() feed('A67890xxxx') set_extmark(ns, marks[1], 0, 3) set_extmark(ns, marks[2], 0, 4) @@ -1079,7 +1158,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[7], 3, 0, 2, 0) end) - it('substitions with backrefs, newline inserted into sub #extmarks_sub', function() + it('substitions with backrefs, newline inserted into sub', function() feed('A67890xxxx') set_extmark(ns, marks[1], 0, 3) set_extmark(ns, marks[2], 0, 4) @@ -1096,7 +1175,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[6], 2, 0, 3, 0) end) - it('substitions a ^ #extmarks_sub', function() + it('substitions a ^', function() set_extmark(ns, marks[1], 0, 0) set_extmark(ns, marks[2], 0, 1) feed([[:s:^:x]]) @@ -1104,7 +1183,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[2], 0, 1, 0, 2) end) - it('using without increase in order of magnitude #extmarks_inc_dec', function() + it('using without increase in order of magnitude', function() -- do_addsub in ops.c feed('ddiabc998xxxTc') set_extmark(ns, marks[1], 0, 2) @@ -1120,7 +1199,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[5], 0, 7, 0, 7) end) - it('using when increase in order of magnitude #extmarks_inc_dec', function() + it('using when increase in order of magnitude', function() -- do_addsub in ops.c feed('ddiabc999xxxTc') set_extmark(ns, marks[1], 0, 2) @@ -1136,7 +1215,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[5], 0, 7, 0, 8) end) - it('using when negative and without decrease in order of magnitude #extmarks_inc_dec', function() + it('using when negative and without decrease in order of magnitude', function() feed('ddiabc-999xxxT-') set_extmark(ns, marks[1], 0, 2) set_extmark(ns, marks[2], 0, 3) @@ -1151,7 +1230,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[5], 0, 8, 0, 8) end) - it('using when negative and decrease in order of magnitude #extmarks_inc_dec', function() + it('using when negative and decrease in order of magnitude', function() feed('ddiabc-1000xxxT-') set_extmark(ns, marks[1], 0, 2) set_extmark(ns, marks[2], 0, 3) @@ -1166,7 +1245,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[5], 0, 9, 0, 8) end) - it('using without decrease in order of magnitude #extmarks_inc_dec', function() + it('using without decrease in order of magnitude', function() -- do_addsub in ops.c feed('ddiabc999xxxTc') set_extmark(ns, marks[1], 0, 2) @@ -1182,7 +1261,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[5], 0, 7, 0, 7) end) - it('using when decrease in order of magnitude #extmarks_inc_dec', function() + it('using when decrease in order of magnitude', function() -- do_addsub in ops.c feed('ddiabc1000xxxTc') set_extmark(ns, marks[1], 0, 2) @@ -1198,7 +1277,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[5], 0, 8, 0, 7) end) - it('using when negative and without increase in order of magnitude #extmarks_inc_dec', function() + it('using when negative and without increase in order of magnitude', function() feed('ddiabc-998xxxT-') set_extmark(ns, marks[1], 0, 2) set_extmark(ns, marks[2], 0, 3) @@ -1213,7 +1292,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[5], 0, 8, 0, 8) end) - it('using when negative and increase in order of magnitude #extmarks_inc_dec', function() + it('using when negative and increase in order of magnitude', function() feed('ddiabc-999xxxT-') set_extmark(ns, marks[1], 0, 2) set_extmark(ns, marks[2], 0, 3) @@ -1236,7 +1315,7 @@ describe('API/extmarks', function() eq("Invalid ns_id", pcall_err(curbufmeths.get_extmark_by_id, ns_invalid, marks[1])) end) - it('when col = line-length, set the mark on eol #extmarks', function() + it('when col = line-length, set the mark on eol', function() set_extmark(ns, marks[1], 0, -1) local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({0, init_text:len()}, rv) @@ -1246,19 +1325,19 @@ describe('API/extmarks', function() eq({0, init_text:len()}, rv) end) - it('when col = line-length, set the mark on eol #extmarks', function() + it('when col = line-length, set the mark on eol', function() local invalid_col = init_text:len() + 1 eq("col value outside range", pcall_err(set_extmark, ns, marks[1], 0, invalid_col)) end) - it('fails when line > line_count #extmarks', function() + it('fails when line > line_count', function() local invalid_col = init_text:len() + 1 local invalid_lnum = 3 eq('line value outside range', pcall_err(set_extmark, ns, marks[1], invalid_lnum, invalid_col)) eq({}, curbufmeths.get_extmark_by_id(ns, marks[1])) end) - it('bug from check_col in extmark_set #extmarks_sub', function() + it('bug from check_col in extmark_set', function() -- This bug was caused by extmark_set always using check_col. check_col -- always uses the current buffer. This wasn't working during undo so we -- now use check_col and check_lnum only when they are required. @@ -1282,6 +1361,16 @@ describe('API/extmarks', function() local id = bufmeths.set_extmark(buf, ns, 0, 1, 0, {}) eq({{id, 1, 0}}, bufmeths.get_extmarks(buf, ns, 0, -1, {})) end) + + it('does not crash with append/delete/undo seqence', function() + meths.exec([[ + let ns = nvim_create_namespace('myplugin') + call nvim_buf_set_extmark(0, ns, 0, 0, 0, {}) + call append(0, '') + %delete + undo]],false) + eq(2, meths.eval('1+1')) -- did not crash + end) end) describe('Extmarks buffer api with many marks', function() @@ -1326,12 +1415,12 @@ describe('Extmarks buffer api with many marks', function() return marks end - it("can get marks #extmarks", function() + it("can get marks", function() eq(ns_marks[ns1], get_marks(ns1)) eq(ns_marks[ns2], get_marks(ns2)) end) - it("can clear all marks in ns #extmarks", function() + it("can clear all marks in ns", function() curbufmeths.clear_namespace(ns1, 0, -1) eq({}, get_marks(ns1)) eq(ns_marks[ns2], get_marks(ns2)) @@ -1340,7 +1429,7 @@ describe('Extmarks buffer api with many marks', function() eq({}, get_marks(ns2)) end) - it("can clear line range #extmarks", function() + it("can clear line range", function() curbufmeths.clear_namespace(ns1, 10, 20) for id, mark in pairs(ns_marks[ns1]) do if 10 <= mark[1] and mark[1] < 20 then @@ -1351,7 +1440,7 @@ describe('Extmarks buffer api with many marks', function() eq(ns_marks[ns2], get_marks(ns2)) end) - it("can delete line #extmarks", function() + it("can delete line", function() feed('10Gdd') for _, marks in pairs(ns_marks) do for id, mark in pairs(marks) do @@ -1366,7 +1455,7 @@ describe('Extmarks buffer api with many marks', function() eq(ns_marks[ns2], get_marks(ns2)) end) - it("can delete lines #extmarks", function() + it("can delete lines", function() feed('10G10dd') for _, marks in pairs(ns_marks) do for id, mark in pairs(marks) do @@ -1381,7 +1470,7 @@ describe('Extmarks buffer api with many marks', function() eq(ns_marks[ns2], get_marks(ns2)) end) - it("can wipe buffer #extmarks", function() + it("can wipe buffer", function() command('bwipe!') eq({}, get_marks(ns1)) eq({}, get_marks(ns2)) -- cgit From 48a869dc6d29514e943070da9f22f702f5179826 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Mon, 20 Jan 2020 19:29:12 +0100 Subject: shed biking: it's always extmarks, never marks extended --- test/functional/api/extmark_spec.lua | 1477 +++++++++++++++++++++++++++ test/functional/api/mark_extended_spec.lua | 1478 ---------------------------- 2 files changed, 1477 insertions(+), 1478 deletions(-) create mode 100644 test/functional/api/extmark_spec.lua delete mode 100644 test/functional/api/mark_extended_spec.lua (limited to 'test/functional/api') diff --git a/test/functional/api/extmark_spec.lua b/test/functional/api/extmark_spec.lua new file mode 100644 index 0000000000..5bf3fa554f --- /dev/null +++ b/test/functional/api/extmark_spec.lua @@ -0,0 +1,1477 @@ +local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') + +local request = helpers.request +local eq = helpers.eq +local ok = helpers.ok +local curbufmeths = helpers.curbufmeths +local bufmeths = helpers.bufmeths +local pcall_err = helpers.pcall_err +local insert = helpers.insert +local feed = helpers.feed +local clear = helpers.clear +local command = helpers.command +local meths = helpers.meths + +local function expect(contents) + return eq(contents, helpers.curbuf_contents()) +end + +local function check_undo_redo(ns, mark, sr, sc, er, ec) --s = start, e = end + local rv = curbufmeths.get_extmark_by_id(ns, mark) + eq({er, ec}, rv) + feed("u") + rv = curbufmeths.get_extmark_by_id(ns, mark) + eq({sr, sc}, rv) + feed("") + rv = curbufmeths.get_extmark_by_id(ns, mark) + eq({er, ec}, rv) +end + +local function set_extmark(ns_id, id, line, col, opts) + if opts == nil then + opts = {} + end + return curbufmeths.set_extmark(ns_id, id, line, col, opts) +end + +local function get_extmarks(ns_id, start, end_, opts) + if opts == nil then + opts = {} + end + return curbufmeths.get_extmarks(ns_id, start, end_, opts) +end + +local function batch_set(ns_id, positions) + local ids = {} + for _, pos in ipairs(positions) do + table.insert(ids, set_extmark(ns_id, 0, pos[1], pos[2])) + end + return ids +end + +local function batch_check(ns_id, ids, positions) + local actual, expected = {}, {} + for i,id in ipairs(ids) do + expected[id] = positions[i] + end + for _, mark in pairs(get_extmarks(ns_id, 0, -1, {})) do + actual[mark[1]] = {mark[2], mark[3]} + end + eq(expected, actual) +end + +local function batch_check_undo_redo(ns_id, ids, before, after) + batch_check(ns_id, ids, after) + feed("u") + batch_check(ns_id, ids, before) + feed("") + batch_check(ns_id, ids, after) +end + +describe('API/extmarks', function() + local screen + local marks, positions, init_text, row, col + local ns, ns2 + + before_each(function() + -- Initialize some namespaces and insert 12345 into a buffer + marks = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} + positions = {{0, 0,}, {0, 2}, {0, 3}} + + init_text = "12345" + row = 0 + col = 2 + + clear() + + insert(init_text) + ns = request('nvim_create_namespace', "my-fancy-plugin") + ns2 = request('nvim_create_namespace', "my-fancy-plugin2") + end) + + it('adds, updates and deletes marks', function() + local rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + eq(marks[1], rv) + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({positions[1][1], positions[1][2]}, rv) + -- Test adding a second mark on same row works + rv = set_extmark(ns, marks[2], positions[2][1], positions[2][2]) + eq(marks[2], rv) + + -- Test an update, (same pos) + rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + eq(marks[1], rv) + rv = curbufmeths.get_extmark_by_id(ns, marks[2]) + eq({positions[2][1], positions[2][2]}, rv) + -- Test an update, (new pos) + row = positions[1][1] + col = positions[1][2] + 1 + rv = set_extmark(ns, marks[1], row, col) + eq(marks[1], rv) + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({row, col}, rv) + + -- remove the test marks + eq(true, curbufmeths.del_extmark(ns, marks[1])) + eq(false, curbufmeths.del_extmark(ns, marks[1])) + eq(true, curbufmeths.del_extmark(ns, marks[2])) + eq(false, curbufmeths.del_extmark(ns, marks[3])) + eq(false, curbufmeths.del_extmark(ns, 1000)) + end) + + it('can clear a specific namespace range', function() + set_extmark(ns, 1, 0, 1) + set_extmark(ns2, 1, 0, 1) + -- force a new undo buffer + feed('o') + curbufmeths.clear_namespace(ns2, 0, -1) + eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + feed('u') + eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + feed('') + eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + end) + + it('can clear a namespace range using 0,-1', function() + set_extmark(ns, 1, 0, 1) + set_extmark(ns2, 1, 0, 1) + -- force a new undo buffer + feed('o') + curbufmeths.clear_namespace(-1, 0, -1) + eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + feed('u') + eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + feed('') + eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + end) + + it('querying for information and ranges', function() + --marks = {1, 2, 3} + --positions = {{0, 0,}, {0, 2}, {0, 3}} + -- add some more marks + for i, m in ipairs(marks) do + if positions[i] ~= nil then + local rv = set_extmark(ns, m, positions[i][1], positions[i][2]) + eq(m, rv) + end + end + + -- {0, 0} and {-1, -1} work as extreme values + eq({{1, 0, 0}}, get_extmarks(ns, {0, 0}, {0, 0})) + eq({}, get_extmarks(ns, {-1, -1}, {-1, -1})) + local rv = get_extmarks(ns, {0, 0}, {-1, -1}) + for i, m in ipairs(marks) do + if positions[i] ~= nil then + eq({m, positions[i][1], positions[i][2]}, rv[i]) + end + end + + -- 0 and -1 works as short hand extreme values + eq({{1, 0, 0}}, get_extmarks(ns, 0, 0)) + eq({}, get_extmarks(ns, -1, -1)) + rv = get_extmarks(ns, 0, -1) + for i, m in ipairs(marks) do + if positions[i] ~= nil then + eq({m, positions[i][1], positions[i][2]}, rv[i]) + end + end + + -- next with mark id + rv = get_extmarks(ns, marks[1], {-1, -1}, {limit=1}) + eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + rv = get_extmarks(ns, marks[2], {-1, -1}, {limit=1}) + eq({{marks[2], positions[2][1], positions[2][2]}}, rv) + -- next with positional when mark exists at position + rv = get_extmarks(ns, positions[1], {-1, -1}, {limit=1}) + eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + -- next with positional index (no mark at position) + rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, {limit=1}) + eq({{marks[2], positions[2][1], positions[2][2]}}, rv) + -- next with Extremity index + rv = get_extmarks(ns, {0,0}, {-1, -1}, {limit=1}) + eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + + -- nextrange with mark id + rv = get_extmarks(ns, marks[1], marks[3]) + eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) + eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) + -- nextrange with `limit` + rv = get_extmarks(ns, marks[1], marks[3], {limit=2}) + eq(2, table.getn(rv)) + -- nextrange with positional when mark exists at position + rv = get_extmarks(ns, positions[1], positions[3]) + eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) + eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) + rv = get_extmarks(ns, positions[2], positions[3]) + eq(2, table.getn(rv)) + -- nextrange with positional index (no mark at position) + local lower = {positions[1][1], positions[2][2] -1} + local upper = {positions[2][1], positions[3][2] - 1} + rv = get_extmarks(ns, lower, upper) + eq({{marks[2], positions[2][1], positions[2][2]}}, rv) + lower = {positions[3][1], positions[3][2] + 1} + upper = {positions[3][1], positions[3][2] + 2} + rv = get_extmarks(ns, lower, upper) + eq({}, rv) + -- nextrange with extremity index + lower = {positions[2][1], positions[2][2]+1} + upper = {-1, -1} + rv = get_extmarks(ns, lower, upper) + eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + + -- prev with mark id + rv = get_extmarks(ns, marks[3], {0, 0}, {limit=1}) + eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + rv = get_extmarks(ns, marks[2], {0, 0}, {limit=1}) + eq({{marks[2], positions[2][1], positions[2][2]}}, rv) + -- prev with positional when mark exists at position + rv = get_extmarks(ns, positions[3], {0, 0}, {limit=1}) + eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + -- prev with positional index (no mark at position) + rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, {limit=1}) + eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + -- prev with Extremity index + rv = get_extmarks(ns, {-1,-1}, {0,0}, {limit=1}) + eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + + -- prevrange with mark id + rv = get_extmarks(ns, marks[3], marks[1]) + eq({marks[3], positions[3][1], positions[3][2]}, rv[1]) + eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) + eq({marks[1], positions[1][1], positions[1][2]}, rv[3]) + -- prevrange with limit + rv = get_extmarks(ns, marks[3], marks[1], {limit=2}) + eq(2, table.getn(rv)) + -- prevrange with positional when mark exists at position + rv = get_extmarks(ns, positions[3], positions[1]) + eq({{marks[3], positions[3][1], positions[3][2]}, + {marks[2], positions[2][1], positions[2][2]}, + {marks[1], positions[1][1], positions[1][2]}}, rv) + rv = get_extmarks(ns, positions[2], positions[1]) + eq(2, table.getn(rv)) + -- prevrange with positional index (no mark at position) + lower = {positions[2][1], positions[2][2] + 1} + upper = {positions[3][1], positions[3][2] + 1} + rv = get_extmarks(ns, upper, lower) + eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + lower = {positions[3][1], positions[3][2] + 1} + upper = {positions[3][1], positions[3][2] + 2} + rv = get_extmarks(ns, upper, lower) + eq({}, rv) + -- prevrange with extremity index + lower = {0,0} + upper = {positions[2][1], positions[2][2] - 1} + rv = get_extmarks(ns, upper, lower) + eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + end) + + it('querying for information with limit', function() + -- add some more marks + for i, m in ipairs(marks) do + if positions[i] ~= nil then + local rv = set_extmark(ns, m, positions[i][1], positions[i][2]) + eq(m, rv) + end + end + + local rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=1}) + eq(1, table.getn(rv)) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=2}) + eq(2, table.getn(rv)) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=3}) + eq(3, table.getn(rv)) + + -- now in reverse + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=1}) + eq(1, table.getn(rv)) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=2}) + eq(2, table.getn(rv)) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=3}) + eq(3, table.getn(rv)) + end) + + it('get_marks works when mark col > upper col', function() + feed('A12345') + feed('A12345') + set_extmark(ns, 10, 0, 2) -- this shouldn't be found + set_extmark(ns, 11, 2, 1) -- this shouldn't be found + set_extmark(ns, marks[1], 0, 4) -- check col > our upper bound + set_extmark(ns, marks[2], 1, 1) -- check col < lower bound + set_extmark(ns, marks[3], 2, 0) -- check is inclusive + eq({{marks[1], 0, 4}, + {marks[2], 1, 1}, + {marks[3], 2, 0}}, + get_extmarks(ns, {0, 3}, {2, 0})) + end) + + it('get_marks works in reverse when mark col < lower col', function() + feed('A12345') + feed('A12345') + set_extmark(ns, 10, 0, 1) -- this shouldn't be found + set_extmark(ns, 11, 2, 4) -- this shouldn't be found + set_extmark(ns, marks[1], 2, 1) -- check col < our lower bound + set_extmark(ns, marks[2], 1, 4) -- check col > upper bound + set_extmark(ns, marks[3], 0, 2) -- check is inclusive + local rv = get_extmarks(ns, {2, 3}, {0, 2}) + eq({{marks[1], 2, 1}, + {marks[2], 1, 4}, + {marks[3], 0, 2}}, + rv) + end) + + it('get_marks limit=0 returns nothing', function() + set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + local rv = get_extmarks(ns, {-1, -1}, {-1, -1}, {limit=0}) + eq({}, rv) + end) + + + it('marks move with line insertations', function() + set_extmark(ns, marks[1], 0, 0) + feed("yyP") + check_undo_redo(ns, marks[1], 0, 0, 1, 0) + end) + + it('marks move with multiline insertations', function() + feed("a2233") + set_extmark(ns, marks[1], 1, 1) + feed('ggVGyP') + check_undo_redo(ns, marks[1], 1, 1, 4, 1) + end) + + it('marks move with line join', function() + -- do_join in ops.c + feed("a222") + set_extmark(ns, marks[1], 1, 0) + feed('ggJ') + check_undo_redo(ns, marks[1], 1, 0, 0, 6) + end) + + it('join works when no marks are present', function() + screen = Screen.new(15, 10) + screen:attach() + feed("a1") + feed('kJ') + -- This shouldn't seg fault + screen:expect([[ + 12345^ 1 | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + | + ]]) + end) + + it('marks move with multiline join', function() + -- do_join in ops.c + feed("a222333444") + set_extmark(ns, marks[1], 3, 0) + feed('2GVGJ') + check_undo_redo(ns, marks[1], 3, 0, 1, 8) + end) + + it('marks move with line deletes', function() + feed("a222333444") + set_extmark(ns, marks[1], 2, 1) + feed('ggjdd') + check_undo_redo(ns, marks[1], 2, 1, 1, 1) + end) + + it('marks move with multiline deletes', function() + feed("a222333444") + set_extmark(ns, marks[1], 3, 0) + feed('gg2dd') + check_undo_redo(ns, marks[1], 3, 0, 1, 0) + -- regression test, undoing multiline delete when mark is on row 1 + feed('ugg3dd') + check_undo_redo(ns, marks[1], 3, 0, 0, 0) + end) + + it('marks move with open line', function() + -- open_line in misc1.c + -- testing marks below are also moved + feed("yyP") + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 1, 4) + feed('1G') + check_undo_redo(ns, marks[1], 0, 4, 1, 4) + check_undo_redo(ns, marks[2], 1, 4, 2, 4) + feed('2Go') + check_undo_redo(ns, marks[1], 1, 4, 1, 4) + check_undo_redo(ns, marks[2], 2, 4, 3, 4) + end) + + it('marks move with char inserts', function() + -- insertchar in edit.c (the ins_str branch) + screen = Screen.new(15, 10) + screen:attach() + set_extmark(ns, marks[1], 0, 3) + feed('0') + insert('abc') + screen:expect([[ + ab^c12345 | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + | + ]]) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({0, 6}, rv) + check_undo_redo(ns, marks[1], 0, 3, 0, 6) + end) + + -- gravity right as definted in tk library + it('marks have gravity right', function() + -- insertchar in edit.c (the ins_str branch) + set_extmark(ns, marks[1], 0, 2) + feed('03l') + insert("X") + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + + -- check multibyte chars + feed('03l') + insert("~~") + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + end) + + it('we can insert multibyte chars', function() + -- insertchar in edit.c + feed('a12345') + set_extmark(ns, marks[1], 1, 2) + -- Insert a fullwidth (two col) tilde, NICE + feed('0i~') + check_undo_redo(ns, marks[1], 1, 2, 1, 5) + end) + + it('marks move with blockwise inserts', function() + -- op_insert in ops.c + feed('a12345') + set_extmark(ns, marks[1], 1, 2) + feed('0lkI9') + check_undo_redo(ns, marks[1], 1, 2, 1, 3) + end) + + it('marks move with line splits (using enter)', function() + -- open_line in misc1.c + -- testing marks below are also moved + feed("yyP") + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 1, 4) + feed('1Gla') + check_undo_redo(ns, marks[1], 0, 4, 1, 2) + check_undo_redo(ns, marks[2], 1, 4, 2, 4) + end) + + it('marks at last line move on insert new line', function() + -- open_line in misc1.c + set_extmark(ns, marks[1], 0, 4) + feed('0i') + check_undo_redo(ns, marks[1], 0, 4, 1, 4) + end) + + it('yet again marks move with line splits', function() + -- the first test above wasn't catching all errors.. + feed("A67890") + set_extmark(ns, marks[1], 0, 4) + feed("04li") + check_undo_redo(ns, marks[1], 0, 4, 1, 0) + end) + + it('and one last time line splits...', function() + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 2) + feed("02li") + check_undo_redo(ns, marks[1], 0, 1, 0, 1) + check_undo_redo(ns, marks[2], 0, 2, 1, 0) + end) + + it('multiple marks move with mark splits', function() + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 3) + feed("0li") + check_undo_redo(ns, marks[1], 0, 1, 1, 0) + check_undo_redo(ns, marks[2], 0, 3, 1, 2) + end) + + it('deleting right before a mark works', function() + -- op_delete in ops.c + set_extmark(ns, marks[1], 0, 2) + feed('0lx') + check_undo_redo(ns, marks[1], 0, 2, 0, 1) + end) + + it('deleting right after a mark works', function() + -- op_delete in ops.c + set_extmark(ns, marks[1], 0, 2) + feed('02lx') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + end) + + it('marks move with char deletes', function() + -- op_delete in ops.c + set_extmark(ns, marks[1], 0, 2) + feed('02dl') + check_undo_redo(ns, marks[1], 0, 2, 0, 0) + -- from the other side (nothing should happen) + feed('$x') + check_undo_redo(ns, marks[1], 0, 0, 0, 0) + end) + + it('marks move with char deletes over a range', function() + -- op_delete in ops.c + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + feed('0l3dl') + check_undo_redo(ns, marks[1], 0, 2, 0, 1) + check_undo_redo(ns, marks[2], 0, 3, 0, 1) + -- delete 1, nothing should happen to our marks + feed('u') + feed('$x') + check_undo_redo(ns, marks[2], 0, 3, 0, 3) + end) + + it('deleting marks at end of line works', function() + set_extmark(ns, marks[1], 0, 4) + feed('$x') + check_undo_redo(ns, marks[1], 0, 4, 0, 4) + -- check the copy happened correctly on delete at eol + feed('$x') + check_undo_redo(ns, marks[1], 0, 4, 0, 3) + feed('u') + check_undo_redo(ns, marks[1], 0, 4, 0, 4) + end) + + it('marks move with blockwise deletes', function() + -- op_delete in ops.c + feed('a12345') + set_extmark(ns, marks[1], 1, 4) + feed('hhhkd') + check_undo_redo(ns, marks[1], 1, 4, 1, 1) + end) + + it('marks move with blockwise deletes over a range', function() + -- op_delete in ops.c + feed('a12345') + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 1, 2) + feed('0k3lx') + check_undo_redo(ns, marks[1], 0, 1, 0, 0) + check_undo_redo(ns, marks[2], 0, 3, 0, 0) + check_undo_redo(ns, marks[3], 1, 2, 1, 0) + -- delete 1, nothing should happen to our marks + feed('u') + feed('$jx') + check_undo_redo(ns, marks[2], 0, 3, 0, 3) + check_undo_redo(ns, marks[3], 1, 2, 1, 2) + end) + + it('works with char deletes over multilines', function() + feed('a12345test-me') + set_extmark(ns, marks[1], 2, 5) + feed('gg') + feed('dv?-m?') + check_undo_redo(ns, marks[1], 2, 5, 0, 0) + end) + + it('marks outside of deleted range move with visual char deletes', function() + -- op_delete in ops.c + set_extmark(ns, marks[1], 0, 3) + feed('0vx') + check_undo_redo(ns, marks[1], 0, 3, 0, 2) + + feed("u") + feed('0vlx') + check_undo_redo(ns, marks[1], 0, 3, 0, 1) + + feed("u") + feed('0v2lx') + check_undo_redo(ns, marks[1], 0, 3, 0, 0) + + -- from the other side (nothing should happen) + feed('$vx') + check_undo_redo(ns, marks[1], 0, 0, 0, 0) + end) + + it('marks outside of deleted range move with char deletes', function() + -- op_delete in ops.c + set_extmark(ns, marks[1], 0, 3) + feed('0x') + check_undo_redo(ns, marks[1], 0, 3, 0, 2) + + feed("u") + feed('02x') + check_undo_redo(ns, marks[1], 0, 3, 0, 1) + + feed("u") + feed('0v3lx') + check_undo_redo(ns, marks[1], 0, 3, 0, 0) + + -- from the other side (nothing should happen) + feed("u") + feed('$vx') + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + end) + + it('marks move with P(backward) paste', function() + -- do_put in ops.c + feed('0iabc') + set_extmark(ns, marks[1], 0, 7) + feed('0veyP') + check_undo_redo(ns, marks[1], 0, 7, 0, 15) + end) + + it('marks move with p(forward) paste', function() + -- do_put in ops.c + feed('0iabc') + set_extmark(ns, marks[1], 0, 7) + feed('0veyp') + check_undo_redo(ns, marks[1], 0, 7, 0, 15) + end) + + it('marks move with blockwise P(backward) paste', function() + -- do_put in ops.c + feed('a12345') + set_extmark(ns, marks[1], 1, 4) + feed('hhkyP') + check_undo_redo(ns, marks[1], 1, 4, 1, 7) + end) + + it('marks move with blockwise p(forward) paste', function() + -- do_put in ops.c + feed('a12345') + set_extmark(ns, marks[1], 1, 4) + feed('hhkyp') + check_undo_redo(ns, marks[1], 1, 4, 1, 7) + end) + + describe('multiline regions', function() + before_each(function() + feed('dd') + -- Achtung: code has been spiced with some unicode, + -- to make life more interesting. + -- luacheck whines about TABs inside strings for whatever reason. + -- luacheck: push ignore 621 + insert([[ + static int nlua_rpcrequest(lua_State *lstate) + { + Ïf (!nlua_is_deferred_safe(lstate)) { + // strictly not allowed + Яetörn luaL_error(lstate, e_luv_api_disabled, "rpcrequest"); + } + return nlua_rpc(lstate, true); + }]]) + -- luacheck: pop + end) + + it('delete', function() + local pos1 = { + {2, 4}, {2, 12}, {2, 13}, {2, 14}, {2, 25}, + {4, 8}, {4, 10}, {4, 20}, + {5, 3}, {6, 10} + } + local ids = batch_set(ns, pos1) + batch_check(ns, ids, pos1) + feed('3Gfiv2+ftd') + batch_check_undo_redo(ns, ids, pos1, { + {2, 4}, {2, 12}, {2, 13}, {2, 13}, {2, 13}, + {2, 13}, {2, 15}, {2, 25}, + {3, 3}, {4, 10} + }) + end) + + -- TODO(bfredl): add more tests! + end) + + it('replace works', function() + set_extmark(ns, marks[1], 0, 2) + feed('0r2') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + end) + + it('blockwise replace works', function() + feed('a12345') + set_extmark(ns, marks[1], 0, 2) + feed('0llkr1') + check_undo_redo(ns, marks[1], 0, 2, 0, 3) + end) + + it('shift line', function() + -- shift_line in ops.c + feed(':set shiftwidth=4') + set_extmark(ns, marks[1], 0, 2) + feed('0>>') + check_undo_redo(ns, marks[1], 0, 2, 0, 6) + expect(' 12345') + + feed('>>') + -- this is counter-intuitive. But what happens + -- is that 4 spaces gets extended to one tab (== 8 spaces) + check_undo_redo(ns, marks[1], 0, 6, 0, 3) + expect('\t12345') + + feed('') -- have to escape, same as << + check_undo_redo(ns, marks[1], 0, 3, 0, 6) + end) + + it('blockwise shift', function() + -- shift_block in ops.c + feed(':set shiftwidth=4') + feed('a12345') + set_extmark(ns, marks[1], 1, 2) + feed('0k>') + check_undo_redo(ns, marks[1], 1, 2, 1, 6) + feed('j>') + expect('\t12345\n\t12345') + check_undo_redo(ns, marks[1], 1, 6, 1, 3) + + feed('j') + check_undo_redo(ns, marks[1], 1, 3, 1, 6) + end) + + it('tab works with expandtab', function() + -- ins_tab in edit.c + feed(':set expandtab') + feed(':set shiftwidth=2') + set_extmark(ns, marks[1], 0, 2) + feed('0i') + check_undo_redo(ns, marks[1], 0, 2, 0, 6) + end) + + it('tabs work', function() + -- ins_tab in edit.c + feed(':set noexpandtab') + feed(':set shiftwidth=2') + feed(':set softtabstop=2') + feed(':set tabstop=8') + set_extmark(ns, marks[1], 0, 2) + feed('0i') + check_undo_redo(ns, marks[1], 0, 2, 0, 4) + feed('0iX') + check_undo_redo(ns, marks[1], 0, 4, 0, 6) + end) + + it('marks move when using :move', function() + set_extmark(ns, marks[1], 0, 0) + feed('A2:1move 2') + check_undo_redo(ns, marks[1], 0, 0, 1, 0) + -- test codepath when moving lines up + feed(':2move 0') + check_undo_redo(ns, marks[1], 1, 0, 0, 0) + end) + + it('marks move when using :move part 2', function() + -- make sure we didn't get lucky with the math... + feed('A23456') + set_extmark(ns, marks[1], 1, 0) + feed(':2,3move 5') + check_undo_redo(ns, marks[1], 1, 0, 3, 0) + -- test codepath when moving lines up + feed(':4,5move 1') + check_undo_redo(ns, marks[1], 3, 0, 1, 0) + end) + + it('undo and redo of set and unset marks', function() + -- Force a new undo head + feed('o') + set_extmark(ns, marks[1], 0, 1) + feed('o') + set_extmark(ns, marks[2], 0, -1) + set_extmark(ns, marks[3], 0, -1) + + feed("u") + local rv = get_extmarks(ns, {0, 0}, {-1, -1}) + eq(3, table.getn(rv)) + + feed("") + rv = get_extmarks(ns, {0, 0}, {-1, -1}) + eq(3, table.getn(rv)) + + -- Test updates + feed('o') + set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + rv = get_extmarks(ns, marks[1], marks[1], {limit=1}) + eq(1, table.getn(rv)) + feed("u") + feed("") + -- old value is NOT kept in history + check_undo_redo(ns, marks[1], positions[1][1], positions[1][2], positions[1][1], positions[1][2]) + + -- Test unset + feed('o') + curbufmeths.del_extmark(ns, marks[3]) + feed("u") + rv = get_extmarks(ns, {0, 0}, {-1, -1}) + -- undo does NOT restore deleted marks + eq(2, table.getn(rv)) + feed("") + rv = get_extmarks(ns, {0, 0}, {-1, -1}) + eq(2, table.getn(rv)) + end) + + it('undo and redo of marks deleted during edits', function() + -- test extmark_adjust + feed('A12345') + set_extmark(ns, marks[1], 1, 2) + feed('dd') + check_undo_redo(ns, marks[1], 1, 2, 1, 0) + end) + + it('namespaces work properly', function() + local rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + eq(1, rv) + rv = set_extmark(ns2, marks[1], positions[1][1], positions[1][2]) + eq(1, rv) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) + eq(1, table.getn(rv)) + rv = get_extmarks(ns2, {0, 0}, {-1, -1}) + eq(1, table.getn(rv)) + + -- Set more marks for testing the ranges + set_extmark(ns, marks[2], positions[2][1], positions[2][2]) + set_extmark(ns, marks[3], positions[3][1], positions[3][2]) + set_extmark(ns2, marks[2], positions[2][1], positions[2][2]) + set_extmark(ns2, marks[3], positions[3][1], positions[3][2]) + + -- get_next (limit set) + rv = get_extmarks(ns, {0, 0}, positions[2], {limit=1}) + eq(1, table.getn(rv)) + rv = get_extmarks(ns2, {0, 0}, positions[2], {limit=1}) + eq(1, table.getn(rv)) + -- get_prev (limit set) + rv = get_extmarks(ns, positions[1], {0, 0}, {limit=1}) + eq(1, table.getn(rv)) + rv = get_extmarks(ns2, positions[1], {0, 0}, {limit=1}) + eq(1, table.getn(rv)) + + -- get_next (no limit) + rv = get_extmarks(ns, positions[1], positions[2]) + eq(2, table.getn(rv)) + rv = get_extmarks(ns2, positions[1], positions[2]) + eq(2, table.getn(rv)) + -- get_prev (no limit) + rv = get_extmarks(ns, positions[2], positions[1]) + eq(2, table.getn(rv)) + rv = get_extmarks(ns2, positions[2], positions[1]) + eq(2, table.getn(rv)) + + curbufmeths.del_extmark(ns, marks[1]) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) + eq(2, table.getn(rv)) + curbufmeths.del_extmark(ns2, marks[1]) + rv = get_extmarks(ns2, {0, 0}, {-1, -1}) + eq(2, table.getn(rv)) + end) + + it('mark set can create unique identifiers', function() + -- create mark with id 1 + eq(1, set_extmark(ns, 1, positions[1][1], positions[1][2])) + -- ask for unique id, it should be the next one, i e 2 + eq(2, set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(3, set_extmark(ns, 3, positions[2][1], positions[2][2])) + eq(4, set_extmark(ns, 0, positions[1][1], positions[1][2])) + + -- mixing manual and allocated id:s are not recommened, but it should + -- do something reasonable + eq(6, set_extmark(ns, 6, positions[2][1], positions[2][2])) + eq(7, set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(8, set_extmark(ns, 0, positions[1][1], positions[1][2])) + end) + + it('auto indenting with enter works', function() + -- op_reindent in ops.c + feed(':set cindent') + feed(':set autoindent') + feed(':set shiftwidth=2') + feed("0iint A {1M1b") + -- Set the mark on the M, should move.. + set_extmark(ns, marks[1], 0, 12) + -- Set the mark before the cursor, should stay there + set_extmark(ns, marks[2], 0, 10) + feed("i") + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({1, 3}, rv) + rv = curbufmeths.get_extmark_by_id(ns, marks[2]) + eq({0, 10}, rv) + check_undo_redo(ns, marks[1], 0, 12, 1, 3) + end) + + it('auto indenting entire line works', function() + feed(':set cindent') + feed(':set autoindent') + feed(':set shiftwidth=2') + -- will force an indent of 2 + feed("0iint A {0i1M1") + set_extmark(ns, marks[1], 1, 1) + feed("0i") + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({1, 3}, rv) + check_undo_redo(ns, marks[1], 1, 1, 1, 3) + -- now check when cursor at eol + feed("uA") + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({1, 3}, rv) + end) + + it('removing auto indenting with works', function() + feed(':set cindent') + feed(':set autoindent') + feed(':set shiftwidth=2') + feed("0i") + set_extmark(ns, marks[1], 0, 3) + feed("bi") + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({0, 1}, rv) + check_undo_redo(ns, marks[1], 0, 3, 0, 1) + -- check when cursor at eol + feed("uA") + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({0, 1}, rv) + end) + + it('indenting multiple lines with = works', function() + feed(':set cindent') + feed(':set autoindent') + feed(':set shiftwidth=2') + feed("0iint A {1M12M2") + set_extmark(ns, marks[1], 1, 1) + set_extmark(ns, marks[2], 2, 1) + feed('=gg') + check_undo_redo(ns, marks[1], 1, 1, 1, 3) + check_undo_redo(ns, marks[2], 2, 1, 2, 5) + end) + + it('substitutes by deleting inside the replace matches', function() + -- do_sub in ex_cmds.c + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + feed(':s/34/xx') + check_undo_redo(ns, marks[1], 0, 2, 0, 4) + check_undo_redo(ns, marks[2], 0, 3, 0, 4) + end) + + it('substitutes when insert text > deleted', function() + -- do_sub in ex_cmds.c + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + feed(':s/34/xxx') + check_undo_redo(ns, marks[1], 0, 2, 0, 5) + check_undo_redo(ns, marks[2], 0, 3, 0, 5) + end) + + it('substitutes when marks around eol', function() + -- do_sub in ex_cmds.c + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 0, 5) + feed(':s/5/xxx') + check_undo_redo(ns, marks[1], 0, 4, 0, 7) + check_undo_redo(ns, marks[2], 0, 5, 0, 7) + end) + + it('substitutes over range insert text > deleted', function() + -- do_sub in ex_cmds.c + feed('Ax34xx') + feed('Axxx34') + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 1, 1) + set_extmark(ns, marks[3], 2, 4) + feed(':1,3s/34/xxx') + check_undo_redo(ns, marks[1], 0, 2, 0, 5) + check_undo_redo(ns, marks[2], 1, 1, 1, 4) + check_undo_redo(ns, marks[3], 2, 4, 2, 6) + end) + + it('substitutes multiple matches in a line', function() + -- do_sub in ex_cmds.c + feed('ddi3x3x3') + set_extmark(ns, marks[1], 0, 0) + set_extmark(ns, marks[2], 0, 2) + set_extmark(ns, marks[3], 0, 4) + feed(':s/3/yy/g') + check_undo_redo(ns, marks[1], 0, 0, 0, 2) + check_undo_redo(ns, marks[2], 0, 2, 0, 5) + check_undo_redo(ns, marks[3], 0, 4, 0, 8) + end) + + it('substitions over multiple lines with newline in pattern', function() + feed('A67890xx') + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 1, 0) + set_extmark(ns, marks[4], 1, 5) + set_extmark(ns, marks[5], 2, 0) + feed([[:1,2s:5\n:5 ]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 0, 6) + check_undo_redo(ns, marks[3], 1, 0, 0, 6) + check_undo_redo(ns, marks[4], 1, 5, 0, 11) + check_undo_redo(ns, marks[5], 2, 0, 1, 0) + end) + + it('inserting', function() + feed('A67890xx') + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 1, 0) + set_extmark(ns, marks[4], 1, 5) + set_extmark(ns, marks[5], 2, 0) + set_extmark(ns, marks[6], 1, 2) + feed([[:1,2s:5\n67:X]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 0, 5) + check_undo_redo(ns, marks[3], 1, 0, 0, 5) + check_undo_redo(ns, marks[4], 1, 5, 0, 8) + check_undo_redo(ns, marks[5], 2, 0, 1, 0) + check_undo_redo(ns, marks[6], 1, 2, 0, 5) + end) + + it('substitions with multiple newlines in pattern', function() + feed('A67890xx') + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 0, 5) + set_extmark(ns, marks[3], 1, 0) + set_extmark(ns, marks[4], 1, 5) + set_extmark(ns, marks[5], 2, 0) + feed([[:1,2s:\n.*\n:X]]) + check_undo_redo(ns, marks[1], 0, 4, 0, 4) + check_undo_redo(ns, marks[2], 0, 5, 0, 6) + check_undo_redo(ns, marks[3], 1, 0, 0, 6) + check_undo_redo(ns, marks[4], 1, 5, 0, 6) + check_undo_redo(ns, marks[5], 2, 0, 0, 6) + end) + + it('substitions over multiple lines with replace in substition', function() + feed('A67890xx') + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 2) + set_extmark(ns, marks[3], 0, 4) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 2, 0) + feed([[:1,2s:3:\r]]) + check_undo_redo(ns, marks[1], 0, 1, 0, 1) + check_undo_redo(ns, marks[2], 0, 2, 1, 0) + check_undo_redo(ns, marks[3], 0, 4, 1, 1) + check_undo_redo(ns, marks[4], 1, 0, 2, 0) + check_undo_redo(ns, marks[5], 2, 0, 3, 0) + feed('u') + feed([[:1,2s:3:\rxx]]) + eq({1, 3}, curbufmeths.get_extmark_by_id(ns, marks[3])) + end) + + it('substitions over multiple lines with replace in substition', function() + feed('Ax3xx') + set_extmark(ns, marks[1], 1, 0) + set_extmark(ns, marks[2], 1, 1) + set_extmark(ns, marks[3], 1, 2) + feed([[:2,2s:3:\r]]) + check_undo_redo(ns, marks[1], 1, 0, 1, 0) + check_undo_redo(ns, marks[2], 1, 1, 2, 0) + check_undo_redo(ns, marks[3], 1, 2, 2, 0) + end) + + it('substitions over multiple lines with replace in substition', function() + feed('Ax3xx') + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 2) + set_extmark(ns, marks[3], 0, 4) + set_extmark(ns, marks[4], 1, 1) + set_extmark(ns, marks[5], 2, 0) + feed([[:1,2s:3:\r]]) + check_undo_redo(ns, marks[1], 0, 1, 0, 1) + check_undo_redo(ns, marks[2], 0, 2, 1, 0) + check_undo_redo(ns, marks[3], 0, 4, 1, 1) + check_undo_redo(ns, marks[4], 1, 1, 3, 0) + check_undo_redo(ns, marks[5], 2, 0, 4, 0) + feed('u') + feed([[:1,2s:3:\rxx]]) + check_undo_redo(ns, marks[3], 0, 4, 1, 3) + end) + + it('substitions with newline in match and sub, delta is 0', function() + feed('A67890xx') + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 0) + feed([[:1,1s:5\n:\r]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 1, 0) + check_undo_redo(ns, marks[3], 0, 5, 1, 0) + check_undo_redo(ns, marks[4], 1, 0, 1, 0) + check_undo_redo(ns, marks[5], 1, 5, 1, 5) + check_undo_redo(ns, marks[6], 2, 0, 2, 0) + end) + + it('substitions with newline in match and sub, delta > 0', function() + feed('A67890xx') + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 0) + feed([[:1,1s:5\n:\r\r]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 2, 0) + check_undo_redo(ns, marks[3], 0, 5, 2, 0) + check_undo_redo(ns, marks[4], 1, 0, 2, 0) + check_undo_redo(ns, marks[5], 1, 5, 2, 5) + check_undo_redo(ns, marks[6], 2, 0, 3, 0) + end) + + it('substitions with newline in match and sub, delta < 0', function() + feed('A67890xxxx') + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 1) + set_extmark(ns, marks[7], 3, 0) + feed([[:1,2s:5\n.*\n:\r]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 1, 0) + check_undo_redo(ns, marks[3], 0, 5, 1, 0) + check_undo_redo(ns, marks[4], 1, 0, 1, 0) + check_undo_redo(ns, marks[5], 1, 5, 1, 0) + check_undo_redo(ns, marks[6], 2, 1, 1, 1) + check_undo_redo(ns, marks[7], 3, 0, 2, 0) + end) + + it('substitions with backrefs, newline inserted into sub', function() + feed('A67890xxxx') + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 0) + feed([[:1,1s:5\(\n\):\0\1]]) + check_undo_redo(ns, marks[1], 0, 3, 0, 3) + check_undo_redo(ns, marks[2], 0, 4, 2, 0) + check_undo_redo(ns, marks[3], 0, 5, 2, 0) + check_undo_redo(ns, marks[4], 1, 0, 2, 0) + check_undo_redo(ns, marks[5], 1, 5, 2, 5) + check_undo_redo(ns, marks[6], 2, 0, 3, 0) + end) + + it('substitions a ^', function() + set_extmark(ns, marks[1], 0, 0) + set_extmark(ns, marks[2], 0, 1) + feed([[:s:^:x]]) + check_undo_redo(ns, marks[1], 0, 0, 0, 1) + check_undo_redo(ns, marks[2], 0, 1, 0, 2) + end) + + it('using without increase in order of magnitude', function() + -- do_addsub in ops.c + feed('ddiabc998xxxTc') + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 0, 6) + set_extmark(ns, marks[5], 0, 7) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 6) + check_undo_redo(ns, marks[3], 0, 5, 0, 6) + check_undo_redo(ns, marks[4], 0, 6, 0, 6) + check_undo_redo(ns, marks[5], 0, 7, 0, 7) + end) + + it('using when increase in order of magnitude', function() + -- do_addsub in ops.c + feed('ddiabc999xxxTc') + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 0, 6) + set_extmark(ns, marks[5], 0, 7) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 7) + check_undo_redo(ns, marks[3], 0, 5, 0, 7) + check_undo_redo(ns, marks[4], 0, 6, 0, 7) + check_undo_redo(ns, marks[5], 0, 7, 0, 8) + end) + + it('using when negative and without decrease in order of magnitude', function() + feed('ddiabc-999xxxT-') + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 7) + check_undo_redo(ns, marks[3], 0, 6, 0, 7) + check_undo_redo(ns, marks[4], 0, 7, 0, 7) + check_undo_redo(ns, marks[5], 0, 8, 0, 8) + end) + + it('using when negative and decrease in order of magnitude', function() + feed('ddiabc-1000xxxT-') + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 7) + set_extmark(ns, marks[4], 0, 8) + set_extmark(ns, marks[5], 0, 9) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 7) + check_undo_redo(ns, marks[3], 0, 7, 0, 7) + check_undo_redo(ns, marks[4], 0, 8, 0, 7) + check_undo_redo(ns, marks[5], 0, 9, 0, 8) + end) + + it('using without decrease in order of magnitude', function() + -- do_addsub in ops.c + feed('ddiabc999xxxTc') + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 0, 6) + set_extmark(ns, marks[5], 0, 7) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 6) + check_undo_redo(ns, marks[3], 0, 5, 0, 6) + check_undo_redo(ns, marks[4], 0, 6, 0, 6) + check_undo_redo(ns, marks[5], 0, 7, 0, 7) + end) + + it('using when decrease in order of magnitude', function() + -- do_addsub in ops.c + feed('ddiabc1000xxxTc') + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 6) + check_undo_redo(ns, marks[3], 0, 6, 0, 6) + check_undo_redo(ns, marks[4], 0, 7, 0, 6) + check_undo_redo(ns, marks[5], 0, 8, 0, 7) + end) + + it('using when negative and without increase in order of magnitude', function() + feed('ddiabc-998xxxT-') + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 7) + check_undo_redo(ns, marks[3], 0, 6, 0, 7) + check_undo_redo(ns, marks[4], 0, 7, 0, 7) + check_undo_redo(ns, marks[5], 0, 8, 0, 8) + end) + + it('using when negative and increase in order of magnitude', function() + feed('ddiabc-999xxxT-') + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) + feed('') + check_undo_redo(ns, marks[1], 0, 2, 0, 2) + check_undo_redo(ns, marks[2], 0, 3, 0, 8) + check_undo_redo(ns, marks[3], 0, 6, 0, 8) + check_undo_redo(ns, marks[4], 0, 7, 0, 8) + check_undo_redo(ns, marks[5], 0, 8, 0, 9) + end) + + it('throws consistent error codes', function() + local ns_invalid = ns2 + 1 + eq("Invalid ns_id", pcall_err(set_extmark, ns_invalid, marks[1], positions[1][1], positions[1][2])) + eq("Invalid ns_id", pcall_err(curbufmeths.del_extmark, ns_invalid, marks[1])) + eq("Invalid ns_id", pcall_err(get_extmarks, ns_invalid, positions[1], positions[2])) + eq("Invalid ns_id", pcall_err(curbufmeths.get_extmark_by_id, ns_invalid, marks[1])) + end) + + it('when col = line-length, set the mark on eol', function() + set_extmark(ns, marks[1], 0, -1) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({0, init_text:len()}, rv) + -- Test another + set_extmark(ns, marks[1], 0, -1) + rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({0, init_text:len()}, rv) + end) + + it('when col = line-length, set the mark on eol', function() + local invalid_col = init_text:len() + 1 + eq("col value outside range", pcall_err(set_extmark, ns, marks[1], 0, invalid_col)) + end) + + it('fails when line > line_count', function() + local invalid_col = init_text:len() + 1 + local invalid_lnum = 3 + eq('line value outside range', pcall_err(set_extmark, ns, marks[1], invalid_lnum, invalid_col)) + eq({}, curbufmeths.get_extmark_by_id(ns, marks[1])) + end) + + it('bug from check_col in extmark_set', function() + -- This bug was caused by extmark_set always using check_col. check_col + -- always uses the current buffer. This wasn't working during undo so we + -- now use check_col and check_lnum only when they are required. + feed('A67890xx') + feed('A1234567890xx') + set_extmark(ns, marks[1], 3, 4) + feed([[:1,5s:5\n:5 ]]) + check_undo_redo(ns, marks[1], 3, 4, 2, 6) + end) + + it('in read-only buffer', function() + command("view! runtime/doc/help.txt") + eq(true, curbufmeths.get_option('ro')) + local id = set_extmark(ns, 0, 0, 2) + eq({{id, 0, 2}}, get_extmarks(ns,0, -1)) + end) + + it('can set a mark to other buffer', function() + local buf = request('nvim_create_buf', 0, 1) + request('nvim_buf_set_lines', buf, 0, -1, 1, {"", ""}) + local id = bufmeths.set_extmark(buf, ns, 0, 1, 0, {}) + eq({{id, 1, 0}}, bufmeths.get_extmarks(buf, ns, 0, -1, {})) + end) + + it('does not crash with append/delete/undo seqence', function() + meths.exec([[ + let ns = nvim_create_namespace('myplugin') + call nvim_buf_set_extmark(0, ns, 0, 0, 0, {}) + call append(0, '') + %delete + undo]],false) + eq(2, meths.eval('1+1')) -- did not crash + end) +end) + +describe('Extmarks buffer api with many marks', function() + local ns1 + local ns2 + local ns_marks = {} + before_each(function() + clear() + ns1 = request('nvim_create_namespace', "ns1") + ns2 = request('nvim_create_namespace', "ns2") + ns_marks = {[ns1]={}, [ns2]={}} + local lines = {} + for i = 1,30 do + lines[#lines+1] = string.rep("x ",i) + end + curbufmeths.set_lines(0, -1, true, lines) + local ns = ns1 + local q = 0 + for i = 0,29 do + for j = 0,i do + local id = set_extmark(ns,0, i,j) + eq(nil, ns_marks[ns][id]) + ok(id > 0) + ns_marks[ns][id] = {i,j} + ns = ns1+ns2-ns + q = q + 1 + end + end + eq(233, #ns_marks[ns1]) + eq(232, #ns_marks[ns2]) + + end) + + local function get_marks(ns) + local mark_list = get_extmarks(ns, 0, -1) + local marks = {} + for _, mark in ipairs(mark_list) do + local id, row, col = unpack(mark) + eq(nil, marks[id], "duplicate mark") + marks[id] = {row,col} + end + return marks + end + + it("can get marks", function() + eq(ns_marks[ns1], get_marks(ns1)) + eq(ns_marks[ns2], get_marks(ns2)) + end) + + it("can clear all marks in ns", function() + curbufmeths.clear_namespace(ns1, 0, -1) + eq({}, get_marks(ns1)) + eq(ns_marks[ns2], get_marks(ns2)) + curbufmeths.clear_namespace(ns2, 0, -1) + eq({}, get_marks(ns1)) + eq({}, get_marks(ns2)) + end) + + it("can clear line range", function() + curbufmeths.clear_namespace(ns1, 10, 20) + for id, mark in pairs(ns_marks[ns1]) do + if 10 <= mark[1] and mark[1] < 20 then + ns_marks[ns1][id] = nil + end + end + eq(ns_marks[ns1], get_marks(ns1)) + eq(ns_marks[ns2], get_marks(ns2)) + end) + + it("can delete line", function() + feed('10Gdd') + for _, marks in pairs(ns_marks) do + for id, mark in pairs(marks) do + if mark[1] == 9 then + marks[id] = {9,0} + elseif mark[1] >= 10 then + mark[1] = mark[1] - 1 + end + end + end + eq(ns_marks[ns1], get_marks(ns1)) + eq(ns_marks[ns2], get_marks(ns2)) + end) + + it("can delete lines", function() + feed('10G10dd') + for _, marks in pairs(ns_marks) do + for id, mark in pairs(marks) do + if 9 <= mark[1] and mark[1] < 19 then + marks[id] = {9,0} + elseif mark[1] >= 19 then + mark[1] = mark[1] - 10 + end + end + end + eq(ns_marks[ns1], get_marks(ns1)) + eq(ns_marks[ns2], get_marks(ns2)) + end) + + it("can wipe buffer", function() + command('bwipe!') + eq({}, get_marks(ns1)) + eq({}, get_marks(ns2)) + end) +end) diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua deleted file mode 100644 index 8aa8ed07c5..0000000000 --- a/test/functional/api/mark_extended_spec.lua +++ /dev/null @@ -1,1478 +0,0 @@ -local helpers = require('test.functional.helpers')(after_each) -local Screen = require('test.functional.ui.screen') - -local request = helpers.request -local eq = helpers.eq -local ok = helpers.ok -local curbufmeths = helpers.curbufmeths -local bufmeths = helpers.bufmeths -local pcall_err = helpers.pcall_err -local insert = helpers.insert -local feed = helpers.feed -local clear = helpers.clear -local command = helpers.command -local meths = helpers.meths - -local function expect(contents) - return eq(contents, helpers.curbuf_contents()) -end - -local function check_undo_redo(ns, mark, sr, sc, er, ec) --s = start, e = end - local rv = curbufmeths.get_extmark_by_id(ns, mark) - eq({er, ec}, rv) - feed("u") - rv = curbufmeths.get_extmark_by_id(ns, mark) - eq({sr, sc}, rv) - feed("") - rv = curbufmeths.get_extmark_by_id(ns, mark) - eq({er, ec}, rv) -end - -local function set_extmark(ns_id, id, line, col, opts) - if opts == nil then - opts = {} - end - return curbufmeths.set_extmark(ns_id, id, line, col, opts) -end - -local function get_extmarks(ns_id, start, end_, opts) - if opts == nil then - opts = {} - end - return curbufmeths.get_extmarks(ns_id, start, end_, opts) -end - -local function batch_set(ns_id, positions) - local ids = {} - for _, pos in ipairs(positions) do - table.insert(ids, set_extmark(ns_id, 0, pos[1], pos[2])) - end - return ids -end - -local function batch_check(ns_id, ids, positions) - local actual, expected = {}, {} - for i,id in ipairs(ids) do - expected[id] = positions[i] - end - for _, mark in pairs(get_extmarks(ns_id, 0, -1, {})) do - actual[mark[1]] = {mark[2], mark[3]} - end - eq(expected, actual) -end - -local function batch_check_undo_redo(ns_id, ids, before, after) - batch_check(ns_id, ids, after) - feed("u") - batch_check(ns_id, ids, before) - feed("") - batch_check(ns_id, ids, after) -end - -describe('API/extmarks', function() - local screen - local marks, positions, init_text, row, col - local ns, ns2 - - before_each(function() - -- Initialize some namespaces and insert 12345 into a buffer - marks = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} - positions = {{0, 0,}, {0, 2}, {0, 3}} - - init_text = "12345" - row = 0 - col = 2 - - clear() - - insert(init_text) - ns = request('nvim_create_namespace', "my-fancy-plugin") - ns2 = request('nvim_create_namespace', "my-fancy-plugin2") - end) - - it('adds, updates and deletes marks', function() - local rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - eq(marks[1], rv) - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({positions[1][1], positions[1][2]}, rv) - -- Test adding a second mark on same row works - rv = set_extmark(ns, marks[2], positions[2][1], positions[2][2]) - eq(marks[2], rv) - - -- Test an update, (same pos) - rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - eq(marks[1], rv) - rv = curbufmeths.get_extmark_by_id(ns, marks[2]) - eq({positions[2][1], positions[2][2]}, rv) - -- Test an update, (new pos) - row = positions[1][1] - col = positions[1][2] + 1 - rv = set_extmark(ns, marks[1], row, col) - eq(marks[1], rv) - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({row, col}, rv) - - -- remove the test marks - eq(true, curbufmeths.del_extmark(ns, marks[1])) - eq(false, curbufmeths.del_extmark(ns, marks[1])) - eq(true, curbufmeths.del_extmark(ns, marks[2])) - eq(false, curbufmeths.del_extmark(ns, marks[3])) - eq(false, curbufmeths.del_extmark(ns, 1000)) - end) - - it('can clear a specific namespace range', function() - set_extmark(ns, 1, 0, 1) - set_extmark(ns2, 1, 0, 1) - -- force a new undo buffer - feed('o') - curbufmeths.clear_namespace(ns2, 0, -1) - eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) - feed('u') - eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) - feed('') - eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) - end) - - it('can clear a namespace range using 0,-1', function() - set_extmark(ns, 1, 0, 1) - set_extmark(ns2, 1, 0, 1) - -- force a new undo buffer - feed('o') - curbufmeths.clear_namespace(-1, 0, -1) - eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) - feed('u') - eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) - feed('') - eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) - end) - - it('querying for information and ranges', function() - --marks = {1, 2, 3} - --positions = {{0, 0,}, {0, 2}, {0, 3}} - -- add some more marks - for i, m in ipairs(marks) do - if positions[i] ~= nil then - local rv = set_extmark(ns, m, positions[i][1], positions[i][2]) - eq(m, rv) - end - end - - -- {0, 0} and {-1, -1} work as extreme values - eq({{1, 0, 0}}, get_extmarks(ns, {0, 0}, {0, 0})) - eq({}, get_extmarks(ns, {-1, -1}, {-1, -1})) - local rv = get_extmarks(ns, {0, 0}, {-1, -1}) - for i, m in ipairs(marks) do - if positions[i] ~= nil then - eq({m, positions[i][1], positions[i][2]}, rv[i]) - end - end - - -- 0 and -1 works as short hand extreme values - eq({{1, 0, 0}}, get_extmarks(ns, 0, 0)) - eq({}, get_extmarks(ns, -1, -1)) - rv = get_extmarks(ns, 0, -1) - for i, m in ipairs(marks) do - if positions[i] ~= nil then - eq({m, positions[i][1], positions[i][2]}, rv[i]) - end - end - - -- next with mark id - rv = get_extmarks(ns, marks[1], {-1, -1}, {limit=1}) - eq({{marks[1], positions[1][1], positions[1][2]}}, rv) - rv = get_extmarks(ns, marks[2], {-1, -1}, {limit=1}) - eq({{marks[2], positions[2][1], positions[2][2]}}, rv) - -- next with positional when mark exists at position - rv = get_extmarks(ns, positions[1], {-1, -1}, {limit=1}) - eq({{marks[1], positions[1][1], positions[1][2]}}, rv) - -- next with positional index (no mark at position) - rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, {limit=1}) - eq({{marks[2], positions[2][1], positions[2][2]}}, rv) - -- next with Extremity index - rv = get_extmarks(ns, {0,0}, {-1, -1}, {limit=1}) - eq({{marks[1], positions[1][1], positions[1][2]}}, rv) - - -- nextrange with mark id - rv = get_extmarks(ns, marks[1], marks[3]) - eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) - eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) - -- nextrange with `limit` - rv = get_extmarks(ns, marks[1], marks[3], {limit=2}) - eq(2, table.getn(rv)) - -- nextrange with positional when mark exists at position - rv = get_extmarks(ns, positions[1], positions[3]) - eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) - eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) - rv = get_extmarks(ns, positions[2], positions[3]) - eq(2, table.getn(rv)) - -- nextrange with positional index (no mark at position) - local lower = {positions[1][1], positions[2][2] -1} - local upper = {positions[2][1], positions[3][2] - 1} - rv = get_extmarks(ns, lower, upper) - eq({{marks[2], positions[2][1], positions[2][2]}}, rv) - lower = {positions[3][1], positions[3][2] + 1} - upper = {positions[3][1], positions[3][2] + 2} - rv = get_extmarks(ns, lower, upper) - eq({}, rv) - -- nextrange with extremity index - lower = {positions[2][1], positions[2][2]+1} - upper = {-1, -1} - rv = get_extmarks(ns, lower, upper) - eq({{marks[3], positions[3][1], positions[3][2]}}, rv) - - -- prev with mark id - rv = get_extmarks(ns, marks[3], {0, 0}, {limit=1}) - eq({{marks[3], positions[3][1], positions[3][2]}}, rv) - rv = get_extmarks(ns, marks[2], {0, 0}, {limit=1}) - eq({{marks[2], positions[2][1], positions[2][2]}}, rv) - -- prev with positional when mark exists at position - rv = get_extmarks(ns, positions[3], {0, 0}, {limit=1}) - eq({{marks[3], positions[3][1], positions[3][2]}}, rv) - -- prev with positional index (no mark at position) - rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, {limit=1}) - eq({{marks[1], positions[1][1], positions[1][2]}}, rv) - -- prev with Extremity index - rv = get_extmarks(ns, {-1,-1}, {0,0}, {limit=1}) - eq({{marks[3], positions[3][1], positions[3][2]}}, rv) - - -- prevrange with mark id - rv = get_extmarks(ns, marks[3], marks[1]) - eq({marks[3], positions[3][1], positions[3][2]}, rv[1]) - eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) - eq({marks[1], positions[1][1], positions[1][2]}, rv[3]) - -- prevrange with limit - rv = get_extmarks(ns, marks[3], marks[1], {limit=2}) - eq(2, table.getn(rv)) - -- prevrange with positional when mark exists at position - rv = get_extmarks(ns, positions[3], positions[1]) - eq({{marks[3], positions[3][1], positions[3][2]}, - {marks[2], positions[2][1], positions[2][2]}, - {marks[1], positions[1][1], positions[1][2]}}, rv) - rv = get_extmarks(ns, positions[2], positions[1]) - eq(2, table.getn(rv)) - -- prevrange with positional index (no mark at position) - lower = {positions[2][1], positions[2][2] + 1} - upper = {positions[3][1], positions[3][2] + 1} - rv = get_extmarks(ns, upper, lower) - eq({{marks[3], positions[3][1], positions[3][2]}}, rv) - lower = {positions[3][1], positions[3][2] + 1} - upper = {positions[3][1], positions[3][2] + 2} - rv = get_extmarks(ns, upper, lower) - eq({}, rv) - -- prevrange with extremity index - lower = {0,0} - upper = {positions[2][1], positions[2][2] - 1} - rv = get_extmarks(ns, upper, lower) - eq({{marks[1], positions[1][1], positions[1][2]}}, rv) - end) - - it('querying for information with limit', function() - -- add some more marks - for i, m in ipairs(marks) do - if positions[i] ~= nil then - local rv = set_extmark(ns, m, positions[i][1], positions[i][2]) - eq(m, rv) - end - end - - local rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=1}) - eq(1, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=2}) - eq(2, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=3}) - eq(3, table.getn(rv)) - - -- now in reverse - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=1}) - eq(1, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=2}) - eq(2, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=3}) - eq(3, table.getn(rv)) - end) - - it('get_marks works when mark col > upper col', function() - feed('A12345') - feed('A12345') - set_extmark(ns, 10, 0, 2) -- this shouldn't be found - set_extmark(ns, 11, 2, 1) -- this shouldn't be found - set_extmark(ns, marks[1], 0, 4) -- check col > our upper bound - set_extmark(ns, marks[2], 1, 1) -- check col < lower bound - set_extmark(ns, marks[3], 2, 0) -- check is inclusive - eq({{marks[1], 0, 4}, - {marks[2], 1, 1}, - {marks[3], 2, 0}}, - get_extmarks(ns, {0, 3}, {2, 0})) - end) - - it('get_marks works in reverse when mark col < lower col', function() - feed('A12345') - feed('A12345') - set_extmark(ns, 10, 0, 1) -- this shouldn't be found - set_extmark(ns, 11, 2, 4) -- this shouldn't be found - set_extmark(ns, marks[1], 2, 1) -- check col < our lower bound - set_extmark(ns, marks[2], 1, 4) -- check col > upper bound - set_extmark(ns, marks[3], 0, 2) -- check is inclusive - local rv = get_extmarks(ns, {2, 3}, {0, 2}) - eq({{marks[1], 2, 1}, - {marks[2], 1, 4}, - {marks[3], 0, 2}}, - rv) - end) - - it('get_marks limit=0 returns nothing', function() - set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - local rv = get_extmarks(ns, {-1, -1}, {-1, -1}, {limit=0}) - eq({}, rv) - end) - - - it('marks move with line insertations', function() - set_extmark(ns, marks[1], 0, 0) - feed("yyP") - check_undo_redo(ns, marks[1], 0, 0, 1, 0) - end) - - it('marks move with multiline insertations', function() - feed("a2233") - set_extmark(ns, marks[1], 1, 1) - feed('ggVGyP') - check_undo_redo(ns, marks[1], 1, 1, 4, 1) - end) - - it('marks move with line join', function() - -- do_join in ops.c - feed("a222") - set_extmark(ns, marks[1], 1, 0) - feed('ggJ') - check_undo_redo(ns, marks[1], 1, 0, 0, 6) - end) - - it('join works when no marks are present', function() - screen = Screen.new(15, 10) - screen:attach() - feed("a1") - feed('kJ') - -- This shouldn't seg fault - screen:expect([[ - 12345^ 1 | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - | - ]]) - end) - - it('marks move with multiline join', function() - -- do_join in ops.c - feed("a222333444") - set_extmark(ns, marks[1], 3, 0) - feed('2GVGJ') - check_undo_redo(ns, marks[1], 3, 0, 1, 8) - end) - - it('marks move with line deletes', function() - feed("a222333444") - set_extmark(ns, marks[1], 2, 1) - feed('ggjdd') - check_undo_redo(ns, marks[1], 2, 1, 1, 1) - end) - - it('marks move with multiline deletes', function() - feed("a222333444") - set_extmark(ns, marks[1], 3, 0) - feed('gg2dd') - check_undo_redo(ns, marks[1], 3, 0, 1, 0) - -- regression test, undoing multiline delete when mark is on row 1 - feed('ugg3dd') - check_undo_redo(ns, marks[1], 3, 0, 0, 0) - end) - - it('marks move with open line', function() - -- open_line in misc1.c - -- testing marks below are also moved - feed("yyP") - set_extmark(ns, marks[1], 0, 4) - set_extmark(ns, marks[2], 1, 4) - feed('1G') - check_undo_redo(ns, marks[1], 0, 4, 1, 4) - check_undo_redo(ns, marks[2], 1, 4, 2, 4) - feed('2Go') - check_undo_redo(ns, marks[1], 1, 4, 1, 4) - check_undo_redo(ns, marks[2], 2, 4, 3, 4) - end) - - it('marks move with char inserts', function() - -- insertchar in edit.c (the ins_str branch) - screen = Screen.new(15, 10) - screen:attach() - set_extmark(ns, marks[1], 0, 3) - feed('0') - insert('abc') - screen:expect([[ - ab^c12345 | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - | - ]]) - local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({0, 6}, rv) - check_undo_redo(ns, marks[1], 0, 3, 0, 6) - end) - - -- gravity right as definted in tk library - it('marks have gravity right', function() - -- insertchar in edit.c (the ins_str branch) - set_extmark(ns, marks[1], 0, 2) - feed('03l') - insert("X") - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - - -- check multibyte chars - feed('03l') - insert("~~") - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - end) - - it('we can insert multibyte chars', function() - -- insertchar in edit.c - feed('a12345') - set_extmark(ns, marks[1], 1, 2) - -- Insert a fullwidth (two col) tilde, NICE - feed('0i~') - check_undo_redo(ns, marks[1], 1, 2, 1, 5) - end) - - it('marks move with blockwise inserts', function() - -- op_insert in ops.c - feed('a12345') - set_extmark(ns, marks[1], 1, 2) - feed('0lkI9') - check_undo_redo(ns, marks[1], 1, 2, 1, 3) - end) - - it('marks move with line splits (using enter)', function() - -- open_line in misc1.c - -- testing marks below are also moved - feed("yyP") - set_extmark(ns, marks[1], 0, 4) - set_extmark(ns, marks[2], 1, 4) - feed('1Gla') - check_undo_redo(ns, marks[1], 0, 4, 1, 2) - check_undo_redo(ns, marks[2], 1, 4, 2, 4) - end) - - it('marks at last line move on insert new line', function() - -- open_line in misc1.c - set_extmark(ns, marks[1], 0, 4) - feed('0i') - check_undo_redo(ns, marks[1], 0, 4, 1, 4) - end) - - it('yet again marks move with line splits', function() - -- the first test above wasn't catching all errors.. - feed("A67890") - set_extmark(ns, marks[1], 0, 4) - feed("04li") - check_undo_redo(ns, marks[1], 0, 4, 1, 0) - end) - - it('and one last time line splits...', function() - set_extmark(ns, marks[1], 0, 1) - set_extmark(ns, marks[2], 0, 2) - feed("02li") - check_undo_redo(ns, marks[1], 0, 1, 0, 1) - check_undo_redo(ns, marks[2], 0, 2, 1, 0) - end) - - it('multiple marks move with mark splits', function() - set_extmark(ns, marks[1], 0, 1) - set_extmark(ns, marks[2], 0, 3) - feed("0li") - check_undo_redo(ns, marks[1], 0, 1, 1, 0) - check_undo_redo(ns, marks[2], 0, 3, 1, 2) - end) - - it('deleting right before a mark works', function() - -- op_delete in ops.c - set_extmark(ns, marks[1], 0, 2) - feed('0lx') - check_undo_redo(ns, marks[1], 0, 2, 0, 1) - end) - - it('deleting right after a mark works', function() - -- op_delete in ops.c - set_extmark(ns, marks[1], 0, 2) - feed('02lx') - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - end) - - it('marks move with char deletes', function() - -- op_delete in ops.c - set_extmark(ns, marks[1], 0, 2) - feed('02dl') - check_undo_redo(ns, marks[1], 0, 2, 0, 0) - -- from the other side (nothing should happen) - feed('$x') - check_undo_redo(ns, marks[1], 0, 0, 0, 0) - end) - - it('marks move with char deletes over a range', function() - -- op_delete in ops.c - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 0, 3) - feed('0l3dl') - check_undo_redo(ns, marks[1], 0, 2, 0, 1) - check_undo_redo(ns, marks[2], 0, 3, 0, 1) - -- delete 1, nothing should happen to our marks - feed('u') - feed('$x') - check_undo_redo(ns, marks[2], 0, 3, 0, 3) - end) - - it('deleting marks at end of line works', function() - -- mark_extended.c/extmark_col_adjust_delete - set_extmark(ns, marks[1], 0, 4) - feed('$x') - check_undo_redo(ns, marks[1], 0, 4, 0, 4) - -- check the copy happened correctly on delete at eol - feed('$x') - check_undo_redo(ns, marks[1], 0, 4, 0, 3) - feed('u') - check_undo_redo(ns, marks[1], 0, 4, 0, 4) - end) - - it('marks move with blockwise deletes', function() - -- op_delete in ops.c - feed('a12345') - set_extmark(ns, marks[1], 1, 4) - feed('hhhkd') - check_undo_redo(ns, marks[1], 1, 4, 1, 1) - end) - - it('marks move with blockwise deletes over a range', function() - -- op_delete in ops.c - feed('a12345') - set_extmark(ns, marks[1], 0, 1) - set_extmark(ns, marks[2], 0, 3) - set_extmark(ns, marks[3], 1, 2) - feed('0k3lx') - check_undo_redo(ns, marks[1], 0, 1, 0, 0) - check_undo_redo(ns, marks[2], 0, 3, 0, 0) - check_undo_redo(ns, marks[3], 1, 2, 1, 0) - -- delete 1, nothing should happen to our marks - feed('u') - feed('$jx') - check_undo_redo(ns, marks[2], 0, 3, 0, 3) - check_undo_redo(ns, marks[3], 1, 2, 1, 2) - end) - - it('works with char deletes over multilines', function() - feed('a12345test-me') - set_extmark(ns, marks[1], 2, 5) - feed('gg') - feed('dv?-m?') - check_undo_redo(ns, marks[1], 2, 5, 0, 0) - end) - - it('marks outside of deleted range move with visual char deletes', function() - -- op_delete in ops.c - set_extmark(ns, marks[1], 0, 3) - feed('0vx') - check_undo_redo(ns, marks[1], 0, 3, 0, 2) - - feed("u") - feed('0vlx') - check_undo_redo(ns, marks[1], 0, 3, 0, 1) - - feed("u") - feed('0v2lx') - check_undo_redo(ns, marks[1], 0, 3, 0, 0) - - -- from the other side (nothing should happen) - feed('$vx') - check_undo_redo(ns, marks[1], 0, 0, 0, 0) - end) - - it('marks outside of deleted range move with char deletes', function() - -- op_delete in ops.c - set_extmark(ns, marks[1], 0, 3) - feed('0x') - check_undo_redo(ns, marks[1], 0, 3, 0, 2) - - feed("u") - feed('02x') - check_undo_redo(ns, marks[1], 0, 3, 0, 1) - - feed("u") - feed('0v3lx') - check_undo_redo(ns, marks[1], 0, 3, 0, 0) - - -- from the other side (nothing should happen) - feed("u") - feed('$vx') - check_undo_redo(ns, marks[1], 0, 3, 0, 3) - end) - - it('marks move with P(backward) paste', function() - -- do_put in ops.c - feed('0iabc') - set_extmark(ns, marks[1], 0, 7) - feed('0veyP') - check_undo_redo(ns, marks[1], 0, 7, 0, 15) - end) - - it('marks move with p(forward) paste', function() - -- do_put in ops.c - feed('0iabc') - set_extmark(ns, marks[1], 0, 7) - feed('0veyp') - check_undo_redo(ns, marks[1], 0, 7, 0, 15) - end) - - it('marks move with blockwise P(backward) paste', function() - -- do_put in ops.c - feed('a12345') - set_extmark(ns, marks[1], 1, 4) - feed('hhkyP') - check_undo_redo(ns, marks[1], 1, 4, 1, 7) - end) - - it('marks move with blockwise p(forward) paste', function() - -- do_put in ops.c - feed('a12345') - set_extmark(ns, marks[1], 1, 4) - feed('hhkyp') - check_undo_redo(ns, marks[1], 1, 4, 1, 7) - end) - - describe('multiline regions', function() - before_each(function() - feed('dd') - -- Achtung: code has been spiced with some unicode, - -- to make life more interesting. - -- luacheck whines about TABs inside strings for whatever reason. - -- luacheck: push ignore 621 - insert([[ - static int nlua_rpcrequest(lua_State *lstate) - { - Ïf (!nlua_is_deferred_safe(lstate)) { - // strictly not allowed - Яetörn luaL_error(lstate, e_luv_api_disabled, "rpcrequest"); - } - return nlua_rpc(lstate, true); - }]]) - -- luacheck: pop - end) - - it('delete', function() - local pos1 = { - {2, 4}, {2, 12}, {2, 13}, {2, 14}, {2, 25}, - {4, 8}, {4, 10}, {4, 20}, - {5, 3}, {6, 10} - } - local ids = batch_set(ns, pos1) - batch_check(ns, ids, pos1) - feed('3Gfiv2+ftd') - batch_check_undo_redo(ns, ids, pos1, { - {2, 4}, {2, 12}, {2, 13}, {2, 13}, {2, 13}, - {2, 13}, {2, 15}, {2, 25}, - {3, 3}, {4, 10} - }) - end) - - -- TODO(bfredl): add more tests! - end) - - it('replace works', function() - set_extmark(ns, marks[1], 0, 2) - feed('0r2') - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - end) - - it('blockwise replace works', function() - feed('a12345') - set_extmark(ns, marks[1], 0, 2) - feed('0llkr1') - check_undo_redo(ns, marks[1], 0, 2, 0, 3) - end) - - it('shift line', function() - -- shift_line in ops.c - feed(':set shiftwidth=4') - set_extmark(ns, marks[1], 0, 2) - feed('0>>') - check_undo_redo(ns, marks[1], 0, 2, 0, 6) - expect(' 12345') - - feed('>>') - -- this is counter-intuitive. But what happens - -- is that 4 spaces gets extended to one tab (== 8 spaces) - check_undo_redo(ns, marks[1], 0, 6, 0, 3) - expect('\t12345') - - feed('') -- have to escape, same as << - check_undo_redo(ns, marks[1], 0, 3, 0, 6) - end) - - it('blockwise shift', function() - -- shift_block in ops.c - feed(':set shiftwidth=4') - feed('a12345') - set_extmark(ns, marks[1], 1, 2) - feed('0k>') - check_undo_redo(ns, marks[1], 1, 2, 1, 6) - feed('j>') - expect('\t12345\n\t12345') - check_undo_redo(ns, marks[1], 1, 6, 1, 3) - - feed('j') - check_undo_redo(ns, marks[1], 1, 3, 1, 6) - end) - - it('tab works with expandtab', function() - -- ins_tab in edit.c - feed(':set expandtab') - feed(':set shiftwidth=2') - set_extmark(ns, marks[1], 0, 2) - feed('0i') - check_undo_redo(ns, marks[1], 0, 2, 0, 6) - end) - - it('tabs work', function() - -- ins_tab in edit.c - feed(':set noexpandtab') - feed(':set shiftwidth=2') - feed(':set softtabstop=2') - feed(':set tabstop=8') - set_extmark(ns, marks[1], 0, 2) - feed('0i') - check_undo_redo(ns, marks[1], 0, 2, 0, 4) - feed('0iX') - check_undo_redo(ns, marks[1], 0, 4, 0, 6) - end) - - it('marks move when using :move', function() - set_extmark(ns, marks[1], 0, 0) - feed('A2:1move 2') - check_undo_redo(ns, marks[1], 0, 0, 1, 0) - -- test codepath when moving lines up - feed(':2move 0') - check_undo_redo(ns, marks[1], 1, 0, 0, 0) - end) - - it('marks move when using :move part 2', function() - -- make sure we didn't get lucky with the math... - feed('A23456') - set_extmark(ns, marks[1], 1, 0) - feed(':2,3move 5') - check_undo_redo(ns, marks[1], 1, 0, 3, 0) - -- test codepath when moving lines up - feed(':4,5move 1') - check_undo_redo(ns, marks[1], 3, 0, 1, 0) - end) - - it('undo and redo of set and unset marks', function() - -- Force a new undo head - feed('o') - set_extmark(ns, marks[1], 0, 1) - feed('o') - set_extmark(ns, marks[2], 0, -1) - set_extmark(ns, marks[3], 0, -1) - - feed("u") - local rv = get_extmarks(ns, {0, 0}, {-1, -1}) - eq(3, table.getn(rv)) - - feed("") - rv = get_extmarks(ns, {0, 0}, {-1, -1}) - eq(3, table.getn(rv)) - - -- Test updates - feed('o') - set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - rv = get_extmarks(ns, marks[1], marks[1], {limit=1}) - eq(1, table.getn(rv)) - feed("u") - feed("") - -- old value is NOT kept in history - check_undo_redo(ns, marks[1], positions[1][1], positions[1][2], positions[1][1], positions[1][2]) - - -- Test unset - feed('o') - curbufmeths.del_extmark(ns, marks[3]) - feed("u") - rv = get_extmarks(ns, {0, 0}, {-1, -1}) - -- undo does NOT restore deleted marks - eq(2, table.getn(rv)) - feed("") - rv = get_extmarks(ns, {0, 0}, {-1, -1}) - eq(2, table.getn(rv)) - end) - - it('undo and redo of marks deleted during edits', function() - -- test extmark_adjust - feed('A12345') - set_extmark(ns, marks[1], 1, 2) - feed('dd') - check_undo_redo(ns, marks[1], 1, 2, 1, 0) - end) - - it('namespaces work properly', function() - local rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - eq(1, rv) - rv = set_extmark(ns2, marks[1], positions[1][1], positions[1][2]) - eq(1, rv) - rv = get_extmarks(ns, {0, 0}, {-1, -1}) - eq(1, table.getn(rv)) - rv = get_extmarks(ns2, {0, 0}, {-1, -1}) - eq(1, table.getn(rv)) - - -- Set more marks for testing the ranges - set_extmark(ns, marks[2], positions[2][1], positions[2][2]) - set_extmark(ns, marks[3], positions[3][1], positions[3][2]) - set_extmark(ns2, marks[2], positions[2][1], positions[2][2]) - set_extmark(ns2, marks[3], positions[3][1], positions[3][2]) - - -- get_next (limit set) - rv = get_extmarks(ns, {0, 0}, positions[2], {limit=1}) - eq(1, table.getn(rv)) - rv = get_extmarks(ns2, {0, 0}, positions[2], {limit=1}) - eq(1, table.getn(rv)) - -- get_prev (limit set) - rv = get_extmarks(ns, positions[1], {0, 0}, {limit=1}) - eq(1, table.getn(rv)) - rv = get_extmarks(ns2, positions[1], {0, 0}, {limit=1}) - eq(1, table.getn(rv)) - - -- get_next (no limit) - rv = get_extmarks(ns, positions[1], positions[2]) - eq(2, table.getn(rv)) - rv = get_extmarks(ns2, positions[1], positions[2]) - eq(2, table.getn(rv)) - -- get_prev (no limit) - rv = get_extmarks(ns, positions[2], positions[1]) - eq(2, table.getn(rv)) - rv = get_extmarks(ns2, positions[2], positions[1]) - eq(2, table.getn(rv)) - - curbufmeths.del_extmark(ns, marks[1]) - rv = get_extmarks(ns, {0, 0}, {-1, -1}) - eq(2, table.getn(rv)) - curbufmeths.del_extmark(ns2, marks[1]) - rv = get_extmarks(ns2, {0, 0}, {-1, -1}) - eq(2, table.getn(rv)) - end) - - it('mark set can create unique identifiers', function() - -- create mark with id 1 - eq(1, set_extmark(ns, 1, positions[1][1], positions[1][2])) - -- ask for unique id, it should be the next one, i e 2 - eq(2, set_extmark(ns, 0, positions[1][1], positions[1][2])) - eq(3, set_extmark(ns, 3, positions[2][1], positions[2][2])) - eq(4, set_extmark(ns, 0, positions[1][1], positions[1][2])) - - -- mixing manual and allocated id:s are not recommened, but it should - -- do something reasonable - eq(6, set_extmark(ns, 6, positions[2][1], positions[2][2])) - eq(7, set_extmark(ns, 0, positions[1][1], positions[1][2])) - eq(8, set_extmark(ns, 0, positions[1][1], positions[1][2])) - end) - - it('auto indenting with enter works', function() - -- op_reindent in ops.c - feed(':set cindent') - feed(':set autoindent') - feed(':set shiftwidth=2') - feed("0iint A {1M1b") - -- Set the mark on the M, should move.. - set_extmark(ns, marks[1], 0, 12) - -- Set the mark before the cursor, should stay there - set_extmark(ns, marks[2], 0, 10) - feed("i") - local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({1, 3}, rv) - rv = curbufmeths.get_extmark_by_id(ns, marks[2]) - eq({0, 10}, rv) - check_undo_redo(ns, marks[1], 0, 12, 1, 3) - end) - - it('auto indenting entire line works', function() - feed(':set cindent') - feed(':set autoindent') - feed(':set shiftwidth=2') - -- will force an indent of 2 - feed("0iint A {0i1M1") - set_extmark(ns, marks[1], 1, 1) - feed("0i") - local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({1, 3}, rv) - check_undo_redo(ns, marks[1], 1, 1, 1, 3) - -- now check when cursor at eol - feed("uA") - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({1, 3}, rv) - end) - - it('removing auto indenting with works', function() - feed(':set cindent') - feed(':set autoindent') - feed(':set shiftwidth=2') - feed("0i") - set_extmark(ns, marks[1], 0, 3) - feed("bi") - local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({0, 1}, rv) - check_undo_redo(ns, marks[1], 0, 3, 0, 1) - -- check when cursor at eol - feed("uA") - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({0, 1}, rv) - end) - - it('indenting multiple lines with = works', function() - feed(':set cindent') - feed(':set autoindent') - feed(':set shiftwidth=2') - feed("0iint A {1M12M2") - set_extmark(ns, marks[1], 1, 1) - set_extmark(ns, marks[2], 2, 1) - feed('=gg') - check_undo_redo(ns, marks[1], 1, 1, 1, 3) - check_undo_redo(ns, marks[2], 2, 1, 2, 5) - end) - - it('substitutes by deleting inside the replace matches', function() - -- do_sub in ex_cmds.c - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 0, 3) - feed(':s/34/xx') - check_undo_redo(ns, marks[1], 0, 2, 0, 4) - check_undo_redo(ns, marks[2], 0, 3, 0, 4) - end) - - it('substitutes when insert text > deleted', function() - -- do_sub in ex_cmds.c - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 0, 3) - feed(':s/34/xxx') - check_undo_redo(ns, marks[1], 0, 2, 0, 5) - check_undo_redo(ns, marks[2], 0, 3, 0, 5) - end) - - it('substitutes when marks around eol', function() - -- do_sub in ex_cmds.c - set_extmark(ns, marks[1], 0, 4) - set_extmark(ns, marks[2], 0, 5) - feed(':s/5/xxx') - check_undo_redo(ns, marks[1], 0, 4, 0, 7) - check_undo_redo(ns, marks[2], 0, 5, 0, 7) - end) - - it('substitutes over range insert text > deleted', function() - -- do_sub in ex_cmds.c - feed('Ax34xx') - feed('Axxx34') - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 1, 1) - set_extmark(ns, marks[3], 2, 4) - feed(':1,3s/34/xxx') - check_undo_redo(ns, marks[1], 0, 2, 0, 5) - check_undo_redo(ns, marks[2], 1, 1, 1, 4) - check_undo_redo(ns, marks[3], 2, 4, 2, 6) - end) - - it('substitutes multiple matches in a line', function() - -- do_sub in ex_cmds.c - feed('ddi3x3x3') - set_extmark(ns, marks[1], 0, 0) - set_extmark(ns, marks[2], 0, 2) - set_extmark(ns, marks[3], 0, 4) - feed(':s/3/yy/g') - check_undo_redo(ns, marks[1], 0, 0, 0, 2) - check_undo_redo(ns, marks[2], 0, 2, 0, 5) - check_undo_redo(ns, marks[3], 0, 4, 0, 8) - end) - - it('substitions over multiple lines with newline in pattern', function() - feed('A67890xx') - set_extmark(ns, marks[1], 0, 3) - set_extmark(ns, marks[2], 0, 4) - set_extmark(ns, marks[3], 1, 0) - set_extmark(ns, marks[4], 1, 5) - set_extmark(ns, marks[5], 2, 0) - feed([[:1,2s:5\n:5 ]]) - check_undo_redo(ns, marks[1], 0, 3, 0, 3) - check_undo_redo(ns, marks[2], 0, 4, 0, 6) - check_undo_redo(ns, marks[3], 1, 0, 0, 6) - check_undo_redo(ns, marks[4], 1, 5, 0, 11) - check_undo_redo(ns, marks[5], 2, 0, 1, 0) - end) - - it('inserting', function() - feed('A67890xx') - set_extmark(ns, marks[1], 0, 3) - set_extmark(ns, marks[2], 0, 4) - set_extmark(ns, marks[3], 1, 0) - set_extmark(ns, marks[4], 1, 5) - set_extmark(ns, marks[5], 2, 0) - set_extmark(ns, marks[6], 1, 2) - feed([[:1,2s:5\n67:X]]) - check_undo_redo(ns, marks[1], 0, 3, 0, 3) - check_undo_redo(ns, marks[2], 0, 4, 0, 5) - check_undo_redo(ns, marks[3], 1, 0, 0, 5) - check_undo_redo(ns, marks[4], 1, 5, 0, 8) - check_undo_redo(ns, marks[5], 2, 0, 1, 0) - check_undo_redo(ns, marks[6], 1, 2, 0, 5) - end) - - it('substitions with multiple newlines in pattern', function() - feed('A67890xx') - set_extmark(ns, marks[1], 0, 4) - set_extmark(ns, marks[2], 0, 5) - set_extmark(ns, marks[3], 1, 0) - set_extmark(ns, marks[4], 1, 5) - set_extmark(ns, marks[5], 2, 0) - feed([[:1,2s:\n.*\n:X]]) - check_undo_redo(ns, marks[1], 0, 4, 0, 4) - check_undo_redo(ns, marks[2], 0, 5, 0, 6) - check_undo_redo(ns, marks[3], 1, 0, 0, 6) - check_undo_redo(ns, marks[4], 1, 5, 0, 6) - check_undo_redo(ns, marks[5], 2, 0, 0, 6) - end) - - it('substitions over multiple lines with replace in substition', function() - feed('A67890xx') - set_extmark(ns, marks[1], 0, 1) - set_extmark(ns, marks[2], 0, 2) - set_extmark(ns, marks[3], 0, 4) - set_extmark(ns, marks[4], 1, 0) - set_extmark(ns, marks[5], 2, 0) - feed([[:1,2s:3:\r]]) - check_undo_redo(ns, marks[1], 0, 1, 0, 1) - check_undo_redo(ns, marks[2], 0, 2, 1, 0) - check_undo_redo(ns, marks[3], 0, 4, 1, 1) - check_undo_redo(ns, marks[4], 1, 0, 2, 0) - check_undo_redo(ns, marks[5], 2, 0, 3, 0) - feed('u') - feed([[:1,2s:3:\rxx]]) - eq({1, 3}, curbufmeths.get_extmark_by_id(ns, marks[3])) - end) - - it('substitions over multiple lines with replace in substition', function() - feed('Ax3xx') - set_extmark(ns, marks[1], 1, 0) - set_extmark(ns, marks[2], 1, 1) - set_extmark(ns, marks[3], 1, 2) - feed([[:2,2s:3:\r]]) - check_undo_redo(ns, marks[1], 1, 0, 1, 0) - check_undo_redo(ns, marks[2], 1, 1, 2, 0) - check_undo_redo(ns, marks[3], 1, 2, 2, 0) - end) - - it('substitions over multiple lines with replace in substition', function() - feed('Ax3xx') - set_extmark(ns, marks[1], 0, 1) - set_extmark(ns, marks[2], 0, 2) - set_extmark(ns, marks[3], 0, 4) - set_extmark(ns, marks[4], 1, 1) - set_extmark(ns, marks[5], 2, 0) - feed([[:1,2s:3:\r]]) - check_undo_redo(ns, marks[1], 0, 1, 0, 1) - check_undo_redo(ns, marks[2], 0, 2, 1, 0) - check_undo_redo(ns, marks[3], 0, 4, 1, 1) - check_undo_redo(ns, marks[4], 1, 1, 3, 0) - check_undo_redo(ns, marks[5], 2, 0, 4, 0) - feed('u') - feed([[:1,2s:3:\rxx]]) - check_undo_redo(ns, marks[3], 0, 4, 1, 3) - end) - - it('substitions with newline in match and sub, delta is 0', function() - feed('A67890xx') - set_extmark(ns, marks[1], 0, 3) - set_extmark(ns, marks[2], 0, 4) - set_extmark(ns, marks[3], 0, 5) - set_extmark(ns, marks[4], 1, 0) - set_extmark(ns, marks[5], 1, 5) - set_extmark(ns, marks[6], 2, 0) - feed([[:1,1s:5\n:\r]]) - check_undo_redo(ns, marks[1], 0, 3, 0, 3) - check_undo_redo(ns, marks[2], 0, 4, 1, 0) - check_undo_redo(ns, marks[3], 0, 5, 1, 0) - check_undo_redo(ns, marks[4], 1, 0, 1, 0) - check_undo_redo(ns, marks[5], 1, 5, 1, 5) - check_undo_redo(ns, marks[6], 2, 0, 2, 0) - end) - - it('substitions with newline in match and sub, delta > 0', function() - feed('A67890xx') - set_extmark(ns, marks[1], 0, 3) - set_extmark(ns, marks[2], 0, 4) - set_extmark(ns, marks[3], 0, 5) - set_extmark(ns, marks[4], 1, 0) - set_extmark(ns, marks[5], 1, 5) - set_extmark(ns, marks[6], 2, 0) - feed([[:1,1s:5\n:\r\r]]) - check_undo_redo(ns, marks[1], 0, 3, 0, 3) - check_undo_redo(ns, marks[2], 0, 4, 2, 0) - check_undo_redo(ns, marks[3], 0, 5, 2, 0) - check_undo_redo(ns, marks[4], 1, 0, 2, 0) - check_undo_redo(ns, marks[5], 1, 5, 2, 5) - check_undo_redo(ns, marks[6], 2, 0, 3, 0) - end) - - it('substitions with newline in match and sub, delta < 0', function() - feed('A67890xxxx') - set_extmark(ns, marks[1], 0, 3) - set_extmark(ns, marks[2], 0, 4) - set_extmark(ns, marks[3], 0, 5) - set_extmark(ns, marks[4], 1, 0) - set_extmark(ns, marks[5], 1, 5) - set_extmark(ns, marks[6], 2, 1) - set_extmark(ns, marks[7], 3, 0) - feed([[:1,2s:5\n.*\n:\r]]) - check_undo_redo(ns, marks[1], 0, 3, 0, 3) - check_undo_redo(ns, marks[2], 0, 4, 1, 0) - check_undo_redo(ns, marks[3], 0, 5, 1, 0) - check_undo_redo(ns, marks[4], 1, 0, 1, 0) - check_undo_redo(ns, marks[5], 1, 5, 1, 0) - check_undo_redo(ns, marks[6], 2, 1, 1, 1) - check_undo_redo(ns, marks[7], 3, 0, 2, 0) - end) - - it('substitions with backrefs, newline inserted into sub', function() - feed('A67890xxxx') - set_extmark(ns, marks[1], 0, 3) - set_extmark(ns, marks[2], 0, 4) - set_extmark(ns, marks[3], 0, 5) - set_extmark(ns, marks[4], 1, 0) - set_extmark(ns, marks[5], 1, 5) - set_extmark(ns, marks[6], 2, 0) - feed([[:1,1s:5\(\n\):\0\1]]) - check_undo_redo(ns, marks[1], 0, 3, 0, 3) - check_undo_redo(ns, marks[2], 0, 4, 2, 0) - check_undo_redo(ns, marks[3], 0, 5, 2, 0) - check_undo_redo(ns, marks[4], 1, 0, 2, 0) - check_undo_redo(ns, marks[5], 1, 5, 2, 5) - check_undo_redo(ns, marks[6], 2, 0, 3, 0) - end) - - it('substitions a ^', function() - set_extmark(ns, marks[1], 0, 0) - set_extmark(ns, marks[2], 0, 1) - feed([[:s:^:x]]) - check_undo_redo(ns, marks[1], 0, 0, 0, 1) - check_undo_redo(ns, marks[2], 0, 1, 0, 2) - end) - - it('using without increase in order of magnitude', function() - -- do_addsub in ops.c - feed('ddiabc998xxxTc') - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 0, 3) - set_extmark(ns, marks[3], 0, 5) - set_extmark(ns, marks[4], 0, 6) - set_extmark(ns, marks[5], 0, 7) - feed('') - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - check_undo_redo(ns, marks[2], 0, 3, 0, 6) - check_undo_redo(ns, marks[3], 0, 5, 0, 6) - check_undo_redo(ns, marks[4], 0, 6, 0, 6) - check_undo_redo(ns, marks[5], 0, 7, 0, 7) - end) - - it('using when increase in order of magnitude', function() - -- do_addsub in ops.c - feed('ddiabc999xxxTc') - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 0, 3) - set_extmark(ns, marks[3], 0, 5) - set_extmark(ns, marks[4], 0, 6) - set_extmark(ns, marks[5], 0, 7) - feed('') - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - check_undo_redo(ns, marks[2], 0, 3, 0, 7) - check_undo_redo(ns, marks[3], 0, 5, 0, 7) - check_undo_redo(ns, marks[4], 0, 6, 0, 7) - check_undo_redo(ns, marks[5], 0, 7, 0, 8) - end) - - it('using when negative and without decrease in order of magnitude', function() - feed('ddiabc-999xxxT-') - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 0, 3) - set_extmark(ns, marks[3], 0, 6) - set_extmark(ns, marks[4], 0, 7) - set_extmark(ns, marks[5], 0, 8) - feed('') - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - check_undo_redo(ns, marks[2], 0, 3, 0, 7) - check_undo_redo(ns, marks[3], 0, 6, 0, 7) - check_undo_redo(ns, marks[4], 0, 7, 0, 7) - check_undo_redo(ns, marks[5], 0, 8, 0, 8) - end) - - it('using when negative and decrease in order of magnitude', function() - feed('ddiabc-1000xxxT-') - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 0, 3) - set_extmark(ns, marks[3], 0, 7) - set_extmark(ns, marks[4], 0, 8) - set_extmark(ns, marks[5], 0, 9) - feed('') - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - check_undo_redo(ns, marks[2], 0, 3, 0, 7) - check_undo_redo(ns, marks[3], 0, 7, 0, 7) - check_undo_redo(ns, marks[4], 0, 8, 0, 7) - check_undo_redo(ns, marks[5], 0, 9, 0, 8) - end) - - it('using without decrease in order of magnitude', function() - -- do_addsub in ops.c - feed('ddiabc999xxxTc') - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 0, 3) - set_extmark(ns, marks[3], 0, 5) - set_extmark(ns, marks[4], 0, 6) - set_extmark(ns, marks[5], 0, 7) - feed('') - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - check_undo_redo(ns, marks[2], 0, 3, 0, 6) - check_undo_redo(ns, marks[3], 0, 5, 0, 6) - check_undo_redo(ns, marks[4], 0, 6, 0, 6) - check_undo_redo(ns, marks[5], 0, 7, 0, 7) - end) - - it('using when decrease in order of magnitude', function() - -- do_addsub in ops.c - feed('ddiabc1000xxxTc') - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 0, 3) - set_extmark(ns, marks[3], 0, 6) - set_extmark(ns, marks[4], 0, 7) - set_extmark(ns, marks[5], 0, 8) - feed('') - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - check_undo_redo(ns, marks[2], 0, 3, 0, 6) - check_undo_redo(ns, marks[3], 0, 6, 0, 6) - check_undo_redo(ns, marks[4], 0, 7, 0, 6) - check_undo_redo(ns, marks[5], 0, 8, 0, 7) - end) - - it('using when negative and without increase in order of magnitude', function() - feed('ddiabc-998xxxT-') - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 0, 3) - set_extmark(ns, marks[3], 0, 6) - set_extmark(ns, marks[4], 0, 7) - set_extmark(ns, marks[5], 0, 8) - feed('') - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - check_undo_redo(ns, marks[2], 0, 3, 0, 7) - check_undo_redo(ns, marks[3], 0, 6, 0, 7) - check_undo_redo(ns, marks[4], 0, 7, 0, 7) - check_undo_redo(ns, marks[5], 0, 8, 0, 8) - end) - - it('using when negative and increase in order of magnitude', function() - feed('ddiabc-999xxxT-') - set_extmark(ns, marks[1], 0, 2) - set_extmark(ns, marks[2], 0, 3) - set_extmark(ns, marks[3], 0, 6) - set_extmark(ns, marks[4], 0, 7) - set_extmark(ns, marks[5], 0, 8) - feed('') - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - check_undo_redo(ns, marks[2], 0, 3, 0, 8) - check_undo_redo(ns, marks[3], 0, 6, 0, 8) - check_undo_redo(ns, marks[4], 0, 7, 0, 8) - check_undo_redo(ns, marks[5], 0, 8, 0, 9) - end) - - it('throws consistent error codes', function() - local ns_invalid = ns2 + 1 - eq("Invalid ns_id", pcall_err(set_extmark, ns_invalid, marks[1], positions[1][1], positions[1][2])) - eq("Invalid ns_id", pcall_err(curbufmeths.del_extmark, ns_invalid, marks[1])) - eq("Invalid ns_id", pcall_err(get_extmarks, ns_invalid, positions[1], positions[2])) - eq("Invalid ns_id", pcall_err(curbufmeths.get_extmark_by_id, ns_invalid, marks[1])) - end) - - it('when col = line-length, set the mark on eol', function() - set_extmark(ns, marks[1], 0, -1) - local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({0, init_text:len()}, rv) - -- Test another - set_extmark(ns, marks[1], 0, -1) - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({0, init_text:len()}, rv) - end) - - it('when col = line-length, set the mark on eol', function() - local invalid_col = init_text:len() + 1 - eq("col value outside range", pcall_err(set_extmark, ns, marks[1], 0, invalid_col)) - end) - - it('fails when line > line_count', function() - local invalid_col = init_text:len() + 1 - local invalid_lnum = 3 - eq('line value outside range', pcall_err(set_extmark, ns, marks[1], invalid_lnum, invalid_col)) - eq({}, curbufmeths.get_extmark_by_id(ns, marks[1])) - end) - - it('bug from check_col in extmark_set', function() - -- This bug was caused by extmark_set always using check_col. check_col - -- always uses the current buffer. This wasn't working during undo so we - -- now use check_col and check_lnum only when they are required. - feed('A67890xx') - feed('A1234567890xx') - set_extmark(ns, marks[1], 3, 4) - feed([[:1,5s:5\n:5 ]]) - check_undo_redo(ns, marks[1], 3, 4, 2, 6) - end) - - it('in read-only buffer', function() - command("view! runtime/doc/help.txt") - eq(true, curbufmeths.get_option('ro')) - local id = set_extmark(ns, 0, 0, 2) - eq({{id, 0, 2}}, get_extmarks(ns,0, -1)) - end) - - it('can set a mark to other buffer', function() - local buf = request('nvim_create_buf', 0, 1) - request('nvim_buf_set_lines', buf, 0, -1, 1, {"", ""}) - local id = bufmeths.set_extmark(buf, ns, 0, 1, 0, {}) - eq({{id, 1, 0}}, bufmeths.get_extmarks(buf, ns, 0, -1, {})) - end) - - it('does not crash with append/delete/undo seqence', function() - meths.exec([[ - let ns = nvim_create_namespace('myplugin') - call nvim_buf_set_extmark(0, ns, 0, 0, 0, {}) - call append(0, '') - %delete - undo]],false) - eq(2, meths.eval('1+1')) -- did not crash - end) -end) - -describe('Extmarks buffer api with many marks', function() - local ns1 - local ns2 - local ns_marks = {} - before_each(function() - clear() - ns1 = request('nvim_create_namespace', "ns1") - ns2 = request('nvim_create_namespace', "ns2") - ns_marks = {[ns1]={}, [ns2]={}} - local lines = {} - for i = 1,30 do - lines[#lines+1] = string.rep("x ",i) - end - curbufmeths.set_lines(0, -1, true, lines) - local ns = ns1 - local q = 0 - for i = 0,29 do - for j = 0,i do - local id = set_extmark(ns,0, i,j) - eq(nil, ns_marks[ns][id]) - ok(id > 0) - ns_marks[ns][id] = {i,j} - ns = ns1+ns2-ns - q = q + 1 - end - end - eq(233, #ns_marks[ns1]) - eq(232, #ns_marks[ns2]) - - end) - - local function get_marks(ns) - local mark_list = get_extmarks(ns, 0, -1) - local marks = {} - for _, mark in ipairs(mark_list) do - local id, row, col = unpack(mark) - eq(nil, marks[id], "duplicate mark") - marks[id] = {row,col} - end - return marks - end - - it("can get marks", function() - eq(ns_marks[ns1], get_marks(ns1)) - eq(ns_marks[ns2], get_marks(ns2)) - end) - - it("can clear all marks in ns", function() - curbufmeths.clear_namespace(ns1, 0, -1) - eq({}, get_marks(ns1)) - eq(ns_marks[ns2], get_marks(ns2)) - curbufmeths.clear_namespace(ns2, 0, -1) - eq({}, get_marks(ns1)) - eq({}, get_marks(ns2)) - end) - - it("can clear line range", function() - curbufmeths.clear_namespace(ns1, 10, 20) - for id, mark in pairs(ns_marks[ns1]) do - if 10 <= mark[1] and mark[1] < 20 then - ns_marks[ns1][id] = nil - end - end - eq(ns_marks[ns1], get_marks(ns1)) - eq(ns_marks[ns2], get_marks(ns2)) - end) - - it("can delete line", function() - feed('10Gdd') - for _, marks in pairs(ns_marks) do - for id, mark in pairs(marks) do - if mark[1] == 9 then - marks[id] = {9,0} - elseif mark[1] >= 10 then - mark[1] = mark[1] - 1 - end - end - end - eq(ns_marks[ns1], get_marks(ns1)) - eq(ns_marks[ns2], get_marks(ns2)) - end) - - it("can delete lines", function() - feed('10G10dd') - for _, marks in pairs(ns_marks) do - for id, mark in pairs(marks) do - if 9 <= mark[1] and mark[1] < 19 then - marks[id] = {9,0} - elseif mark[1] >= 19 then - mark[1] = mark[1] - 10 - end - end - end - eq(ns_marks[ns1], get_marks(ns1)) - eq(ns_marks[ns2], get_marks(ns2)) - end) - - it("can wipe buffer", function() - command('bwipe!') - eq({}, get_marks(ns1)) - eq({}, get_marks(ns2)) - end) -end) -- cgit From 7ce9a5c7da0fb5d6117cf9526c39e01faf7e908d Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 25 Jan 2020 13:29:52 +0100 Subject: api: add nvim_get_runtime_file for finding runtime files --- test/functional/api/vim_spec.lua | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'test/functional/api') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index d901a5e2eb..fb3755cb8e 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -23,6 +23,7 @@ local pcall_err = helpers.pcall_err local format_string = helpers.format_string local intchar2lua = helpers.intchar2lua local mergedicts_copy = helpers.mergedicts_copy +local endswith = helpers.endswith describe('API', function() before_each(clear) @@ -1853,4 +1854,27 @@ describe('API', function() command('silent! call nvim_create_buf(0, 1)') end) end) + + describe('nvim_get_runtime_file', function() + it('works', function() + eq({}, meths.get_runtime_file("bork.borkbork", false)) + eq({}, meths.get_runtime_file("bork.borkbork", true)) + eq(1, #meths.get_runtime_file("autoload/msgpack.vim", false)) + eq(1, #meths.get_runtime_file("autoload/msgpack.vim", true)) + local val = meths.get_runtime_file("autoload/remote/*.vim", true) + eq(2, #val) + local p = helpers.alter_slashes + if endswith(val[1], "define.vim") then + ok(endswith(val[1], p("autoload/remote/define.vim"))) + ok(endswith(val[2], p("autoload/remote/host.vim"))) + else + ok(endswith(val[1], p("autoload/remote/host.vim"))) + ok(endswith(val[2], p("autoload/remote/define.vim"))) + end + val = meths.get_runtime_file("autoload/remote/*.vim", false) + eq(1, #val) + ok(endswith(val[1], p("autoload/remote/define.vim")) + or endswith(val[1], p("autoload/remote/host.vim"))) + end) + end) end) -- cgit From 48c219829786c14b6e511229a59e2fda32ffe352 Mon Sep 17 00:00:00 2001 From: Jesse Date: Tue, 5 May 2020 13:18:41 +0200 Subject: paste: support replace mode (#11945) * paste: support replace mode * Clean up Co-authored-by: Jesse Bakker --- test/functional/api/vim_spec.lua | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'test/functional/api') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index fb3755cb8e..2e9d0f57ac 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -571,6 +571,28 @@ describe('API', function() eq({0,7,1,0}, funcs.getpos('.')) eq(false, nvim('get_option', 'paste')) end) + it('Replace-mode', function() + -- Within single line + nvim('put', {'aabbccdd', 'eeffgghh', 'iijjkkll'}, "c", true, false) + command('normal l') + command('startreplace') + nvim('paste', '123456', true, -1) + expect([[ + a123456d + eeffgghh + iijjkkll]]) + command('%delete _') + -- Across lines + nvim('put', {'aabbccdd', 'eeffgghh', 'iijjkkll'}, "c", true, false) + command('normal l') + command('startreplace') + nvim('paste', '123\n456', true, -1) + expect([[ + a123 + 456d + eeffgghh + iijjkkll]]) + end) it('crlf=false does not break lines at CR, CRLF', function() nvim('paste', 'line 1\r\n\r\rline 2\nline 3\rline 4\r', false, -1) expect('line 1\r\n\r\rline 2\nline 3\rline 4\r') -- cgit From e6e6affc0ee675861f3b1f093ae3e6572cd3b4a0 Mon Sep 17 00:00:00 2001 From: erw7 Date: Mon, 25 May 2020 14:57:44 +0900 Subject: nvim_input: add test --- test/functional/api/vim_spec.lua | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'test/functional/api') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 2e9d0f57ac..bd39413e60 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -482,6 +482,11 @@ describe('API', function() eq(true, status) -- nvim_input() did not fail. eq("E117:", v_errnum) -- v:errmsg was updated. end) + + it('does not crash even if trans_special result is largest #11788, #12287', function() + command("call nvim_input('')") + eq(1, eval('1')) + end) end) describe('nvim_paste', function() -- cgit From 977c0f292fe155dbf1748d6a0ff020f89cf7a894 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 29 May 2020 18:45:32 +0200 Subject: API: nvim_create_buf: unset 'modeline' in scratch-buffer #12379 Although 'nomodeline' is not strictly part of the definition of a "scratch-buffer" it is obviously the right default. --- test/functional/api/vim_spec.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'test/functional/api') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 2e9d0f57ac..debdfb9e9a 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1808,7 +1808,7 @@ describe('API', function() eq({id=1}, meths.get_current_buf()) end) - it("doesn't cause BufEnter or BufWinEnter autocmds", function() + it("does not trigger BufEnter, BufWinEnter", function() command("let g:fired = v:false") command("au BufEnter,BufWinEnter * let g:fired = v:true") @@ -1818,7 +1818,7 @@ describe('API', function() eq(false, eval('g:fired')) end) - it('|scratch-buffer|', function() + it('scratch-buffer', function() eq({id=2}, meths.create_buf(false, true)) eq({id=3}, meths.create_buf(true, true)) eq({id=4}, meths.create_buf(true, true)) @@ -1845,6 +1845,7 @@ describe('API', function() eq('nofile', meths.buf_get_option(b, 'buftype')) eq('hide', meths.buf_get_option(b, 'bufhidden')) eq(false, meths.buf_get_option(b, 'swapfile')) + eq(false, meths.buf_get_option(b, 'modeline')) end -- @@ -1860,8 +1861,9 @@ describe('API', function() eq('nofile', meths.buf_get_option(edited_buf, 'buftype')) eq('hide', meths.buf_get_option(edited_buf, 'bufhidden')) eq(false, meths.buf_get_option(edited_buf, 'swapfile')) + eq(false, meths.buf_get_option(edited_buf, 'modeline')) - -- scratch buffer can be wiped without error + -- Scratch buffer can be wiped without error. command('bwipe') screen:expect([[ ^ | -- cgit From 909af2f3f10b49faf5f56ca866d316dbb0a94384 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 3 Jun 2020 01:36:26 -0400 Subject: vim-patch:8.2.0491: cannot recognize a