aboutsummaryrefslogtreecommitdiff
path: root/test/functional/normal
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2021-09-17 09:16:40 -0700
committerGitHub <noreply@github.com>2021-09-17 09:16:40 -0700
commitd8de4eb685e35646c7d541e9a75bdc296127b7e2 (patch)
tree4bb05ec713856715ac9ba57e5d116eed344511b9 /test/functional/normal
parentd56002f7b722facd97b0958e141c8ed2d01495f7 (diff)
downloadrneovim-d8de4eb685e35646c7d541e9a75bdc296127b7e2.tar.gz
rneovim-d8de4eb685e35646c7d541e9a75bdc296127b7e2.tar.bz2
rneovim-d8de4eb685e35646c7d541e9a75bdc296127b7e2.zip
test: reorg #15698
Problem: Subdirectories like "visual", "insert", "normal" encourage people to separate *related* tests for no good reason. Typically the _mode_ is not the relevant topic of a test (and when it is, _then_ create an appropriate describe() or it()). Solution: - Delete the various `test/functional/<mode>/` subdirectories, move their tests to more meaningful topics. - Rename `…/normal/` to `…/editor/`. - Move or merge `…/visual/*` and `…/insert/*` tests into here where appropriate. - Rename `…/eval/` to `…/vimscript/`. - Move `…/viml/*` into here also. * test(reorg): insert/* => editor/mode_insert_spec.lua * test(reorg): cmdline/* => editor/mode_cmdline_spec.lua * test(reorg): eval core tests => eval_spec.lua
Diffstat (limited to 'test/functional/normal')
-rw-r--r--test/functional/normal/K_spec.lua38
-rw-r--r--test/functional/normal/count_spec.lua39
-rw-r--r--test/functional/normal/fold_spec.lua362
-rw-r--r--test/functional/normal/jump_spec.lua139
-rw-r--r--test/functional/normal/lang_spec.lua63
-rw-r--r--test/functional/normal/langmap_spec.lua280
-rw-r--r--test/functional/normal/macro_spec.lua30
-rw-r--r--test/functional/normal/meta_key_spec.lua22
-rw-r--r--test/functional/normal/put_spec.lua939
-rw-r--r--test/functional/normal/search_spec.lua17
-rw-r--r--test/functional/normal/tabpage_spec.lua38
-rw-r--r--test/functional/normal/undo_spec.lua61
12 files changed, 0 insertions, 2028 deletions
diff --git a/test/functional/normal/K_spec.lua b/test/functional/normal/K_spec.lua
deleted file mode 100644
index 40f36491e4..0000000000
--- a/test/functional/normal/K_spec.lua
+++ /dev/null
@@ -1,38 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local eq, clear, eval, feed, retry =
- helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.retry
-
-describe('K', function()
- local test_file = 'K_spec_out'
- before_each(function()
- clear()
- os.remove(test_file)
- end)
- after_each(function()
- os.remove(test_file)
- end)
-
- it("invokes colon-prefixed 'keywordprg' as Vim command", function()
- helpers.source([[
- let @a='fnord'
- set keywordprg=:put]])
-
- -- K on the text "a" resolves to `:put a`.
- feed('ia<ESC>K')
- helpers.expect([[
- a
- fnord]])
- end)
-
- it("invokes non-prefixed 'keywordprg' as shell command", function()
- helpers.source([[
- let @a='fnord'
- set keywordprg=echo\ fnord>>]])
-
- -- K on the text "K_spec_out" resolves to `!echo fnord >> K_spec_out`.
- feed('i'..test_file..'<ESC>K')
- retry(nil, nil, function() eq(1, eval('filereadable("'..test_file..'")')) end)
- eq({'fnord'}, eval("readfile('"..test_file.."')"))
- end)
-
-end)
diff --git a/test/functional/normal/count_spec.lua b/test/functional/normal/count_spec.lua
deleted file mode 100644
index 94f741250a..0000000000
--- a/test/functional/normal/count_spec.lua
+++ /dev/null
@@ -1,39 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local eq = helpers.eq
-local eval = helpers.eval
-local feed = helpers.feed
-local clear = helpers.clear
-local command = helpers.command
-
-describe('v:count/v:count1', function()
- before_each(function()
- clear()
-
- command('map <silent> _x :<C-u>let g:count = "v:count=". v:count .", v:count1=". v:count1<CR>')
- end)
-
- describe('in cmdwin', function()
- it('equal 0/1 when no count is given', function()
- feed('q:_x')
- eq('v:count=0, v:count1=1', eval('g:count'))
- end)
-
- it('equal 2/2 when count of 2 is given', function()
- feed('q:2_x')
- eq('v:count=2, v:count1=2', eval('g:count'))
- end)
- end)
-
- describe('in normal mode', function()
- it('equal 0/1 when no count is given', function()
- feed('_x')
- eq('v:count=0, v:count1=1', eval('g:count'))
- end)
-
- it('equal 2/2 when count of 2 is given', function()
- feed('2_x')
- eq('v:count=2, v:count1=2', eval('g:count'))
- end)
- end)
-end)
diff --git a/test/functional/normal/fold_spec.lua b/test/functional/normal/fold_spec.lua
deleted file mode 100644
index 00e83bedc8..0000000000
--- a/test/functional/normal/fold_spec.lua
+++ /dev/null
@@ -1,362 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local clear = helpers.clear
-local insert = helpers.insert
-local feed = helpers.feed
-local expect = helpers.expect
-local feed_command = helpers.feed_command
-local funcs = helpers.funcs
-local foldlevel = funcs.foldlevel
-local foldclosedend = funcs.foldclosedend
-local eq = helpers.eq
-
-describe('Folds', function()
- local tempfname = 'Xtest-fold.txt'
- clear()
- before_each(function() feed_command('enew!') end)
- after_each(function() os.remove(tempfname) end)
- it('manual folding adjusts with filter', function()
- insert([[
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20]])
- feed_command('4,$fold', '%foldopen', '10,$fold', '%foldopen')
- feed_command('1,8! cat')
- feed('5ggzdzMGdd')
- expect([[
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9]])
- end)
- describe('adjusting folds after :move', function()
- local function manually_fold_indent()
- -- setting foldmethod twice is a trick to get vim to set the folds for me
- feed_command('set foldmethod=indent', 'set foldmethod=manual')
- -- Ensure that all folds will get closed (makes it easier to test the
- -- length of folds).
- feed_command('set foldminlines=0')
- -- Start with all folds open (so :move ranges aren't affected by closed
- -- folds).
- feed_command('%foldopen!')
- end
-
- local function get_folds()
- local rettab = {}
- for i = 1, funcs.line('$') do
- table.insert(rettab, foldlevel(i))
- end
- return rettab
- end
-
- local function test_move_indent(insert_string, move_command)
- -- This test is easy because we just need to ensure that the resulting
- -- fold is the same as calculated when creating folds from scratch.
- insert(insert_string)
- feed_command(move_command)
- local after_move_folds = get_folds()
- -- Doesn't change anything, but does call foldUpdateAll()
- feed_command('set foldminlines=0')
- eq(after_move_folds, get_folds())
- -- Set up the buffer with insert_string for the manual fold testing.
- feed_command('enew!')
- insert(insert_string)
- manually_fold_indent()
- feed_command(move_command)
- end
-
- it('neither closes nor corrupts folds', function()
- test_move_indent([[
-a
- a
- a
- a
- a
- a
-a
- a
- a
- a
- a
- a
-a
- a
- a
- a
- a
- a]], '7,12m0')
- expect([[
-a
- a
- a
- a
- a
- a
-a
- a
- a
- a
- a
- a
-a
- a
- a
- a
- a
- a]])
- -- lines are not closed, folds are correct
- for i = 1,funcs.line('$') do
- eq(-1, funcs.foldclosed(i))
- if i == 1 or i == 7 or i == 13 then
- eq(0, foldlevel(i))
- elseif i == 4 then
- eq(2, foldlevel(i))
- else
- eq(1, foldlevel(i))
- end
- end
- -- folds are not corrupted
- feed('zM')
- eq(6, foldclosedend(2))
- eq(12, foldclosedend(8))
- eq(18, foldclosedend(14))
- end)
- it("doesn't split a fold when the move is within it", function()
- test_move_indent([[
-a
- a
- a
- a
- a
- a
- a
- a
- a
-a]], '5m6')
- eq({0, 1, 1, 2, 2, 2, 2, 1, 1, 0}, get_folds())
- end)
- it('truncates folds that end in the moved range', function()
- test_move_indent([[
-a
- a
- a
- a
- a
-a
-a]], '4,5m6')
- eq({0, 1, 2, 0, 0, 0, 0}, get_folds())
- end)
- it('moves folds that start between moved range and destination', function()
- test_move_indent([[
-a
- a
- a
- a
- a
-a
-a
- a
- a
- a
-a
-a
- a]], '3,4m$')
- eq({0, 1, 1, 0, 0, 1, 2, 1, 0, 0, 1, 0, 0}, get_folds())
- end)
- it('does not affect folds outside changed lines', function()
- test_move_indent([[
- a
- a
- a
-a
-a
-a
- a
- a
- a]], '4m5')
- eq({1, 1, 1, 0, 0, 0, 1, 1, 1}, get_folds())
- end)
- it('moves and truncates folds that start in moved range', function()
- test_move_indent([[
-a
- a
- a
- a
- a
-a
-a
-a
-a
-a]], '1,3m7')
- eq({0, 0, 0, 0, 0, 1, 2, 0, 0, 0}, get_folds())
- end)
- it('breaks a fold when moving text into it', function()
- test_move_indent([[
-a
- a
- a
- a
- a
-a
-a]], '$m4')
- eq({0, 1, 2, 2, 0, 0, 0}, get_folds())
- end)
- it('adjusts correctly when moving a range backwards', function()
- test_move_indent([[
-a
- a
- a
- a
-a]], '2,3m0')
- eq({1, 2, 0, 0, 0}, get_folds())
- end)
- it('handles shifting all remaining folds', function()
- test_move_indent([[
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
-a]], '13m7')
- eq({1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0}, get_folds())
- end)
- end)
- it('updates correctly on :read', function()
- -- luacheck: ignore 621
- helpers.write_file(tempfname, [[
- a
-
-
- a]])
- insert([[
- a
- a
- a
- a
- ]])
- feed_command('set foldmethod=indent', '2', '%foldopen')
- feed_command('read ' .. tempfname)
- -- Just to check we have the correct file text.
- expect([[
- a
- a
- a
-
-
- a
- a
- a
- ]])
- for i = 1,2 do
- eq(1, funcs.foldlevel(i))
- end
- for i = 3,5 do
- eq(0, funcs.foldlevel(i))
- end
- for i = 6,8 do
- eq(1, funcs.foldlevel(i))
- end
- end)
- it('combines folds when removing separating space', function()
- -- luacheck: ignore 621
- insert([[
- a
- a
- a
- a
- a
- a
- a
- a
- ]])
- feed_command('set foldmethod=indent', '3,5d')
- eq(5, funcs.foldclosedend(1))
- end)
- it("doesn't combine folds that have a specified end", function()
- insert([[
- {{{
- }}}
-
-
-
- {{{
-
- }}}
- ]])
- feed_command('set foldmethod=marker', '3,5d', '%foldclose')
- eq(2, funcs.foldclosedend(1))
- end)
- it('splits folds according to >N and <N with foldexpr', function()
- helpers.source([[
- function TestFoldExpr(lnum)
- let thisline = getline(a:lnum)
- if thisline == 'a'
- return 1
- elseif thisline == 'b'
- return 0
- elseif thisline == 'c'
- return '<1'
- elseif thisline == 'd'
- return '>1'
- endif
- return 0
- endfunction
- ]])
- helpers.write_file(tempfname, [[
- b
- b
- a
- a
- d
- a
- a
- c]])
- insert([[
- a
- a
- a
- a
- a
- a
- ]])
- feed_command('set foldmethod=expr', 'set foldexpr=TestFoldExpr(v:lnum)', '2', 'foldopen')
- feed_command('read ' .. tempfname, '%foldclose')
- eq(2, funcs.foldclosedend(1))
- eq(0, funcs.foldlevel(3))
- eq(0, funcs.foldlevel(4))
- eq(6, funcs.foldclosedend(5))
- eq(10, funcs.foldclosedend(7))
- eq(14, funcs.foldclosedend(11))
- end)
-end)
diff --git a/test/functional/normal/jump_spec.lua b/test/functional/normal/jump_spec.lua
deleted file mode 100644
index 9e7158e2f7..0000000000
--- a/test/functional/normal/jump_spec.lua
+++ /dev/null
@@ -1,139 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local clear = helpers.clear
-local command = helpers.command
-local eq = helpers.eq
-local funcs = helpers.funcs
-local feed = helpers.feed
-local redir_exec = helpers.redir_exec
-local write_file = helpers.write_file
-
-describe('jumplist', function()
- local fname1 = 'Xtest-functional-normal-jump'
- local fname2 = fname1..'2'
- before_each(clear)
- after_each(function()
- os.remove(fname1)
- os.remove(fname2)
- end)
-
- it('does not add a new entry on startup', function()
- eq('\n jump line col file/text\n>', funcs.execute('jumps'))
- end)
-
- it('does not require two <C-O> strokes to jump back', function()
- write_file(fname1, 'first file contents')
- write_file(fname2, 'second file contents')
-
- command('args '..fname1..' '..fname2)
- local buf1 = funcs.bufnr(fname1)
- local buf2 = funcs.bufnr(fname2)
-
- command('next')
- feed('<C-O>')
- eq(buf1, funcs.bufnr('%'))
-
- command('first')
- command('snext')
- feed('<C-O>')
- eq(buf1, funcs.bufnr('%'))
- feed('<C-I>')
- eq(buf2, funcs.bufnr('%'))
- feed('<C-O>')
- eq(buf1, funcs.bufnr('%'))
-
- command('drop '..fname2)
- feed('<C-O>')
- eq(buf1, funcs.bufnr('%'))
- end)
-end)
-
-describe("jumpoptions=stack behaves like 'tagstack'", function()
- before_each(function()
- clear()
- feed(':clearjumps<cr>')
-
- -- Add lines so that we have locations to jump to.
- for i = 1,101,1
- do
- feed('iLine ' .. i .. '<cr><esc>')
- end
-
- -- Jump around to add some locations to the jump list.
- feed('0gg')
- feed('10gg')
- feed('20gg')
- feed('30gg')
- feed('40gg')
- feed('50gg')
-
- feed(':set jumpoptions=stack<cr>')
- end)
-
- after_each(function()
- feed('set jumpoptions=')
- end)
-
- it('discards the tail when navigating from the middle', function()
- feed('<C-O>')
- feed('<C-O>')
-
- eq( '\n'
- .. ' jump line col file/text\n'
- .. ' 4 102 0 \n'
- .. ' 3 1 0 Line 1\n'
- .. ' 2 10 0 Line 10\n'
- .. ' 1 20 0 Line 20\n'
- .. '> 0 30 0 Line 30\n'
- .. ' 1 40 0 Line 40\n'
- .. ' 2 50 0 Line 50',
- redir_exec('jumps'))
-
- feed('90gg')
-
- eq( '\n'
- .. ' jump line col file/text\n'
- .. ' 5 102 0 \n'
- .. ' 4 1 0 Line 1\n'
- .. ' 3 10 0 Line 10\n'
- .. ' 2 20 0 Line 20\n'
- .. ' 1 30 0 Line 30\n'
- .. '>',
- redir_exec('jumps'))
- end)
-
- it('does not add the same location twice adjacently', function()
- feed('60gg')
- feed('60gg')
-
- eq( '\n'
- .. ' jump line col file/text\n'
- .. ' 7 102 0 \n'
- .. ' 6 1 0 Line 1\n'
- .. ' 5 10 0 Line 10\n'
- .. ' 4 20 0 Line 20\n'
- .. ' 3 30 0 Line 30\n'
- .. ' 2 40 0 Line 40\n'
- .. ' 1 50 0 Line 50\n'
- .. '>',
- redir_exec('jumps'))
- end)
-
- it('does add the same location twice nonadjacently', function()
- feed('10gg')
- feed('20gg')
-
- eq( '\n'
- .. ' jump line col file/text\n'
- .. ' 8 102 0 \n'
- .. ' 7 1 0 Line 1\n'
- .. ' 6 10 0 Line 10\n'
- .. ' 5 20 0 Line 20\n'
- .. ' 4 30 0 Line 30\n'
- .. ' 3 40 0 Line 40\n'
- .. ' 2 50 0 Line 50\n'
- .. ' 1 10 0 Line 10\n'
- .. '>',
- redir_exec('jumps'))
- end)
-end)
diff --git a/test/functional/normal/lang_spec.lua b/test/functional/normal/lang_spec.lua
deleted file mode 100644
index 24d1262f5f..0000000000
--- a/test/functional/normal/lang_spec.lua
+++ /dev/null
@@ -1,63 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear, insert, eq = helpers.clear, helpers.insert, helpers.eq
-local command, expect = helpers.command, helpers.expect
-local feed, eval = helpers.feed, helpers.eval
-local exc_exec = helpers.exc_exec
-
-describe('gu and gU', function()
- before_each(clear)
-
- it('works in any locale with default casemap', function()
- eq('internal,keepascii', eval('&casemap'))
- insert("iI")
- feed("VgU")
- expect("II")
- feed("Vgu")
- expect("ii")
- end)
-
- describe('works in Turkish locale', function()
- clear()
-
- local err = exc_exec('lang ctype tr_TR.UTF-8')
- if err ~= 0 then
- pending("Locale tr_TR.UTF-8 not supported", function() end)
- return
- end
-
- before_each(function()
- command('lang ctype tr_TR.UTF-8')
- end)
-
- it('with default casemap', function()
- eq('internal,keepascii', eval('&casemap'))
- -- expect ASCII behavior
- insert("iI")
- feed("VgU")
- expect("II")
- feed("Vgu")
- expect("ii")
- end)
-
- it('with casemap=""', function()
- command('set casemap=')
- -- expect either Turkish locale behavior or ASCII behavior
- local iupper = eval("toupper('i')")
- if iupper == "İ" then
- insert("iI")
- feed("VgU")
- expect("İI")
- feed("Vgu")
- expect("iı")
- elseif iupper == "I" then
- insert("iI")
- feed("VgU")
- expect("II")
- feed("Vgu")
- expect("ii")
- else
- error("expected toupper('i') to be either 'I' or 'İ'")
- end
- end)
- end)
-end)
diff --git a/test/functional/normal/langmap_spec.lua b/test/functional/normal/langmap_spec.lua
deleted file mode 100644
index e4349a22e7..0000000000
--- a/test/functional/normal/langmap_spec.lua
+++ /dev/null
@@ -1,280 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local eq, neq, call = helpers.eq, helpers.neq, helpers.call
-local eval, feed, clear = helpers.eval, helpers.feed, helpers.clear
-local command, insert, expect = helpers.command, helpers.insert, helpers.expect
-local feed_command = helpers.feed_command
-local curwin = helpers.curwin
-
-describe("'langmap'", function()
- before_each(function()
- clear()
- insert('iii www')
- command('set langmap=iw,wi')
- feed('gg0')
- end)
-
- it("converts keys in normal mode", function()
- feed('ix')
- expect('iii ww')
- feed('whello<esc>')
- expect('iii helloww')
- end)
- it("gives characters that are mapped by :nmap.", function()
- command('map i 0x')
- feed('w')
- expect('ii www')
- end)
- describe("'langnoremap' option.", function()
- before_each(function()
- command('nmapclear')
- end)
- it("'langnoremap' is by default ON", function()
- eq(eval('&langnoremap'), 1)
- end)
- it("Results of maps are not converted when 'langnoremap' ON.",
- function()
- command('nmap x i')
- feed('xdl<esc>')
- expect('dliii www')
- end)
- it("applies when deciding whether to map recursively", function()
- command('nmap l i')
- command('nmap w j')
- feed('ll')
- expect('liii www')
- end)
- it("does not stop applying 'langmap' on first character of a mapping",
- function()
- command('1t1')
- command('1t1')
- command('goto 1')
- command('nmap w j')
- feed('iiahello')
- expect([[
- iii www
- iii www
- ihelloii www]])
- end)
- it("Results of maps are converted when 'langnoremap' OFF.",
- function()
- command('set nolangnoremap')
- command('nmap x i')
- feed('xdl<esc>')
- expect('iii ww')
- end)
- end)
- -- e.g. CTRL-W_j , mj , 'j and "jp
- it('conversions are applied to keys in middle of command',
- function()
- -- Works in middle of window command
- feed('<C-w>s')
- local origwin = curwin()
- feed('<C-w>i')
- neq(curwin(), origwin)
- -- Works when setting a mark
- feed('yy3p3gg0mwgg0mi')
- eq(call('getpos', "'i"), {0, 3, 1, 0})
- eq(call('getpos', "'w"), {0, 1, 1, 0})
- feed('3dd')
- -- Works when moving to a mark
- feed("'i")
- eq(call('getpos', '.'), {0, 1, 1, 0})
- -- Works when selecting a register
- feed('qillqqwhhq')
- eq(eval('@i'), 'hh')
- eq(eval('@w'), 'll')
- feed('a<C-r>i<esc>')
- expect('illii www')
- feed('"ip')
- expect('illllii www')
- -- Works with i_CTRL-O
- feed('0a<C-O>ihi<esc>')
- expect('illllii hiwww')
- end)
-
- describe('exceptions', function()
- -- All "command characters" that 'langmap' does not apply to.
- -- These tests consist of those places where some subset of ASCII
- -- characters define certain commands, yet 'langmap' is not applied to
- -- them.
- -- n.b. I think these shouldn't be exceptions.
- it(':s///c confirmation', function()
- command('set langmap=yn,ny')
- feed('qa')
- feed_command('s/i/w/gc')
- feed('yynq')
- expect('wwi www')
- feed('u@a')
- expect('wwi www')
- eq(eval('@a'), ':s/i/w/gc\ryyn')
- end)
- it('insert-mode CTRL-G', function()
- command('set langmap=jk,kj')
- command('d')
- insert([[
- hello
- hello
- hello]])
- expect([[
- hello
- hello
- hello]])
- feed('qa')
- feed('gg3|ahello<C-G>jx<esc>')
- feed('q')
- expect([[
- helhellolo
- helxlo
- hello]])
- eq(eval('@a'), 'gg3|ahellojx')
- end)
- it('command-line CTRL-\\', function()
- command('set langmap=en,ne')
- feed(':<C-\\>e\'hello\'\r<C-B>put ="<C-E>"<CR>')
- expect([[
- iii www
- hello]])
- end)
- it('command-line CTRL-R', function()
- helpers.source([[
- let i_value = 0
- let j_value = 0
- call setreg('i', 'i_value')
- call setreg('j', 'j_value')
- set langmap=ij,ji
- ]])
- feed(':let <C-R>i=1<CR>')
- eq(eval('i_value'), 1)
- eq(eval('j_value'), 0)
- end)
- -- it('-- More -- prompt', function()
- -- -- The 'b' 'j' 'd' 'f' commands at the -- More -- prompt
- -- end)
- it('ask yes/no after backwards range', function()
- command('set langmap=yn,ny')
- feed('dd')
- insert([[
- hello
- there
- these
- are
- some
- lines
- ]])
- feed_command('4,2d')
- feed('n')
- expect([[
- hello
- there
- these
- are
- some
- lines
- ]])
- end)
- it('prompt for number', function()
- command('set langmap=12,21')
- helpers.source([[
- let gotten_one = 0
- function Map()
- let answer = inputlist(['a', '1.', '2.', '3.'])
- if answer == 1
- let g:gotten_one = 1
- endif
- endfunction
- nnoremap x :call Map()<CR>
- ]])
- feed('x1<CR>')
- eq(eval('gotten_one'), 1)
- command('let g:gotten_one = 0')
- feed_command('call Map()')
- feed('1<CR>')
- eq(eval('gotten_one'), 1)
- end)
- end)
- it('conversions are not applied during setreg()',
- function()
- call('setreg', 'i', 'ww')
- eq(eval('@i'), 'ww')
- end)
- it('conversions not applied in insert mode', function()
- feed('aiiiwww')
- expect('iiiiwwwii www')
- end)
- it('conversions not applied in search mode', function()
- feed('/iii<cr>x')
- expect('ii www')
- end)
- it('conversions not applied in cmdline mode', function()
- feed(':call append(1, "iii")<cr>')
- expect([[
- iii www
- iii]])
- end)
-
- local function testrecording(command_string, expect_string, setup_function)
- if setup_function then setup_function() end
- feed('qa' .. command_string .. 'q')
- expect(expect_string)
- eq(helpers.funcs.nvim_replace_termcodes(command_string, true, true, true),
- eval('@a'))
- if setup_function then setup_function() end
- -- n.b. may need nvim_replace_termcodes() here.
- feed('@a')
- expect(expect_string)
- end
-
- local function local_setup()
- -- Can't use `insert` as it uses `i` and we've swapped the meaning of that
- -- with the `langmap` setting.
- command('%d')
- command("put ='hello'")
- command('1d')
- end
-
- it('does not affect recording special keys', function()
- testrecording('A<BS><esc>', 'hell', local_setup)
- testrecording('>><lt><lt>', 'hello', local_setup)
- command('nnoremap \\ x')
- testrecording('\\', 'ello', local_setup)
- testrecording('A<C-V><BS><esc>', 'hello<BS>', local_setup)
- end)
- pending('Translates modified keys correctly', function()
- command('nnoremap <M-i> x')
- command('nnoremap <M-w> l')
- testrecording('<M-w>', 'ello', local_setup)
- testrecording('<M-i>x', 'hllo', local_setup)
- end)
- pending('handles multi-byte characters', function()
- command('set langmap=ïx')
- testrecording('ï', 'ello', local_setup)
- -- The test below checks that what's recorded is correct.
- -- It doesn't check the behaviour, as in order to cause some behaviour we
- -- need to map the multi-byte character, and there is a known bug
- -- preventing this from working (see the test below).
- command('set langmap=xï')
- testrecording('x', 'hello', local_setup)
- end)
- pending('handles multibyte mappings', function()
- -- See this vim issue for the problem, may as well add a test.
- -- https://github.com/vim/vim/issues/297
- command('set langmap=ïx')
- command('nnoremap x diw')
- testrecording('ï', '', local_setup)
- command('set nolangnoremap')
- command('set langmap=xï')
- command('nnoremap ï ix<esc>')
- testrecording('x', 'xhello', local_setup)
- end)
- -- This test is to ensure the behaviour doesn't change from what's already
- -- around. I (hardenedapple) personally think this behaviour should be
- -- changed.
- it('treats control modified keys as characters', function()
- command('nnoremap <C-w> iw<esc>')
- command('nnoremap <C-i> ii<esc>')
- testrecording('<C-w>', 'whello', local_setup)
- testrecording('<C-i>', 'ihello', local_setup)
- end)
-
-end)
diff --git a/test/functional/normal/macro_spec.lua b/test/functional/normal/macro_spec.lua
deleted file mode 100644
index 102d8fc723..0000000000
--- a/test/functional/normal/macro_spec.lua
+++ /dev/null
@@ -1,30 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local eq = helpers.eq
-local eval = helpers.eval
-local feed = helpers.feed
-local clear = helpers.clear
-local expect = helpers.expect
-local command = helpers.command
-
-describe('macros', function()
- before_each(clear)
- it('can be recorded and replayed', function()
- feed('qiahello<esc>q')
- expect('hello')
- eq(eval('@i'), 'ahello')
- feed('@i')
- expect('hellohello')
- eq(eval('@i'), 'ahello')
- end)
- it('applies maps', function()
- command('imap x l')
- command('nmap l a')
- feed('qilxxx<esc>q')
- expect('lll')
- eq(eval('@i'), 'lxxx')
- feed('@i')
- expect('llllll')
- eq(eval('@i'), 'lxxx')
- end)
-end)
diff --git a/test/functional/normal/meta_key_spec.lua b/test/functional/normal/meta_key_spec.lua
deleted file mode 100644
index 9f9fad67d2..0000000000
--- a/test/functional/normal/meta_key_spec.lua
+++ /dev/null
@@ -1,22 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
-local command = helpers.command
-local expect = helpers.expect
-
-describe('meta-keys-in-normal-mode', function()
- before_each(function()
- clear()
- end)
-
- it('ALT/META', function()
- -- Unmapped ALT-chords behave as Esc+c
- insert('hello')
- feed('0<A-x><M-x>')
- expect('llo')
- -- Mapped ALT-chord behaves as mapped.
- command('nnoremap <M-l> Ameta-l<Esc>')
- command('nnoremap <A-j> Aalt-j<Esc>')
- feed('<A-j><M-l>')
- expect('lloalt-jmeta-l')
- end)
-end)
diff --git a/test/functional/normal/put_spec.lua b/test/functional/normal/put_spec.lua
deleted file mode 100644
index 26967ecbba..0000000000
--- a/test/functional/normal/put_spec.lua
+++ /dev/null
@@ -1,939 +0,0 @@
-local Screen = require('test.functional.ui.screen')
-local helpers = require('test.functional.helpers')(after_each)
-
-local clear = helpers.clear
-local insert = helpers.insert
-local feed = helpers.feed
-local expect = helpers.expect
-local eq = helpers.eq
-local map = helpers.tbl_map
-local filter = helpers.tbl_filter
-local feed_command = helpers.feed_command
-local curbuf_contents = helpers.curbuf_contents
-local funcs = helpers.funcs
-local dedent = helpers.dedent
-local getreg = funcs.getreg
-
-local function reset()
- feed_command('enew!')
- insert([[
- Line of words 1
- Line of words 2]])
- feed_command('goto 1')
- feed('itest_string.<esc>u')
- funcs.setreg('a', 'test_stringa', 'V')
- funcs.setreg('b', 'test_stringb\ntest_stringb\ntest_stringb', 'b')
- funcs.setreg('"', 'test_string"', 'v')
- feed_command('set virtualedit=')
-end
-
--- We check the last inserted register ". in each of these tests because it is
--- implemented completely differently in do_put().
--- It is implemented differently so that control characters and imap'ped
--- characters work in the same manner when pasted as when inserted.
-describe('put command', function()
- clear()
- before_each(reset)
-
- local function visual_marks_zero()
- for _,v in pairs(funcs.getpos("'<")) do
- if v ~= 0 then
- return false
- end
- end
- for _,v in pairs(funcs.getpos("'>")) do
- if v ~= 0 then
- return false
- end
- end
- return true
- end
-
- -- {{{ Where test definitions are run
- local function run_test_variations(test_variations, extra_setup)
- reset()
- if extra_setup then extra_setup() end
- local init_contents = curbuf_contents()
- local init_cursorpos = funcs.getcurpos()
- local assert_no_change = function (exception_table, after_undo)
- expect(init_contents)
- -- When putting the ". register forwards, undo doesn't move
- -- the cursor back to where it was before.
- -- This is because it uses the command character 'a' to
- -- start the insert, and undo after that leaves the cursor
- -- one place to the right (unless we were at the end of the
- -- line when we pasted).
- if not (exception_table.undo_position and after_undo) then
- eq(funcs.getcurpos(), init_cursorpos)
- end
- end
-
- for _, test in pairs(test_variations) do
- it(test.description, function()
- if extra_setup then extra_setup() end
- local orig_dotstr = funcs.getreg('.')
- helpers.ok(visual_marks_zero())
- -- Make sure every test starts from the same conditions
- assert_no_change(test.exception_table, false)
- local was_cli = test.test_action()
- test.test_assertions(test.exception_table, false)
- -- Check that undo twice puts us back to the original conditions
- -- (i.e. puts the cursor and text back to before)
- feed('u')
- assert_no_change(test.exception_table, true)
-
- -- Should not have changed the ". register
- -- If we paste the ". register with a count we can't avoid
- -- changing this register, hence avoid this check.
- if not test.exception_table.dot_reg_changed then
- eq(funcs.getreg('.'), orig_dotstr)
- end
-
- -- Doing something, undoing it, and then redoing it should
- -- leave us in the same state as just doing it once.
- -- For :ex actions we want '@:', for normal actions we want '.'
-
- -- The '.' redo doesn't work for visual put so just exit if
- -- it was tested.
- -- We check that visual put was used by checking if the '< and
- -- '> marks were changed.
- if not visual_marks_zero() then
- return
- end
-
- if test.exception_table.undo_position then
- funcs.setpos('.', init_cursorpos)
- end
- if was_cli then
- feed('@:')
- else
- feed('.')
- end
-
- test.test_assertions(test.exception_table, true)
- end)
- end
- end -- run_test_variations()
- -- }}}
-
- local function create_test_defs(test_defs, command_base, command_creator, -- {{{
- expect_base, expect_creator)
- local rettab = {}
- local exceptions
- for _, v in pairs(test_defs) do
- if v[4] then
- exceptions = v[4]
- else
- exceptions = {}
- end
- table.insert(rettab,
- {
- test_action = command_creator(command_base, v[1]),
- test_assertions = expect_creator(expect_base, v[2]),
- description = v[3],
- exception_table = exceptions,
- })
- end
- return rettab
- end -- create_test_defs() }}}
-
- local function find_cursor_position(expect_string) -- {{{
- -- There must only be one occurance of the character 'x' in
- -- expect_string.
- -- This function removes that occurance, and returns the position that
- -- it was in.
- -- This returns the cursor position that would leave the 'x' in that
- -- place if we feed 'ix<esc>' and the string existed before it.
- for linenum, line in pairs(funcs.split(expect_string, '\n', 1)) do
- local column = line:find('x')
- if column then
- return {linenum, column}, expect_string:gsub('x', '')
- end
- end
- end -- find_cursor_position() }}}
-
- -- Action function creators {{{
- local function create_p_action(test_map, substitution)
- local temp_val = test_map:gsub('p', substitution)
- return function()
- feed(temp_val)
- return false
- end
- end
-
- local function create_put_action(command_base, substitution)
- local temp_val = command_base:gsub('put', substitution)
- return function()
- feed_command(temp_val)
- return true
- end
- end
- -- }}}
-
- -- Expect function creator {{{
- local function expect_creator(conversion_function, expect_base, conversion_table)
- local temp_expect_string = conversion_function(expect_base, conversion_table)
- local cursor_position, expect_string = find_cursor_position(temp_expect_string)
- return function(exception_table, after_redo)
- expect(expect_string)
-
- -- Have to use getcurpos() instead of curwinmeths.get_cursor() in
- -- order to account for virtualedit.
- -- We always want the curswant element in getcurpos(), which is
- -- sometimes different to the column element in
- -- curwinmeths.get_cursor().
- -- NOTE: The ".gp command leaves the cursor after the pasted text
- -- when running, but does not when the command is redone with the
- -- '.' command.
- if not (exception_table.redo_position and after_redo) then
- local actual_position = funcs.getcurpos()
- eq(cursor_position, {actual_position[2], actual_position[5]})
- end
- end
- end -- expect_creator() }}}
-
- -- Test definitions {{{
- local function copy_def(def)
- local rettab = { '', {}, '', nil }
- rettab[1] = def[1]
- for k,v in pairs(def[2]) do
- rettab[2][k] = v
- end
- rettab[3] = def[3]
- if def[4] then
- rettab[4] = {}
- for k,v in pairs(def[4]) do
- rettab[4][k] = v
- end
- end
- return rettab
- end
-
- local normal_command_defs = {
- {
- 'p',
- {cursor_after = false, put_backwards = false, dot_register = false},
- 'pastes after cursor with p',
- },
- {
- 'gp',
- {cursor_after = true, put_backwards = false, dot_register = false},
- 'leaves cursor after text with gp',
- },
- {
- '".p',
- {cursor_after = false, put_backwards = false, dot_register = true},
- 'works with the ". register',
- },
- {
- '".gp',
- {cursor_after = true, put_backwards = false, dot_register = true},
- 'gp works with the ". register',
- {redo_position = true},
- },
- {
- 'P',
- {cursor_after = false, put_backwards = true, dot_register = false},
- 'pastes before cursor with P',
- },
- {
- 'gP',
- {cursor_after = true, put_backwards = true, dot_register = false},
- 'gP pastes before cursor and leaves cursor after text',
- },
- {
- '".P',
- {cursor_after = false, put_backwards = true, dot_register = true},
- 'P works with ". register',
- },
- {
- '".gP',
- {cursor_after = true, put_backwards = true, dot_register = true},
- 'gP works with ". register',
- {redo_position = true},
- },
- }
-
- -- Add a definition applying a count for each definition above.
- -- Could do this for each transformation (p -> P, p -> gp etc), but I think
- -- it's neater this way (balance between being explicit and too verbose).
- for i = 1,#normal_command_defs do
- local cur = normal_command_defs[i]
-
- -- Make modified copy of current definition that includes a count.
- local newdef = copy_def(cur)
- newdef[2].count = 2
- cur[2].count = 1
- newdef[1] = '2' .. newdef[1]
- newdef[3] = 'double ' .. newdef[3]
-
- if cur[2].dot_register then
- if not cur[4] then
- newdef[4] = {}
- end
- newdef[4].dot_reg_changed = true
- end
-
- normal_command_defs[#normal_command_defs + 1] = newdef
- end
-
- local ex_command_defs = {
- {
- 'put',
- {put_backwards = false, dot_register = false},
- 'pastes linewise forwards with :put',
- },
- {
- 'put!',
- {put_backwards = true, dot_register = false},
- 'pastes linewise backwards with :put!',
- },
- {
- 'put .',
- {put_backwards = false, dot_register = true},
- 'pastes linewise with the dot register',
- },
- {
- 'put! .',
- {put_backwards = true, dot_register = true},
- 'pastes linewise backwards with the dot register',
- },
- }
-
- local function non_dotdefs(def_table)
- return filter(function(d) return not d[2].dot_register end, def_table)
- end
-
- -- }}}
-
- -- Conversion functions {{{
- local function convert_charwise(expect_base, conversion_table,
- virtualedit_end, visual_put)
- expect_base = dedent(expect_base)
- -- There is no difference between 'P' and 'p' when VIsual_active
- if not visual_put then
- if conversion_table.put_backwards then
- -- Special case for virtualedit at the end of a line.
- local replace_string
- if not virtualedit_end then
- replace_string = 'test_stringx"%1'
- else
- replace_string = 'test_stringx"'
- end
- expect_base = expect_base:gsub('(.)test_stringx"', replace_string)
- end
- end
- if conversion_table.count > 1 then
- local rep_string = 'test_string"'
- local extra_puts = rep_string:rep(conversion_table.count - 1)
- expect_base = expect_base:gsub('test_stringx"', extra_puts .. 'test_stringx"')
- end
- if conversion_table.cursor_after then
- expect_base = expect_base:gsub('test_stringx"', 'test_string"x')
- end
- if conversion_table.dot_register then
- expect_base = expect_base:gsub('(test_stringx?)"', '%1.')
- end
- return expect_base
- end -- convert_charwise()
-
- local function make_back(string)
- local prev_line
- local rettab = {}
- local string_found = false
- for _, line in pairs(funcs.split(string, '\n', 1)) do
- if line:find('test_string') then
- string_found = true
- table.insert(rettab, line)
- else
- if string_found then
- if prev_line then
- table.insert(rettab, prev_line)
- prev_line = nil
- end
- table.insert(rettab, line)
- else
- table.insert(rettab, prev_line)
- prev_line = line
- end
- end
- end
- -- In case there are no lines after the text that was put.
- if prev_line and string_found then
- table.insert(rettab, prev_line)
- end
- return table.concat(rettab, '\n')
- end -- make_back()
-
- local function convert_linewise(expect_base, conversion_table, _, use_a, indent)
- expect_base = dedent(expect_base)
- if conversion_table.put_backwards then
- expect_base = make_back(expect_base)
- end
- local p_str = 'test_string"'
- if use_a then
- p_str = 'test_stringa'
- end
-
- if conversion_table.dot_register then
- expect_base = expect_base:gsub('x' .. p_str, 'xtest_string.')
- p_str = 'test_string.'
- end
-
- if conversion_table.cursor_after then
- expect_base = expect_base:gsub('x' .. p_str .. '\n', p_str .. '\nx')
- end
-
- -- The 'indent' argument is only used here because a single put with an
- -- indent doesn't require special handling. It doesn't require special
- -- handling because the cursor is never put before the indent, hence
- -- the modification of 'test_stringx"' gives the same overall answer as
- -- modifying ' test_stringx"'.
-
- -- Only happens when using normal mode command actions.
- if conversion_table.count and conversion_table.count > 1 then
- if not indent then
- indent = ''
- end
- local rep_string = indent .. p_str .. '\n'
- local extra_puts = rep_string:rep(conversion_table.count - 1)
- local orig_string, new_string
- if conversion_table.cursor_after then
- orig_string = indent .. p_str .. '\nx'
- new_string = extra_puts .. orig_string
- else
- orig_string = indent .. 'x' .. p_str .. '\n'
- new_string = orig_string .. extra_puts
- end
- expect_base = expect_base:gsub(orig_string, new_string)
- end
- return expect_base
- end
-
- local function put_x_last(orig_line, p_str)
- local prev_end, cur_end, cur_start = 0, 0, 0
- while cur_start do
- prev_end = cur_end
- cur_start, cur_end = orig_line:find(p_str, prev_end)
- end
- -- Assume (because that is the only way I call it) that p_str matches
- -- the pattern 'test_string.'
- return orig_line:sub(1, prev_end - 1) .. 'x' .. orig_line:sub(prev_end)
- end
-
- local function convert_blockwise(expect_base, conversion_table, visual,
- use_b, trailing_whitespace)
- expect_base = dedent(expect_base)
- local p_str = 'test_string"'
- if use_b then
- p_str = 'test_stringb'
- end
-
- if conversion_table.dot_register then
- expect_base = expect_base:gsub('(x?)' .. p_str, '%1test_string.')
- -- Looks strange, but the dot is a special character in the pattern
- -- and a literal character in the replacement.
- expect_base = expect_base:gsub('test_stringx.', 'test_stringx.')
- p_str = 'test_string.'
- end
-
- -- No difference between 'p' and 'P' in visual mode.
- if not visual then
- if conversion_table.put_backwards then
- -- One for the line where the cursor is left, one for all other
- -- lines.
- expect_base = expect_base:gsub('([^x])' .. p_str, p_str .. '%1')
- expect_base = expect_base:gsub('([^x])x' .. p_str, 'x' .. p_str .. '%1')
- if not trailing_whitespace then
- expect_base = expect_base:gsub(' \n', '\n')
- expect_base = expect_base:gsub(' $', '')
- end
- end
- end
-
- if conversion_table.count and conversion_table.count > 1 then
- local p_pattern = p_str:gsub('%.', '%%.')
- expect_base = expect_base:gsub(p_pattern,
- p_str:rep(conversion_table.count))
- expect_base = expect_base:gsub('test_stringx([b".])',
- p_str:rep(conversion_table.count - 1)
- .. '%0')
- end
-
- if conversion_table.cursor_after then
- if not visual then
- local prev_line
- local rettab = {}
- local prev_in_block = false
- for _, line in pairs(funcs.split(expect_base, '\n', 1)) do
- if line:find('test_string') then
- if prev_line then
- prev_line = prev_line:gsub('x', '')
- table.insert(rettab, prev_line)
- end
- prev_line = line
- prev_in_block = true
- else
- if prev_in_block then
- prev_line = put_x_last(prev_line, p_str)
- table.insert(rettab, prev_line)
- prev_in_block = false
- end
- table.insert(rettab, line)
- end
- end
- if prev_line and prev_in_block then
- table.insert(rettab, put_x_last(prev_line, p_str))
- end
-
- expect_base = table.concat(rettab, '\n')
- else
- expect_base = expect_base:gsub('x(.)', '%1x')
- end
- end
-
- return expect_base
- end
- -- }}}
-
- -- Convenience functions {{{
- local function run_normal_mode_tests(test_string, base_map, extra_setup,
- virtualedit_end, selection_string)
- local function convert_closure(e, c)
- return convert_charwise(e, c, virtualedit_end, selection_string)
- end
- local function expect_normal_creator(expect_base, conversion_table)
- local test_expect = expect_creator(convert_closure, expect_base, conversion_table)
- return function(exception_table, after_redo)
- test_expect(exception_table, after_redo)
- if selection_string then
- eq(getreg('"'), selection_string)
- else
- eq(getreg('"'), 'test_string"')
- end
- end
- end
- run_test_variations(
- create_test_defs(
- normal_command_defs,
- base_map,
- create_p_action,
- test_string,
- expect_normal_creator
- ),
- extra_setup
- )
- end -- run_normal_mode_tests()
-
- local function convert_linewiseer(expect_base, conversion_table)
- return expect_creator(convert_linewise, expect_base, conversion_table)
- end
-
- local function run_linewise_tests(expect_base, base_command, extra_setup)
- local linewise_test_defs = create_test_defs(
- ex_command_defs, base_command,
- create_put_action, expect_base, convert_linewiseer)
- run_test_variations(linewise_test_defs, extra_setup)
- end -- run_linewise_tests()
- -- }}}
-
- -- Actual tests
- describe('default pasting', function()
- local expect_string = [[
- Ltest_stringx"ine of words 1
- Line of words 2]]
- run_normal_mode_tests(expect_string, 'p')
-
- run_linewise_tests([[
- Line of words 1
- xtest_string"
- Line of words 2]],
- 'put'
- )
- end)
-
- describe('linewise register', function()
- -- put with 'p'
- local local_ex_command_defs = non_dotdefs(normal_command_defs)
- local base_expect_string = [[
- Line of words 1
- xtest_stringa
- Line of words 2]]
- local function local_convert_linewise(expect_base, conversion_table)
- return convert_linewise(expect_base, conversion_table, nil, true)
- end
- local function expect_lineput(expect_base, conversion_table)
- return expect_creator(local_convert_linewise, expect_base, conversion_table)
- end
- run_test_variations(
- create_test_defs(
- local_ex_command_defs,
- '"ap',
- create_p_action,
- base_expect_string,
- expect_lineput
- )
- )
-
- -- put with :put
- local linewise_put_defs = non_dotdefs(ex_command_defs)
- base_expect_string = [[
- Line of words 1
- xtest_stringa
- Line of words 2]]
- run_test_variations(
- create_test_defs(
- linewise_put_defs,
- 'put a', create_put_action,
- base_expect_string, convert_linewiseer
- )
- )
-
- end)
-
- describe('blockwise register', function()
- local blockwise_put_defs = non_dotdefs(normal_command_defs)
- local test_base = [[
- Lxtest_stringbine of words 1
- Ltest_stringbine of words 2
- test_stringb]]
-
- local function expect_block_creator(expect_base, conversion_table)
- return expect_creator(function(e,c) return convert_blockwise(e,c,nil,true) end,
- expect_base, conversion_table)
- end
-
- run_test_variations(
- create_test_defs(
- blockwise_put_defs,
- '"bp',
- create_p_action,
- test_base,
- expect_block_creator
- )
- )
- end)
-
- it('adds correct indentation when put with [p and ]p', function()
- feed('G>>"a]pix<esc>')
- -- luacheck: ignore
- expect([[
- Line of words 1
- Line of words 2
- xtest_stringa]])
- feed('uu"a[pix<esc>')
- -- luacheck: ignore
- expect([[
- Line of words 1
- xtest_stringa
- Line of words 2]])
- end)
-
- describe('linewise paste with autoindent', function()
- -- luacheck: ignore
- run_linewise_tests([[
- Line of words 1
- Line of words 2
- xtest_string"]],
- 'put'
- ,
- function()
- funcs.setline('$', ' Line of words 2')
- -- Set curswant to '8' to be at the end of the tab character
- -- This is where the cursor is put back after the 'u' command.
- funcs.setpos('.', {0, 2, 1, 0, 8})
- feed_command('set autoindent')
- end
- )
- end)
-
- describe('put inside tabs with virtualedit', function()
- local test_string = [[
- Line of words 1
- test_stringx" Line of words 2]]
- run_normal_mode_tests(test_string, 'p', function()
- funcs.setline('$', ' Line of words 2')
- feed_command('set virtualedit=all')
- funcs.setpos('.', {0, 2, 1, 2, 3})
- end)
- end)
-
- describe('put after the line with virtualedit', function()
- -- luacheck: ignore 621
- local test_string = [[
- Line of words 1 test_stringx"
- Line of words 2]]
- run_normal_mode_tests(test_string, 'p', function()
- funcs.setline('$', ' Line of words 2')
- feed_command('set virtualedit=all')
- funcs.setpos('.', {0, 1, 16, 1, 17})
- end, true)
- end)
-
- describe('Visual put', function()
- describe('basic put', function()
- local test_string = [[
- test_stringx" words 1
- Line of words 2]]
- run_normal_mode_tests(test_string, 'v2ep', nil, nil, 'Line of')
- end)
- describe('over trailing newline', function()
- local test_string = 'Line of test_stringx"Line of words 2'
- run_normal_mode_tests(test_string, 'v$p', function()
- funcs.setpos('.', {0, 1, 9, 0, 9})
- end,
- nil,
- 'words 1\n')
- end)
- describe('linewise mode', function()
- local test_string = [[
- xtest_string"
- Line of words 2]]
- local function expect_vis_linewise(expect_base, conversion_table)
- return expect_creator(function(e, c)
- return convert_linewise(e, c, nil, nil)
- end,
- expect_base, conversion_table)
- end
- run_test_variations(
- create_test_defs(
- normal_command_defs,
- 'Vp',
- create_p_action,
- test_string,
- expect_vis_linewise
- ),
- function() funcs.setpos('.', {0, 1, 1, 0, 1}) end
- )
-
- describe('with whitespace at bol', function()
- local function expect_vis_lineindented(expect_base, conversion_table)
- local test_expect = expect_creator(function(e, c)
- return convert_linewise(e, c, nil, nil, ' ')
- end,
- expect_base, conversion_table)
- return function(exception_table, after_redo)
- test_expect(exception_table, after_redo)
- eq(getreg('"'), 'Line of words 1\n')
- end
- end
- local base_expect_string = [[
- xtest_string"
- Line of words 2]]
- run_test_variations(
- create_test_defs(
- normal_command_defs,
- 'Vp',
- create_p_action,
- base_expect_string,
- expect_vis_lineindented
- ),
- function()
- feed('i test_string.<esc>u')
- funcs.setreg('"', ' test_string"', 'v')
- end
- )
- end)
-
- end)
-
- describe('blockwise visual mode', function()
- local test_base = [[
- test_stringx"e of words 1
- test_string"e of words 2]]
-
- local function expect_block_creator(expect_base, conversion_table)
- local test_expect = expect_creator(function(e, c)
- return convert_blockwise(e, c, true)
- end, expect_base, conversion_table)
- return function(e,c)
- test_expect(e,c)
- eq(getreg('"'), 'Lin\nLin')
- end
- end
-
- local select_down_test_defs = create_test_defs(
- normal_command_defs,
- '<C-v>jllp',
- create_p_action,
- test_base,
- expect_block_creator
- )
- run_test_variations(select_down_test_defs)
-
-
- -- Undo and redo of a visual block put leave the cursor in the top
- -- left of the visual block area no matter where the cursor was
- -- when it started.
- local undo_redo_no = map(function(table)
- local rettab = copy_def(table)
- if not rettab[4] then
- rettab[4] = {}
- end
- rettab[4].undo_position = true
- rettab[4].redo_position = true
- return rettab
- end,
- normal_command_defs)
-
- -- Selection direction doesn't matter
- run_test_variations(
- create_test_defs(
- undo_redo_no,
- '<C-v>kllp',
- create_p_action,
- test_base,
- expect_block_creator
- ),
- function() funcs.setpos('.', {0, 2, 1, 0, 1}) end
- )
-
- describe('blockwise cursor after undo', function()
- -- A bit of a hack of the reset above.
- -- In the tests that selection direction doesn't matter, we
- -- don't check the undo/redo position because it doesn't fit
- -- the same pattern as everything else.
- -- Here we fix this by directly checking the undo/redo position
- -- in the test_assertions of our test definitions.
- local function assertion_creator(_,_)
- return function(_,_)
- feed('u')
- -- Have to use feed('u') here to set curswant, because
- -- ex_undo() doesn't do that.
- eq(funcs.getcurpos(), {0, 1, 1, 0, 1})
- feed('<C-r>')
- eq(funcs.getcurpos(), {0, 1, 1, 0, 1})
- end
- end
-
- run_test_variations(
- create_test_defs(
- undo_redo_no,
- '<C-v>kllp',
- create_p_action,
- test_base,
- assertion_creator
- ),
- function() funcs.setpos('.', {0, 2, 1, 0, 1}) end
- )
- end)
- end)
-
-
- describe("with 'virtualedit'", function()
- describe('splitting a tab character', function()
- local base_expect_string = [[
- Line of words 1
- test_stringx" Line of words 2]]
- run_normal_mode_tests(
- base_expect_string,
- 'vp',
- function()
- funcs.setline('$', ' Line of words 2')
- feed_command('set virtualedit=all')
- funcs.setpos('.', {0, 2, 1, 2, 3})
- end,
- nil,
- ' '
- )
- end)
- describe('after end of line', function()
- local base_expect_string = [[
- Line of words 1 test_stringx"
- Line of words 2]]
- run_normal_mode_tests(
- base_expect_string,
- 'vp',
- function()
- feed_command('set virtualedit=all')
- funcs.setpos('.', {0, 1, 16, 2, 18})
- end,
- true,
- ' '
- )
- end)
- end)
- end)
-
- describe('. register special tests', function()
- -- luacheck: ignore 621
- before_each(reset)
- it('applies control character actions', function()
- feed('i<C-t><esc>u')
- expect([[
- Line of words 1
- Line of words 2]])
- feed('".p')
- expect([[
- Line of words 1
- Line of words 2]])
- feed('u1go<C-v>j".p')
- eq([[
- ine of words 1
- ine of words 2]], curbuf_contents())
- end)
-
- local function bell_test(actions, should_ring)
- local screen = Screen.new()
- screen:attach()
- if should_ring then
- -- check bell is not set by nvim before the action
- screen:sleep(50)
- end
- helpers.ok(not screen.bell and not screen.visualbell)
- actions()
- screen:expect{condition=function()
- if should_ring then
- if not screen.bell and not screen.visualbell then
- error('Bell was not rung after action')
- end
- else
- if screen.bell or screen.visualbell then
- error('Bell was rung after action')
- end
- end
- end, unchanged=(not should_ring)}
- screen:detach()
- end
-
- it('should not ring the bell with gp at end of line', function()
- bell_test(function() feed('$".gp') end)
-
- -- Even if the last character is a multibyte character.
- reset()
- funcs.setline(1, 'helloม')
- bell_test(function() feed('$".gp') end)
- end)
-
- it('should not ring the bell with gp and end of file', function()
- funcs.setpos('.', {0, 2, 1, 0})
- bell_test(function() feed('$vl".gp') end)
- end)
-
- it('should ring the bell when deleting if not appropriate', function()
- feed_command('goto 2')
- feed('i<bs><esc>')
- expect([[
- ine of words 1
- Line of words 2]])
- bell_test(function() feed('".P') end, true)
- end)
-
- it('should restore cursor position after undo of ".p', function()
- local origpos = funcs.getcurpos()
- feed('".pu')
- eq(origpos, funcs.getcurpos())
- end)
-
- it("should be unaffected by 'autoindent' with V\".2p", function()
- feed_command('set autoindent')
- feed('i test_string.<esc>u')
- feed('V".2p')
- expect([[
- test_string.
- test_string.
- Line of words 2]])
- end)
- end)
-end)
-
diff --git a/test/functional/normal/search_spec.lua b/test/functional/normal/search_spec.lua
deleted file mode 100644
index d5df131725..0000000000
--- a/test/functional/normal/search_spec.lua
+++ /dev/null
@@ -1,17 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear = helpers.clear
-local command = helpers.command
-local eq = helpers.eq
-local pcall_err = helpers.pcall_err
-
-describe('search (/)', function()
- before_each(clear)
-
- it('fails with huge column (%c) value #9930', function()
- eq([[Vim:E951: \% value too large]],
- pcall_err(command, "/\\v%18446744071562067968c"))
- eq([[Vim:E951: \% value too large]],
- pcall_err(command, "/\\v%2147483648c"))
- end)
-end)
-
diff --git a/test/functional/normal/tabpage_spec.lua b/test/functional/normal/tabpage_spec.lua
deleted file mode 100644
index d1d6854b07..0000000000
--- a/test/functional/normal/tabpage_spec.lua
+++ /dev/null
@@ -1,38 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local clear = helpers.clear
-local command = helpers.command
-local eq = helpers.eq
-local feed = helpers.feed
-local eval = helpers.eval
-
-describe('tabpage', function()
- before_each(clear)
-
- it('advances to the next page via <C-W>gt', function()
- -- add some tabpages
- command('tabnew')
- command('tabnew')
- command('tabnew')
-
- eq(4, eval('tabpagenr()'))
-
- feed('<C-W>gt')
-
- eq(1, eval('tabpagenr()'))
- end)
-
- it('retreats to the previous page via <C-W>gT', function()
- -- add some tabpages
- command('tabnew')
- command('tabnew')
- command('tabnew')
-
- eq(4, eval('tabpagenr()'))
-
- feed('<C-W>gT')
-
- eq(3, eval('tabpagenr()'))
- end)
-end)
-
diff --git a/test/functional/normal/undo_spec.lua b/test/functional/normal/undo_spec.lua
deleted file mode 100644
index a023ca3d90..0000000000
--- a/test/functional/normal/undo_spec.lua
+++ /dev/null
@@ -1,61 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local clear = helpers.clear
-local command = helpers.command
-local expect = helpers.expect
-local feed = helpers.feed
-local insert = helpers.insert
-
-describe('u CTRL-R g- g+', function()
- before_each(clear)
-
- local function create_history(num_steps)
- if num_steps == 0 then return end
- insert('1')
- if num_steps == 1 then return end
- feed('o2<esc>')
- feed('o3<esc>')
- feed('u')
- if num_steps == 2 then return end
- feed('o4<esc>')
- if num_steps == 3 then return end
- feed('u')
- end
-
- local function undo_and_redo(hist_pos, undo, redo, expect_str)
- command('enew!')
- create_history(hist_pos)
- local cur_contents = helpers.curbuf_contents()
- feed(undo)
- expect(expect_str)
- feed(redo)
- expect(cur_contents)
- end
-
- -- TODO Look for message saying 'Already at oldest change'
- it('does nothing when no changes have happened', function()
- undo_and_redo(0, 'u', '<C-r>', '')
- undo_and_redo(0, 'g-', 'g+', '')
- end)
- it('undoes a change when at a leaf', function()
- undo_and_redo(1, 'u', '<C-r>', '')
- undo_and_redo(1, 'g-', 'g+', '')
- end)
- it('undoes a change when in a non-leaf', function()
- undo_and_redo(2, 'u', '<C-r>', '1')
- undo_and_redo(2, 'g-', 'g+', '1')
- end)
- it('undoes properly around a branch point', function()
- undo_and_redo(3, 'u', '<C-r>', [[
- 1
- 2]])
- undo_and_redo(3, 'g-', 'g+', [[
- 1
- 2
- 3]])
- end)
- it('can find the previous sequence after undoing to a branch', function()
- undo_and_redo(4, 'u', '<C-r>', '1')
- undo_and_redo(4, 'g-', 'g+', '1')
- end)
-end)