aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rw-r--r--test/functional/editor/jump_spec.lua115
-rw-r--r--test/functional/editor/mark_spec.lua380
2 files changed, 495 insertions, 0 deletions
diff --git a/test/functional/editor/jump_spec.lua b/test/functional/editor/jump_spec.lua
index d09c20f226..d3d3d7f79d 100644
--- a/test/functional/editor/jump_spec.lua
+++ b/test/functional/editor/jump_spec.lua
@@ -1,4 +1,5 @@
local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local command = helpers.command
@@ -7,6 +8,7 @@ local funcs = helpers.funcs
local feed = helpers.feed
local exec_capture = helpers.exec_capture
local write_file = helpers.write_file
+local curbufmeths = helpers.curbufmeths
describe('jumplist', function()
local fname1 = 'Xtest-functional-normal-jump'
@@ -137,3 +139,116 @@ describe("jumpoptions=stack behaves like 'tagstack'", function()
exec_capture('jumps'))
end)
end)
+
+describe("jumpoptions=view", function()
+ local file1 = 'Xtestfile-functional-editor-jumps'
+ local file2 = 'Xtestfile-functional-editor-jumps-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('restores the view', function()
+ local screen = Screen.new(5, 8)
+ screen:attach()
+ command("edit " .. file1)
+ feed("12Gztj")
+ feed("gg<C-o>")
+ screen:expect([[
+ 12 line |
+ ^13 line |
+ 14 line |
+ 15 line |
+ 16 line |
+ 17 line |
+ 18 line |
+ |
+ ]])
+ end)
+
+ it('restores the view across files', function()
+ local screen = Screen.new(5, 5)
+ screen:attach()
+ command("args " .. file1 .. " " .. file2)
+ feed("12Gzt")
+ command("next")
+ feed("G")
+ screen:expect([[
+ 27 line |
+ 28 line |
+ 29 line |
+ ^30 line |
+ |
+ ]])
+ feed("<C-o><C-o>")
+ screen:expect([[
+ ^12 line |
+ 13 line |
+ 14 line |
+ 15 line |
+ |
+ ]])
+ end)
+
+ it('restores the view across files with <C-^>', function()
+ local screen = Screen.new(5, 5)
+ screen:attach()
+ command("args " .. file1 .. " " .. file2)
+ feed("12Gzt")
+ command("next")
+ feed("G")
+ screen:expect([[
+ 27 line |
+ 28 line |
+ 29 line |
+ ^30 line |
+ |
+ ]])
+ feed("<C-^>")
+ screen:expect([[
+ ^12 line |
+ 13 line |
+ 14 line |
+ 15 line |
+ |
+ ]])
+ end)
+
+ it('falls back to standard behavior when view can\'t be recovered', function()
+ local screen = Screen.new(5, 8)
+ screen:attach()
+ command("edit " .. file1)
+ feed("7GzbG")
+ curbufmeths.set_lines(0, 2, true, {})
+ -- Move to line 7, and set it as the last line visible on the view with zb, meaning to recover
+ -- the view it needs to put the cursor 7 lines from the top line. Then go to the end of the
+ -- file, delete 2 lines before line 7, meaning the jump/mark is moved 2 lines up to line 5.
+ -- Therefore when trying to jump back to it it's not possible to set a 7 line offset from the
+ -- mark position to the top line, since there's only 5 lines from the mark position to line 0.
+ -- Therefore falls back to standard behavior which is centering the view/line.
+ feed("<C-o>")
+ screen:expect([[
+ 4 line |
+ 5 line |
+ 6 line |
+ ^7 line |
+ 8 line |
+ 9 line |
+ 10 line |
+ |
+ ]])
+ end)
+end)
diff --git a/test/functional/editor/mark_spec.lua b/test/functional/editor/mark_spec.lua
new file mode 100644
index 0000000000..8b469286ec
--- /dev/null
+++ b/test/functional/editor/mark_spec.lua
@@ -0,0 +1,380 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local meths = helpers.meths
+local curbufmeths = helpers.curbufmeths
+local clear = helpers.clear
+local command = helpers.command
+local funcs = helpers.funcs
+local eq = helpers.eq
+local feed = helpers.feed
+local write_file = helpers.write_file
+local pcall_err = helpers.pcall_err
+local cursor = function() return helpers.meths.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}, curbufmeths.get_mark("a"))
+ feed("jmb")
+ eq({2, 0}, curbufmeths.get_mark("b"))
+ feed("jmB")
+ eq({3, 0}, curbufmeths.get_mark("B"))
+ command("4kc")
+ eq({4, 0}, curbufmeths.get_mark("c"))
+ end)
+
+ it("errors when set out of range with :mark", function()
+ command("edit " .. file1)
+ local err = pcall_err(helpers.exec_capture, "1000mark x")
+ eq("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(helpers.exec_capture, "1000kx")
+ eq("Vim(k):E16: Invalid range: 1000kx", err)
+ end)
+
+ it("errors on unknown mark name with :mark", function()
+ command("edit " .. file1)
+ local err = pcall_err(helpers.exec_capture, "mark #")
+ eq("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(helpers.exec_capture, "normal! '#")
+ eq("Vim(normal):E78: Unknown mark", err)
+ end)
+
+ it("errors on unknown mark name with `", function()
+ command("edit " .. file1)
+ local err = pcall_err(helpers.exec_capture, "normal! `#")
+ eq("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(helpers.exec_capture, "normal! 'z")
+ eq("Vim(normal):E20: Mark not set", err)
+ err = pcall_err(helpers.exec_capture, "normal! '.")
+ eq("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(helpers.exec_capture, "normal! `z")
+ eq("Vim(normal):E20: Mark not set", err)
+ err = pcall_err(helpers.exec_capture, "normal! `>")
+ eq("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(helpers.exec_capture, "normal! 'Z")
+ eq("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(helpers.exec_capture, "normal! `Z")
+ eq("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, meths.get_current_buf().id)
+ 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, meths.get_current_buf().id)
+ 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, meths.get_current_buf().id)
+ 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, meths.get_current_buf().id)
+ eq({2, 2}, 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(helpers.exec_capture, "normal! 'A")
+ eq("Vim(normal):E92: Buffer 1 not found", err)
+ os.remove(file1)
+ 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(funcs.foldclosed('.') ~= -1) -- folded
+ feed("'a")
+ eq(-1, funcs.foldclosed('.'))
+
+ feed("zc")
+ assert(funcs.foldclosed('.') ~= -1) -- folded
+ -- TODO: remove this workaround after fixing #15873
+ feed("k`a")
+ eq(-1, funcs.foldclosed('.'))
+
+ feed("zc")
+ assert(funcs.foldclosed('.') ~= -1) -- folded
+ feed("kg'a")
+ eq(-1, funcs.foldclosed('.'))
+
+ feed("zc")
+ assert(funcs.foldclosed('.') ~= -1) -- folded
+ feed("kg`a")
+ eq(-1, funcs.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(funcs.foldclosed('.') == 2) -- folded
+ feed("ma")
+ feed("'a")
+ feed("`a")
+ feed("g'a")
+ feed("g`a")
+ -- should still be folded
+ eq(2, funcs.foldclosed('.'))
+ 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', function()
+ local screen = Screen.new(5, 8)
+ screen:attach()
+ 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 |
+ |
+ ]])
+ end)
+
+ it('is restored across files', function()
+ local screen = Screen.new(5, 5)
+ screen:attach()
+ 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)
+ screen:attach()
+ 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([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ [No Name] |
+ 6 line |
+ ^7 line |
+ 8 line |
+ {MATCH:.*} |
+ |
+ ]])
+ end)
+end)