aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/testdir
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/testdir')
-rw-r--r--src/nvim/testdir/setup.vim4
-rw-r--r--src/nvim/testdir/test_autocmd.vim7
-rw-r--r--src/nvim/testdir/test_cindent.vim11
-rw-r--r--src/nvim/testdir/test_cmdline.vim10
-rw-r--r--src/nvim/testdir/test_edit.vim4
-rw-r--r--src/nvim/testdir/test_indent.vim155
-rw-r--r--src/nvim/testdir/test_normal.vim241
-rw-r--r--src/nvim/testdir/test_spell.vim121
-rw-r--r--src/nvim/testdir/test_spell_utf8.vim18
-rw-r--r--src/nvim/testdir/test_spellfile.vim596
-rw-r--r--src/nvim/testdir/test_substitute.vim2
-rw-r--r--src/nvim/testdir/test_timers.vim2
-rw-r--r--src/nvim/testdir/test_virtualedit.vim3
-rw-r--r--src/nvim/testdir/test_visual.vim77
14 files changed, 1208 insertions, 43 deletions
diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim
index f1092af358..dfcde37f62 100644
--- a/src/nvim/testdir/setup.vim
+++ b/src/nvim/testdir/setup.vim
@@ -30,6 +30,10 @@ set switchbuf=
mapclear
mapclear!
+" Make "Q" switch to Ex mode.
+" This does not work for all tests.
+nnoremap Q gQ
+
" Prevent Nvim log from writing to stderr.
let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log'
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index 660801d575..fcef57e47a 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -169,7 +169,9 @@ func Test_autocmd_bufunload_avoiding_SEGV_01()
exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
augroup END
- call assert_fails('edit bb.txt', 'E937:')
+ " Todo: check for E937 generated first
+ " call assert_fails('edit bb.txt', 'E937:')
+ call assert_fails('edit bb.txt', 'E517:')
autocmd! test_autocmd_bufunload
augroup! test_autocmd_bufunload
@@ -540,7 +542,7 @@ func Test_three_windows()
e Xtestje2
sp Xtestje1
call assert_fails('e', 'E937:')
- call assert_equal('Xtestje2', expand('%'))
+ call assert_equal('Xtestje1', expand('%'))
" Test changing buffers in a BufWipeout autocommand. If this goes wrong
" there are ml_line errors and/or a Crash.
@@ -563,7 +565,6 @@ func Test_three_windows()
au!
enew
- bwipe! Xtestje1
call delete('Xtestje1')
call delete('Xtestje2')
call delete('Xtestje3')
diff --git a/src/nvim/testdir/test_cindent.vim b/src/nvim/testdir/test_cindent.vim
index 7ba8ef3397..ccc8168c09 100644
--- a/src/nvim/testdir/test_cindent.vim
+++ b/src/nvim/testdir/test_cindent.vim
@@ -5306,11 +5306,20 @@ func Test_cindent_case()
set cindent
norm! f:a:
call assert_equal('case x:: // x', getline(1))
-
set cindent&
bwipe!
endfunc
+" Test for changing multiple lines (using c) with cindent
+func Test_cindent_change_multline()
+ new
+ setlocal cindent
+ call setline(1, ['if (a)', '{', ' i = 1;', '}'])
+ normal! jc3jm = 2;
+ call assert_equal("\tm = 2;", getline(2))
+ close!
+endfunc
+
" This was reading past the end of the line
func Test_cindent_check_funcdecl()
new
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index aedcad5296..8ee894c35f 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -1226,6 +1226,16 @@ func Test_cmdline_expand_home()
call delete('Xdir', 'rf')
endfunc
+" Test for normal mode commands not supported in the cmd window
+func Test_cmdwin_blocked_commands()
+ call assert_fails('call feedkeys("q:\<C-T>\<CR>", "xt")', 'E11:')
+ call assert_fails('call feedkeys("q:\<C-]>\<CR>", "xt")', 'E11:')
+ call assert_fails('call feedkeys("q:\<C-^>\<CR>", "xt")', 'E11:')
+ call assert_fails('call feedkeys("q:Q\<CR>", "xt")', 'E11:')
+ call assert_fails('call feedkeys("q:Z\<CR>", "xt")', 'E11:')
+ call assert_fails('call feedkeys("q:\<F1>\<CR>", "xt")', 'E11:')
+endfunc
+
" test that ";" works to find a match at the start of the first line
func Test_zero_line_search()
new
diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim
index 275c8f7a15..c14afbe5b9 100644
--- a/src/nvim/testdir/test_edit.vim
+++ b/src/nvim/testdir/test_edit.vim
@@ -270,6 +270,10 @@ func Test_edit_10()
call cursor(1, 4)
call feedkeys("A\<s-home>start\<esc>", 'txin')
call assert_equal(['startdef', 'ghi'], getline(1, '$'))
+ " start select mode again with gv
+ set selectmode=cmd
+ call feedkeys('gvabc', 'xt')
+ call assert_equal('abctdef', getline(1))
set selectmode= keymodel=
bw!
endfunc
diff --git a/src/nvim/testdir/test_indent.vim b/src/nvim/testdir/test_indent.vim
index 516b3fbdd1..3b5b643177 100644
--- a/src/nvim/testdir/test_indent.vim
+++ b/src/nvim/testdir/test_indent.vim
@@ -121,4 +121,159 @@ func Test_copyindent()
close!
endfunc
+" Test for changing multiple lines with lisp indent
+func Test_lisp_indent_change_multiline()
+ new
+ setlocal lisp autoindent
+ call setline(1, ['(if a', ' (if b', ' (return 5)))'])
+ normal! jc2j(return 4))
+ call assert_equal(' (return 4))', getline(2))
+ close!
+endfunc
+
+func Test_lisp_indent()
+ new
+ setlocal lisp autoindent
+ call setline(1, ['(if a', ' ;; comment', ' \ abc', '', ' " str1\', ' " st\b', ' (return 5)'])
+ normal! jo;; comment
+ normal! jo\ abc
+ normal! jo;; ret
+ normal! jostr1"
+ normal! jostr2"
+ call assert_equal([' ;; comment', ' ;; comment', ' \ abc', ' \ abc', '', ' ;; ret', ' " str1\', ' str1"', ' " st\b', ' str2"'], getline(2, 11))
+ close!
+endfunc
+
+func Test_lisp_indent_quoted()
+ " This was going past the end of the line
+ new
+ setlocal lisp autoindent
+ call setline(1, ['"[', '='])
+ normal Gvk=
+
+ bwipe!
+endfunc
+
+" Test for setting the 'indentexpr' from a modeline
+func Test_modeline_indent_expr()
+ let modeline = &modeline
+ set modeline
+ func GetIndent()
+ return line('.') * 2
+ endfunc
+ call writefile(['# vim: indentexpr=GetIndent()'], 'Xfile.txt')
+ set modelineexpr
+ new Xfile.txt
+ call assert_equal('GetIndent()', &indentexpr)
+ exe "normal Oa\nb\n"
+ call assert_equal([' a', ' b'], getline(1, 2))
+
+ set modelineexpr&
+ delfunc GetIndent
+ let &modeline = modeline
+ close!
+ call delete('Xfile.txt')
+endfunc
+
+func Test_indent_func_with_gq()
+
+ function GetTeXIndent()
+ " Sample indent expression for TeX files
+ let lnum = prevnonblank(v:lnum - 1)
+ " At the start of the file use zero indent.
+ if lnum == 0
+ return 0
+ endif
+ let line = getline(lnum)
+ let ind = indent(lnum)
+ " Add a 'shiftwidth' after beginning of environments.
+ if line =~ '\\begin{center}'
+ let ind = ind + shiftwidth()
+ endif
+ return ind
+ endfunction
+
+ new
+ setl et sw=2 sts=2 ts=2 tw=50 indentexpr=GetTeXIndent()
+ put =[ '\documentclass{article}', '', '\begin{document}', '',
+ \ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce ut enim non',
+ \ 'libero efficitur aliquet. Maecenas metus justo, facilisis convallis blandit',
+ \ 'non, semper eu urna. Suspendisse diam diam, iaculis faucibus lorem eu,',
+ \ 'fringilla condimentum lectus. Quisque euismod diam at convallis vulputate.',
+ \ 'Pellentesque laoreet tortor sit amet mauris euismod ornare. Sed varius',
+ \ 'bibendum orci vel vehicula. Pellentesque tempor, ipsum et auctor accumsan,',
+ \ 'metus lectus ultrices odio, sed elementum mi ante at arcu.', '', '\begin{center}', '',
+ \ 'Proin nec risus consequat nunc dapibus consectetur. Mauris lacinia est a augue',
+ \ 'tristique accumsan. Morbi pretium, felis molestie eleifend condimentum, arcu',
+ \ 'ipsum congue nisl, quis euismod purus libero in ante.', '',
+ \ 'Donec id semper purus.',
+ \ 'Suspendisse eget aliquam nunc. Maecenas fringilla mauris vitae maximus',
+ \ 'condimentum. Cras a quam in mi dictum eleifend at a lorem. Sed convallis',
+ \ 'ante a commodo facilisis. Nam suscipit vulputate odio, vel dapibus nisl',
+ \ 'dignissim facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et',
+ \ 'ultrices posuere cubilia curae;', '', '']
+ 1d_
+ call cursor(5, 1)
+ ka
+ call cursor(14, 1)
+ kb
+ norm! 'agqap
+ norm! 'bgqG
+ let expected = [ '\documentclass{article}', '', '\begin{document}', '',
+ \ 'Lorem ipsum dolor sit amet, consectetur adipiscing',
+ \ 'elit. Fusce ut enim non libero efficitur aliquet.',
+ \ 'Maecenas metus justo, facilisis convallis blandit',
+ \ 'non, semper eu urna. Suspendisse diam diam,',
+ \ 'iaculis faucibus lorem eu, fringilla condimentum',
+ \ 'lectus. Quisque euismod diam at convallis',
+ \ 'vulputate. Pellentesque laoreet tortor sit amet',
+ \ 'mauris euismod ornare. Sed varius bibendum orci',
+ \ 'vel vehicula. Pellentesque tempor, ipsum et auctor',
+ \ 'accumsan, metus lectus ultrices odio, sed',
+ \ 'elementum mi ante at arcu.', '', '\begin{center}', '',
+ \ ' Proin nec risus consequat nunc dapibus',
+ \ ' consectetur. Mauris lacinia est a augue',
+ \ ' tristique accumsan. Morbi pretium, felis',
+ \ ' molestie eleifend condimentum, arcu ipsum congue',
+ \ ' nisl, quis euismod purus libero in ante.',
+ \ '',
+ \ ' Donec id semper purus. Suspendisse eget aliquam',
+ \ ' nunc. Maecenas fringilla mauris vitae maximus',
+ \ ' condimentum. Cras a quam in mi dictum eleifend',
+ \ ' at a lorem. Sed convallis ante a commodo',
+ \ ' facilisis. Nam suscipit vulputate odio, vel',
+ \ ' dapibus nisl dignissim facilisis. Vestibulum',
+ \ ' ante ipsum primis in faucibus orci luctus et',
+ \ ' ultrices posuere cubilia curae;', '', '']
+ call assert_equal(expected, getline(1, '$'))
+
+ bwipe!
+ delmark ab
+ delfunction GetTeXIndent
+endfu
+
+func Test_formatting_keeps_first_line_indent()
+ let lines =<< trim END
+ foo()
+ {
+ int x; // manually positioned
+ // more text that will be formatted
+ // but not reindented
+ END
+ new
+ call setline(1, lines)
+ setlocal sw=4 cindent tw=45 et
+ normal! 4Ggqj
+ let expected =<< trim END
+ foo()
+ {
+ int x; // manually positioned
+ // more text that will be
+ // formatted but not
+ // reindented
+ END
+ call assert_equal(expected, getline(1, '$'))
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim
index b44d65c2a4..82ba2cfd48 100644
--- a/src/nvim/testdir/test_normal.vim
+++ b/src/nvim/testdir/test_normal.vim
@@ -115,8 +115,8 @@ func Test_normal01_keymodel()
bw!
endfunc
+" Test for select mode
func Test_normal02_selectmode()
- " some basic select mode tests
call Setup_NewWindow()
50
norm! gHy
@@ -345,7 +345,7 @@ func Test_normal08_fold()
bw!
endfunc
-func Test_normal09_operatorfunc()
+func Test_normal09a_operatorfunc()
" Test operatorfunc
call Setup_NewWindow()
" Add some spaces for counting
@@ -375,7 +375,7 @@ func Test_normal09_operatorfunc()
bw!
endfunc
-func Test_normal09a_operatorfunc()
+func Test_normal09b_operatorfunc()
" Test operatorfunc
call Setup_NewWindow()
" Add some spaces for counting
@@ -397,10 +397,45 @@ func Test_normal09a_operatorfunc()
" clean up
unmap <buffer> ,,
set opfunc=
+ call assert_fails('normal Vg@', 'E774:')
bw!
unlet! g:opt
endfunc
+func OperatorfuncRedo(_)
+ let g:opfunc_count = v:count
+endfunc
+
+func Underscorize(_)
+ normal! '[V']r_
+endfunc
+
+func Test_normal09c_operatorfunc()
+ " Test redoing operatorfunc
+ new
+ call setline(1, 'some text')
+ set operatorfunc=OperatorfuncRedo
+ normal v3g@
+ call assert_equal(3, g:opfunc_count)
+ let g:opfunc_count = 0
+ normal .
+ call assert_equal(3, g:opfunc_count)
+
+ bw!
+ unlet g:opfunc_count
+
+ " Test redoing Visual mode
+ set operatorfunc=Underscorize
+ new
+ call setline(1, ['first', 'first', 'third', 'third', 'second'])
+ normal! 1GVjg@
+ normal! 5G.
+ normal! 3G.
+ call assert_equal(['_____', '_____', '_____', '_____', '______'], getline(1, '$'))
+ bwipe!
+ set operatorfunc=
+endfunc
+
func Test_normal10_expand()
" Test for expand()
10new
@@ -456,8 +491,12 @@ func Test_normal12_nv_error()
10new
call setline(1, range(1,5))
" should not do anything, just beep
- exe "norm! <c-k>"
+ call assert_beeps('exe "norm! <c-k>"')
call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
+ call assert_beeps('normal! G2dd')
+ call assert_beeps("normal! g\<C-A>")
+ call assert_beeps("normal! g\<C-X>")
+ call assert_beeps("normal! g\<C-B>")
bw!
endfunc
@@ -1654,6 +1693,14 @@ fun! Test_normal30_changecase()
throw 'Skipped: Turkish locale not available'
endtry
+ call setline(1, ['aaaaaa', 'aaaaaa'])
+ normal! gg10~
+ call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
+ set whichwrap+=~
+ normal! gg10~
+ call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
+ set whichwrap&
+
" clean up
bw!
endfunc
@@ -1683,8 +1730,8 @@ fun! Test_normal31_r_cmd()
bw!
endfunc
+" Test for g*, g#
func Test_normal32_g_cmd1()
- " Test for g*, g#
new
call append(0, ['abc.x_foo', 'x_foobar.abc'])
1
@@ -1699,11 +1746,12 @@ func Test_normal32_g_cmd1()
bw!
endfunc
+" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
+" gi and gI commands
fun! Test_normal33_g_cmd2()
if !has("jumplist")
return
endif
- " Tests for g cmds
call Setup_NewWindow()
" Test for g`
clearjumps
@@ -1715,6 +1763,10 @@ fun! Test_normal33_g_cmd2()
call assert_equal('>', a[-1:])
call assert_equal(1, line('.'))
call assert_equal('1', getline('.'))
+ call cursor(10, 1)
+ norm! g'a
+ call assert_equal('>', a[-1:])
+ call assert_equal(1, line('.'))
" Test for g; and g,
norm! g;
@@ -1756,14 +1808,20 @@ fun! Test_normal33_g_cmd2()
exe "norm! G0\<c-v>4k4ly"
exe "norm! gvood"
call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
+ " gv cannot be used in operator pending mode
+ call assert_beeps('normal! cgv')
+ " gv should beep without a previously selected visual area
+ new
+ call assert_beeps('normal! gv')
+ close
" Test for gk/gj
%d
15vsp
set wrap listchars= sbr=
- let lineA='abcdefghijklmnopqrstuvwxyz'
- let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
- let lineC='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
+ let lineA = 'abcdefghijklmnopqrstuvwxyz'
+ let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
$put =lineA
$put =lineB
@@ -1796,8 +1854,39 @@ fun! Test_normal33_g_cmd2()
norm! g^yl
call assert_equal(15, col('.'))
call assert_equal('l', getreg(0))
+ call assert_beeps('normal 5g$')
+
+ " Test for g$ with double-width character half displayed
+ vsplit
+ 9wincmd |
+ setlocal nowrap nonumber
+ call setline(2, 'asdfasdfヨ')
+ 2
+ normal 0g$
+ call assert_equal(8, col('.'))
+ 10wincmd |
+ normal 0g$
+ call assert_equal(9, col('.'))
+
+ setlocal signcolumn=yes
+ 11wincmd |
+ normal 0g$
+ call assert_equal(8, col('.'))
+ 12wincmd |
+ normal 0g$
+ call assert_equal(9, col('.'))
- norm! 2ggdd
+ close
+
+ " Test for g_
+ call assert_beeps('normal! 100g_')
+ call setline(2, [' foo ', ' foobar '])
+ normal! 2ggg_
+ call assert_equal(5, col('.'))
+ normal! 2g_
+ call assert_equal(8, col('.'))
+
+ norm! 2ggdG
$put =lineC
" Test for gM
@@ -1839,6 +1928,17 @@ fun! Test_normal33_g_cmd2()
$put ='third line'
norm! gi another word
call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
+ call setline(1, 'foobar')
+ normal! Ggifirst line
+ call assert_equal('foobarfirst line', getline(1))
+ " Test gi in 'virtualedit' mode with cursor after the end of the line
+ set virtualedit=all
+ call setline(1, 'foo')
+ exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
+ call setline(1, 'foo')
+ normal! Ggifirst line
+ call assert_equal('foo first line', getline(1))
+ set virtualedit&
" clean up
bw!
@@ -1927,8 +2027,8 @@ func Test_g_ctrl_g()
bwipe!
endfunc
+" Test for g8
fun! Test_normal34_g_cmd3()
- " Test for g8
new
let a=execute(':norm! 1G0g8')
call assert_equal("\nNUL", a)
@@ -1945,11 +2045,10 @@ fun! Test_normal34_g_cmd3()
bw!
endfunc
+" Test 8g8 which finds invalid utf8 at or after the cursor.
func Test_normal_8g8()
new
- " Test 8g8 which finds invalid utf8 at or after the cursor.
-
" With invalid byte.
call setline(1, "___\xff___")
norm! 1G08g8g
@@ -1978,8 +2077,8 @@ func Test_normal_8g8()
bw!
endfunc
+" Test for g<
fun! Test_normal35_g_cmd4()
- " Test for g<
" Cannot capture its output,
" probably a bug, therefore, test disabled:
throw "Skipped: output of g< can't be tested currently"
@@ -1988,6 +2087,7 @@ fun! Test_normal35_g_cmd4()
call assert_true(!empty(b), 'failed `execute(g<)`')
endfunc
+" Test for gp gP go
fun! Test_normal36_g_cmd5()
new
call append(0, 'abcdefghijklmnopqrstuvwxyz')
@@ -2026,8 +2126,8 @@ fun! Test_normal36_g_cmd5()
bw!
endfunc
+" Test for gt and gT
fun! Test_normal37_g_cmd6()
- " basic test for gt and gT
tabnew 1.txt
tabnew 2.txt
tabnew 3.txt
@@ -2050,11 +2150,11 @@ fun! Test_normal37_g_cmd6()
tabclose
endfor
" clean up
- call assert_fails(':tabclose', 'E784')
+ call assert_fails(':tabclose', 'E784:')
endfunc
+" Test for <Home> and <C-Home> key
fun! Test_normal38_nvhome()
- " Test for <Home> and <C-Home> key
new
call setline(1, range(10))
$
@@ -2069,11 +2169,14 @@ fun! Test_normal38_nvhome()
call assert_equal([0, 5, 1, 0, 1], getcurpos())
exe "norm! \<c-home>"
call assert_equal([0, 1, 1, 0, 1], getcurpos())
+ exe "norm! G\<c-kHome>"
+ call assert_equal([0, 1, 1, 0, 1], getcurpos())
" clean up
bw!
endfunc
+" Test for cw cW ce
fun! Test_normal39_cw()
" Test for cw and cW on whitespace
" and cpo+=w setting
@@ -2095,12 +2198,27 @@ fun! Test_normal39_cw()
norm! 2gg0cwfoo
call assert_equal('foo', getline('.'))
+ call setline(1, 'one; two')
+ call cursor(1, 1)
+ call feedkeys('cwvim', 'xt')
+ call assert_equal('vim; two', getline(1))
+ call feedkeys('0cWone', 'xt')
+ call assert_equal('one two', getline(1))
+ "When cursor is at the end of a word 'ce' will change until the end of the
+ "next word, but 'cw' will change only one character
+ call setline(1, 'one two')
+ call feedkeys('0ecwce', 'xt')
+ call assert_equal('once two', getline(1))
+ call setline(1, 'one two')
+ call feedkeys('0ecely', 'xt')
+ call assert_equal('only', getline(1))
+
" clean up
bw!
endfunc
+" Test for CTRL-\ commands
fun! Test_normal40_ctrl_bsl()
- " Basic test for CTRL-\ commands
new
call append(0, 'here are some words')
exe "norm! 1gg0a\<C-\>\<C-N>"
@@ -2124,9 +2242,8 @@ fun! Test_normal40_ctrl_bsl()
bw!
endfunc
+" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
fun! Test_normal41_insert_reg()
- " Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>=
- " in insert mode
new
set sts=2 sw=2 ts=8 tw=0
call append(0, ["aaa\tbbb\tccc", '', '', ''])
@@ -2144,8 +2261,8 @@ fun! Test_normal41_insert_reg()
bw!
endfunc
+" Test for Ctrl-D and Ctrl-U
func Test_normal42_halfpage()
- " basic test for Ctrl-D and Ctrl-U
call Setup_NewWindow()
call assert_equal(5, &scroll)
exe "norm! \<c-d>"
@@ -2181,8 +2298,8 @@ func Test_normal42_halfpage()
bw!
endfunc
+" Tests for text object aw
fun! Test_normal43_textobject1()
- " basic tests for text object aw
new
call append(0, ['foobar,eins,foobar', 'foo,zwei,foo '])
" diw
@@ -2212,8 +2329,8 @@ fun! Test_normal43_textobject1()
bw!
endfunc
+" Test for is and as text objects
func Test_normal44_textobjects2()
- " basic testing for is and as text objects
new
call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
" Test for dis - does not remove trailing whitespace
@@ -2504,6 +2621,18 @@ func Test_gr_command()
normal 4gro
call assert_equal('ooooecond line', getline(2))
let &cpo = save_cpo
+ normal! ggvegrx
+ call assert_equal('xxxxx line', getline(1))
+ exe "normal! gggr\<C-V>122"
+ call assert_equal('zxxxx line', getline(1))
+ set virtualedit=all
+ normal! 15|grl
+ call assert_equal('zxxxx line l', getline(1))
+ set virtualedit&
+ set nomodifiable
+ call assert_fails('normal! grx', 'E21:')
+ call assert_fails('normal! gRx', 'E21:')
+ set modifiable&
enew!
endfunc
@@ -2701,10 +2830,11 @@ fun! Test_normal_gdollar_cmd()
bw!
endfunc
-func Test_normal_gk()
+func Test_normal_gk_gj()
" needs 80 column new window
new
vert 80new
+ call assert_beeps('normal gk')
put =[repeat('x',90)..' {{{1', 'x {{{1']
norm! gk
" In a 80 column wide terminal the window will be only 78 char
@@ -2719,12 +2849,12 @@ func Test_normal_gk()
norm! gk
call assert_equal(95, col('.'))
call assert_equal(95, virtcol('.'))
- bw!
- bw!
+ %bw!
" needs 80 column new window
new
vert 80new
+ call assert_beeps('normal gj')
set number
set numberwidth=10
set cpoptions+=n
@@ -2743,9 +2873,14 @@ func Test_normal_gk()
call assert_equal(1, col('.'))
norm! gj
call assert_equal(76, col('.'))
- bw!
- bw!
- set cpoptions& number& numberwidth&
+ " When 'nowrap' is set, gk and gj behave like k and j
+ set nowrap
+ normal! gk
+ call assert_equal([2, 76], [line('.'), col('.')])
+ normal! gj
+ call assert_equal([3, 76], [line('.'), col('.')])
+ %bw!
+ set cpoptions& number& numberwidth& wrap&
endfunc
" Test for cursor movement with '-' in 'cpoptions'
@@ -2765,6 +2900,54 @@ func Test_normal_cpo_minus()
close!
endfunc
+" Test for using : to run a multi-line Ex command in operator pending mode
+func Test_normal_yank_with_excmd()
+ new
+ call setline(1, ['foo', 'bar', 'baz'])
+ let @a = ''
+ call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
+ call assert_equal('f', @a)
+ close!
+endfunc
+
+" Test for supplying a count to a normal-mode command across a cursorhold call
+func Test_normal_cursorhold_with_count()
+ throw 'Skipped: Nvim removed <CursorHold> key'
+ func s:cHold()
+ let g:cHold_Called += 1
+ endfunc
+ new
+ augroup normalcHoldTest
+ au!
+ au CursorHold <buffer> call s:cHold()
+ augroup END
+ let g:cHold_Called = 0
+ call feedkeys("3\<CursorHold>2ix", 'xt')
+ call assert_equal(1, g:cHold_Called)
+ call assert_equal(repeat('x', 32), getline(1))
+ augroup normalcHoldTest
+ au!
+ augroup END
+ au! normalcHoldTest
+ close!
+ delfunc s:cHold
+endfunc
+
+" Test for using a count and a command with CTRL-W
+func Test_wincmd_with_count()
+ call feedkeys("\<C-W>12n", 'xt')
+ call assert_equal(12, winheight(0))
+endfunc
+
+" Test for 'b', 'B' 'ge' and 'gE' commands
+func Test_backward_motion()
+ normal! gg
+ call assert_beeps('normal! b')
+ call assert_beeps('normal! B')
+ call assert_beeps('normal! gE')
+ call assert_beeps('normal! ge')
+endfunc
+
" Some commands like yy, cc, dd, >>, << and !! accept a count after
" typing the first letter of the command.
func Test_normal_count_after_operator()
diff --git a/src/nvim/testdir/test_spell.vim b/src/nvim/testdir/test_spell.vim
index d0895a48b4..5099818384 100644
--- a/src/nvim/testdir/test_spell.vim
+++ b/src/nvim/testdir/test_spell.vim
@@ -16,6 +16,8 @@ func TearDown()
call delete('Xtest.latin1.add.spl')
call delete('Xtest.latin1.spl')
call delete('Xtest.latin1.sug')
+ " set 'encoding' to clear the word list
+ set encoding=utf-8
endfunc
func Test_wrap_search()
@@ -131,6 +133,106 @@ foobar/?
set spell&
endfunc
+func Test_spell_file_missing()
+ let s:spell_file_missing = 0
+ augroup TestSpellFileMissing
+ autocmd! SpellFileMissing * let s:spell_file_missing += 1
+ augroup END
+
+ set spell spelllang=ab_cd
+ let messages = GetMessages()
+ " This message is not shown in Nvim because of #3027
+ " call assert_equal('Warning: Cannot find word list "ab.utf-8.spl" or "ab.ascii.spl"', messages[-1])
+ call assert_equal(1, s:spell_file_missing)
+
+ new XTestSpellFileMissing
+ augroup TestSpellFileMissing
+ autocmd! SpellFileMissing * bwipe
+ augroup END
+ call assert_fails('set spell spelllang=ab_cd', 'E797:')
+
+ " clean up
+ augroup TestSpellFileMissing
+ autocmd! SpellFileMissing
+ augroup END
+ augroup! TestSpellFileMissing
+ unlet s:spell_file_missing
+ set spell& spelllang&
+ %bwipe!
+endfunc
+
+func Test_spelldump()
+ " In case the spell file is not found avoid getting the download dialog, we
+ " would get stuck at the prompt.
+ let g:en_not_found = 0
+ augroup TestSpellFileMissing
+ au! SpellFileMissing * let g:en_not_found = 1
+ augroup END
+ set spell spelllang=en
+ spellrare! emacs
+ if g:en_not_found
+ call assert_report("Could not find English spell file")
+ else
+ spelldump
+
+ " Check assumption about region: 1: us, 2: au, 3: ca, 4: gb, 5: nz.
+ call assert_equal('/regions=usaucagbnz', getline(1))
+ call assert_notequal(0, search('^theater/1$')) " US English only.
+ call assert_notequal(0, search('^theatre/2345$')) " AU, CA, GB or NZ English.
+
+ call assert_notequal(0, search('^emacs/?$')) " ? for a rare word.
+ call assert_notequal(0, search('^the the/!$')) " ! for a wrong word.
+ endif
+
+ " clean up
+ unlet g:en_not_found
+ augroup TestSpellFileMissing
+ autocmd! SpellFileMissing
+ augroup END
+ augroup! TestSpellFileMissing
+ bwipe
+ set spell&
+endfunc
+
+func Test_spelldump_bang()
+ new
+ call setline(1, 'This is a sample sentence.')
+ redraw
+
+ " In case the spell file is not found avoid getting the download dialog, we
+ " would get stuck at the prompt.
+ let g:en_not_found = 0
+ augroup TestSpellFileMissing
+ au! SpellFileMissing * let g:en_not_found = 1
+ augroup END
+
+ set spell
+
+ if g:en_not_found
+ call assert_report("Could not find English spell file")
+ else
+ redraw
+ spelldump!
+
+ " :spelldump! includes the number of times a word was found while updating
+ " the screen.
+ " Common word count starts at 10, regular word count starts at 0.
+ call assert_notequal(0, search("^is\t11$")) " common word found once.
+ call assert_notequal(0, search("^the\t10$")) " common word never found.
+ call assert_notequal(0, search("^sample\t1$")) " regular word found once.
+ call assert_equal(0, search("^screen\t")) " regular word never found.
+ endif
+
+ " clean up
+ unlet g:en_not_found
+ augroup TestSpellFileMissing
+ autocmd! SpellFileMissing
+ augroup END
+ augroup! TestSpellFileMissing
+ %bwipe!
+ set spell&
+endfunc
+
func Test_spelllang_inv_region()
set spell spelllang=en_xx
let messages = GetMessages()
@@ -185,6 +287,18 @@ func Test_spellreall()
bwipe!
endfunc
+func Test_spell_dump_word_length()
+ " this was running over MAXWLEN
+ new
+ noremap 0 0a0zW0000000
+ sil! norm 0z=0
+ sil norm 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ sil! norm 0z=0
+
+ bwipe!
+ nunmap 0
+endfunc
+
" Test spellsuggest({word} [, {max} [, {capital}]])
func Test_spellsuggest()
" Verify suggestions are given even when spell checking is not enabled.
@@ -626,6 +740,10 @@ func Test_zz_sal_and_addition()
set spl=Xtest_ca.latin1.spl
call assert_equal("elequint", FirstSpellWord())
call assert_equal("elekwint", SecondSpellWord())
+
+ bwipe!
+ set spellfile=
+ set spl&
endfunc
func Test_spellfile_value()
@@ -709,9 +827,6 @@ func Test_spell_good_word_invalid()
sil! norm z=
bwipe!
- " clear the internal word list
- " set enc=latin1
- set enc=utf-8
endfunc
func LoadAffAndDic(aff_contents, dic_contents)
diff --git a/src/nvim/testdir/test_spell_utf8.vim b/src/nvim/testdir/test_spell_utf8.vim
index 3d240a8f2c..b7e3da37cb 100644
--- a/src/nvim/testdir/test_spell_utf8.vim
+++ b/src/nvim/testdir/test_spell_utf8.vim
@@ -13,6 +13,8 @@ func TearDown()
call delete('Xtest.utf-8.add.spl')
call delete('Xtest.utf-8.spl')
call delete('Xtest.utf-8.sug')
+ " set 'encoding' to clear the word list
+ set encoding=utf-8
endfunc
let g:test_data_aff1 = [
@@ -484,7 +486,6 @@ let g:test_data_aff_sal = [
\ ]
func LoadAffAndDic(aff_contents, dic_contents)
- set enc=utf-8
set spellfile=
call writefile(a:aff_contents, "Xtest.aff")
call writefile(a:dic_contents, "Xtest.dic")
@@ -760,6 +761,7 @@ func Test_spell_sal_and_addition()
call assert_equal("elequint", FirstSpellWord())
call assert_equal("elekwint", SecondSpellWord())
+ bwipe!
set spellfile=
set spl&
endfunc
@@ -803,10 +805,20 @@ func Test_word_index()
sil norm z=
bwipe!
- " clear the word list
- set enc=utf-8
call delete('Xtmpfile')
endfunc
+func Test_check_empty_line()
+ " This was using freed memory
+ enew
+ spellgood! fl
+ norm z=
+ norm yy
+ sil! norm P]svc
+ norm P]s
+
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_spellfile.vim b/src/nvim/testdir/test_spellfile.vim
index 0f48ab8f6f..f1331a9f2a 100644
--- a/src/nvim/testdir/test_spellfile.vim
+++ b/src/nvim/testdir/test_spellfile.vim
@@ -167,10 +167,604 @@ func Test_spell_normal()
call assert_equal([], glob('Xspellfile.add',0,1))
call assert_equal([], glob('Xspellfile2.add',0,1))
- set spellfile=
+ set spellfile= spell& spelllang&
bw!
endfunc
+" Spell file content test. Write 'content' to the spell file prefixed by the
+" spell file header and then enable spell checking. If 'emsg' is not empty,
+" then check for error.
+func Spellfile_Test(content, emsg)
+ let splfile = './Xtest/spell/Xtest.utf-8.spl'
+ " Add the spell file header and version (VIMspell2)
+ let v = 0z56494D7370656C6C32 + a:content
+ call writefile(v, splfile, 'b')
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ if a:emsg != ''
+ call assert_fails('set spell', a:emsg)
+ else
+ " FIXME: With some invalid spellfile contents, there are no error
+ " messages. So don't know how to check for the test result.
+ set spell
+ endif
+ set nospell spelllang& rtp&
+endfunc
+
+" Test for spell file format errors.
+" The spell file format is described in spellfile.c
+func Test_spellfile_format_error()
+ let save_rtp = &rtp
+ call mkdir('Xtest/spell', 'p')
+ let splfile = './Xtest/spell/Xtest.utf-8.spl'
+
+ " empty spell file
+ call writefile([], splfile)
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ call assert_fails('set spell', 'E757:')
+ set nospell spelllang&
+
+ " invalid file ID
+ call writefile(0z56494D, splfile, 'b')
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ call assert_fails('set spell', 'E757:')
+ set nospell spelllang&
+
+ " missing version number
+ call writefile(0z56494D7370656C6C, splfile, 'b')
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ call assert_fails('set spell', 'E771:')
+ set nospell spelllang&
+
+ " invalid version number
+ call writefile(0z56494D7370656C6C7A, splfile, 'b')
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ call assert_fails('set spell', 'E772:')
+ set nospell spelllang&
+
+ " no sections
+ call Spellfile_Test(0z, 'E758:')
+
+ " missing section length
+ call Spellfile_Test(0z00, 'E758:')
+
+ " unsupported required section
+ call Spellfile_Test(0z7A0100000004, 'E770:')
+
+ " unsupported not-required section
+ call Spellfile_Test(0z7A0000000004, 'E758:')
+
+ " SN_REGION: invalid number of region names
+ call Spellfile_Test(0z0000000000FF, 'E759:')
+
+ " SN_CHARFLAGS: missing <charflagslen> length
+ call Spellfile_Test(0z010000000004, 'E758:')
+
+ " SN_CHARFLAGS: invalid <charflagslen> length
+ call Spellfile_Test(0z0100000000010201, '')
+
+ " SN_CHARFLAGS: charflagslen == 0 and folcharslen != 0
+ call Spellfile_Test(0z01000000000400000101, 'E759:')
+
+ " SN_CHARFLAGS: missing <folcharslen> length
+ call Spellfile_Test(0z01000000000100, 'E758:')
+
+ " SN_PREFCOND: invalid prefcondcnt
+ call Spellfile_Test(0z03000000000100, 'E759:')
+
+ " SN_PREFCOND: invalid condlen
+ call Spellfile_Test(0z0300000000020001, 'E759:')
+
+ " SN_REP: invalid repcount
+ call Spellfile_Test(0z04000000000100, 'E758:')
+
+ " SN_REP: missing rep
+ call Spellfile_Test(0z0400000000020004, 'E758:')
+
+ " SN_REP: zero repfromlen
+ call Spellfile_Test(0z040000000003000100, 'E759:')
+
+ " SN_REP: invalid reptolen
+ call Spellfile_Test(0z0400000000050001014101, '')
+
+ " SN_REP: zero reptolen
+ call Spellfile_Test(0z0400000000050001014100, 'E759:')
+
+ " SN_SAL: missing salcount
+ call Spellfile_Test(0z05000000000102, 'E758:')
+
+ " SN_SAL: missing salfromlen
+ call Spellfile_Test(0z050000000003080001, 'E758:')
+
+ " SN_SAL: missing saltolen
+ call Spellfile_Test(0z0500000000050400010161, 'E758:')
+
+ " SN_WORDS: non-NUL terminated word
+ call Spellfile_Test(0z0D000000000376696D, 'E758:')
+
+ " SN_WORDS: very long word
+ let v = eval('0z0D000000012C' .. repeat('41', 300))
+ call Spellfile_Test(v, 'E759:')
+
+ " SN_SOFO: missing sofofromlen
+ call Spellfile_Test(0z06000000000100, 'E758:')
+
+ " SN_SOFO: missing sofotolen
+ call Spellfile_Test(0z06000000000400016100, 'E758:')
+
+ " SN_SOFO: missing sofoto
+ call Spellfile_Test(0z0600000000050001610000, 'E759:')
+
+ " SN_COMPOUND: compmax is less than 2
+ call Spellfile_Test(0z08000000000101, 'E759:')
+
+ " SN_COMPOUND: missing compsylmax and other options
+ call Spellfile_Test(0z0800000000020401, 'E759:')
+
+ " SN_COMPOUND: missing compoptions
+ call Spellfile_Test(0z080000000005040101, 'E758:')
+
+ " SN_INFO: missing info
+ call Spellfile_Test(0z0F0000000005040101, '')
+
+ " SN_MIDWORD: missing midword
+ call Spellfile_Test(0z0200000000040102, '')
+
+ " SN_MAP: missing midword
+ call Spellfile_Test(0z0700000000040102, '')
+
+ " SN_SYLLABLE: missing SYLLABLE item
+ call Spellfile_Test(0z0900000000040102, '')
+
+ " SN_SYLLABLE: More than SY_MAXLEN size
+ let v = eval('0z090000000022612F' .. repeat('62', 32))
+ call Spellfile_Test(v, '')
+
+ " LWORDTREE: missing
+ call Spellfile_Test(0zFF, 'E758:')
+
+ " LWORDTREE: missing tree node
+ call Spellfile_Test(0zFF00000004, 'E758:')
+
+ " LWORDTREE: missing tree node value
+ call Spellfile_Test(0zFF0000000402, 'E758:')
+
+ " KWORDTREE: missing tree node
+ call Spellfile_Test(0zFF0000000000000004, 'E758:')
+
+ " PREFIXTREE: missing tree node
+ call Spellfile_Test(0zFF000000000000000000000004, 'E758:')
+
+ let &rtp = save_rtp
+ call delete('Xtest', 'rf')
+endfunc
+
+" Test for format errors in suggest file
+func Test_sugfile_format_error()
+ let save_rtp = &rtp
+ call mkdir('Xtest/spell', 'p')
+ let splfile = './Xtest/spell/Xtest.utf-8.spl'
+ let sugfile = './Xtest/spell/Xtest.utf-8.sug'
+
+ " create an empty spell file with a suggest timestamp
+ call writefile(0z56494D7370656C6C320B00000000080000000000000044FF000000000000000000000000, splfile, 'b')
+
+ " 'encoding' is set before each test to clear the previously loaded suggest
+ " file from memory.
+
+ " empty suggest file
+ set encoding=utf-8
+ call writefile([], sugfile)
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ set spell
+ call assert_fails("let s = spellsuggest('abc')", 'E778:')
+ set nospell spelllang&
+
+ " zero suggest version
+ set encoding=utf-8
+ call writefile(0z56494D73756700, sugfile)
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ set spell
+ call assert_fails("let s = spellsuggest('abc')", 'E779:')
+ set nospell spelllang&
+
+ " unsupported suggest version
+ set encoding=utf-8
+ call writefile(0z56494D7375671F, sugfile)
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ set spell
+ call assert_fails("let s = spellsuggest('abc')", 'E780:')
+ set nospell spelllang&
+
+ " missing suggest timestamp
+ set encoding=utf-8
+ call writefile(0z56494D73756701, sugfile)
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ set spell
+ call assert_fails("let s = spellsuggest('abc')", 'E781:')
+ set nospell spelllang&
+
+ " incorrect suggest timestamp
+ set encoding=utf-8
+ call writefile(0z56494D7375670100000000000000FF, sugfile)
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ set spell
+ call assert_fails("let s = spellsuggest('abc')", 'E781:')
+ set nospell spelllang&
+
+ " missing suggest wordtree
+ set encoding=utf-8
+ call writefile(0z56494D737567010000000000000044, sugfile)
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ set spell
+ call assert_fails("let s = spellsuggest('abc')", 'E782:')
+ set nospell spelllang&
+
+ " invalid suggest word count in SUGTABLE
+ set encoding=utf-8
+ call writefile(0z56494D7375670100000000000000440000000022, sugfile)
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ set spell
+ call assert_fails("let s = spellsuggest('abc')", 'E782:')
+ set nospell spelllang&
+
+ " missing sugline in SUGTABLE
+ set encoding=utf-8
+ call writefile(0z56494D7375670100000000000000440000000000000005, sugfile)
+ set runtimepath=./Xtest
+ set spelllang=Xtest
+ set spell
+ call assert_fails("let s = spellsuggest('abc')", 'E782:')
+ set nospell spelllang&
+
+ let &rtp = save_rtp
+ call delete('Xtest', 'rf')
+endfunc
+
+" Test for using :mkspell to create a spell file from a list of words
+func Test_wordlist_dic()
+ " duplicate encoding
+ let lines =<< trim [END]
+ # This is an example word list
+
+ /encoding=latin1
+ /encoding=latin1
+ example
+ [END]
+ call writefile(lines, 'Xwordlist.dic')
+ let output = execute('mkspell Xwordlist.spl Xwordlist.dic')
+ call assert_match('Duplicate /encoding= line ignored in Xwordlist.dic line 4: /encoding=latin1', output)
+
+ " multiple encoding for a word
+ let lines =<< trim [END]
+ example
+ /encoding=latin1
+ example
+ [END]
+ call writefile(lines, 'Xwordlist.dic')
+ let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
+ call assert_match('/encoding= line after word ignored in Xwordlist.dic line 2: /encoding=latin1', output)
+
+ " unsupported encoding for a word
+ let lines =<< trim [END]
+ /encoding=Xtest
+ example
+ [END]
+ call writefile(lines, 'Xwordlist.dic')
+ let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
+ call assert_match('Conversion in Xwordlist.dic not supported: from Xtest to utf-8', output)
+
+ " duplicate region
+ let lines =<< trim [END]
+ /regions=usca
+ /regions=usca
+ example
+ [END]
+ call writefile(lines, 'Xwordlist.dic')
+ let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
+ call assert_match('Duplicate /regions= line ignored in Xwordlist.dic line 2: regions=usca', output)
+
+ " maximum regions
+ let lines =<< trim [END]
+ /regions=uscauscauscauscausca
+ example
+ [END]
+ call writefile(lines, 'Xwordlist.dic')
+ let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
+ call assert_match('Too many regions in Xwordlist.dic line 1: uscauscauscauscausca', output)
+
+ " unsupported '/' value
+ let lines =<< trim [END]
+ /test=abc
+ example
+ [END]
+ call writefile(lines, 'Xwordlist.dic')
+ let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
+ call assert_match('/ line ignored in Xwordlist.dic line 1: /test=abc', output)
+
+ " unsupported flag
+ let lines =<< trim [END]
+ example/+
+ [END]
+ call writefile(lines, 'Xwordlist.dic')
+ let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
+ call assert_match('Unrecognized flags in Xwordlist.dic line 1: +', output)
+
+ " non-ascii word
+ call writefile(["ʀʀ"], 'Xwordlist.dic')
+ let output = execute('mkspell! -ascii Xwordlist.spl Xwordlist.dic')
+ call assert_match('Ignored 1 words with non-ASCII characters', output)
+
+ call delete('Xwordlist.spl')
+ call delete('Xwordlist.dic')
+endfunc
+
+" Test for the :mkspell command
+func Test_mkspell()
+ call assert_fails('mkspell Xtest_us.spl', 'E751:')
+ call assert_fails('mkspell a b c d e f g h i j k', 'E754:')
+
+ call writefile([], 'Xtest.spl')
+ call writefile([], 'Xtest.dic')
+ call assert_fails('mkspell Xtest.spl Xtest.dic', 'E13:')
+ call delete('Xtest.spl')
+ call delete('Xtest.dic')
+
+ call mkdir('Xtest.spl')
+ call assert_fails('mkspell! Xtest.spl Xtest.dic', 'E17:')
+ call delete('Xtest.spl', 'rf')
+
+ call assert_fails('mkspell en en_US abc_xyz', 'E755:')
+endfunc
+
+" Tests for :mkspell with a .dic and .aff file
+func Test_aff_file_format_error()
+ " FIXME: For some reason, the :mkspell command below doesn't fail on the
+ " MS-Windows CI build. Disable this test on MS-Windows for now.
+ CheckNotMSWindows
+
+ " No word count in .dic file
+ call writefile([], 'Xtest.dic')
+ call writefile([], 'Xtest.aff')
+ call assert_fails('mkspell! Xtest.spl Xtest', 'E760:')
+
+ " create a .dic file for the tests below
+ call writefile(['1', 'work'], 'Xtest.dic')
+
+ " Invalid encoding in .aff file
+ call writefile(['# comment', 'SET Xinvalidencoding'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Conversion in Xtest.aff not supported: from xinvalidencoding', output)
+
+ " Invalid flag in .aff file
+ call writefile(['FLAG xxx'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Invalid value for FLAG in Xtest.aff line 1: xxx', output)
+
+ " set FLAGS after using flag for an affix
+ call writefile(['SFX L Y 1', 'SFX L 0 re [^x]', 'FLAG long'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('FLAG after using flags in Xtest.aff line 3: long', output)
+
+ " INFO in affix file
+ let save_encoding = &encoding
+ call mkdir('Xrtp/spell', 'p')
+ call writefile(['1', 'work'], 'Xrtp/spell/Xtest.dic')
+ call writefile(['NAME klingon', 'VERSION 1.4', 'AUTHOR Spock'],
+ \ 'Xrtp/spell/Xtest.aff')
+ silent mkspell! Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest
+ let save_rtp = &rtp
+ set runtimepath=./Xrtp
+ set spelllang=Xtest
+ set spell
+ let output = split(execute('spellinfo'), "\n")
+ call assert_equal("NAME klingon", output[1])
+ call assert_equal("VERSION 1.4", output[2])
+ call assert_equal("AUTHOR Spock", output[3])
+ let &rtp = save_rtp
+ call delete('Xrtp', 'rf')
+ set spell& spelllang& spellfile&
+ %bw!
+ " 'encoding' must be set again to clear the spell file in memory
+ let &encoding = save_encoding
+
+ " COMPOUNDFORBIDFLAG flag after PFX in an affix file
+ call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDFLAG c', 'COMPOUNDFORBIDFLAG x'],
+ \ 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in Xtest.aff line 4', output)
+
+ " COMPOUNDPERMITFLAG flag after PFX in an affix file
+ call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDPERMITFLAG c'],
+ \ 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in Xtest.aff line 3', output)
+
+ " Wrong COMPOUNDRULES flag value in an affix file
+ call writefile(['COMPOUNDRULES a'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Wrong COMPOUNDRULES value in Xtest.aff line 1: a', output)
+
+ " Wrong COMPOUNDWORDMAX flag value in an affix file
+ call writefile(['COMPOUNDWORDMAX 0'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Wrong COMPOUNDWORDMAX value in Xtest.aff line 1: 0', output)
+
+ " Wrong COMPOUNDMIN flag value in an affix file
+ call writefile(['COMPOUNDMIN 0'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Wrong COMPOUNDMIN value in Xtest.aff line 1: 0', output)
+
+ " Wrong COMPOUNDSYLMAX flag value in an affix file
+ call writefile(['COMPOUNDSYLMAX 0'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Wrong COMPOUNDSYLMAX value in Xtest.aff line 1: 0', output)
+
+ " Wrong CHECKCOMPOUNDPATTERN flag value in an affix file
+ call writefile(['CHECKCOMPOUNDPATTERN 0'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Wrong CHECKCOMPOUNDPATTERN value in Xtest.aff line 1: 0', output)
+
+ " Duplicate affix entry in an affix file
+ call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L Y 1', 'PFX L 0 re x'],
+ \ 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Duplicate affix in Xtest.aff line 3: L', output)
+
+ " Duplicate affix entry in an affix file
+ call writefile(['PFX L Y 1', 'PFX L Y 1'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Unrecognized or duplicate item in Xtest.aff line 2: PFX', output)
+
+ " Different combining flags in an affix file
+ call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L N 1'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Different combining flag in continued affix block in Xtest.aff line 3', output)
+
+ " Try to reuse a affix used for BAD flag
+ call writefile(['BAD x', 'PFX x Y 1', 'PFX x 0 re x'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in Xtest.aff line 2: x', output)
+
+ " Trailing characters in an affix entry
+ call writefile(['PFX L Y 1 Test', 'PFX L 0 re x'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Trailing text in Xtest.aff line 1: Test', output)
+
+ " Trailing characters in an affix entry
+ call writefile(['PFX L Y 1', 'PFX L 0 re x Test'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Trailing text in Xtest.aff line 2: Test', output)
+
+ " Incorrect combine flag in an affix entry
+ call writefile(['PFX L X 1', 'PFX L 0 re x'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Expected Y or N in Xtest.aff line 1: X', output)
+
+ " Invalid count for REP item
+ call writefile(['REP a'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Expected REP(SAL) count in Xtest.aff line 1', output)
+
+ " Trailing characters in REP item
+ call writefile(['REP 1', 'REP f ph test'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Trailing text in Xtest.aff line 2: test', output)
+
+ " Invalid count for MAP item
+ call writefile(['MAP a'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Expected MAP count in Xtest.aff line 1', output)
+
+ " Duplicate character in a MAP item
+ call writefile(['MAP 2', 'MAP xx', 'MAP yy'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Duplicate character in MAP in Xtest.aff line 2', output)
+
+ " Use COMPOUNDSYLMAX without SYLLABLE
+ call writefile(['COMPOUNDSYLMAX 2'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('COMPOUNDSYLMAX used without SYLLABLE', output)
+
+ " Missing SOFOTO
+ call writefile(['SOFOFROM abcdef'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Missing SOFOTO line in Xtest.aff', output)
+
+ " Length of SOFOFROM and SOFOTO differ
+ call writefile(['SOFOFROM abcde', 'SOFOTO ABCD'], 'Xtest.aff')
+ call assert_fails('mkspell! Xtest.spl Xtest', 'E759:')
+
+ " Both SAL and SOFOFROM/SOFOTO items
+ call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Both SAL and SOFO lines in Xtest.aff', output)
+
+ " use an alphabet flag when FLAG is num
+ call writefile(['FLAG num', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Flag is not a number in Xtest.aff line 2: L', output)
+
+ " use number and alphabet flag when FLAG is num
+ call writefile(['FLAG num', 'SFX 4f Y 1', 'SFX 4f 0 re [^x]'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Affix name too long in Xtest.aff line 2: 4f', output)
+
+ " use a single character flag when FLAG is long
+ call writefile(['FLAG long', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('Illegal flag in Xtest.aff line 2: L', output)
+
+ " duplicate word in the .dic file
+ call writefile(['2', 'good', 'good', 'good'], 'Xtest.dic')
+ call writefile(['NAME vim'], 'Xtest.aff')
+ let output = execute('mkspell! Xtest.spl Xtest')
+ call assert_match('First duplicate word in Xtest.dic line 3: good', output)
+ call assert_match('2 duplicate word(s) in Xtest.dic', output)
+
+ call delete('Xtest.dic')
+ call delete('Xtest.aff')
+ call delete('Xtest.spl')
+ call delete('Xtest.sug')
+endfunc
+
+func Test_spell_add_word()
+ set spellfile=
+ call assert_fails('spellgood abc', 'E764:')
+
+ set spellfile=Xtest.utf-8.add
+ call assert_fails('2spellgood abc', 'E765:')
+
+ edit Xtest.utf-8.add
+ call setline(1, 'sample')
+ call assert_fails('spellgood abc', 'E139:')
+ set spellfile&
+ %bw!
+endfunc
+
+" When 'spellfile' is not set, adding a new good word will automatically set
+" the 'spellfile'
+func Test_init_spellfile()
+ let save_rtp = &rtp
+ let save_encoding = &encoding
+ call mkdir('Xrtp/spell', 'p')
+ call writefile(['vim'], 'Xrtp/spell/Xtest.dic')
+ silent mkspell Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest.dic
+ set runtimepath=./Xrtp
+ set spelllang=Xtest
+ set spell
+ silent spellgood abc
+ call assert_equal('./Xrtp/spell/Xtest.utf-8.add', &spellfile)
+ call assert_equal(['abc'], readfile('Xrtp/spell/Xtest.utf-8.add'))
+ call assert_true(filereadable('Xrtp/spell/Xtest.utf-8.spl'))
+ set spell& spelllang& spellfile&
+ call delete('Xrtp', 'rf')
+ let &encoding = save_encoding
+ let &rtp = save_rtp
+ %bw!
+endfunc
+
+" Test for the 'mkspellmem' option
+func Test_mkspellmem_opt()
+ call assert_fails('set mkspellmem=1000', 'E474:')
+ call assert_fails('set mkspellmem=1000,', 'E474:')
+ call assert_fails('set mkspellmem=1000,50', 'E474:')
+ call assert_fails('set mkspellmem=1000,50,', 'E474:')
+ call assert_fails('set mkspellmem=1000,50,10,', 'E474:')
+ call assert_fails('set mkspellmem=1000,50,0', 'E474:')
+endfunc
+
" Test CHECKCOMPOUNDPATTERN (see :help spell-CHECKCOMPOUNDPATTERN)
func Test_spellfile_CHECKCOMPOUNDPATTERN()
call writefile(['4',
diff --git a/src/nvim/testdir/test_substitute.vim b/src/nvim/testdir/test_substitute.vim
index 8483435062..bd44079882 100644
--- a/src/nvim/testdir/test_substitute.vim
+++ b/src/nvim/testdir/test_substitute.vim
@@ -140,7 +140,7 @@ func Test_substitute_repeat()
" This caused an invalid memory access.
split Xfile
s/^/x
- call feedkeys("gQsc\<CR>y", 'tx')
+ call feedkeys("Qsc\<CR>y", 'tx')
bwipe!
endfunc
diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim
index 09eed4e10d..5c67efb831 100644
--- a/src/nvim/testdir/test_timers.vim
+++ b/src/nvim/testdir/test_timers.vim
@@ -279,7 +279,7 @@ func Test_ex_mode()
endfunc
let timer = timer_start(40, function('g:Foo'), {'repeat':-1})
" This used to throw error E749.
- exe "normal gQsleep 100m\rvi\r"
+ exe "normal Qsleep 100m\rvi\r"
call timer_stop(timer)
endfunc
diff --git a/src/nvim/testdir/test_virtualedit.vim b/src/nvim/testdir/test_virtualedit.vim
index 250b896532..522ca17675 100644
--- a/src/nvim/testdir/test_virtualedit.vim
+++ b/src/nvim/testdir/test_virtualedit.vim
@@ -301,6 +301,9 @@ func Test_replace_on_tab()
call append(0, "'r'\t")
normal gg^5lrxAy
call assert_equal("'r' x y", getline(1))
+ call setline(1, 'aaaaaaaaaaaa')
+ exe "normal! gg2lgR\<Tab>"
+ call assert_equal("aa\taaaa", getline(1))
bwipe!
set virtualedit=
endfunc
diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim
index 492750fa66..349c4fde50 100644
--- a/src/nvim/testdir/test_visual.vim
+++ b/src/nvim/testdir/test_visual.vim
@@ -700,7 +700,6 @@ func Test_linewise_select_mode()
exe "normal GkkgH\<Del>"
call assert_equal(['', 'b', 'c'], getline(1, '$'))
-
" linewise select mode: delete middle two lines
call deletebufline('', 1, '$')
call append('$', ['a', 'b', 'c'])
@@ -722,6 +721,15 @@ func Test_linewise_select_mode()
bwipe!
endfunc
+" Test for blockwise select mode (g CTRL-H)
+func Test_blockwise_select_mode()
+ new
+ call setline(1, ['foo', 'bar'])
+ call feedkeys("g\<BS>\<Right>\<Down>mm", 'xt')
+ call assert_equal(['mmo', 'mmr'], getline(1, '$'))
+ close!
+endfunc
+
func Test_visual_mode_put()
new
@@ -1105,6 +1113,73 @@ func Test_block_insert_replace_tabs()
bwipe!
endfunc
+" Test for * register in :
+func Test_star_register()
+ call assert_fails('*bfirst', 'E16:')
+ new
+ call setline(1, ['foo', 'bar', 'baz', 'qux'])
+ exe "normal jVj\<ESC>"
+ *yank r
+ call assert_equal("bar\nbaz\n", @r)
+
+ delmarks < >
+ call assert_fails('*yank', 'E20:')
+ close!
+endfunc
+
+" Test for using visual mode maps in select mode
+func Test_select_mode_map()
+ new
+ vmap <buffer> <F2> 3l
+ call setline(1, 'Test line')
+ call feedkeys("gh\<F2>map", 'xt')
+ call assert_equal('map line', getline(1))
+
+ vmap <buffer> <F2> ygV
+ call feedkeys("0gh\<Right>\<Right>\<F2>cwabc", 'xt')
+ call assert_equal('abc line', getline(1))
+
+ vmap <buffer> <F2> :<C-U>let v=100<CR>
+ call feedkeys("gggh\<Right>\<Right>\<F2>foo", 'xt')
+ call assert_equal('foo line', getline(1))
+
+ " reselect the select mode using gv from a visual mode map
+ vmap <buffer> <F2> gv
+ set selectmode=cmd
+ call feedkeys("0gh\<F2>map", 'xt')
+ call assert_equal('map line', getline(1))
+ set selectmode&
+
+ close!
+endfunc
+
+" Test for changing text in visual mode with 'exclusive' selection
+func Test_exclusive_selection()
+ new
+ call setline(1, ['one', 'two'])
+ set selection=exclusive
+ call feedkeys("vwcabc", 'xt')
+ call assert_equal('abctwo', getline(1))
+ call setline(1, ["\tone"])
+ set virtualedit=all
+ call feedkeys('0v2lcl', 'xt')
+ call assert_equal('l one', getline(1))
+ set virtualedit&
+ set selection&
+ close!
+endfunc
+
+" Test for starting visual mode with a count
+" This test should be run withou any previous visual modes. So this should be
+" run as a first test.
+func Test_AAA_start_visual_mode_with_count()
+ new
+ call setline(1, ['aaaaaaa', 'aaaaaaa', 'aaaaaaa', 'aaaaaaa'])
+ normal! gg2Vy
+ call assert_equal("aaaaaaa\naaaaaaa\n", @")
+ close!
+endfunc
+
func Test_visual_put_in_block()
new
call setline(1, ['xxxx', 'y∞yy', 'zzzz'])