diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2020-01-20 19:29:12 +0100 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2020-01-20 19:36:35 +0100 |
commit | 48a869dc6d29514e943070da9f22f702f5179826 (patch) | |
tree | a419f94caa361cbc79480e3468fea437e710f312 /test/functional/api/mark_extended_spec.lua | |
parent | 4d4035400ea9cc349fa77d5ac6128c9249c5cb7a (diff) | |
download | rneovim-48a869dc6d29514e943070da9f22f702f5179826.tar.gz rneovim-48a869dc6d29514e943070da9f22f702f5179826.tar.bz2 rneovim-48a869dc6d29514e943070da9f22f702f5179826.zip |
shed biking: it's always extmarks, never marks extended
Diffstat (limited to 'test/functional/api/mark_extended_spec.lua')
-rw-r--r-- | test/functional/api/mark_extended_spec.lua | 1478 |
1 files changed, 0 insertions, 1478 deletions
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("<c-r>") - 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("<c-r>") - 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<esc>') - 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('<c-r>') - 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<esc>') - 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('<c-r>') - 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('A<cr>12345<esc>') - feed('A<cr>12345<esc>') - 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('A<cr>12345<esc>') - feed('A<cr>12345<esc>') - 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("a<cr>22<cr>33<esc>") - 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("a<cr>222<esc>") - 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("a<cr>1<esc>") - 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("a<cr>222<cr>333<cr>444<esc>") - 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("a<cr>222<cr>333<cr>444<esc>") - 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("a<cr>222<cr>333<cr>444<esc>") - 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<s-o><esc>') - check_undo_redo(ns, marks[1], 0, 4, 1, 4) - check_undo_redo(ns, marks[2], 1, 4, 2, 4) - feed('2Go<esc>') - 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<esc>') - insert("~~") - check_undo_redo(ns, marks[1], 0, 2, 0, 2) - end) - - it('we can insert multibyte chars', function() - -- insertchar in edit.c - feed('a<cr>12345<esc>') - set_extmark(ns, marks[1], 1, 2) - -- Insert a fullwidth (two col) tilde, NICE - feed('0i~<esc>') - check_undo_redo(ns, marks[1], 1, 2, 1, 5) - end) - - it('marks move with blockwise inserts', function() - -- op_insert in ops.c - feed('a<cr>12345<esc>') - set_extmark(ns, marks[1], 1, 2) - feed('0<c-v>lkI9<esc>') - 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<cr><esc>') - 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<cr><esc>') - 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<esc>") - set_extmark(ns, marks[1], 0, 4) - feed("04li<cr><esc>") - 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<cr><esc>") - 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<cr><esc>") - 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<esc>') - 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('a<cr>12345<esc>') - set_extmark(ns, marks[1], 1, 4) - feed('h<c-v>hhkd') - 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('a<cr>12345<esc>') - set_extmark(ns, marks[1], 0, 1) - set_extmark(ns, marks[2], 0, 3) - set_extmark(ns, marks[3], 1, 2) - feed('0<c-v>k3lx') - 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('$<c-v>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('a<cr>12345<cr>test-me<esc>') - set_extmark(ns, marks[1], 2, 5) - feed('gg') - feed('dv?-m?<cr>') - 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<esc>') - check_undo_redo(ns, marks[1], 0, 3, 0, 2) - - feed("u") - feed('0vlx<esc>') - check_undo_redo(ns, marks[1], 0, 3, 0, 1) - - feed("u") - feed('0v2lx<esc>') - 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<esc>') - check_undo_redo(ns, marks[1], 0, 3, 0, 2) - - feed("u") - feed('02x<esc>') - check_undo_redo(ns, marks[1], 0, 3, 0, 1) - - feed("u") - feed('0v3lx<esc>') - 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<esc>') - 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<esc>') - 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('a<cr>12345<esc>') - set_extmark(ns, marks[1], 1, 4) - feed('<c-v>hhkyP<esc>') - 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('a<cr>12345<esc>') - set_extmark(ns, marks[1], 1, 4) - feed('<c-v>hhkyp<esc>') - 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('a<cr>12345<esc>') - set_extmark(ns, marks[1], 0, 2) - feed('0<c-v>llkr1<esc>') - check_undo_redo(ns, marks[1], 0, 2, 0, 3) - end) - - it('shift line', function() - -- shift_line in ops.c - feed(':set shiftwidth=4<cr><esc>') - 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('<LT><LT>') -- 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<cr><esc>') - feed('a<cr>12345<esc>') - set_extmark(ns, marks[1], 1, 2) - feed('0<c-v>k>') - check_undo_redo(ns, marks[1], 1, 2, 1, 6) - feed('<c-v>j>') - expect('\t12345\n\t12345') - check_undo_redo(ns, marks[1], 1, 6, 1, 3) - - feed('<c-v>j<LT>') - 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<cr><esc>') - feed(':set shiftwidth=2<cr><esc>') - set_extmark(ns, marks[1], 0, 2) - feed('0i<tab><tab><esc>') - check_undo_redo(ns, marks[1], 0, 2, 0, 6) - end) - - it('tabs work', function() - -- ins_tab in edit.c - feed(':set noexpandtab<cr><esc>') - feed(':set shiftwidth=2<cr><esc>') - feed(':set softtabstop=2<cr><esc>') - feed(':set tabstop=8<cr><esc>') - set_extmark(ns, marks[1], 0, 2) - feed('0i<tab><esc>') - check_undo_redo(ns, marks[1], 0, 2, 0, 4) - feed('0iX<tab><esc>') - 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('A<cr>2<esc>:1move 2<cr><esc>') - check_undo_redo(ns, marks[1], 0, 0, 1, 0) - -- test codepath when moving lines up - feed(':2move 0<cr><esc>') - 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('A<cr>2<cr>3<cr>4<cr>5<cr>6<esc>') - set_extmark(ns, marks[1], 1, 0) - feed(':2,3move 5<cr><esc>') - check_undo_redo(ns, marks[1], 1, 0, 3, 0) - -- test codepath when moving lines up - feed(':4,5move 1<cr><esc>') - 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<esc>') - set_extmark(ns, marks[1], 0, 1) - feed('o<esc>') - 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("<c-r>") - rv = get_extmarks(ns, {0, 0}, {-1, -1}) - eq(3, table.getn(rv)) - - -- Test updates - feed('o<esc>') - 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("<c-r>") - -- 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<esc>') - 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("<c-r>") - 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('A<cr>12345<esc>') - 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<cr><esc>') - feed(':set autoindent<cr><esc>') - feed(':set shiftwidth=2<cr><esc>') - feed("0iint <esc>A {1M1<esc>b<esc>") - -- 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<cr><esc>") - 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<cr><esc>') - feed(':set autoindent<cr><esc>') - feed(':set shiftwidth=2<cr><esc>') - -- <c-f> will force an indent of 2 - feed("0iint <esc>A {<cr><esc>0i1M1<esc>") - set_extmark(ns, marks[1], 1, 1) - feed("0i<c-f><esc>") - 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<c-f><esc>") - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({1, 3}, rv) - end) - - it('removing auto indenting with <C-D> works', function() - feed(':set cindent<cr><esc>') - feed(':set autoindent<cr><esc>') - feed(':set shiftwidth=2<cr><esc>') - feed("0i<tab><esc>") - set_extmark(ns, marks[1], 0, 3) - feed("bi<c-d><esc>") - 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<c-d><esc>") - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({0, 1}, rv) - end) - - it('indenting multiple lines with = works', function() - feed(':set cindent<cr><esc>') - feed(':set autoindent<cr><esc>') - feed(':set shiftwidth=2<cr><esc>') - feed("0iint <esc>A {<cr><bs>1M1<cr><bs>2M2<esc>") - 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<cr>') - 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<cr>') - 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<cr>') - 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('A<cr>x34xx<esc>') - feed('A<cr>xxx34<esc>') - 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<cr><esc>') - 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<esc>') - 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<cr><esc>') - 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('A<cr>67890<cr>xx<esc>') - 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 <cr>]]) - 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('A<cr>67890<cr>xx<esc>') - 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<cr>]]) - 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('A<cr>67890<cr>xx<esc>') - 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<cr>]]) - 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('A<cr>67890<cr>xx<esc>') - 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<cr>]]) - 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<cr>]]) - eq({1, 3}, curbufmeths.get_extmark_by_id(ns, marks[3])) - end) - - it('substitions over multiple lines with replace in substition', function() - feed('A<cr>x3<cr>xx<esc>') - 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<cr>]]) - 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('A<cr>x3<cr>xx<esc>') - 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<cr>]]) - 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<cr>]]) - check_undo_redo(ns, marks[3], 0, 4, 1, 3) - end) - - it('substitions with newline in match and sub, delta is 0', function() - feed('A<cr>67890<cr>xx<esc>') - 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<cr>]]) - 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('A<cr>67890<cr>xx<esc>') - 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<cr>]]) - 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('A<cr>67890<cr>xx<cr>xx<esc>') - 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<cr>]]) - 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('A<cr>67890<cr>xx<cr>xx<esc>') - 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<cr>]]) - 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<cr>]]) - check_undo_redo(ns, marks[1], 0, 0, 0, 1) - check_undo_redo(ns, marks[2], 0, 1, 0, 2) - end) - - it('using <c-a> without increase in order of magnitude', function() - -- do_addsub in ops.c - feed('ddiabc998xxx<esc>Tc') - 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('<c-a>') - 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 <c-a> when increase in order of magnitude', function() - -- do_addsub in ops.c - feed('ddiabc999xxx<esc>Tc') - 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('<c-a>') - 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 <c-a> when negative and without decrease in order of magnitude', function() - feed('ddiabc-999xxx<esc>T-') - 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('<c-a>') - 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 <c-a> when negative and decrease in order of magnitude', function() - feed('ddiabc-1000xxx<esc>T-') - 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('<c-a>') - 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 <c-x> without decrease in order of magnitude', function() - -- do_addsub in ops.c - feed('ddiabc999xxx<esc>Tc') - 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('<c-x>') - 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 <c-x> when decrease in order of magnitude', function() - -- do_addsub in ops.c - feed('ddiabc1000xxx<esc>Tc') - 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('<c-x>') - 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 <c-x> when negative and without increase in order of magnitude', function() - feed('ddiabc-998xxx<esc>T-') - 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('<c-x>') - 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 <c-x> when negative and increase in order of magnitude', function() - feed('ddiabc-999xxx<esc>T-') - 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('<c-x>') - 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('A<cr>67890<cr>xx<esc>') - feed('A<cr>12345<cr>67890<cr>xx<esc>') - set_extmark(ns, marks[1], 3, 4) - feed([[:1,5s:5\n:5 <cr>]]) - 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) |