123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 |
- local t = require('test.testutil')
- local n = require('test.functional.testnvim')()
- local Screen = require('test.functional.ui.screen')
- local api = n.api
- local clear = n.clear
- local command = n.command
- local fn = n.fn
- local eq = t.eq
- local feed = n.feed
- local write_file = t.write_file
- local pcall_err = t.pcall_err
- local cursor = function()
- return n.api.nvim_win_get_cursor(0)
- end
- describe('named marks', function()
- local file1 = 'Xtestfile-functional-editor-marks'
- local file2 = 'Xtestfile-functional-editor-marks-2'
- before_each(function()
- clear()
- write_file(file1, '1test1\n1test2\n1test3\n1test4', false, false)
- write_file(file2, '2test1\n2test2\n2test3\n2test4', false, false)
- end)
- after_each(function()
- os.remove(file1)
- os.remove(file2)
- end)
- it('can be set', function()
- command('edit ' .. file1)
- command('mark a')
- eq({ 1, 0 }, api.nvim_buf_get_mark(0, 'a'))
- feed('jmb')
- eq({ 2, 0 }, api.nvim_buf_get_mark(0, 'b'))
- feed('jmB')
- eq({ 3, 0 }, api.nvim_buf_get_mark(0, 'B'))
- command('4kc')
- eq({ 4, 0 }, api.nvim_buf_get_mark(0, 'c'))
- end)
- it('errors when set out of range with :mark', function()
- command('edit ' .. file1)
- local err = pcall_err(n.exec_capture, '1000mark x')
- eq('nvim_exec2(): Vim(mark):E16: Invalid range: 1000mark x', err)
- end)
- it('errors when set out of range with :k', function()
- command('edit ' .. file1)
- local err = pcall_err(n.exec_capture, '1000kx')
- eq('nvim_exec2(): Vim(k):E16: Invalid range: 1000kx', err)
- end)
- it('errors on unknown mark name with :mark', function()
- command('edit ' .. file1)
- local err = pcall_err(n.exec_capture, 'mark #')
- eq('nvim_exec2(): Vim(mark):E191: Argument must be a letter or forward/backward quote', err)
- end)
- it("errors on unknown mark name with '", function()
- command('edit ' .. file1)
- local err = pcall_err(n.exec_capture, "normal! '#")
- eq('nvim_exec2(): Vim(normal):E78: Unknown mark', err)
- end)
- it('errors on unknown mark name with `', function()
- command('edit ' .. file1)
- local err = pcall_err(n.exec_capture, 'normal! `#')
- eq('nvim_exec2(): Vim(normal):E78: Unknown mark', err)
- end)
- it("errors when moving to a mark that is not set with '", function()
- command('edit ' .. file1)
- local err = pcall_err(n.exec_capture, "normal! 'z")
- eq('nvim_exec2(): Vim(normal):E20: Mark not set', err)
- err = pcall_err(n.exec_capture, "normal! '.")
- eq('nvim_exec2(): Vim(normal):E20: Mark not set', err)
- end)
- it('errors when moving to a mark that is not set with `', function()
- command('edit ' .. file1)
- local err = pcall_err(n.exec_capture, 'normal! `z')
- eq('nvim_exec2(): Vim(normal):E20: Mark not set', err)
- err = pcall_err(n.exec_capture, 'normal! `>')
- eq('nvim_exec2(): Vim(normal):E20: Mark not set', err)
- end)
- it("errors when moving to a global mark that is not set with '", function()
- command('edit ' .. file1)
- local err = pcall_err(n.exec_capture, "normal! 'Z")
- eq('nvim_exec2(): Vim(normal):E20: Mark not set', err)
- end)
- it('errors when moving to a global mark that is not set with `', function()
- command('edit ' .. file1)
- local err = pcall_err(n.exec_capture, 'normal! `Z')
- eq('nvim_exec2(): Vim(normal):E20: Mark not set', err)
- end)
- it("can move to them using '", function()
- command('args ' .. file1 .. ' ' .. file2)
- feed('j')
- feed('ma')
- feed("G'a")
- eq({ 2, 0 }, cursor())
- feed('mA')
- command('next')
- feed("'A")
- eq(1, api.nvim_get_current_buf())
- eq({ 2, 0 }, cursor())
- end)
- it('can move to them using `', function()
- command('args ' .. file1 .. ' ' .. file2)
- feed('jll')
- feed('ma')
- feed('G`a')
- eq({ 2, 2 }, cursor())
- feed('mA')
- command('next')
- feed('`A')
- eq(1, api.nvim_get_current_buf())
- eq({ 2, 2 }, cursor())
- end)
- it("can move to them using g'", function()
- command('args ' .. file1 .. ' ' .. file2)
- feed('jll')
- feed('ma')
- feed("Gg'a")
- eq({ 2, 0 }, cursor())
- feed('mA')
- command('next')
- feed("g'A")
- eq(1, api.nvim_get_current_buf())
- eq({ 2, 0 }, cursor())
- end)
- it('can move to them using g`', function()
- command('args ' .. file1 .. ' ' .. file2)
- feed('jll')
- feed('ma')
- feed('Gg`a')
- eq({ 2, 2 }, cursor())
- feed('mA')
- command('next')
- feed('g`A')
- eq(1, api.nvim_get_current_buf())
- eq({ 2, 2 }, cursor())
- end)
- it("can move to them using :'", function()
- command('args ' .. file1 .. ' ' .. file2)
- feed('j')
- feed('ma')
- feed('G')
- command("'a")
- eq({ 2, 0 }, cursor())
- feed('mA')
- command('next')
- command("'A")
- eq(1, api.nvim_get_current_buf())
- eq({ 2, 0 }, cursor())
- end)
- it("errors when it can't find the buffer", function()
- command('args ' .. file1 .. ' ' .. file2)
- feed('mA')
- command('next')
- command('bw! ' .. file1)
- local err = pcall_err(n.exec_capture, "normal! 'A")
- eq('nvim_exec2(): Vim(normal):E92: Buffer 1 not found', err)
- os.remove(file1)
- end)
- it('errors when using a mark in another buffer in command range', function()
- feed('ifoo<Esc>mA')
- command('enew')
- feed('ibar<Esc>')
- eq("Vim(print):E20: Mark not set: 'Aprint", pcall_err(command, [['Aprint]]))
- end)
- it("leave a context mark when moving with '", function()
- command('edit ' .. file1)
- feed('llmamA')
- feed('10j0') -- first col, last line
- local pos = cursor()
- feed("'a")
- feed('<C-o>')
- eq(pos, cursor())
- feed("'A")
- feed('<C-o>')
- eq(pos, cursor())
- end)
- it('leave a context mark when moving with `', function()
- command('edit ' .. file1)
- feed('llmamA')
- feed('10j0') -- first col, last line
- local pos = cursor()
- feed('`a')
- feed('<C-o>')
- eq(pos, cursor())
- feed('`A')
- feed('<C-o>')
- eq(pos, cursor())
- end)
- it("leave a context mark when the mark changes buffer with g'", function()
- command('args ' .. file1 .. ' ' .. file2)
- local pos
- feed('GmA')
- command('next')
- pos = cursor()
- command('clearjumps')
- feed("g'A") -- since the mark is in another buffer, it leaves a context mark
- feed('<C-o>')
- eq(pos, cursor())
- end)
- it('leave a context mark when the mark changes buffer with g`', function()
- command('args ' .. file1 .. ' ' .. file2)
- local pos
- feed('GmA')
- command('next')
- pos = cursor()
- command('clearjumps')
- feed('g`A') -- since the mark is in another buffer, it leaves a context mark
- feed('<C-o>')
- eq(pos, cursor())
- end)
- it("do not leave a context mark when moving with g'", function()
- command('edit ' .. file1)
- local pos
- feed('ma')
- pos = cursor() -- Mark pos
- feed('10j0') -- first col, last line
- feed("g'a")
- feed('<C-o>') -- should do nothing
- eq(pos, cursor())
- feed('mA')
- pos = cursor() -- Mark pos
- feed('10j0') -- first col, last line
- feed("g'a")
- feed('<C-o>') -- should do nothing
- eq(pos, cursor())
- end)
- it('do not leave a context mark when moving with g`', function()
- command('edit ' .. file1)
- local pos
- feed('ma')
- pos = cursor() -- Mark pos
- feed('10j0') -- first col, last line
- feed('g`a')
- feed('<C-o>') -- should do nothing
- eq(pos, cursor())
- feed('mA')
- pos = cursor() -- Mark pos
- feed('10j0') -- first col, last line
- feed("g'a")
- feed('<C-o>') -- should do nothing
- eq(pos, cursor())
- end)
- it('open folds when moving to them', function()
- command('edit ' .. file1)
- feed('jzfG') -- Fold from the second line to the end
- command('3mark a')
- feed('G') -- On top of the fold
- assert(fn.foldclosed('.') ~= -1) -- folded
- feed("'a")
- eq(-1, fn.foldclosed('.'))
- feed('zc')
- assert(fn.foldclosed('.') ~= -1) -- folded
- -- TODO: remove this workaround after fixing #15873
- feed('k`a')
- eq(-1, fn.foldclosed('.'))
- feed('zc')
- assert(fn.foldclosed('.') ~= -1) -- folded
- feed("kg'a")
- eq(-1, fn.foldclosed('.'))
- feed('zc')
- assert(fn.foldclosed('.') ~= -1) -- folded
- feed('kg`a')
- eq(-1, fn.foldclosed('.'))
- end)
- it("do not open folds when moving to them doesn't move the cursor", function()
- command('edit ' .. file1)
- feed('jzfG') -- Fold from the second line to the end
- assert(fn.foldclosed('.') == 2) -- folded
- feed('ma')
- feed("'a")
- feed('`a')
- feed("g'a")
- feed('g`a')
- -- should still be folded
- eq(2, fn.foldclosed('.'))
- end)
- it("getting '{ '} '( ') does not move cursor", function()
- api.nvim_buf_set_lines(0, 0, 0, true, { 'aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee' })
- api.nvim_win_set_cursor(0, { 2, 0 })
- fn.getpos("'{")
- eq({ 2, 0 }, api.nvim_win_get_cursor(0))
- fn.getpos("'}")
- eq({ 2, 0 }, api.nvim_win_get_cursor(0))
- fn.getpos("'(")
- eq({ 2, 0 }, api.nvim_win_get_cursor(0))
- fn.getpos("')")
- eq({ 2, 0 }, api.nvim_win_get_cursor(0))
- end)
- it('in command range does not move cursor #19248', function()
- api.nvim_create_user_command('Test', ':', { range = true })
- api.nvim_buf_set_lines(0, 0, 0, true, { 'aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee' })
- api.nvim_win_set_cursor(0, { 2, 0 })
- command([['{,'}Test]])
- eq({ 2, 0 }, api.nvim_win_get_cursor(0))
- end)
- end)
- describe('named marks view', function()
- local file1 = 'Xtestfile-functional-editor-marks'
- local file2 = 'Xtestfile-functional-editor-marks-2'
- local function content()
- local c = {}
- for i = 1, 30 do
- c[i] = i .. ' line'
- end
- return table.concat(c, '\n')
- end
- before_each(function()
- clear()
- write_file(file1, content(), false, false)
- write_file(file2, content(), false, false)
- command('set jumpoptions+=view')
- end)
- after_each(function()
- os.remove(file1)
- os.remove(file2)
- end)
- it('is restored in normal mode but not op-pending mode', function()
- local screen = Screen.new(5, 8)
- command('edit ' .. file1)
- feed('<C-e>jWma')
- feed("G'a")
- local expected = [[
- 2 line |
- ^3 line |
- 4 line |
- 5 line |
- 6 line |
- 7 line |
- 8 line |
- |
- ]]
- screen:expect({ grid = expected })
- feed('G`a')
- screen:expect([[
- 2 line |
- 3 ^line |
- 4 line |
- 5 line |
- 6 line |
- 7 line |
- 8 line |
- |
- ]])
- -- not in op-pending mode #20886
- feed('ggj=`a')
- screen:expect([[
- 1 line |
- ^2 line |
- 3 line |
- 4 line |
- 5 line |
- 6 line |
- 7 line |
- |
- ]])
- end)
- it('is restored across files', function()
- local screen = Screen.new(5, 5)
- command('args ' .. file1 .. ' ' .. file2)
- feed('<C-e>mA')
- local mark_view = [[
- ^2 line |
- 3 line |
- 4 line |
- 5 line |
- |
- ]]
- screen:expect(mark_view)
- command('next')
- screen:expect([[
- ^1 line |
- 2 line |
- 3 line |
- 4 line |
- |
- ]])
- feed("'A")
- screen:expect(mark_view)
- end)
- it("fallback to standard behavior when view can't be recovered", function()
- local screen = Screen.new(10, 10)
- command('edit ' .. file1)
- feed('7GzbmaG') -- Seven lines from the top
- command('new') -- Screen size for window is now half the height can't be restored
- feed("<C-w>p'a")
- screen:expect([[
- |
- {1:~ }|*3
- {2:[No Name] }|
- 6 line |
- ^7 line |
- 8 line |
- {3:<itor-marks }|
- |
- ]])
- end)
- it('fallback to standard behavior when mark is loaded from shada', function()
- local screen = Screen.new(10, 6)
- command('edit ' .. file1)
- feed('G')
- feed('mA')
- screen:expect([[
- 26 line |
- 27 line |
- 28 line |
- 29 line |
- ^30 line |
- |
- ]])
- command('set shadafile=Xtestfile-functional-editor-marks-shada')
- finally(function()
- command('set shadafile=NONE')
- os.remove('Xtestfile-functional-editor-marks-shada')
- end)
- command('wshada!')
- command('bwipe!')
- screen:expect([[
- ^ |
- {1:~ }|*4
- |
- ]])
- command('rshada!')
- command('edit ' .. file1)
- feed('`"')
- screen:expect([[
- 26 line |
- 27 line |
- 28 line |
- 29 line |
- ^30 line |
- |
- ]])
- feed('`A')
- screen:expect_unchanged()
- end)
- end)
|