diff options
| author | Eliseo Martínez <eliseomarmol@gmail.com> | 2014-05-12 02:25:17 +0200 |
|---|---|---|
| committer | Eliseo Martínez <eliseomarmol@gmail.com> | 2014-05-15 20:46:01 +0200 |
| commit | da51dc9cf202772f60bd2da975dbef257bd9237c (patch) | |
| tree | 5c16b93238a153f55634e9323077f30c8133970c /src/nvim/testdir | |
| parent | ffe61e5ba1721340ca51d56bae3ddaca415fb5bc (diff) | |
| download | rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.tar.gz rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.tar.bz2 rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.zip | |
Introduce nvim namespace: Move files.
Move files from src/ to src/nvim/.
- src/nvim/ becomes the new root dir for nvim executable sources.
- src/libnvim/ is planned to become root dir of the neovim library.
Diffstat (limited to 'src/nvim/testdir')
228 files changed, 34165 insertions, 0 deletions
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile new file mode 100644 index 0000000000..f720d7a2b4 --- /dev/null +++ b/src/nvim/testdir/Makefile @@ -0,0 +1,156 @@ +# +# Makefile to run all tests for Vim +# + +export SHELL := sh + +VIMPROG := ../../build/bin/nvim + +SCRIPTS := test_eval.out \ + test1.out test2.out test3.out test4.out test5.out \ + test6.out test7.out test8.out test9.out test10.out \ + test11.out test12.out test13.out test14.out test15.out \ + test17.out test18.out test19.out test20.out \ + test21.out test22.out test23.out test24.out test25.out \ + test26.out test27.out test28.out test29.out test30.out \ + test31.out test32.out test33.out test34.out test35.out \ + test36.out test37.out test38.out test39.out test40.out \ + test41.out test42.out test43.out test44.out test45.out \ + test46.out test47.out test48.out test49.out \ + test51.out test52.out test53.out test54.out test55.out \ + test56.out test57.out test58.out test59.out test60.out \ + test61.out test62.out test63.out test64.out test65.out \ + test66.out test67.out test68.out test69.out test70.out \ + test71.out test72.out test73.out test74.out test75.out \ + test76.out test77.out test78.out test79.out test80.out \ + test81.out test82.out test83.out test84.out test85.out \ + test86.out test87.out test88.out test89.out test90.out \ + test91.out test92.out test93.out test94.out test95.out \ + test96.out test97.out test98.out test99.out test100.out \ + test101.out test102.out test103.out test104.out test105.out \ + test106.out + +SCRIPTS_GUI := test16.out + + +ifdef VALGRIND_GDB + VGDB := --vgdb=yes \ + --vgdb-error=0 +endif + +ifdef USE_VALGRIND + VALGRIND_TOOL := --tool=memcheck \ + --leak-check=yes \ + --track-origins=yes +# VALGRIND_TOOL := exp-sgcheck + TOOL := valgrind -q \ + -q \ + $(VALGRIND_TOOL) \ + --suppressions=../../.valgrind.supp \ + --error-exitcode=123 \ + --log-file=valgrind.\%p.$* \ + $(VGDB) \ + --trace-children=yes +else + ifdef USE_GDB + TOOL = gdb --args + endif +endif + +ifdef TESTNUM + SCRIPTS := test$(TESTNUM).out +endif + +nongui: nolog $(SCRIPTS) report + +gui: nolog $(SCRIPTS) $(SCRIPTS_GUI) report + +.gdbinit: + echo 'set $$_exitcode = -1\nrun\nif $$_exitcode != -1\n quit\nend' > .gdbinit + +report: + @echo + @echo 'Test results:' + @/bin/sh -c "if test -f test.log; then \ + cat test.log; \ + echo TEST FAILURE; \ + exit 1; \ + else \ + echo ALL DONE; \ + fi" + +$(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG) + +RM_ON_RUN := test.out X* viminfo +RM_ON_START := tiny.vim small.vim mbyte.vim mzscheme.vim lua.vim test.ok +RUN_VIM := $(TOOL) $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in + +clean: + -rm -rf *.out \ + *.failed \ + *.rej \ + *.orig \ + test.log \ + $(RM_ON_RUN) \ + $(RM_ON_START) \ + valgrind.* \ + .*.swp \ + .*.swo + +test1.out: .gdbinit test1.in + -rm -rf $*.failed $(RM_ON_RUN) $(RM_ON_START) wrongtermsize + $(RUN_VIM) $*.in + @/bin/sh -c "if test -e wrongtermsize; then \ + echo; \ + echo test1 FAILED - terminal size must be 80x24 or larger; \ + echo; exit 1; \ + elif diff test.out $*.ok; then \ + mv -f test.out $*.out; \ + else \ + echo; \ + echo test1 FAILED - Something basic is wrong; \ + echo; \ + exit 1; \ + fi" + -rm -rf X* viminfo + +%.out: %.in .gdbinit + -rm -rf $*.failed test.ok $(RM_ON_RUN) + cp $*.ok test.ok + # Sleep a moment to avoid that the xterm title is messed up. + # 200 msec is sufficient, but only modern sleep supports a fraction of + # a second, fall back to a second if it fails. + @-/bin/sh -c "sleep .2 > /dev/null 2>&1 || sleep 1" + $(RUN_VIM) $*.in + + # For flaky tests retry one time. + @/bin/sh -c "if test -f test.out -a $* = test61; then \ + if diff test.out $*.ok; then \ + echo flaky test ok first time; \ + else rm -rf $*.failed $(RM_ON_RUN); \ + $(RUN_VIM) $*.in; \ + fi; \ + fi" + + # Check if the test.out file matches test.ok. + @/bin/sh -c "if test -f test.out; then \ + if diff test.out $*.ok; then \ + mv -f test.out $*.out; \ + else \ + echo $* FAILED >> test.log; \ + mv -f test.out $*.failed; \ + fi; \ + else \ + echo $* NO OUTPUT >>test.log; \ + fi" + @/bin/sh -c "if test -f valgrind; then \ + mv -f valgrind valgrind.$*; \ + fi" + -rm -rf X* test.ok viminfo + +test49.out: test49.vim + +test60.out: test60.vim + +nolog: + -rm -f test.log diff --git a/src/nvim/testdir/dotest.in b/src/nvim/testdir/dotest.in new file mode 100644 index 0000000000..b2a0e1a68e --- /dev/null +++ b/src/nvim/testdir/dotest.in @@ -0,0 +1,3 @@ +:set cp +:map dotest /^STARTTEST
j:set ff=unix cpo-=A
:.,/ENDTEST/-1w! Xdotest
:set ff& cpo+=A
nj0:so! Xdotest
dotest +dotest diff --git a/src/nvim/testdir/sautest/autoload/Test104.vim b/src/nvim/testdir/sautest/autoload/Test104.vim new file mode 100644 index 0000000000..d1e0e17a3b --- /dev/null +++ b/src/nvim/testdir/sautest/autoload/Test104.vim @@ -0,0 +1 @@ +let Test104#numvar = 123 diff --git a/src/nvim/testdir/sautest/autoload/footest.vim b/src/nvim/testdir/sautest/autoload/footest.vim new file mode 100644 index 0000000000..f467bc376d --- /dev/null +++ b/src/nvim/testdir/sautest/autoload/footest.vim @@ -0,0 +1,5 @@ +" Autoload script used by test55 and test60 +let footest#x = 1 +func footest#F() + return 0 +endfunc diff --git a/src/nvim/testdir/test1.in b/src/nvim/testdir/test1.in new file mode 100644 index 0000000000..735d539673 --- /dev/null +++ b/src/nvim/testdir/test1.in @@ -0,0 +1,57 @@ + +First a simple test to check if the test script works. + +If Vim was not compiled with the +eval feature, the small.vim script will be +set to copy the test.ok file to test.out, so that it looks like the test +succeeded. Otherwise an empty small.vim is written. small.vim is sourced by +tests that require the +eval feature or other features that are missing in the +small version. + +If Vim was not compiled with the +windows feature, the tiny.vim script will be +set like small.vim above. tiny.vim is sourced by tests that require the ++windows feature or other features that are missing in the tiny version. + +If Vim was not compiled with the +multi_byte feature, the mbyte.vim script will +be set like small.vim above. mbyte.vim is sourced by tests that require the ++multi_byte feature. +Similar logic is applied to the +mzscheme feature, using mzscheme.vim. +Similar logic is applied to the +lua feature, using lua.vim. + +STARTTEST +:" If columns or lines are too small, create wrongtermsize. +:" (Some tests will fail. When columns and/or lines are small) +:if &lines < 24 || &columns < 80 | sp another | w! wrongtermsize | qa! | endif +:" +:" Write a single line to test.out to check if testing works at all. +:%d +athis is a test:w! test.out +:" Create small.vim and tiny.vim empty, create mbyte.vim to skip the test. +0D:w! small.vim +:w! tiny.vim +ae! test.ok +w! test.out +qa! +:w! mbyte.vim +:w! mzscheme.vim +:w! lua.vim +:" +:" If +multi_byte feature supported, make mbyte.vim empty. +:if has("multi_byte") | sp another | w! mbyte.vim | q | endif +:" +:" If +mzscheme feature supported, make mzscheme.vim empty. +:if has("mzscheme") | sp another | w! mzscheme.vim | q | endif +:" +:" If +lua feature supported, make lua.vim empty. +:if has("lua") | sp another | w! lua.vim | q | endif +:" +:" If +eval feature supported quit here, leaving tiny.vim and small.vim empty. +:" Otherwise write small.vim to skip the test. +:if 1 | q! | endif +:w! small.vim +:" If +windows feature not supported :sp will fail and tiny.vim will be +:" written to skip the test. +:sp another +:wq! tiny.vim +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test1.ok b/src/nvim/testdir/test1.ok new file mode 100644 index 0000000000..90bfcb5106 --- /dev/null +++ b/src/nvim/testdir/test1.ok @@ -0,0 +1 @@ +this is a test diff --git a/src/nvim/testdir/test10.in b/src/nvim/testdir/test10.in new file mode 100644 index 0000000000..2d0d546606 --- /dev/null +++ b/src/nvim/testdir/test10.in @@ -0,0 +1,114 @@ +Test for 'errorformat'. This will fail if the quickfix feature was disabled. + +STARTTEST +:so small.vim +:" Also test a BOM is ignored. +:so mbyte.vim +:set encoding=utf-8 +:7/start of errorfile/,/end of errorfile/w! Xerrorfile1 +:7/start of errorfile/,/end of errorfile/-1w! Xerrorfile2 +:/start of testfile/,/end of testfile/w! Xtestfile +:set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m +:set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m +:cf Xerrorfile2 +:clast +:copen +:let a=w:quickfix_title +:wincmd p +lgR=a
+:cf Xerrorfile1 +grA +:cn +gRLINE 6, COL 19 +:cn +gRNO COLUMN SPECIFIED +:cn +gRAGAIN NO COLUMN +:cn +gRCOL 1 +:cn +gRCOL 2 +:cn +gRCOL 10 +:cn +gRVCOL 10 +:cn +grI +:cn +gR. SPACE POINTER +:cn +gR. DOT POINTER +:cn +gR. DASH POINTER +:cn +gR. TAB-SPACE POINTER +:clast +:cprev +:cprev +:wincmd w +:let a=w:quickfix_title +:wincmd p +lgR=a
+:w! test.out " Write contents of this file +:qa! +ENDTEST + +start of errorfile +"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set. +"Xtestfile", line 6 col 19; this is an error +gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c +Xtestfile:9: parse error before `asd' +make: *** [vim] Error 1 +in file "Xtestfile" linenr 10: there is an error + +2 returned +"Xtestfile", line 11 col 1; this is an error +"Xtestfile", line 12 col 2; this is another error +"Xtestfile", line 14:10; this is an error in column 10 +=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time +"Xtestfile", linenr 16: yet another problem +Error in "Xtestfile" at line 17: +x should be a dot + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17 + ^ +Error in "Xtestfile" at line 18: +x should be a dot + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18 +.............^ +Error in "Xtestfile" at line 19: +x should be a dot + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19 +--------------^ +Error in "Xtestfile" at line 20: +x should be a dot + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20 + ^ + +Does anyone know what is the problem and how to correction it? +"Xtestfile", line 21 col 9: What is the title of the quickfix window? +"Xtestfile", line 22 col 9: What is the title of the quickfix window? +end of errorfile + +start of testfile + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22 +end of testfile diff --git a/src/nvim/testdir/test10.ok b/src/nvim/testdir/test10.ok new file mode 100644 index 0000000000..76a02f40b4 --- /dev/null +++ b/src/nvim/testdir/test10.ok @@ -0,0 +1,23 @@ +start of testfile + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3 + xxxxxxxxxxAxxxxxxxxxxxxxxxxxxx line 4 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5 + xxxxxxxxxxxxxxxxxLINE 6, COL 19 line 6 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8 + NO COLUMN SPECIFIEDxxxxxxxxxxx line 9 + AGAIN NO COLUMNxxxxxxxxxxxxxxx line 10 +COL 1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11 + COL 2xxxxxxxxxxxxxxxxxxxxxxxxx line 12 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13 + xxxxxxxxCOL 10xxxxxxxxxxxxxxxx line 14 + xVCOL 10xxxxxxxxxxxxxxxxxxxxxx line 15 + Ixxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16 + xxxx. SPACE POINTERxxxxxxxxxxx line 17 + xxxxx. DOT POINTERxxxxxxxxxxxx line 18 + xxxxxx. DASH POINTERxxxxxxxxxx line 19 + xxxxxxx. TAB-SPACE POINTERxxxx line 20 + xxxxxxxx:cf Xerrorfile1xxxxxxx line 21 + xxxxxxxx:cf Xerrorfile2xxxxxxx line 22 +end of testfile diff --git a/src/nvim/testdir/test100.in b/src/nvim/testdir/test100.in new file mode 100644 index 0000000000..e42331946c --- /dev/null +++ b/src/nvim/testdir/test100.in @@ -0,0 +1,42 @@ +Tests for 'undolevel' setting being global-local + +STARTTEST +:so small.vim +:set nocompatible viminfo+=nviminfo ul=5 +:fu! FillBuffer() + :for i in range(1,13) + :put=i + :exe "setg ul=" . &g:ul + :endfor +:endfu +:fu! UndoLevel() + :redir @a | setglobal undolevels? | echon ' global' | setlocal undolevels? | echon ' local' |redir end + :$put a +:endfu +:new one +:0put ='ONE: expecting global undolevels: 5, local undolevels: -123456 (default)' +:call FillBuffer() +:call feedkeys(":earlier 10\n", 't') +:call UndoLevel() +:%w! test.out +:new two +:0put ='TWO: expecting global undolevels: 5, local undolevels: 2 (first) then 10 (afterwards)' +:setlocal ul=2 +:call FillBuffer() +:call feedkeys(":earlier 10\n", 't') +:call UndoLevel() +:setlocal ul=10 +:call UndoLevel() +:%w >> test.out +:wincmd p +:redir >>test.out | echo "global value shouldn't be changed and still be 5!" | echo 'ONE: expecting global undolevels: 5, local undolevels: -123456 (default)'|:setglobal undolevels? | echon ' global' | setlocal undolevels? | echon ' local' |echo "" |redir end +:new three +:setglobal ul=50 +:1put ='global value should be changed to 50' +:2put ='THREE: expecting global undolevels: 50, local undolevels: -123456 (default)' +:call UndoLevel() +:%w >> test.out +:"sleep 10 +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test100.ok b/src/nvim/testdir/test100.ok new file mode 100644 index 0000000000..95b318461c --- /dev/null +++ b/src/nvim/testdir/test100.ok @@ -0,0 +1,41 @@ +ONE: expecting global undolevels: 5, local undolevels: -123456 (default) +1 +2 +3 +4 +5 +6 +7 + + + undolevels=5 global + undolevels=-123456 local +TWO: expecting global undolevels: 5, local undolevels: 2 (first) then 10 (afterwards) +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 + + + undolevels=5 global + undolevels=2 local + + undolevels=5 global + undolevels=10 local + +global value shouldn't be changed and still be 5! +ONE: expecting global undolevels: 5, local undolevels: -123456 (default) + undolevels=5 global + undolevels=-123456 local + +global value should be changed to 50 +THREE: expecting global undolevels: 50, local undolevels: -123456 (default) + + undolevels=50 global + undolevels=-123456 local diff --git a/src/nvim/testdir/test101.in b/src/nvim/testdir/test101.in new file mode 100644 index 0000000000..04c934f2c5 --- /dev/null +++ b/src/nvim/testdir/test101.in @@ -0,0 +1,45 @@ +Test for v:hlsearch vim: set ft=vim : + +STARTTEST +:" Last abc: Q +:so small.vim +:new +:call setline(1, repeat(['aaa'], 10)) +:set hlsearch nolazyredraw +:let r=[] +:command -nargs=0 -bar AddR :call add(r, [screenattr(1, 1), v:hlsearch]) +/aaa +:AddR +:nohlsearch +:AddR +:let v:hlsearch=1 +:AddR +:let v:hlsearch=0 +:AddR +:set hlsearch +:AddR +:let v:hlsearch=0 +:AddR +n:AddR +:let v:hlsearch=0 +:AddR +/ +:AddR +:let r1=r[0][0] +:" I guess it is not guaranteed that screenattr outputs always the same character +:call map(r, 'v:val[1].":".(v:val[0]==r1?"highlighted":"not highlighted")') +:try +: let v:hlsearch=[] +:catch +: call add(r, matchstr(v:exception,'^Vim(let):E\d\+:')) +:endtry +:bwipeout! +:$put=r +:call garbagecollect(1) +:" +:/^start:/,$wq! test.out +:" vim: et ts=4 isk-=\: +:call getchar() +ENDTEST + +start: diff --git a/src/nvim/testdir/test101.ok b/src/nvim/testdir/test101.ok new file mode 100644 index 0000000000..3ed7436cf7 --- /dev/null +++ b/src/nvim/testdir/test101.ok @@ -0,0 +1,11 @@ +start: +1:highlighted +0:not highlighted +1:highlighted +0:not highlighted +1:highlighted +0:not highlighted +1:highlighted +0:not highlighted +1:highlighted +Vim(let):E706: diff --git a/src/nvim/testdir/test102.in b/src/nvim/testdir/test102.in new file mode 100644 index 0000000000..35e9f6c2cf --- /dev/null +++ b/src/nvim/testdir/test102.in @@ -0,0 +1,12 @@ +Test if fnameescape is correct for special chars like ! + +STARTTEST +:%d +:let fname = 'Xspa ce' +:try | exe "w! " . fnameescape(fname) | put='Space' | endtry +:let fname = 'Xemark!' +:try | exe "w! " . fnameescape(fname) | put='ExclamationMark' | endtry +:w! test.out +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test102.ok b/src/nvim/testdir/test102.ok new file mode 100644 index 0000000000..a25fea192c --- /dev/null +++ b/src/nvim/testdir/test102.ok @@ -0,0 +1,3 @@ + +Space +ExclamationMark diff --git a/src/nvim/testdir/test103.in b/src/nvim/testdir/test103.in new file mode 100644 index 0000000000..7c7591e3b9 --- /dev/null +++ b/src/nvim/testdir/test103.in @@ -0,0 +1,37 @@ +Test for visual mode not being reset causing E315 error. +STARTTEST +:so small.vim +:enew +:let g:msg="Everything's fine." +:function! TriggerTheProblem() +: " At this point there is no visual selection because :call reset it. +: " Let's restore the selection: +: normal gv +: '<,'>del _ +: try +: exe "normal \<Esc>" +: catch /^Vim\%((\a\+)\)\=:E315/ +: echom 'Snap! E315 error!' +: let g:msg='Snap! E315 error!' +: endtry +:endfunction +:enew +:setl buftype=nofile +:call append(line('$'), 'Delete this line.') +:" +:" +:" NOTE: this has to be done by a call to a function because executing :del the +:" ex-way will require the colon operator which resets the visual mode thus +:" preventing the problem: +:" +GV:call TriggerTheProblem() +:%del _ +:call append(line('$'), g:msg) +:w! test.out +:brewind +ENDTEST + +STARTTEST +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test103.ok b/src/nvim/testdir/test103.ok new file mode 100644 index 0000000000..9ea6dd6eea --- /dev/null +++ b/src/nvim/testdir/test103.ok @@ -0,0 +1,2 @@ + +Everything's fine. diff --git a/src/nvim/testdir/test104.in b/src/nvim/testdir/test104.in new file mode 100644 index 0000000000..fd847131e9 --- /dev/null +++ b/src/nvim/testdir/test104.in @@ -0,0 +1,30 @@ +Tests for :let. vim: set ft=vim ts=8 : + +STARTTEST +:so small.vim +:set runtimepath+=./sautest +:" Test to not autoload when assigning. It causes internal error. +:try +: let Test104#numvar = function('tr') +: $put ='OK: ' . string(Test104#numvar) +:catch +: $put ='FAIL: ' . v:exception +:endtry +:let a = 1 +:let b = 2 +:for letargs in ['a b', '{0 == 1 ? "a" : "b"}', '{0 == 1 ? "a" : "b"} a', 'a {0 == 1 ? "a" : "b"}'] +: try +: redir => messages +: execute 'let' letargs +: redir END +: $put ='OK:' +: $put =split(substitute(messages, '\n', '\0 ', 'g'), '\n') +: catch +: $put ='FAIL: ' . v:exception +: redir END +: endtry +:endfor +:/^Results/,$wq! test.out +ENDTEST + +Results of test104: diff --git a/src/nvim/testdir/test104.ok b/src/nvim/testdir/test104.ok new file mode 100644 index 0000000000..5fb20945c3 --- /dev/null +++ b/src/nvim/testdir/test104.ok @@ -0,0 +1,13 @@ +Results of test104: +OK: function('tr') +OK: + a #1 + b #2 +OK: + b #2 +OK: + b #2 + a #1 +OK: + a #1 + b #2 diff --git a/src/nvim/testdir/test105.in b/src/nvim/testdir/test105.in new file mode 100644 index 0000000000..284f3bf4eb --- /dev/null +++ b/src/nvim/testdir/test105.in @@ -0,0 +1,45 @@ +Test filename modifiers vim: set ft=vim : + +STARTTEST +:source small.vim +:%delete _ +:set shell=sh +:set shellslash +:let tab="\t" +:command -nargs=1 Put :let expr=<q-args> | $put =expr.tab.strtrans(string(eval(expr))) +:let $HOME=fnamemodify('.', ':p:h:h:h') +:Put fnamemodify('.', ':p' )[-1:] +:Put fnamemodify('.', ':p:h' )[-1:] +:Put fnamemodify('test.out', ':p' )[-1:] +:Put fnamemodify('test.out', ':.' ) +:Put fnamemodify('../testdir/a', ':.' ) +:Put fnamemodify('test.out', ':~' ) +:Put fnamemodify('../testdir/a', ':~' ) +:Put fnamemodify('../testdir/a', ':t' ) +:Put fnamemodify('.', ':p:t' ) +:Put fnamemodify('test.out', ':p:t' ) +:Put fnamemodify('test.out', ':p:e' ) +:Put fnamemodify('test.out', ':p:t:e' ) +:Put fnamemodify('abc.fb2.tar.gz', ':r' ) +:Put fnamemodify('abc.fb2.tar.gz', ':r:r' ) +:Put fnamemodify('abc.fb2.tar.gz', ':r:r:r' ) +:Put substitute(fnamemodify('abc.fb2.tar.gz', ':p:r:r'), '.*\(src/testdir/.*\)', '\1', '') +:Put fnamemodify('abc.fb2.tar.gz', ':e' ) +:Put fnamemodify('abc.fb2.tar.gz', ':e:e' ) +:Put fnamemodify('abc.fb2.tar.gz', ':e:e:e' ) +:Put fnamemodify('abc.fb2.tar.gz', ':e:e:e:e') +:Put fnamemodify('abc.fb2.tar.gz', ':e:e:r' ) +:Put fnamemodify('abc def', ':S' ) +:Put fnamemodify('abc" "def', ':S' ) +:Put fnamemodify('abc"%"def', ':S' ) +:Put fnamemodify('abc'' ''def', ':S' ) +:Put fnamemodify('abc''%''def', ':S' ) +:Put fnamemodify("abc\ndef", ':S' ) +:set shell=tcsh +:Put fnamemodify("abc\ndef", ':S' ) +:$put ='vim: ts=8' +:1 delete _ +:w! test.out +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test105.ok b/src/nvim/testdir/test105.ok new file mode 100644 index 0000000000..0681597c05 --- /dev/null +++ b/src/nvim/testdir/test105.ok @@ -0,0 +1,29 @@ +fnamemodify('.', ':p' )[-1:] '/' +fnamemodify('.', ':p:h' )[-1:] 'r' +fnamemodify('test.out', ':p' )[-1:] 't' +fnamemodify('test.out', ':.' ) 'test.out' +fnamemodify('../testdir/a', ':.' ) 'a' +fnamemodify('test.out', ':~' ) '~/src/testdir/test.out' +fnamemodify('../testdir/a', ':~' ) '~/src/testdir/a' +fnamemodify('../testdir/a', ':t' ) 'a' +fnamemodify('.', ':p:t' ) '' +fnamemodify('test.out', ':p:t' ) 'test.out' +fnamemodify('test.out', ':p:e' ) 'out' +fnamemodify('test.out', ':p:t:e' ) 'out' +fnamemodify('abc.fb2.tar.gz', ':r' ) 'abc.fb2.tar' +fnamemodify('abc.fb2.tar.gz', ':r:r' ) 'abc.fb2' +fnamemodify('abc.fb2.tar.gz', ':r:r:r' ) 'abc' +substitute(fnamemodify('abc.fb2.tar.gz', ':p:r:r'), '.*\(src/testdir/.*\)', '\1', '') 'src/testdir/abc.fb2' +fnamemodify('abc.fb2.tar.gz', ':e' ) 'gz' +fnamemodify('abc.fb2.tar.gz', ':e:e' ) 'tar.gz' +fnamemodify('abc.fb2.tar.gz', ':e:e:e' ) 'fb2.tar.gz' +fnamemodify('abc.fb2.tar.gz', ':e:e:e:e') 'fb2.tar.gz' +fnamemodify('abc.fb2.tar.gz', ':e:e:r' ) 'tar' +fnamemodify('abc def', ':S' ) '''abc def''' +fnamemodify('abc" "def', ':S' ) '''abc" "def''' +fnamemodify('abc"%"def', ':S' ) '''abc"%"def''' +fnamemodify('abc'' ''def', ':S' ) '''abc''\'''' ''\''''def''' +fnamemodify('abc''%''def', ':S' ) '''abc''\''''%''\''''def''' +fnamemodify("abc\ndef", ':S' ) '''abc^@def''' +fnamemodify("abc\ndef", ':S' ) '''abc\^@def''' +vim: ts=8 diff --git a/src/nvim/testdir/test106.in b/src/nvim/testdir/test106.in new file mode 100644 index 0000000000..eb99e650ae --- /dev/null +++ b/src/nvim/testdir/test106.in @@ -0,0 +1,16 @@ +Tests for errorformat. vim: set ft=vim ts=8 : + +STARTTEST +:so small.vim +:if !has('quickfix') | e! test.ok | wq! test.out | endif +:set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%# +:cgetexpr ['WWWW', 'EEEE', 'CCCC'] +:$put =strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) +:cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC'] +:$put =strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) +:cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY'] +:$put =strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) +:/^Results/,$wq! test.out +ENDTEST + +Results of test106: diff --git a/src/nvim/testdir/test106.ok b/src/nvim/testdir/test106.ok new file mode 100644 index 0000000000..0a18cecf1c --- /dev/null +++ b/src/nvim/testdir/test106.ok @@ -0,0 +1,4 @@ +Results of test106: +[['W', 1], ['E^@CCCC', 1]] +[['W', 1], ['E^@CCCC', 1]] +[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]] diff --git a/src/nvim/testdir/test10a.in b/src/nvim/testdir/test10a.in new file mode 100644 index 0000000000..19e8652fe5 --- /dev/null +++ b/src/nvim/testdir/test10a.in @@ -0,0 +1,73 @@ +Test for 'errorformat'. + +STARTTEST +:so small.vim +:/start of errorfile/,/end of errorfile/w! Xerrorfile +:/start of testfile/,/end of testfile/w! Xtestfile +:cf Xerrorfile +rA +:cn +rB +:cn +rC +:cn +rD +:cn +rE +:w! test.out " Write contents of this file +:qa! +ENDTEST + +start of errorfile + + printf(" %d \n", (number/other)%10 ); +..................^ +%CC-E-NOSEMI, Missing ";". +at line number 4 in file SYS$DISK:XTESTFILE + + other=10000000; +.............^ +%CC-E-UNDECLARED, In this statement, "oszt" is not declared. +at line number 7 in file SYS$DISK:XTESTFILE + + for (i = 0; i<7 ; i++ ){ +..................^ +%CC-E-UNDECLARED, In this statement, "i" is not declared. +at line number 16 in file SYS$DISK:XTESTFILE + +some other error somewhere here. +...........................^ +%CC-W-WARRING, Sorry, but no expalnation for such an warring. +at line number 19 in file SYS$DISK:XTESTFILE + +and finally some other error exactly here. +.....................................^ +%CC-I-INFORMATIONAL, It should be some informational message. +at line number 20 in file SYS$DISK:XTESTFILE + +Does anyone know what is the problem and how to correct ?? :) +end of errorfile + +start of testfile +01234567890123456789012345678901234567 +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 8 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 10 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 11 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 13 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 15 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 16 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 17 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 19 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 21 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +end of testfile diff --git a/src/nvim/testdir/test10a.ok b/src/nvim/testdir/test10a.ok new file mode 100644 index 0000000000..10e78c9239 --- /dev/null +++ b/src/nvim/testdir/test10a.ok @@ -0,0 +1,23 @@ +start of testfile +01234567890123456789012345678901234567 +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 xxxxxxxxxxAxxxxxxxxxxxxxxxxxxx +line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 7 xxxxxBxxxxxxxxxxxxxxxxxxxxxxxx +line 8 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 10 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 11 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 13 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 15 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 16 xxxxxxxxxxCxxxxxxxxxxxxxxxxxxx +line 17 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 19 xxxxxxxxxxxxxxxxxxxDxxxxxxxxxx +line 20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxE +line 21 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +end of testfile diff --git a/src/nvim/testdir/test11.in b/src/nvim/testdir/test11.in new file mode 100644 index 0000000000..47de470a2d --- /dev/null +++ b/src/nvim/testdir/test11.in @@ -0,0 +1,84 @@ +Tests for autocommands: +- FileWritePre writing a compressed file +- FileReadPost reading a compressed file +- BufNewFile reading a file template +- BufReadPre decompressing the file to be read +- FilterReadPre substituting characters in the temp file +- FilterReadPost substituting characters after filtering +- FileReadPre set options for decompression +- FileReadPost decompress the file + +Note: This test is skipped if "gzip" is not available. +$GZIP is made empty, "-v" would cause trouble. +Use a FileChangedShell autocommand to avoid a prompt for "Xtestfile.gz" being +modified outside of Vim (noticed on Solaris). + +STARTTEST +:so small.vim +:" drop out when there is no gzip program +:if !executable("gzip") +: e! test.ok +: w! test.out +: qa! +:endif +:let $GZIP = "" +:au FileChangedShell * echo "caught FileChangedShell" +:set bin +:au FileWritePre *.gz '[,']!gzip +:au FileWritePost *.gz undo +:/^start of testfile/,/^end of testfile/w! Xtestfile.gz +:au FileReadPost *.gz '[,']!gzip -d +:$r Xtestfile.gz " Read and decompress the testfile +:?startstart?,$w! test.out " Write contents of this file +:au BufNewFile *.c read Xtest.c +:/^start of test.c/+1,/^end of test.c/-1w! Xtest.c +:e! foo.c " Will load Xtest.c +:au FileAppendPre *.out '[,']s/new/NEW/ +:au FileAppendPost *.out !cat Xtest.c >>test.out +:w>>test.out " Append it to the output file +:au! FileAppendPre +:" setup autocommands to decompress before reading and re-compress afterwards +:au BufReadPre *.gz exe '!gzip -d ' . shellescape(expand("<afile>")) +:au BufReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>")) +:au BufReadPost *.gz call rename(expand("<afile>"), expand("<afile>:r")) +:au BufReadPost *.gz exe '!gzip ' . shellescape(expand("<afile>:r")) +:e! Xtestfile.gz " Edit compressed file +:w>>test.out " Append it to the output file +:set shelltemp " need temp files here +:au FilterReadPre *.out call rename(expand("<afile>"), expand("<afile>") . ".t") +:au FilterReadPre *.out exe '!sed s/e/E/ ' . shellescape(expand("<afile>")) . ".t >" . shellescape(expand("<afile>")) +:au FilterReadPre *.out exe '!rm ' . shellescape(expand("<afile>")) . '.t' +:au FilterReadPost *.out '[,']s/x/X/g +:e! test.out " Edit the output file +:23,$!cat +:23,$s/\r$// " remove CR for when sed adds them +:au! FileReadPre *.gz exe '!gzip -d ' . shellescape(expand("<afile>")) +:au FileReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>")) +:au! FileReadPost *.gz '[,']s/l/L/ +:$r Xtestfile.gz " Read compressed file +:w " write it, after filtering +:au! " remove all autocommands +:e " Edit test.out again +:set nobin ff& " use the default fileformat for writing +:w +:qa! +ENDTEST + +startstart +start of testfile +line 2 Abcdefghijklmnopqrstuvwxyz +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 Abcdefghijklmnopqrstuvwxyz +line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 6 Abcdefghijklmnopqrstuvwxyz +line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 8 Abcdefghijklmnopqrstuvwxyz +line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 10 Abcdefghijklmnopqrstuvwxyz +end of testfile + +start of test.c +/* + * Here is a new .c file + */ +end of test.c diff --git a/src/nvim/testdir/test11.ok b/src/nvim/testdir/test11.ok new file mode 100644 index 0000000000..af8c5ce261 --- /dev/null +++ b/src/nvim/testdir/test11.ok @@ -0,0 +1,61 @@ +startstart +start of testfile +line 2 Abcdefghijklmnopqrstuvwxyz +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 Abcdefghijklmnopqrstuvwxyz +line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 6 Abcdefghijklmnopqrstuvwxyz +line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 8 Abcdefghijklmnopqrstuvwxyz +line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 10 Abcdefghijklmnopqrstuvwxyz +end of testfile + +start of test.c +/* + * Here is a new .c file + */ +end of test.c +start of testfile +line 2 Abcdefghijklmnopqrstuvwxyz +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 Abcdefghijklmnopqrstuvwxyz +linE 5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 6 AbcdefghijklmnopqrstuvwXyz +linE 7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 8 AbcdefghijklmnopqrstuvwXyz +linE 9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 10 AbcdefghijklmnopqrstuvwXyz +End of testfile + +/* + * HEre is a NEW .c file + */ +/* + * HEre is a new .c file + */ +start of tEstfile +linE 2 AbcdefghijklmnopqrstuvwXyz +linE 3 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 4 AbcdefghijklmnopqrstuvwXyz +linE 5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 6 AbcdefghijklmnopqrstuvwXyz +linE 7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 8 AbcdefghijklmnopqrstuvwXyz +linE 9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 10 AbcdefghijklmnopqrstuvwXyz +End of testfile +/* + * HEre is a new .c file + */ +start of testfiLe +Line 2 Abcdefghijklmnopqrstuvwxyz +Line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +Line 4 Abcdefghijklmnopqrstuvwxyz +Line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +Line 6 Abcdefghijklmnopqrstuvwxyz +Line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +Line 8 Abcdefghijklmnopqrstuvwxyz +Line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +Line 10 Abcdefghijklmnopqrstuvwxyz +end of testfiLe diff --git a/src/nvim/testdir/test12.in b/src/nvim/testdir/test12.in new file mode 100644 index 0000000000..46e9c45b80 --- /dev/null +++ b/src/nvim/testdir/test12.in @@ -0,0 +1,52 @@ +Tests for 'directory' option. +- ".", in same dir as file +- "./dir", in directory relative to file +- "dir", in directory relative to current dir + +STARTTEST +:so small.vim +:set nocompatible viminfo+=nviminfo +:set dir=.,~ +:/start of testfile/,/end of testfile/w! Xtest1 +:" do an ls of the current dir to find the swap file (should not be there) +:if has("unix") +: !ls .X*.swp >test.out +:else +: r !ls X*.swp >test.out +:endif +:!echo first line >>test.out +:e Xtest1 +:if has("unix") +:" Do an ls of the current dir to find the swap file, remove the leading dot +:" to make the result the same for all systems. +: r!ls .X*.swp +: s/\.*X/X/ +: .w >>test.out +: undo +:else +: !ls X*.swp >>test.out +:endif +:!echo under Xtest1.swp >>test.out +:!mkdir Xtest2 +:set dir=./Xtest2,.,~ +:e Xtest1 +:!ls X*.swp >>test.out +:!echo under under >>test.out +:!ls Xtest2 >>test.out +:!echo under Xtest1.swp >>test.out +:!mkdir Xtest.je +:/start of testfile/,/end of testfile/w! Xtest2/Xtest3 +:set dir=Xtest.je,~ +:e Xtest2/Xtest3 +:swap +:!ls Xtest2 >>test.out +:!echo under Xtest3 >>test.out +:!ls Xtest.je >>test.out +:!echo under Xtest3.swp >>test.out +:qa! +ENDTEST + +start of testfile +line 2 Abcdefghij +line 3 Abcdefghij +end of testfile diff --git a/src/nvim/testdir/test12.ok b/src/nvim/testdir/test12.ok new file mode 100644 index 0000000000..605623b117 --- /dev/null +++ b/src/nvim/testdir/test12.ok @@ -0,0 +1,10 @@ +first line +Xtest1.swp +under Xtest1.swp +under under +Xtest1.swp +under Xtest1.swp +Xtest3 +under Xtest3 +Xtest3.swp +under Xtest3.swp diff --git a/src/nvim/testdir/test13.in b/src/nvim/testdir/test13.in new file mode 100644 index 0000000000..cb8a6fff89 --- /dev/null +++ b/src/nvim/testdir/test13.in @@ -0,0 +1,58 @@ +Tests for autocommands on :close command + +Write three files and open them, each in a window. +Then go to next window, with autocommand that deletes the previous one. +Do this twice, writing the file. + +Also test deleting the buffer on a Unload event. If this goes wrong there +will be the ATTENTION prompt. + +Also test changing buffers in a BufDel autocommand. If this goes wrong there +are ml_line errors and/or a Crash. + +STARTTEST +:so small.vim +:/^start of testfile/,/^end of testfile/w! Xtestje1 +:/^start of testfile/,/^end of testfile/w! Xtestje2 +:/^start of testfile/,/^end of testfile/w! Xtestje3 +:e Xtestje1 +otestje1 +:w +:sp Xtestje2 +otestje2 +:w +:sp Xtestje3 +otestje3 +:w + +:au WinLeave Xtestje2 bwipe + +:w! test.out +:au WinLeave Xtestje1 bwipe Xtestje3 +:close +:w >>test.out +:e Xtestje1 +:bwipe Xtestje2 Xtestje3 test.out +:au! +:au! BufUnload Xtestje1 bwipe +:e Xtestje3 +:w >>test.out +:e Xtestje2 +:sp Xtestje1 +:e +:w >>test.out +:au! +:only +:e Xtestje1 +:bwipe Xtestje2 Xtestje3 test.out test13.in +:au BufWipeout Xtestje1 buf Xtestje1 +:bwipe +:w >>test.out +:qa! +ENDTEST + +start of testfile + contents + contents + contents +end of testfile diff --git a/src/nvim/testdir/test13.ok b/src/nvim/testdir/test13.ok new file mode 100644 index 0000000000..0f1fc347a4 --- /dev/null +++ b/src/nvim/testdir/test13.ok @@ -0,0 +1,30 @@ +start of testfile +testje1 + contents + contents + contents +end of testfile +start of testfile +testje1 + contents + contents + contents +end of testfile +start of testfile +testje3 + contents + contents + contents +end of testfile +start of testfile +testje2 + contents + contents + contents +end of testfile +start of testfile +testje1 + contents + contents + contents +end of testfile diff --git a/src/nvim/testdir/test14.in b/src/nvim/testdir/test14.in new file mode 100644 index 0000000000..fb987ebc88 --- /dev/null +++ b/src/nvim/testdir/test14.in @@ -0,0 +1,99 @@ +Tests for "vaBiB", end could be wrong. +Also test ":s/pat/sub/" with different ~s in sub. +Also test for ^Vxff and ^Vo123 in Insert mode. +Also test "[m", "]m", "[M" and "]M" +Also test search() + +STARTTEST +:so small.vim +/Start cursor here +vaBiBD:?Bug?,/Piece/-2w! test.out +/^- Bug +:s/u/~u~/ +:s/i/~u~/ +:s/o/~~~/ +:.w >>test.out +:if has("ebcdic") +: let tt = "o\<C-V>193\<C-V>xc2\<C-V>o303 \<C-V>90a\<C-V>xfg\<C-V>o578\<Esc>" +:else +: let tt = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>" +:endif +:exe "normal " . tt +:unlet tt +:.w >>test.out +:set vb +/^Piece +2]maA:.w >>test.out +j]maB:.w >>test.out +]maC:.w >>test.out +[maD:.w >>test.out +k2[maE:.w >>test.out +3[maF:.w >>test.out +]MaG:.w >>test.out +j2]MaH:.w >>test.out +]M]MaI:.w >>test.out +2[MaJ:.w >>test.out +k[MaK:.w >>test.out +3[MaL:.w >>test.out +:" +/^foobar +:let startline = line('.') +:call search('foobar', 'c') +:call append(line('$'), line('.') - startline) +j:call search('^$', 'c') +:call append(line('$'), line('.') - startline) +:call search('^$', 'bc') +:call append(line('$'), line('.') - startline) +/two +:call search('.', 'c') +:call append(line('$'), getline('.')[col('.') - 1:]) +:" +/^substitute +:s/foo/bar/ +:$put =@/ +/^substitute +:keeppatterns s/asdf/xyz/ +:$put =@/ +/^substitute +Y:$put =@0 +/bar /e +:$put =@0 +-:keeppatterns /xyz +0dn:/^search()/,$w >>test.out +:qa! +ENDTEST + +- Bug in "vPPPP" on this text (Webb): + { + cmd; + { + cmd; /* <-- Start cursor here */ + { + } + } + } + +Piece of Java +{ + tt m1 { + t1; + } e1 + + tt m2 { + t2; + } e2 + + tt m3 { + if (x) + { + t3; + } + } e3 +} + +foobar + +substitute foo asdf + +one two +search() diff --git a/src/nvim/testdir/test14.ok b/src/nvim/testdir/test14.ok new file mode 100644 index 0000000000..0aa2db3f97 --- /dev/null +++ b/src/nvim/testdir/test14.ok @@ -0,0 +1,26 @@ +- Bug in "vPPPP" on this text (Webb): + { + } +- Bug uuun "vPPPP" uuuuuuuuun this text (Webb): +ABC !ag8 + tt m1 {A + tt m2 {B + tt m3 {C + tt m3 {DC + tt m1 {EA +{F + }G e1 + }H e3 +}I + }JH e3 + }K e2 +{LF +search() +0 +1 +1 +two +foo +^substitute +substitute bar xyz +xyz diff --git a/src/nvim/testdir/test15.in b/src/nvim/testdir/test15.in new file mode 100644 index 0000000000..366529a550 --- /dev/null +++ b/src/nvim/testdir/test15.in @@ -0,0 +1,136 @@ +Tests for :right on text with embedded TAB. +Also test formatting a paragraph. +Also test undo after ":%s" and formatting. + +STARTTEST +:so small.vim +:set tw=65 + +:/^\s*test for :left/,/^\s*test for :center/ left +:/^\s*test for :center/,/^\s*test for :right/ center +:/^\s*test for :right/,/^xxx/-1 right +:set fo+=tcroql tw=72 +/xxxxxxxx$ +0gq6kk +:set nocp viminfo+=nviminfo +:" undo/redo here to make the next undo only work on the following changes +u +:map gg :.,.+2s/^/x/<CR>kk:set tw=3<CR>gqq +/^aa +ggu +:?test for :left?,$w! test.out +:qa! +ENDTEST + + test for :left + a a + fa a + dfa a + sdfa a + asdfa a + xasdfa a +asxxdfa a + + test for :center + a a + fa afd asdf + dfa a + sdfa afd asdf + asdfa a + xasdfa asdfasdfasdfasdfasdf +asxxdfa a + + test for :right + a a + fa a + dfa a + sdfa a + asdfa a + xasdfa a + asxxdfa a + asxa;ofa a + asdfaqwer a + a ax + fa ax + dfa ax + sdfa ax + asdfa ax + xasdfa ax + asxxdfa ax + asxa;ofa ax + asdfaqwer ax + a axx + fa axx + dfa axx + sdfa axx + asdfa axx + xasdfa axx + asxxdfa axx + asxa;ofa axx + asdfaqwer axx + a axxx + fa axxx + dfa axxx + sdfa axxx + asdfa axxx + xasdfa axxx + asxxdfa axxx + asxa;ofa axxx + asdfaqwer axxx + a axxxo + fa axxxo + dfa axxxo + sdfa axxxo + asdfa axxxo + xasdfa axxxo + asxxdfa axxxo + asxa;ofa axxxo + asdfaqwer axxxo + a axxxoi + fa axxxoi + dfa axxxoi + sdfa axxxoi + asdfa axxxoi + xasdfa axxxoi + asxxdfa axxxoi + asxa;ofa axxxoi + asdfaqwer axxxoi + a axxxoik + fa axxxoik + dfa axxxoik + sdfa axxxoik + asdfa axxxoik + xasdfa axxxoik + asxxdfa axxxoik + asxa;ofa axxxoik + asdfaqwer axxxoik + a axxxoike + fa axxxoike + dfa axxxoike + sdfa axxxoike + asdfa axxxoike + xasdfa axxxoike + asxxdfa axxxoike + asxa;ofa axxxoike + asdfaqwer axxxoike + a axxxoikey + fa axxxoikey + dfa axxxoikey + sdfa axxxoikey + asdfa axxxoikey + xasdfa axxxoikey + asxxdfa axxxoikey + asxa;ofa axxxoikey + asdfaqwer axxxoikey + +xxxxx xx xxxxxx +xxxxxxx xxxxxxxxx xxx xxxx xxxxx xxxxx xxx xx +xxxxxxxxxxxxxxxxxx xxxxx xxxx, xxxx xxxx xxxx xxxx xxx xx xx +xx xxxxxxx. xxxx xxxx. + +> xx xx, xxxx xxxx xxx xxxx xxx xxxxx xxx xxx xxxxxxx xxx xxxxx +> xxxxxx xxxxxxx: xxxx xxxxxxx, xx xxxxxx xxxx xxxxxxxxxx + +aa aa aa aa +bb bb bb bb +cc cc cc cc diff --git a/src/nvim/testdir/test15.ok b/src/nvim/testdir/test15.ok new file mode 100644 index 0000000000..bc09f5e7db --- /dev/null +++ b/src/nvim/testdir/test15.ok @@ -0,0 +1,111 @@ +test for :left +a a +fa a +dfa a +sdfa a +asdfa a +xasdfa a +asxxdfa a + + test for :center + a a + fa afd asdf + dfa a + sdfa afd asdf + asdfa a + xasdfa asdfasdfasdfasdfasdf + asxxdfa a + + test for :right + a a + fa a + dfa a + sdfa a + asdfa a + xasdfa a + asxxdfa a + asxa;ofa a + asdfaqwer a + a ax + fa ax + dfa ax + sdfa ax + asdfa ax + xasdfa ax + asxxdfa ax + asxa;ofa ax + asdfaqwer ax + a axx + fa axx + dfa axx + sdfa axx + asdfa axx + xasdfa axx + asxxdfa axx + asxa;ofa axx + asdfaqwer axx + a axxx + fa axxx + dfa axxx + sdfa axxx + asdfa axxx + xasdfa axxx + asxxdfa axxx + asxa;ofa axxx + asdfaqwer axxx + a axxxo + fa axxxo + dfa axxxo + sdfa axxxo + asdfa axxxo + xasdfa axxxo + asxxdfa axxxo + asxa;ofa axxxo + asdfaqwer axxxo + a axxxoi + fa axxxoi + dfa axxxoi + sdfa axxxoi + asdfa axxxoi + xasdfa axxxoi + asxxdfa axxxoi + asxa;ofa axxxoi + asdfaqwer axxxoi + a axxxoik + fa axxxoik + dfa axxxoik + sdfa axxxoik + asdfa axxxoik + xasdfa axxxoik + asxxdfa axxxoik + asxa;ofa axxxoik + asdfaqwer axxxoik + a axxxoike + fa axxxoike + dfa axxxoike + sdfa axxxoike + asdfa axxxoike + xasdfa axxxoike + asxxdfa axxxoike + asxa;ofa axxxoike + asdfaqwer axxxoike + a axxxoikey + fa axxxoikey + dfa axxxoikey + sdfa axxxoikey + asdfa axxxoikey + xasdfa axxxoikey + asxxdfa axxxoikey + asxa;ofa axxxoikey + asdfaqwer axxxoikey + +xxxxx xx xxxxxx xxxxxxx xxxxxxxxx xxx xxxx xxxxx xxxxx xxx xx +xxxxxxxxxxxxxxxxxx xxxxx xxxx, xxxx xxxx xxxx xxxx xxx xx xx xx xxxxxxx. +xxxx xxxx. + +> xx xx, xxxx xxxx xxx xxxx xxx xxxxx xxx xxx xxxxxxx xxx xxxxx xxxxxx +> xxxxxxx: xxxx xxxxxxx, xx xxxxxx xxxx xxxxxxxxxx + +aa aa aa aa +bb bb bb bb +cc cc cc cc diff --git a/src/nvim/testdir/test16.in b/src/nvim/testdir/test16.in new file mode 100644 index 0000000000..b2cd159a8c --- /dev/null +++ b/src/nvim/testdir/test16.in @@ -0,0 +1,15 @@ +Tests for resetting "secure" flag after GUI has started. +For KDE set a font, empty 'guifont' may cause a hang. + +STARTTEST +:if $DISPLAY == "" | e! test.ok | wq! test.out | endif +:set exrc secure +:if has("gui_kde") +: set guifont=Courier\ 10\ Pitch/8/-1/5/50/0/0/0/0/0 +:endif +:gui -f +:.,$w! test.out +:qa! +ENDTEST + + just some text diff --git a/src/nvim/testdir/test16.ok b/src/nvim/testdir/test16.ok new file mode 100644 index 0000000000..25e2eea5c0 --- /dev/null +++ b/src/nvim/testdir/test16.ok @@ -0,0 +1,2 @@ + + just some text diff --git a/src/nvim/testdir/test17.in b/src/nvim/testdir/test17.in new file mode 100644 index 0000000000..bc542c7625 --- /dev/null +++ b/src/nvim/testdir/test17.in @@ -0,0 +1,141 @@ +Tests for: +- "gf" on ${VAR}, +- ":checkpath!" with various 'include' settings. + +STARTTEST +:so small.vim +:if has("ebcdic") +: set isfname=@,240-249,/,.,-,_,+,,,$,:,~,{,} +:else +: set isfname=@,48-57,/,.,-,_,+,,,$,:,~,{,} +:endif +:function! DeleteDirectory(dir) +: if has("win16") || has("win32") || has("win64") || has("dos16") || has("dos32") +: exec "silent !rmdir /Q /S " . a:dir +: else +: exec "silent !rm -rf " . a:dir +: endif +:endfun +:if has("unix") +:let $CDIR = "." +/CDIR +:else +:if has("amiga") +:let $TDIR = "/testdir" +:else +:let $TDIR = "." +:endif +/TDIR +:endif +:" Dummy writing for making that sure gf doesn't fail even if the current +:" file is modified. It can be occurred when executing the following command +:" directly on Windows without fixing the 'fileformat': +:" > nmake -f Make_dos.mak test17.out +:w! test.out +gf +:set ff=unix +:w! test.out +:brewind +ENDTEST + + ${CDIR}/test17a.in + $TDIR/test17a.in + +STARTTEST +:" check for 'include' without \zs or \ze +:lang C +:call delete("./Xbase.a") +:call DeleteDirectory("Xdir1") +:!mkdir Xdir1 +:!mkdir "Xdir1/dir2" +:e! Xdir1/dir2/foo.a +i#include "bar.a" +:w +:e Xdir1/dir2/bar.a +i#include "baz.a" +:w +:e Xdir1/dir2/baz.a +i#include "foo.a" +:w +:e Xbase.a +:set path=Xdir1/dir2 +i#include <foo.a> +:w +:redir! >>test.out +:checkpath! +:redir END +:brewind +ENDTEST + +STARTTEST +:" check for 'include' with \zs and \ze +:call delete("./Xbase.b") +:call DeleteDirectory("Xdir1") +:!mkdir Xdir1 +:!mkdir "Xdir1/dir2" +:let &include='^\s*%inc\s*/\zs[^/]\+\ze' +:function! DotsToSlashes() +: return substitute(v:fname, '\.', '/', 'g') . '.b' +:endfunction +:let &includeexpr='DotsToSlashes()' +:e! Xdir1/dir2/foo.b +i%inc /bar/ +:w +:e Xdir1/dir2/bar.b +i%inc /baz/ +:w +:e Xdir1/dir2/baz.b +i%inc /foo/ +:w +:e Xbase.b +:set path=Xdir1/dir2 +i%inc /foo/ +:w +:redir! >>test.out +:checkpath! +:redir END +:brewind +ENDTEST + +STARTTEST +:" check for 'include' with \zs and no \ze +:call delete("./Xbase.c") +:call DeleteDirectory("Xdir1") +:!mkdir Xdir1 +:!mkdir "Xdir1/dir2" +:let &include='^\s*%inc\s*\%([[:upper:]][^[:space:]]*\s\+\)\?\zs\S\+\ze' +:function! StripNewlineChar() +: if v:fname =~ '\n$' +: return v:fname[:-2] +: endif +: return v:fname +:endfunction +:let &includeexpr='StripNewlineChar()' +:e! Xdir1/dir2/foo.c +i%inc bar.c +:w +:e Xdir1/dir2/bar.c +i%inc baz.c +:w +:e Xdir1/dir2/baz.c +i%inc foo.c +:w +:e Xdir1/dir2/FALSE.c +i%inc foo.c +:w +:e Xbase.c +:set path=Xdir1/dir2 +i%inc FALSE.c foo.c +:w +:redir! >>test.out +:checkpath! +:redir END +:brewind +:" change "\" to "/" for Windows and fix 'fileformat' +:e test.out +:%s#\\#/#g +:set ff& +:w +:q +ENDTEST + diff --git a/src/nvim/testdir/test17.ok b/src/nvim/testdir/test17.ok new file mode 100644 index 0000000000..b2a66d5f85 --- /dev/null +++ b/src/nvim/testdir/test17.ok @@ -0,0 +1,33 @@ +This file is just to test "gf" in test 17. +The contents is not important. +Just testing! + + +--- Included files in path --- +Xdir1/dir2/foo.a +Xdir1/dir2/foo.a --> + Xdir1/dir2/bar.a + Xdir1/dir2/bar.a --> + Xdir1/dir2/baz.a + Xdir1/dir2/baz.a --> + "foo.a" (Already listed) + + +--- Included files in path --- +Xdir1/dir2/foo.b +Xdir1/dir2/foo.b --> + Xdir1/dir2/bar.b + Xdir1/dir2/bar.b --> + Xdir1/dir2/baz.b + Xdir1/dir2/baz.b --> + foo (Already listed) + + +--- Included files in path --- +Xdir1/dir2/foo.c +Xdir1/dir2/foo.c --> + Xdir1/dir2/bar.c + Xdir1/dir2/bar.c --> + Xdir1/dir2/baz.c + Xdir1/dir2/baz.c --> + foo.c (Already listed) diff --git a/src/nvim/testdir/test17a.in b/src/nvim/testdir/test17a.in new file mode 100644 index 0000000000..7e89364797 --- /dev/null +++ b/src/nvim/testdir/test17a.in @@ -0,0 +1,3 @@ +This file is just to test "gf" in test 17. +The contents is not important. +Just testing! diff --git a/src/nvim/testdir/test18.in b/src/nvim/testdir/test18.in new file mode 100644 index 0000000000..9bfd922344 --- /dev/null +++ b/src/nvim/testdir/test18.in @@ -0,0 +1,16 @@ +Tests for not doing smart indenting when it isn't set. + +STARTTEST +:so small.vim +:set nocin nosi ai +/some +2cc#test +:?start?,$w! test.out +:qa! +ENDTEST + +start text + some test text + test text +test text + test text diff --git a/src/nvim/testdir/test18.ok b/src/nvim/testdir/test18.ok new file mode 100644 index 0000000000..e719713785 --- /dev/null +++ b/src/nvim/testdir/test18.ok @@ -0,0 +1,4 @@ +start text + #test +test text + test text diff --git a/src/nvim/testdir/test19.in b/src/nvim/testdir/test19.in new file mode 100644 index 0000000000..aafa34e521 --- /dev/null +++ b/src/nvim/testdir/test19.in @@ -0,0 +1,33 @@ +Tests for "r<Tab>" with 'smarttab' and 'expandtab' set/not set. +Also test that dv_ works correctly + +STARTTEST +:so small.vim +:set smarttab expandtab ts=8 sw=4 +:" make sure that backspace works, no matter what termcap is used +:set t_kD=x7f t_kb=x08 +/some +r :set noexpandtab +/other +r +:" Test replacing with Tabs and then backspacing to undo it +0wR +:" Test replacing with Tabs +0wR +:" Test that copyindent works with expandtab set +:set expandtab smartindent copyindent ts=8 sw=8 sts=8 +o{ +x:set nosol +/Second line/ +fwdv_:?^start?,$w! test.out +:qa! +ENDTEST + +start text + some test text +test text + other test text + a cde + f ghi +test text + Second line beginning with whitespace diff --git a/src/nvim/testdir/test19.ok b/src/nvim/testdir/test19.ok new file mode 100644 index 0000000000..4146214919 --- /dev/null +++ b/src/nvim/testdir/test19.ok @@ -0,0 +1,10 @@ +start text + ome test text +test text + ther test text + a cde + hi +test text +{ + x + with whitespace diff --git a/src/nvim/testdir/test2.in b/src/nvim/testdir/test2.in new file mode 100644 index 0000000000..b7b5a51066 --- /dev/null +++ b/src/nvim/testdir/test2.in @@ -0,0 +1,29 @@ + +This is a test if a URL is recognized by "gf", with the cursor before and +after the "://". Also test ":\\". + +STARTTEST +:so small.vim +/^first +/tmp +:call append(0, expand("<cfile>")) +/^second +/URL +:call append(1, expand("<cfile>")) +:if has("ebcdic") +: set isf=@,240-249,/,.,-,_,+,,,$,:,~,\ +:else +: set isf=@,48-57,/,.,-,_,+,,,$,:,~,\ +:endif +/^third +/name +:call append(2, expand("<cfile>")) +/^fourth +/URL +:call append(3, expand("<cfile>")) +5GdG:wq! test.out +ENDTEST +first test for URL://machine.name/tmp/vimtest2a and other text +second test for URL://machine.name/tmp/vimtest2b. And other text +third test for URL:\\machine.name\vimtest2c and other text +fourth test for URL:\\machine.name\tmp\vimtest2d, and other text diff --git a/src/nvim/testdir/test2.ok b/src/nvim/testdir/test2.ok new file mode 100644 index 0000000000..32978825f8 --- /dev/null +++ b/src/nvim/testdir/test2.ok @@ -0,0 +1,4 @@ +URL://machine.name/tmp/vimtest2a +URL://machine.name/tmp/vimtest2b +URL:\\machine.name\vimtest2c +URL:\\machine.name\tmp\vimtest2d diff --git a/src/nvim/testdir/test20.in b/src/nvim/testdir/test20.in new file mode 100644 index 0000000000..662a1439f2 --- /dev/null +++ b/src/nvim/testdir/test20.in @@ -0,0 +1,28 @@ +Tests Blockwise Visual when there are TABs before the text. +First test for undo working properly when executing commands from a register. +Also test this in an empty buffer. + +STARTTEST +:so tiny.vim +G0"ay$k@au +:new +@auY:quit! +GP +/start here$ +"by$jjlld +/456$ +jj"bP +:/56$/,$-1w! test.out +:qa! +ENDTEST + +123456 +234567 +345678 + +test text test tex start here + some text + test text +test text + +OxjAykdd diff --git a/src/nvim/testdir/test20.ok b/src/nvim/testdir/test20.ok new file mode 100644 index 0000000000..7c50ea8db8 --- /dev/null +++ b/src/nvim/testdir/test20.ok @@ -0,0 +1,10 @@ +123start here56 +234start here67 +345start here78 + +test text test tex rt here + somext + tesext +test text + + diff --git a/src/nvim/testdir/test21.in b/src/nvim/testdir/test21.in new file mode 100644 index 0000000000..491b9f7404 --- /dev/null +++ b/src/nvim/testdir/test21.in @@ -0,0 +1,19 @@ +Tests for [ CTRL-I with a count and CTRL-W CTRL-I with a count + +STARTTEST +:so small.vim +/start +6[ :.w! test.out +?start here +6 :.w >>test.out +:qa! +ENDTEST + +#include test21.in + +/* test text test tex start here + some text + test text + start OK if found this line + start found wrong line +test text diff --git a/src/nvim/testdir/test21.ok b/src/nvim/testdir/test21.ok new file mode 100644 index 0000000000..d9f1b759ce --- /dev/null +++ b/src/nvim/testdir/test21.ok @@ -0,0 +1,2 @@ + start OK if found this line + start OK if found this line diff --git a/src/nvim/testdir/test22.in b/src/nvim/testdir/test22.in new file mode 100644 index 0000000000..f5cc046c6a --- /dev/null +++ b/src/nvim/testdir/test22.in @@ -0,0 +1,13 @@ +Tests for file with some lines ending in CTRL-M, some not
+
+STARTTEST +:set ta tx +:e! +:$-3,$w! test.out +:qa! +ENDTEST + +this lines ends in a
+this one doesn't +this one does
+and the last one doesn't diff --git a/src/nvim/testdir/test22.ok b/src/nvim/testdir/test22.ok new file mode 100644 index 0000000000..38ff89eaf3 --- /dev/null +++ b/src/nvim/testdir/test22.ok @@ -0,0 +1,4 @@ +this lines ends in a
+this one doesn't +this one does
+and the last one doesn't diff --git a/src/nvim/testdir/test23.in b/src/nvim/testdir/test23.in new file mode 100644 index 0000000000..0e0e605531 --- /dev/null +++ b/src/nvim/testdir/test23.in @@ -0,0 +1,15 @@ +Tests for complicated + argument to :edit command + +STARTTEST +:$-1w! Xfile1 +:$w! Xfile2 +:edit +1|s/|/PIPE/|w Xfile1| e Xfile2|1 | s/\//SLASH/|w +:w! test.out +:e Xfile1 +:w >> test.out +:qa! +ENDTEST + +The result should be in Xfile1: "fooPIPEbar", in Xfile2: "fooSLASHbar" +foo|bar +foo/bar diff --git a/src/nvim/testdir/test23.ok b/src/nvim/testdir/test23.ok new file mode 100644 index 0000000000..f1930abad6 --- /dev/null +++ b/src/nvim/testdir/test23.ok @@ -0,0 +1,2 @@ +fooSLASHbar +fooPIPEbar diff --git a/src/nvim/testdir/test24.in b/src/nvim/testdir/test24.in Binary files differnew file mode 100644 index 0000000000..7dfc1afdc6 --- /dev/null +++ b/src/nvim/testdir/test24.in diff --git a/src/nvim/testdir/test24.ok b/src/nvim/testdir/test24.ok new file mode 100644 index 0000000000..cd61210968 --- /dev/null +++ b/src/nvim/testdir/test24.ok @@ -0,0 +1,32 @@ +start +test text test text +test text test text +test text test text +test text test text +test text test text +test text test text +test text test text x61 +test text test text x60-x64 +test text test text x78 5 +test text test text o143 +test text test text o140-o144 +test text test text o41 7 +test text test text \%x42 +test text test text \%o103 +test text test text [\x00] +test text test text [\x00-\x10] +test text test text [\x-z] +test text test text [\u-z] +xx xx a +xx aaaaa xx a +xx aaaaa xx a +xx Aaa xx +xx Aaaa xx +xx Aaa xx +xx foobar xA xx +xx an A xx +XX 9; +YY 77; + xyz + bcd + BB diff --git a/src/nvim/testdir/test25.in b/src/nvim/testdir/test25.in new file mode 100644 index 0000000000..4139865daf --- /dev/null +++ b/src/nvim/testdir/test25.in @@ -0,0 +1,31 @@ +Test for jumping to a tag with 'hidden' set, with symbolic link in path of tag. +This only works for Unix, because of the symbolic link. + +STARTTEST +:so small.vim +:set hidden +:" Create a link from test25.dir to the current directory. +:!rm -f test25.dir +:!ln -s . test25.dir +:" Create tags.text, with the current directory name inserted. +/tags line +:r !pwd +d$/test +hP:.w! tags.test +:" Try jumping to a tag in the current file, but with a path that contains a +:" symbolic link. When wrong, this will give the ATTENTION message. The next +:" space will then be eaten by hit-return, instead of moving the cursor to 'd'. +:set tags=tags.test +G x:.w! test.out +:!rm -f test25.dir tags.test +:qa! +ENDTEST + +tags line: +SECTION_OFF /test25.dir/test25.in /^#define SECTION_OFF 3$/ + +/*tx.c*/ +#define SECTION_OFF 3 +#define NUM_SECTIONS 3 + +SECTION_OFF diff --git a/src/nvim/testdir/test25.ok b/src/nvim/testdir/test25.ok new file mode 100644 index 0000000000..08fc070b7b --- /dev/null +++ b/src/nvim/testdir/test25.ok @@ -0,0 +1 @@ +#efine SECTION_OFF 3 diff --git a/src/nvim/testdir/test26.in b/src/nvim/testdir/test26.in new file mode 100644 index 0000000000..e7cd757661 --- /dev/null +++ b/src/nvim/testdir/test26.in @@ -0,0 +1,44 @@ +Test for :execute, :while and :if + +STARTTEST +:so small.vim +mt:let i = 0 +:while i < 12 +: let i = i + 1 +: if has("ebcdic") +: execute "normal o" . i . "\047" +: else +: execute "normal o" . i . "\033" +: endif +: if i % 2 +: normal Ax +: if i == 9 +: break +: endif +: if i == 5 +: continue +: else +: let j = 9 +: while j > 0 +: if has("ebcdic") +: execute "normal" j . "a" . j . "\x27" +: else +: execute "normal" j . "a" . j . "\x1b" +: endif +: let j = j - 1 +: endwhile +: endif +: endif +: if i == 9 +: if has("ebcdic") +: execute "normal Az\047" +: else +: execute "normal Az\033" +: endif +: endif +:endwhile +:unlet i j +:'t,$w! test.out +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test26.ok b/src/nvim/testdir/test26.ok new file mode 100644 index 0000000000..bc44761187 --- /dev/null +++ b/src/nvim/testdir/test26.ok @@ -0,0 +1,10 @@ + +1x999999999888888887777777666666555554444333221 +2 +3x999999999888888887777777666666555554444333221 +4 +5x +6 +7x999999999888888887777777666666555554444333221 +8 +9x diff --git a/src/nvim/testdir/test27.in b/src/nvim/testdir/test27.in new file mode 100644 index 0000000000..2df16d9eff --- /dev/null +++ b/src/nvim/testdir/test27.in @@ -0,0 +1,20 @@ +Test for expanding file names + +STARTTEST +:!mkdir Xdir1 +:!mkdir Xdir2 +:!mkdir Xdir3 +:cd Xdir3 +:!mkdir Xdir4 +:cd .. +:w Xdir1/file +:w Xdir3/Xdir4/file +:n Xdir?/*/file +Go%:.w! test.out +:n! Xdir?/*/nofile +Go%:.w >>test.out +:e! xx +:!rm -rf Xdir1 Xdir2 Xdir3 +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test27.ok b/src/nvim/testdir/test27.ok new file mode 100644 index 0000000000..c35f2438a9 --- /dev/null +++ b/src/nvim/testdir/test27.ok @@ -0,0 +1,2 @@ +Xdir3/Xdir4/file +Xdir?/*/nofile diff --git a/src/nvim/testdir/test28.in b/src/nvim/testdir/test28.in Binary files differnew file mode 100644 index 0000000000..5542c92666 --- /dev/null +++ b/src/nvim/testdir/test28.in diff --git a/src/nvim/testdir/test28.ok b/src/nvim/testdir/test28.ok new file mode 100644 index 0000000000..911d854655 --- /dev/null +++ b/src/nvim/testdir/test28.ok @@ -0,0 +1,2 @@ +sd +map __2 asdsecondsdsd0map __5 asd0fifth diff --git a/src/nvim/testdir/test29.in b/src/nvim/testdir/test29.in new file mode 100644 index 0000000000..1d6cb6f4d1 --- /dev/null +++ b/src/nvim/testdir/test29.in @@ -0,0 +1,230 @@ +Test for joining lines and marks in them + in compatible and nocompatible modes + and with 'joinspaces' set or not + and with 'cpoptions' flag 'j' set or not + +STARTTEST +:so small.vim +:set nocompatible viminfo+=nviminfo +:set nojoinspaces +:set cpoptions-=j +/firstline/ +j"td/^STARTTEST/-1 +PJjJjJjJjJjJjJjJjJjJjJjJjJjJj05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions+=j +j05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions-=j joinspaces +j"tpJjJjJjJjJjJjJjJjJjJjJjJjJjJj05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions+=j +j05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions-=j nojoinspaces compatible +j"tpJjJjJjJjJjJjJjJjJjJjJjJjJjJj4Jy3l$pjd/STARTTEST/-2 +ENDTEST + +firstline +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +zx cvn. +as dfg? +hjkl iop! +ert +zx cvn. +as dfg? +hjkl iop! +ert + +STARTTEST +/^{/+1 +:set comments=s1:/*,mb:*,ex:*/,:// +:set nojoinspaces fo=j +:set backspace=eol,start +:.,+3join +j4J +:.,+2join +j3J +:.,+2join +j3J +:.,+2join +jj3J +ENDTEST + +{ + +/* + * Make sure the previous comment leader is not removed. + */ + +/* + * Make sure the previous comment leader is not removed. + */ + +// Should the next comment leader be left alone? +// Yes. + +// Should the next comment leader be left alone? +// Yes. + +/* Here the comment leader should be left intact. */ +// And so should this one. + +/* Here the comment leader should be left intact. */ +// And so should this one. + +if (condition) // Remove the next comment leader! + // OK, I will. + action(); + +if (condition) // Remove the next comment leader! + // OK, I will. + action(); +} + +STARTTEST +:" Test with backspace set to the non-compatible setting +/^\d\+ this +:set cp bs=2 +Avim1 +Avim2u +:set cpo-=< +:inoremap <c-u> <left><c-u> +Avim3 +:iunmap <c-u> +Avim4 +:" Test with backspace set to the compatible setting +:set bs= +A vim5A +A vim6Azweiu +:inoremap <c-u> <left><c-u> +A vim7 +:set cp +ENDTEST +1 this shouldn't be deleted +2 this shouldn't be deleted +3 this shouldn't be deleted +4 this should be deleted +5 this shouldn't be deleted +6 this shouldn't be deleted +7 this shouldn't be deleted +8 this shouldn't be deleted (not touched yet) + +STARTTEST +/^{/+1 +:set comments=sO:*\ -,mO:*\ \ ,exO:*/ +:set comments+=s1:/*,mb:*,ex:*/,:// +:set comments+=s1:>#,mb:#,ex:#<,:< +:set cpoptions-=j joinspaces fo=j +:set backspace=eol,start +:.,+3join +j4J +:.,+8join +j9J +:.,+2join +j3J +:.,+2join +j3J +:.,+2join +jj3J +j:.,+2join +jj3J +j:.,+5join +j6J +oSome code!
// Make sure backspacing does not remove this comment leader.0i +ENDTEST + +{ + +/* + * Make sure the previous comment leader is not removed. + */ + +/* + * Make sure the previous comment leader is not removed. + */ + +/* List: + * - item1 + * foo bar baz + * foo bar baz + * - item2 + * foo bar baz + * foo bar baz + */ + +/* List: + * - item1 + * foo bar baz + * foo bar baz + * - item2 + * foo bar baz + * foo bar baz + */ + +// Should the next comment leader be left alone? +// Yes. + +// Should the next comment leader be left alone? +// Yes. + +/* Here the comment leader should be left intact. */ +// And so should this one. + +/* Here the comment leader should be left intact. */ +// And so should this one. + +if (condition) // Remove the next comment leader! + // OK, I will. + action(); + +if (condition) // Remove the next comment leader! + // OK, I will. + action(); + +int i = 7 /* foo *// 3 + // comment + ; + +int i = 7 /* foo *// 3 + // comment + ; + +># Note that the last character of the ending comment leader (left angle + # bracket) is a comment leader itself. Make sure that this comment leader is + # not removed from the next line #< +< On this line a new comment is opened which spans 2 lines. This comment should +< retain its comment leader. + +># Note that the last character of the ending comment leader (left angle + # bracket) is a comment leader itself. Make sure that this comment leader is + # not removed from the next line #< +< On this line a new comment is opened which spans 2 lines. This comment should +< retain its comment leader. + +} + +STARTTEST +:g/^STARTTEST/.,/^ENDTEST/d +:?firstline?+1,$w! test.out +:qa! +ENDTEST diff --git a/src/nvim/testdir/test29.ok b/src/nvim/testdir/test29.ok new file mode 100644 index 0000000000..9dc07ed46b --- /dev/null +++ b/src/nvim/testdir/test29.ok @@ -0,0 +1,97 @@ +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +zx cvn. as dfg? hjkl iop! ert ernop +zx cvn. as dfg? hjkl iop! ert ernop + +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +zx cvn. as dfg? hjkl iop! ert enop +zx cvn. as dfg? hjkl iop! ert ernop + +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +zx cvn. as dfg? hjkl iop! ert a + + +{ +/* Make sure the previous comment leader is not removed. */ +/* Make sure the previous comment leader is not removed. */ +// Should the next comment leader be left alone? Yes. +// Should the next comment leader be left alone? Yes. +/* Here the comment leader should be left intact. */ // And so should this one. +/* Here the comment leader should be left intact. */ // And so should this one. +if (condition) // Remove the next comment leader! OK, I will. + action(); +if (condition) // Remove the next comment leader! OK, I will. + action(); +} + +1 this shouldn't be deleted +2 this shouldn't be deleted +3 this shouldn't be deleted +4 this should be deleted3 + +6 this shouldn't be deleted vim5 +7 this shouldn't be deleted vim6 +8 this shouldn't be deleted (not touched yet) vim7 + + +{ +/* Make sure the previous comment leader is not removed. */ +/* Make sure the previous comment leader is not removed. */ +/* List: item1 foo bar baz foo bar baz item2 foo bar baz foo bar baz */ +/* List: item1 foo bar baz foo bar baz item2 foo bar baz foo bar baz */ +// Should the next comment leader be left alone? Yes. +// Should the next comment leader be left alone? Yes. +/* Here the comment leader should be left intact. */ // And so should this one. +/* Here the comment leader should be left intact. */ // And so should this one. +if (condition) // Remove the next comment leader! OK, I will. + action(); +if (condition) // Remove the next comment leader! OK, I will. + action(); +int i = 7 /* foo *// 3 // comment + ; +int i = 7 /* foo *// 3 // comment + ; +># Note that the last character of the ending comment leader (left angle bracket) is a comment leader itself. Make sure that this comment leader is not removed from the next line #< < On this line a new comment is opened which spans 2 lines. This comment should retain its comment leader. +># Note that the last character of the ending comment leader (left angle bracket) is a comment leader itself. Make sure that this comment leader is not removed from the next line #< < On this line a new comment is opened which spans 2 lines. This comment should retain its comment leader. + +Some code!// Make sure backspacing does not remove this comment leader. +} + diff --git a/src/nvim/testdir/test3.in b/src/nvim/testdir/test3.in new file mode 100644 index 0000000000..a7543945c4 --- /dev/null +++ b/src/nvim/testdir/test3.in @@ -0,0 +1,2056 @@ +/* vim: set cin ts=4 sw=4 : */ + +Test for 'cindent' + +STARTTEST +:so small.vim +:set nocompatible viminfo+=nviminfo modeline +:edit " read modeline +/start of AUTO +=/end of AUTO +ENDTEST + +/* start of AUTO matically checked vim: set ts=4 : */ +{ + if (test) + cmd1; + cmd2; +} + +{ + if (test) + cmd1; + else + cmd2; +} + +{ + if (test) + { + cmd1; + cmd2; + } +} + +{ + if (test) + { + cmd1; + else + } +} + +{ + while (this) + if (test) + cmd1; + cmd2; +} + +{ + while (this) + if (test) + cmd1; + else + cmd2; +} + +{ + if (test) + { + cmd; + } + + if (test) + cmd; +} + +{ + if (test) { + cmd; + } + + if (test) cmd; +} + +{ + cmd1; + for (blah) + while (this) + if (test) + cmd2; + cmd3; +} + +{ + cmd1; + for (blah) + while (this) + if (test) + cmd2; + cmd3; + + if (test) + { + cmd1; + cmd2; + cmd3; + } +} + + +/* Test for 'cindent' do/while mixed with if/else: */ + +{ + do + if (asdf) + asdfasd; + while (cond); + + do + if (asdf) + while (asdf) + asdf; + while (asdf); +} + +/* Test for 'cindent' with two ) on a continuation line */ +{ + if (asdfasdf;asldkfj asdlkfj as;ldkfj sal;d + aal;sdkjf ( ;asldfkja;sldfk + al;sdjfka ;slkdf ) sa;ldkjfsa dlk;) + line up here; +} + + +/* C++ tests: */ + +// foo() these three lines should remain in column 0 +// { +// } + +/* Test for continuation and unterminated lines: */ +{ + i = 99 + 14325 + + 21345 + + 21345 + + 21345 + ( 21345 + + 21345) + + 2345 + + 1234; + c = 1; +} + +/* + testje for indent with empty line + + here */ + +{ + if (testing && + not a joke || + line up here) + hay; + if (testing && + (not a joke || testing + )line up here) + hay; + if (testing && + (not a joke || testing + line up here)) + hay; +} + + +{ + switch (c) + { + case xx: + do + if (asdf) + do + asdfasdf; + while (asdf); + else + asdfasdf; + while (cond); + case yy: + case xx: + case zz: + testing; + } +} + +{ + if (cond) { + foo; + } + else + { + bar; + } +} + +{ + if (alskdfj ;alsdkfjal;skdjf (;sadlkfsa ;dlkf j;alksdfj ;alskdjf + alsdkfj (asldk;fj + awith cino=(0 ;lf this one goes to below the paren with == + ;laksjfd ;lsakdjf ;alskdf asd) + asdfasdf;))) + asdfasdf; +} + + int +func(a, b) + int a; + int c; +{ + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3) + ) +} + +{ + while (asd) + { + if (asdf) + if (test) + if (that) + { + if (asdf) + do + cdasd; + while (as + df); + } + else + if (asdf) + asdf; + else + asdf; + asdf; + } +} + +{ + s = "/*"; b = ';' + s = "/*"; b = ';'; + a = b; +} + +{ + switch (a) + { + case a: + switch (t) + { + case 1: + cmd; + break; + case 2: + cmd; + break; + } + cmd; + break; + case b: + { + int i; + cmd; + } + break; + case c: { + int i; + cmd; + } + case d: if (cond && + test) { /* this line doesn't work right */ + int i; + cmd; + } + break; + } +} + +{ + if (!(vim_strchr(p_cpo, CPO_BUFOPTGLOB) != NULL && entering) && + (bp_to->b_p_initialized || + (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL))) + return; +label : + asdf = asdf ? + asdf : asdf; + asdf = asdf ? + asdf: asdf; +} + +/* Special Comments : This function has the added complexity (compared */ +/* : to addtolist) of having to check for a detail */ +/* : texture and add that to the list first. */ + +char *(array[100]) = { + "testje", + "foo", + "bar", +} + +enum soppie +{ +yes = 0, +no, +maybe +}; + +typedef enum soppie +{ +yes = 0, +no, +maybe +}; + +static enum +{ +yes = 0, +no, +maybe +} soppie; + +public static enum +{ +yes = 0, +no, +maybe +} soppie; + +static private enum +{ +yes = 0, +no, +maybe +} soppie; + +{ + int a, + b; +} + +{ + struct Type + { + int i; + char *str; + } var[] = + { + 0, "zero", + 1, "one", + 2, "two", + 3, "three" + }; + + float matrix[3][3] = + { + { + 0, + 1, + 2 + }, + { + 3, + 4, + 5 + }, + { + 6, + 7, + 8 + } + }; +} + +{ + /* blah ( blah */ + /* where does this go? */ + + /* blah ( blah */ + cmd; + + func(arg1, + /* comment */ + arg2); + a; + { + b; + { + c; /* Hey, NOW it indents?! */ + } + } + + { + func(arg1, + arg2, + arg3); + /* Hey, what am I doing here? Is this coz of the ","? */ + } +} + +main () +{ + if (cond) + { + a = b; + } + if (cond) { + a = c; + } + if (cond) + a = d; + return; +} + +{ + case 2: if (asdf && + asdfasdf) + aasdf; + a = 9; + case 3: if (asdf) + aasdf; + a = 9; + case 4: x = 1; + y = 2; + +label: if (asdf) + here; + +label: if (asdf && + asdfasdf) + { + } + +label: if (asdf && + asdfasdf) { + there; + } + +label: if (asdf && + asdfasdf) + there; +} + +{ + /* + hello with ":set comments= cino=c5" + */ + + /* + hello with ":set comments= cino=" + */ +} + + +{ + if (a < b) { + a = a + 1; + } else + a = a + 2; + + if (a) + do { + testing; + } while (asdfasdf); + a = b + 1; + asdfasdf +} + +class bob +{ + int foo() {return 1;} + int bar; +} + +main() +{ +while(1) +if (foo) +{ +bar; +} +else { +asdf; +} +misplacedline; +} + +{ + if (clipboard.state == SELECT_DONE + && ((row == clipboard.start.lnum + && col >= clipboard.start.col) + || row > clipboard.start.lnum)) +} + +{ +if (1) {i += 4;} +where_am_i; +return 0; +} + +{ +{ +} // sdf(asdf +if (asdf) +asd; +} + +{ +label1: +label2: +} + +{ +int fooRet = foo(pBar1, false /*fKB*/, + true /*fPTB*/, 3 /*nT*/, false /*fDF*/); +f() { +for ( i = 0; + i < m; + /* c */ i++ ) { +a = b; +} +} +} + +{ + f1(/*comment*/); + f2(); +} + +{ +do { +if (foo) { +} else +; +} while (foo); +foo(); // was wrong +} + +int x; // no extra indent because of the ; +void func() +{ +} + +char *tab[] = {"aaa", + "};", /* }; */ NULL} + int indented; +{} + +char *a[] = {"aaa", "bbb", + "ccc", NULL}; +// here + +char *tab[] = {"aaa", + "xx", /* xx */}; /* asdf */ +int not_indented; + +{ + do { + switch (bla) + { + case 1: if (foo) + bar; + } + } while (boo); + wrong; +} + +int foo, + bar; +int foo; + +#if defined(foo) \ + && defined(bar) +char * xx = "asdf\ + foo\ + bor"; +int x; + +char *foo = "asdf\ + asdf\ + asdf", + *bar; + +void f() +{ +#if defined(foo) \ + && defined(bar) +char *foo = "asdf\ + asdf\ + asdf", + *bar; + { + int i; +char *foo = "asdf\ + asdf\ + asdf", + *bar; + } +#endif +} +#endif + +int y; // comment + // comment + + // comment + +{ + Constructor(int a, + int b ) : BaseClass(a) + { + } +} + +void foo() +{ + char one, + two; + struct bla piet, + jan; + enum foo kees, + jannie; + static unsigned sdf, + krap; + unsigned int piet, + jan; + int + kees, + jan; +} + +{ + t(int f, + int d); // ) + d(); +} + +Constructor::Constructor(int a, + int b + ) : + BaseClass(a, + b, + c), + mMember(b), +{ +} + +Constructor::Constructor(int a, + int b ) : + BaseClass(a) +{ +} + +Constructor::Constructor(int a, + int b ) /*x*/ : /*x*/ BaseClass(a), + member(b) +{ +} + +class CAbc : + public BaseClass1, + protected BaseClass2 +{ + int Test() { return FALSE; } + int Test1() { return TRUE; } + + CAbc(int a, int b ) : + BaseClass(a) + { + switch(xxx) + { + case abc: + asdf(); + break; + + case 999: + baer(); + break; + } + } + +public: // <-- this was incoreectly indented before!! + void testfall(); +protected: + void testfall(); +}; + +class CAbc : public BaseClass1, + protected BaseClass2 +{ +}; + +static struct +{ + int a; + int b; +} variable[COUNT] = +{ + { + 123, + 456 + }, + { + 123, + 456 + } +}; + +static struct +{ + int a; + int b; +} variable[COUNT] = +{ + { 123, 456 }, + { 123, 456 } +}; + +void asdf() /* ind_maxparen may cause trouble here */ +{ + if ((0 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1)) break; +} + +foo() +{ + a = cond ? foo() : asdf + + asdf; + + a = cond ? + foo() : asdf + + asdf; +} + +int main(void) +{ + if (a) + if (b) + 2; + else 3; + next_line_of_code(); +} + +barry() +{ + Foo::Foo (int one, + int two) + : something(4) + {} +} + +barry() +{ + Foo::Foo (int one, int two) + : something(4) + {} +} + +Constructor::Constructor(int a, + int b + ) : + BaseClass(a, + b, + c), + mMember(b) +{ +} + int main () + { + if (lala) + do + ++(*lolo); + while (lili + && lele); + lulu; + } + +int main () +{ +switch (c) +{ +case 'c': if (cond) +{ +} +} +} + +main() +{ + (void) MyFancyFuasdfadsfnction( + argument); +} + +main() +{ + char foo[] = "/*"; + /* as + df */ + hello +} + +/* valid namespaces with normal indent */ +namespace +{ +{ + 111111111111; +} +} +namespace /* test */ +{ + 11111111111111111; +} +namespace // test +{ + 111111111111111111; +} +namespace +{ + 111111111111111111; +} +namespace test +{ + 111111111111111111; +} +namespace{ + 111111111111111111; +} +namespace test{ + 111111111111111111; +} +namespace { + 111111111111111111; +} +namespace test { + 111111111111111111; +namespace test2 { + 22222222222222222; +} +} + +/* invalid namespaces use block indent */ +namespace test test2 { + 111111111111111111111; +} +namespace11111111111 { + 111111111111; +} +namespace() { + 1111111111111; +} +namespace() +{ + 111111111111111111; +} +namespace test test2 +{ + 1111111111111111111; +} +namespace111111111 +{ + 111111111111111111; +} + +/* end of AUTO */ + +STARTTEST +:set tw=0 wm=60 columns=80 noai fo=croq +/serious/e +a about life, the universe, and the rest +ENDTEST + +{ + +/* this is + * a real serious important big + * comment + */ + /* insert " about life, the universe, and the rest" after "serious" */ +} + +STARTTEST +:set nocin +/comments +joabout life/happens +jothere/below +oline/this +Ohello +ENDTEST + +{ + /* + * Testing for comments, without 'cin' set + */ + +/* +* what happens here? +*/ + + /* + the end of the comment, try inserting a line below */ + + /* how about + this one */ +} + +STARTTEST +:set cin +/vec2 +== +ENDTEST + +{ + var = this + that + vec[0] * vec[0] + + vec[1] * vec[1] + + vec2[2] * vec[2]; +} + +STARTTEST +:set cin +:set cino=}4 +/testing1 +k2==/testing2 +k2== +ENDTEST + +{ + asdf asdflkajds f; + if (tes & ting) { + asdf asdf asdf ; + asdfa sdf asdf; + } + testing1; + if (tes & ting) + { + asdf asdf asdf ; + asdfa sdf asdf; + } + testing2; +} + +STARTTEST +:set cin +:set cino=(0,)20 +/main +=][ +ENDTEST + +main ( int first_par, /* + * Comment for + * first par + */ + int second_par /* + * Comment for + * second par + */ + ) +{ + func( first_par, /* + * Comment for + * first par + */ + second_par /* + * Comment for + * second par + */ + ); + +} + +STARTTEST +:set cin +:set cino=es,n0s +/main +=][ +ENDTEST + +main(void) +{ + /* Make sure that cino=X0s is not parsed like cino=Xs. */ + if (cond) + foo(); + else + { + bar(); + } +} + +STARTTEST +:set cin +:set cino= +]]=][ +ENDTEST + +{ + do + { + if () + { + if () + asdf; + else + asdf; + } + } while (); + cmd; /* this should go under the } */ +} + +STARTTEST +]]=][ +ENDTEST + +void f() +{ + if ( k() ) { + l(); + + } else { /* Start (two words) end */ + m(); + } + + n(); +} + +STARTTEST +:set cino={s,e-s +]]=][ +ENDTEST + +void f() +{ + if ( k() ) + { + l(); + } else { /* Start (two words) end */ + m(); + } + n(); /* should be under the if () */ +} + +STARTTEST +:set cino={s,fs +]]=/ foo +ENDTEST + +void bar(void) +{ + static array[2][2] = + { + { 1, 2 }, + { 3, 4 }, + } + + while (a) + { + foo(&a); + } + + { + int a; + { + a = a + 1; + } + } + b = a; + } + +void func(void) + { + a = 1; + { + b = 2; + } + c = 3; + d = 4; + } +/* foo */ + +STARTTEST +:set cino= +/while +ohere +ENDTEST + +a() +{ + do { + a = a + + a; + } while ( a ); /* add text under this line */ + if ( a ) + a; +} + +STARTTEST +:set cino= com= +/comment +olabel2: b();
label3 /* post */:
/* pre */ label4:
f(/*com*/);
if (/*com*/)
cmd(); +ENDTEST + +a() +{ +label1: + /* hmm */ + // comment +} + +STARTTEST +:set comments& comments^=s:/*,m:**,ex:*/ +/simple +=5j +ENDTEST + +/* + * A simple comment + */ + +/* + ** A different comment + */ + +STARTTEST +:set cino=c0 +:set comments& comments-=s1:/* comments^=s0:/* +2kdd]]=][ +ENDTEST + +void f() +{ + + /********* + A comment. +*********/ +} + +STARTTEST +:set cino=c0,C1 +:set comments& comments-=s1:/* comments^=s0:/* +2kdd]]=][ +ENDTEST + +void f() +{ + + /********* + A comment. +*********/ +} + +STARTTEST +:set cino= +]]=][ +ENDTEST + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + +STARTTEST +:set cino=(s +2kdd]]=][ +ENDTEST + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + +STARTTEST +:set cino=(s,U1 +2kdd]]=][ +ENDTEST + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + +STARTTEST +:set cino=(0 +2kdd]]=][ +ENDTEST + +void f() +{ + if ( c1 + && ( c2 + || c3)) + foo; +} + +STARTTEST +:set cino=(0,w1 +2kdd]]=][ +ENDTEST + +void f() +{ + if ( c1 + && ( c2 + || c3)) + foo; +} + +STARTTEST +:set cino=(s +2kdd]]=][ +ENDTEST + +void f() +{ + c = c1 && ( + c2 || + c3 + ) && c4; + if ( + c1 && c2 + ) + foo; +} + +STARTTEST +:set cino=(s,m1 +2kdd]]=][ +ENDTEST + +void f() +{ + c = c1 && ( + c2 || + c3 + ) && c4; + if ( + c1 && c2 + ) + foo; +} + +STARTTEST +:set cino=b1 +2kdd]]=][ +ENDTEST + +void f() +{ + switch (x) + { + case 1: + a = b; + break; + default: + a = 0; + break; + } +} + +STARTTEST +:set cino=(0,W5 +2kdd]]=][ +ENDTEST + +void f() +{ + invokeme( + argu, + ment); + invokeme( + argu, + ment + ); + invokeme(argu, + ment + ); +} + +STARTTEST +:set cino=/6 +2kdd]]=][ +ENDTEST + +void f() +{ + statement; + // comment 1 + // comment 2 +} + +STARTTEST +:set cino= +2kdd]]/comment 1/+1 +== +ENDTEST + +void f() +{ + statement; + // comment 1 + // comment 2 +} + +STARTTEST +:set cino=g0 +2kdd]]=][ +ENDTEST + +class CAbc +{ + int Test() { return FALSE; } + +public: // comment + void testfall(); +protected: + void testfall(); +}; + +STARTTEST +:set cino=(0,gs,hs +2kdd]]=][ +ENDTEST + +class Foo : public Bar +{ +public: +virtual void method1(void) = 0; +virtual void method2(int arg1, +int arg2, +int arg3) = 0; +}; + +STARTTEST +:set cino=+20 +2kdd]]=][ +ENDTEST + + void +foo() +{ + if (a) + { + } else + asdf; +} + +STARTTEST +:set cino=(0,W2s +2kdd]]=][ +ENDTEST + +{ + averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd( + asdasdf, + func(asdf, + asdfadsf), + asdfasdf + ); + + /* those are ugly, but consequent */ + + func()->asd(asdasdf, + averylongfunctionname( + abc, + dec)->averylongfunctionname( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf + ), + asdasdf + ); + + averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf( + abc, + dec)->asdfasdfasdf( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf), + asdasdf + ); +} + +STARTTEST +:set cino=M1 +2kdd]]=][ +ENDTEST + +int main () +{ + if (cond1 && + cond2 + ) + foo; +} + +STARTTEST +:set cino=(0,ts +2kdd=][ +ENDTEST + +void func(int a +#if defined(FOO) + , int b + , int c +#endif + ) +{ +} + +STARTTEST +:set cino=(0 +2kdd=][ +ENDTEST + +void +func(int a +#if defined(FOO) + , int b + , int c +#endif + ) +{ +} + +STARTTEST +:set cino& +2kdd=7][ +ENDTEST + +void func(void) +{ + if(x==y) + if(y==z) + foo=1; + else { bar=1; + baz=2; + } + printf("Foo!\n"); +} + +void func1(void) +{ + char* tab[] = {"foo", "bar", + "baz", "quux", + "this line used", "to be indented incorrectly"}; + foo(); +} + +void func2(void) +{ + int tab[] = + {1, 2, + 3, 4, + 5, 6}; + + printf("This line used to be indented incorrectly.\n"); +} + +int foo[] +#ifdef BAR + += { 1, 2, 3, + 4, 5, 6 } + +#endif +; + int baz; + +void func3(void) +{ + int tab[] = { + 1, 2, + 3, 4, + 5, 6}; + +printf("Don't you dare indent this line incorrectly!\n"); +} + +void +func4(a, b, + c) +int a; +int b; +int c; +{ +} + +void +func5( + int a, + int b) +{ +} + +void +func6( + int a) +{ +} + +STARTTEST +:set cino& +:set cino+=l1 +2kdd=][ +ENDTEST + +void func(void) +{ + int tab[] = + { + 1, 2, 3, + 4, 5, 6}; + + printf("Indent this line correctly!\n"); + + switch (foo) + { + case bar: + printf("bar"); + break; + case baz: { + printf("baz"); + break; + } + case quux: +printf("But don't break the indentation of this instruction\n"); +break; + } +} + +STARTTEST +:set cino& +2kdd=][ +ENDTEST + +void func(void) +{ + cout << "a" + << "b" + << ") :" + << "c"; +} + +STARTTEST +:set com=s1:/*,m:*,ex:*/ +]]3jofoo(); +ENDTEST + +void func(void) +{ + /* + * This is a comment. + */ +} + +STARTTEST +:set cino& +2kdd=][ +ENDTEST + +void func(void) +{ + for (int i = 0; i < 10; ++i) + if (i & 1) { + foo(1); + } else + foo(0); +baz(); +} + +STARTTEST +:set cino=k2s,(0 +2kdd3j=][ +ENDTEST + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + + if ( c1 + && ( c2 + || c3)) + foo; + func( c1 + && ( c2 + || c3)) + foo; +} + +STARTTEST +:set cino=k2s,(s +2kdd3j=][ +ENDTEST + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + + if ( c1 + && ( c2 + || c3)) + foo; + func( c1 + && ( c2 + || c3)) + foo; +} + +STARTTEST +:set cino=k2s,(s,U1 +2kdd3j=][ +ENDTEST + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + if (c123456789 + && (c22345 + || c3)) + printf("foo\n"); + + c = c1 && + ( + c2 || + c3 + ) && c4; +} + +STARTTEST +:set cino=k2s,(0,W4 +2kdd3j=][ +ENDTEST + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + if (c123456789 + && (c22345 + || c3)) + printf("foo\n"); + + if ( c1 + && ( c2 + || c3)) + foo; + + a_long_line( + argument, + argument); + a_short_line(argument, + argument); +} + +STARTTEST +:set cino=k2s,u2 +2kdd3j=][ +ENDTEST + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + if (c123456789 + && (c22345 + || c3)) + printf("foo\n"); +} + +STARTTEST +:set cino=k2s,(0,w1 +2kdd3j=][ +ENDTEST + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + if (c123456789 + && (c22345 + || c3)) + printf("foo\n"); + + if ( c1 + && ( c2 + || c3)) + foo; + func( c1 + && ( c2 + || c3)) + foo; +} + +STARTTEST +:set cino=k2,(s +2kdd3j=][ +ENDTEST + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } +} + +STARTTEST +:set cino=N-s +/^NAMESPACESTART +=/^NAMESPACEEND +ENDTEST + +NAMESPACESTART +/* valid namespaces with normal indent */ +namespace +{ + { + 111111111111; +} +} +namespace /* test */ +{ + 11111111111111111; +} +namespace // test +{ + 111111111111111111; +} +namespace +{ + 111111111111111111; +} +namespace test +{ + 111111111111111111; +} +namespace{ + 111111111111111111; +} +namespace test{ + 111111111111111111; +} +namespace { + 111111111111111111; +} +namespace test { + 111111111111111111; +namespace test2 { + 22222222222222222; +} +} + +/* invalid namespaces use block indent */ +namespace test test2 { + 111111111111111111111; +} +namespace11111111111 { + 111111111111; +} +namespace() { + 1111111111111; +} +namespace() +{ + 111111111111111111; +} +namespace test test2 +{ + 1111111111111111111; +} +namespace111111111 +{ + 111111111111111111; +} +NAMESPACEEND + + +STARTTEST +:set cino=j1,J1 +/^JSSTART +=/^JSEND +ENDTEST + +JSSTART +var bar = { +foo: { +that: this, +some: ok, +}, +"bar":{ +a : 2, +b: "123abc", +x: 4, +"y": 5 +} +} +JSEND + +STARTTEST +:set cino=j1,J1 +/^JSSTART +=/^JSEND +ENDTEST + +JSSTART +var foo = [ +1, // indent 8 more +2, +3 +]; // indent 8 less +JSEND + +STARTTEST +:set cino=j1,J1 +/^JSSTART +=/^JSEND +ENDTEST + +JSSTART +function bar() { +var foo = [ +1, +2, +3 +]; // indent 16 less +} +JSEND + +STARTTEST +:set cino=j1,J1 +/^JSSTART +=/^JSEND +ENDTEST + +JSSTART +(function($){ + +var class_name='myclass'; + +function private_method() { +} + +var public_method={ +method: function(options,args){ +private_method(); +} +} + +function init(options) { + +$(this).data(class_name+'_public',$.extend({},{ +foo: 'bar', +bar: 2, // indent 8 more +foobar: [ // indent 8 more +1, // indent 8 more +2, // indent 16 more +3 // indent 16 more +], +callback: function(){ // indent 8 more +return true; // indent 8 more +} // indent 8 more +}, options||{})); +} + +$.fn[class_name]=function() { + +var _arguments=arguments; +return this.each(function(){ + +var options=$(this).data(class_name+'_public'); +if (!options) { +init.apply(this,_arguments); + +} else { +var method=public_method[_arguments[0]]; + +if (typeof(method)!='function') { +console.log(class_name+' has no method "'+_arguments[0]+'"'); +return false; +} +_arguments[0]=options; +method.apply(this,_arguments); +} +}); +} + +})(jQuery); +JSEND + +STARTTEST +:set cino=j1,J1 +/^JSSTART +=/^JSEND +ENDTEST + +JSSTART +function init(options) { +$(this).data(class_name+'_public',$.extend({},{ +foo: 'bar', +bar: 2, +foobar: [ +1, // indent 8 more +2, // indent 8 more +3 // indent 8 more +], +callback: function(){ +return true; +} +}, options||{})); +} +JSEND + +STARTTEST +:set cino=j1,J1 +/^JSSTART +=/^JSEND +ENDTEST + +JSSTART +(function($){ +function init(options) { +$(this).data(class_name+'_public',$.extend({},{ +foo: 'bar', +bar: 2, // indent 8 more +foobar: [ // indent 8 more +1, // indent 8 more +2, // indent 16 more +3 // indent 16 more +], +callback: function(){ // indent 8 more +return true; // indent 8 more +} // indent 8 more +}, options||{})); +} +})(jQuery); +JSEND + +STARTTEST +:g/^STARTTEST/.,/^ENDTEST/d +:1;/start of AUTO/,$wq! test.out +ENDTEST diff --git a/src/nvim/testdir/test3.ok b/src/nvim/testdir/test3.ok new file mode 100644 index 0000000000..d73a5e1230 --- /dev/null +++ b/src/nvim/testdir/test3.ok @@ -0,0 +1,1820 @@ +/* start of AUTO matically checked vim: set ts=4 : */ +{ + if (test) + cmd1; + cmd2; +} + +{ + if (test) + cmd1; + else + cmd2; +} + +{ + if (test) + { + cmd1; + cmd2; + } +} + +{ + if (test) + { + cmd1; + else + } +} + +{ + while (this) + if (test) + cmd1; + cmd2; +} + +{ + while (this) + if (test) + cmd1; + else + cmd2; +} + +{ + if (test) + { + cmd; + } + + if (test) + cmd; +} + +{ + if (test) { + cmd; + } + + if (test) cmd; +} + +{ + cmd1; + for (blah) + while (this) + if (test) + cmd2; + cmd3; +} + +{ + cmd1; + for (blah) + while (this) + if (test) + cmd2; + cmd3; + + if (test) + { + cmd1; + cmd2; + cmd3; + } +} + + +/* Test for 'cindent' do/while mixed with if/else: */ + +{ + do + if (asdf) + asdfasd; + while (cond); + + do + if (asdf) + while (asdf) + asdf; + while (asdf); +} + +/* Test for 'cindent' with two ) on a continuation line */ +{ + if (asdfasdf;asldkfj asdlkfj as;ldkfj sal;d + aal;sdkjf ( ;asldfkja;sldfk + al;sdjfka ;slkdf ) sa;ldkjfsa dlk;) + line up here; +} + + +/* C++ tests: */ + +// foo() these three lines should remain in column 0 +// { +// } + +/* Test for continuation and unterminated lines: */ +{ + i = 99 + 14325 + + 21345 + + 21345 + + 21345 + ( 21345 + + 21345) + + 2345 + + 1234; + c = 1; +} + +/* + testje for indent with empty line + + here */ + +{ + if (testing && + not a joke || + line up here) + hay; + if (testing && + (not a joke || testing + )line up here) + hay; + if (testing && + (not a joke || testing + line up here)) + hay; +} + + +{ + switch (c) + { + case xx: + do + if (asdf) + do + asdfasdf; + while (asdf); + else + asdfasdf; + while (cond); + case yy: + case xx: + case zz: + testing; + } +} + +{ + if (cond) { + foo; + } + else + { + bar; + } +} + +{ + if (alskdfj ;alsdkfjal;skdjf (;sadlkfsa ;dlkf j;alksdfj ;alskdjf + alsdkfj (asldk;fj + awith cino=(0 ;lf this one goes to below the paren with == + ;laksjfd ;lsakdjf ;alskdf asd) + asdfasdf;))) + asdfasdf; +} + + int +func(a, b) + int a; + int c; +{ + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3) + ) +} + +{ + while (asd) + { + if (asdf) + if (test) + if (that) + { + if (asdf) + do + cdasd; + while (as + df); + } + else + if (asdf) + asdf; + else + asdf; + asdf; + } +} + +{ + s = "/*"; b = ';' + s = "/*"; b = ';'; + a = b; +} + +{ + switch (a) + { + case a: + switch (t) + { + case 1: + cmd; + break; + case 2: + cmd; + break; + } + cmd; + break; + case b: + { + int i; + cmd; + } + break; + case c: { + int i; + cmd; + } + case d: if (cond && + test) { /* this line doesn't work right */ + int i; + cmd; + } + break; + } +} + +{ + if (!(vim_strchr(p_cpo, CPO_BUFOPTGLOB) != NULL && entering) && + (bp_to->b_p_initialized || + (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL))) + return; +label : + asdf = asdf ? + asdf : asdf; + asdf = asdf ? + asdf: asdf; +} + +/* Special Comments : This function has the added complexity (compared */ +/* : to addtolist) of having to check for a detail */ +/* : texture and add that to the list first. */ + +char *(array[100]) = { + "testje", + "foo", + "bar", +} + +enum soppie +{ + yes = 0, + no, + maybe +}; + +typedef enum soppie +{ + yes = 0, + no, + maybe +}; + +static enum +{ + yes = 0, + no, + maybe +} soppie; + +public static enum +{ + yes = 0, + no, + maybe +} soppie; + +static private enum +{ + yes = 0, + no, + maybe +} soppie; + +{ + int a, + b; +} + +{ + struct Type + { + int i; + char *str; + } var[] = + { + 0, "zero", + 1, "one", + 2, "two", + 3, "three" + }; + + float matrix[3][3] = + { + { + 0, + 1, + 2 + }, + { + 3, + 4, + 5 + }, + { + 6, + 7, + 8 + } + }; +} + +{ + /* blah ( blah */ + /* where does this go? */ + + /* blah ( blah */ + cmd; + + func(arg1, + /* comment */ + arg2); + a; + { + b; + { + c; /* Hey, NOW it indents?! */ + } + } + + { + func(arg1, + arg2, + arg3); + /* Hey, what am I doing here? Is this coz of the ","? */ + } +} + +main () +{ + if (cond) + { + a = b; + } + if (cond) { + a = c; + } + if (cond) + a = d; + return; +} + +{ + case 2: if (asdf && + asdfasdf) + aasdf; + a = 9; + case 3: if (asdf) + aasdf; + a = 9; + case 4: x = 1; + y = 2; + +label: if (asdf) + here; + +label: if (asdf && + asdfasdf) + { + } + +label: if (asdf && + asdfasdf) { + there; + } + +label: if (asdf && + asdfasdf) + there; +} + +{ + /* + hello with ":set comments= cino=c5" + */ + + /* + hello with ":set comments= cino=" + */ +} + + +{ + if (a < b) { + a = a + 1; + } else + a = a + 2; + + if (a) + do { + testing; + } while (asdfasdf); + a = b + 1; + asdfasdf +} + +class bob +{ + int foo() {return 1;} + int bar; +} + +main() +{ + while(1) + if (foo) + { + bar; + } + else { + asdf; + } + misplacedline; +} + +{ + if (clipboard.state == SELECT_DONE + && ((row == clipboard.start.lnum + && col >= clipboard.start.col) + || row > clipboard.start.lnum)) +} + +{ + if (1) {i += 4;} + where_am_i; + return 0; +} + +{ + { + } // sdf(asdf + if (asdf) + asd; +} + +{ +label1: +label2: +} + +{ + int fooRet = foo(pBar1, false /*fKB*/, + true /*fPTB*/, 3 /*nT*/, false /*fDF*/); + f() { + for ( i = 0; + i < m; + /* c */ i++ ) { + a = b; + } + } +} + +{ + f1(/*comment*/); + f2(); +} + +{ + do { + if (foo) { + } else + ; + } while (foo); + foo(); // was wrong +} + +int x; // no extra indent because of the ; +void func() +{ +} + +char *tab[] = {"aaa", + "};", /* }; */ NULL} + int indented; +{} + +char *a[] = {"aaa", "bbb", + "ccc", NULL}; +// here + +char *tab[] = {"aaa", + "xx", /* xx */}; /* asdf */ +int not_indented; + +{ + do { + switch (bla) + { + case 1: if (foo) + bar; + } + } while (boo); + wrong; +} + +int foo, + bar; +int foo; + +#if defined(foo) \ + && defined(bar) +char * xx = "asdf\ + foo\ + bor"; +int x; + +char *foo = "asdf\ + asdf\ + asdf", + *bar; + +void f() +{ +#if defined(foo) \ + && defined(bar) + char *foo = "asdf\ + asdf\ + asdf", + *bar; + { + int i; + char *foo = "asdf\ + asdf\ + asdf", + *bar; + } +#endif +} +#endif + +int y; // comment +// comment + +// comment + +{ + Constructor(int a, + int b ) : BaseClass(a) + { + } +} + +void foo() +{ + char one, + two; + struct bla piet, + jan; + enum foo kees, + jannie; + static unsigned sdf, + krap; + unsigned int piet, + jan; + int + kees, + jan; +} + +{ + t(int f, + int d); // ) + d(); +} + +Constructor::Constructor(int a, + int b + ) : + BaseClass(a, + b, + c), + mMember(b), +{ +} + +Constructor::Constructor(int a, + int b ) : + BaseClass(a) +{ +} + +Constructor::Constructor(int a, + int b ) /*x*/ : /*x*/ BaseClass(a), + member(b) +{ +} + +class CAbc : + public BaseClass1, + protected BaseClass2 +{ + int Test() { return FALSE; } + int Test1() { return TRUE; } + + CAbc(int a, int b ) : + BaseClass(a) + { + switch(xxx) + { + case abc: + asdf(); + break; + + case 999: + baer(); + break; + } + } + + public: // <-- this was incoreectly indented before!! + void testfall(); + protected: + void testfall(); +}; + +class CAbc : public BaseClass1, + protected BaseClass2 +{ +}; + +static struct +{ + int a; + int b; +} variable[COUNT] = +{ + { + 123, + 456 + }, + { + 123, + 456 + } +}; + +static struct +{ + int a; + int b; +} variable[COUNT] = +{ + { 123, 456 }, + { 123, 456 } +}; + +void asdf() /* ind_maxparen may cause trouble here */ +{ + if ((0 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1)) break; +} + +foo() +{ + a = cond ? foo() : asdf + + asdf; + + a = cond ? + foo() : asdf + + asdf; +} + +int main(void) +{ + if (a) + if (b) + 2; + else 3; + next_line_of_code(); +} + +barry() +{ + Foo::Foo (int one, + int two) + : something(4) + {} +} + +barry() +{ + Foo::Foo (int one, int two) + : something(4) + {} +} + +Constructor::Constructor(int a, + int b + ) : + BaseClass(a, + b, + c), + mMember(b) +{ +} +int main () +{ + if (lala) + do + ++(*lolo); + while (lili + && lele); + lulu; +} + +int main () +{ + switch (c) + { + case 'c': if (cond) + { + } + } +} + +main() +{ + (void) MyFancyFuasdfadsfnction( + argument); +} + +main() +{ + char foo[] = "/*"; + /* as + df */ + hello +} + +/* valid namespaces with normal indent */ +namespace +{ + { + 111111111111; + } +} +namespace /* test */ +{ + 11111111111111111; +} +namespace // test +{ + 111111111111111111; +} +namespace +{ + 111111111111111111; +} +namespace test +{ + 111111111111111111; +} +namespace{ + 111111111111111111; +} +namespace test{ + 111111111111111111; +} +namespace { + 111111111111111111; +} +namespace test { + 111111111111111111; + namespace test2 { + 22222222222222222; + } +} + +/* invalid namespaces use block indent */ +namespace test test2 { + 111111111111111111111; +} +namespace11111111111 { + 111111111111; +} +namespace() { + 1111111111111; +} +namespace() +{ + 111111111111111111; +} +namespace test test2 +{ + 1111111111111111111; +} +namespace111111111 +{ + 111111111111111111; +} + +/* end of AUTO */ + + +{ + +/* this is + * a real serious + * about life, the + * universe, and the + * rest important big + * comment + */ + /* insert " about life, the universe, and the rest" after "serious" */ +} + + +{ + /* + * Testing for comments, without 'cin' set + */ +about life + +/* +* what happens here? +*/ +there + + /* + the end of the comment, try inserting a line below */ +line + + /* how about +hello + this one */ +} + + +{ + var = this + that + vec[0] * vec[0] + + vec[1] * vec[1] + + vec2[2] * vec[2]; +} + + +{ + asdf asdflkajds f; + if (tes & ting) { + asdf asdf asdf ; + asdfa sdf asdf; + } + testing1; + if (tes & ting) + { + asdf asdf asdf ; + asdfa sdf asdf; + } + testing2; +} + + +main ( int first_par, /* + * Comment for + * first par + */ + int second_par /* + * Comment for + * second par + */ + ) +{ + func( first_par, /* + * Comment for + * first par + */ + second_par /* + * Comment for + * second par + */ + ); + +} + + +main(void) +{ + /* Make sure that cino=X0s is not parsed like cino=Xs. */ + if (cond) + foo(); + else + { + bar(); + } +} + + +{ + do + { + if () + { + if () + asdf; + else + asdf; + } + } while (); + cmd; /* this should go under the } */ +} + + +void f() +{ + if ( k() ) { + l(); + + } else { /* Start (two words) end */ + m(); + } + + n(); +} + + +void f() + { + if ( k() ) + { + l(); + } else { /* Start (two words) end */ + m(); + } + n(); /* should be under the if () */ +} + + +void bar(void) + { + static array[2][2] = + { + { 1, 2 }, + { 3, 4 }, + } + + while (a) + { + foo(&a); + } + + { + int a; + { + a = a + 1; + } + } + b = a; + } + +void func(void) + { + a = 1; + { + b = 2; + } + c = 3; + d = 4; + } +/* foo */ + + +a() +{ + do { + a = a + + a; + } while ( a ); /* add text under this line */ + here + if ( a ) + a; +} + + +a() +{ +label1: + /* hmm */ + // comment +label2: b(); +label3 /* post */: +/* pre */ label4: + f(/*com*/); + if (/*com*/) + cmd(); +} + + +/* + * A simple comment + */ + +/* +** A different comment +*/ + + +void f() +{ + + /********* + A comment. + *********/ +} + + +void f() +{ + + /********* + A comment. + *********/ +} + + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + + +void f() +{ + if ( c1 + && ( c2 + || c3)) + foo; +} + + +void f() +{ + if ( c1 + && ( c2 + || c3)) + foo; +} + + +void f() +{ + c = c1 && ( + c2 || + c3 + ) && c4; + if ( + c1 && c2 + ) + foo; +} + + +void f() +{ + c = c1 && ( + c2 || + c3 + ) && c4; + if ( + c1 && c2 + ) + foo; +} + + +void f() +{ + switch (x) + { + case 1: + a = b; + break; + default: + a = 0; + break; + } +} + + +void f() +{ + invokeme( + argu, + ment); + invokeme( + argu, + ment + ); + invokeme(argu, + ment + ); +} + + +void f() +{ + statement; + // comment 1 + // comment 2 +} + + +void f() +{ + statement; + // comment 1 + // comment 2 +} + + +class CAbc +{ + int Test() { return FALSE; } + +public: // comment + void testfall(); +protected: + void testfall(); +}; + + +class Foo : public Bar +{ + public: + virtual void method1(void) = 0; + virtual void method2(int arg1, + int arg2, + int arg3) = 0; +}; + + + void +foo() +{ + if (a) + { + } else + asdf; +} + + +{ + averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd( + asdasdf, + func(asdf, + asdfadsf), + asdfasdf + ); + + /* those are ugly, but consequent */ + + func()->asd(asdasdf, + averylongfunctionname( + abc, + dec)->averylongfunctionname( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf + ), + asdasdf + ); + + averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf( + abc, + dec)->asdfasdfasdf( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf), + asdasdf + ); +} + + +int main () +{ + if (cond1 && + cond2 + ) + foo; +} + + +void func(int a +#if defined(FOO) + , int b + , int c +#endif + ) +{ +} + + + void +func(int a +#if defined(FOO) + , int b + , int c +#endif + ) +{ +} + + +void func(void) +{ + if(x==y) + if(y==z) + foo=1; + else { bar=1; + baz=2; + } + printf("Foo!\n"); +} + +void func1(void) +{ + char* tab[] = {"foo", "bar", + "baz", "quux", + "this line used", "to be indented incorrectly"}; + foo(); +} + +void func2(void) +{ + int tab[] = + {1, 2, + 3, 4, + 5, 6}; + + printf("This line used to be indented incorrectly.\n"); +} + +int foo[] +#ifdef BAR + += { 1, 2, 3, + 4, 5, 6 } + +#endif + ; +int baz; + +void func3(void) +{ + int tab[] = { + 1, 2, + 3, 4, + 5, 6}; + + printf("Don't you dare indent this line incorrectly!\n"); +} + + void +func4(a, b, + c) + int a; + int b; + int c; +{ +} + + void +func5( + int a, + int b) +{ +} + + void +func6( + int a) +{ +} + + +void func(void) +{ + int tab[] = + { + 1, 2, 3, + 4, 5, 6}; + + printf("Indent this line correctly!\n"); + + switch (foo) + { + case bar: + printf("bar"); + break; + case baz: { + printf("baz"); + break; + } + case quux: + printf("But don't break the indentation of this instruction\n"); + break; + } +} + + +void func(void) +{ + cout << "a" + << "b" + << ") :" + << "c"; +} + + +void func(void) +{ + /* + * This is a comment. + */ + foo(); +} + + +void func(void) +{ + for (int i = 0; i < 10; ++i) + if (i & 1) { + foo(1); + } else + foo(0); + baz(); +} + + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + + if ( c1 + && ( c2 + || c3)) + foo; + func( c1 + && ( c2 + || c3)) + foo; +} + + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + + if ( c1 + && ( c2 + || c3)) + foo; + func( c1 + && ( c2 + || c3)) + foo; +} + + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + if (c123456789 + && (c22345 + || c3)) + printf("foo\n"); + + c = c1 && + ( + c2 || + c3 + ) && c4; +} + + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + if (c123456789 + && (c22345 + || c3)) + printf("foo\n"); + + if ( c1 + && ( c2 + || c3)) + foo; + + a_long_line( + argument, + argument); + a_short_line(argument, + argument); +} + + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + if (c123456789 + && (c22345 + || c3)) + printf("foo\n"); +} + + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } + if (c123456789 + && (c22345 + || c3)) + printf("foo\n"); + + if ( c1 + && ( c2 + || c3)) + foo; + func( c1 + && ( c2 + || c3)) + foo; +} + + +void func(void) +{ + if (condition1 + && condition2) + action(); + function(argument1 + && argument2); + + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3)) + { + } +} + + +NAMESPACESTART +/* valid namespaces with normal indent */ +namespace +{ +{ + 111111111111; +} +} +namespace /* test */ +{ +11111111111111111; +} +namespace // test +{ +111111111111111111; +} +namespace +{ +111111111111111111; +} +namespace test +{ +111111111111111111; +} +namespace{ +111111111111111111; +} +namespace test{ +111111111111111111; +} +namespace { +111111111111111111; +} +namespace test { +111111111111111111; +namespace test2 { +22222222222222222; +} +} + +/* invalid namespaces use block indent */ +namespace test test2 { + 111111111111111111111; +} +namespace11111111111 { + 111111111111; +} +namespace() { + 1111111111111; +} +namespace() +{ + 111111111111111111; +} +namespace test test2 +{ + 1111111111111111111; +} +namespace111111111 +{ + 111111111111111111; +} +NAMESPACEEND + + + +JSSTART +var bar = { + foo: { + that: this, + some: ok, + }, + "bar":{ + a : 2, + b: "123abc", + x: 4, + "y": 5 + } +} +JSEND + + +JSSTART +var foo = [ +1, // indent 8 more + 2, + 3 + ]; // indent 8 less +JSEND + + +JSSTART +function bar() { + var foo = [ + 1, + 2, + 3 + ]; // indent 16 less +} +JSEND + + +JSSTART +(function($){ + + var class_name='myclass'; + + function private_method() { + } + + var public_method={ + method: function(options,args){ + private_method(); + } + } + + function init(options) { + + $(this).data(class_name+'_public',$.extend({},{ + foo: 'bar', + bar: 2, // indent 8 more + foobar: [ // indent 8 more + 1, // indent 8 more + 2, // indent 16 more + 3 // indent 16 more + ], + callback: function(){ // indent 8 more + return true; // indent 8 more + } // indent 8 more + }, options||{})); + } + + $.fn[class_name]=function() { + + var _arguments=arguments; + return this.each(function(){ + + var options=$(this).data(class_name+'_public'); + if (!options) { + init.apply(this,_arguments); + + } else { + var method=public_method[_arguments[0]]; + + if (typeof(method)!='function') { + console.log(class_name+' has no method "'+_arguments[0]+'"'); + return false; + } + _arguments[0]=options; + method.apply(this,_arguments); + } + }); + } + +})(jQuery); +JSEND + + +JSSTART +function init(options) { + $(this).data(class_name+'_public',$.extend({},{ + foo: 'bar', + bar: 2, + foobar: [ + 1, // indent 8 more + 2, // indent 8 more + 3 // indent 8 more + ], + callback: function(){ + return true; + } + }, options||{})); +} +JSEND + + +JSSTART +(function($){ + function init(options) { + $(this).data(class_name+'_public',$.extend({},{ + foo: 'bar', + bar: 2, // indent 8 more + foobar: [ // indent 8 more + 1, // indent 8 more + 2, // indent 16 more + 3 // indent 16 more + ], + callback: function(){ // indent 8 more + return true; // indent 8 more + } // indent 8 more + }, options||{})); + } +})(jQuery); +JSEND + diff --git a/src/nvim/testdir/test30.in b/src/nvim/testdir/test30.in new file mode 100644 index 0000000000..4a8778d2de --- /dev/null +++ b/src/nvim/testdir/test30.in @@ -0,0 +1,222 @@ +Test for a lot of variations of the 'fileformats' option + +Note: This test will fail if "cat" is not available. + +STARTTEST +:so small.vim +:" first write three test files, one in each format +:set fileformat=unix +:set fileformats= +:/^1/w! XX1 +:/^2/w! XX2 +:/^3/w! XX3 +:/^4/w! XX4 +:/^5/w! XX5 +:/^6/w! XX6 +:/^7/w! XX7 +:/^8/w! XX8 +:/^9/w! XX9 +:/^10/w! XX10 +:/^unix/;/eof/-1w! XXUnix +:/^dos/;/eof/-1w! XXDos +:set bin noeol +:$w! XXMac +:set nobin eol +:bwipe XXUnix XXDos XXMac +:" create mixed format files +:if has("vms") +: !copy XXUnix,XXDos XXUxDs. +: !copy XXUnix,XXMac XXUxMac. +: !copy XXDos,XXMac XXDosMac. +: !copy XXUnix,XXDos,XXMac XXUxDsMc. +:elseif has("win32") +: !copy /b XXUnix+XXDos XXUxDs +: !copy /b XXUnix+XXMac XXUxMac +: !copy /b XXDos+XXMac XXDosMac +: !copy /b XXUnix+XXDos+XXMac XXUxDsMc +:else +: !cat XXUnix XXDos >XXUxDs +: !cat XXUnix XXMac >XXUxMac +: !cat XXDos XXMac >XXDosMac +: !cat XXUnix XXDos XXMac >XXUxDsMc +:endif +:" +:" try reading and writing with 'fileformats' empty +:set fileformat=unix +:e! XXUnix +:w! test.out +:e! XXDos +:w! XXtt01 +:e! XXMac +:w! XXtt02 +:bwipe XXUnix XXDos XXMac +:set fileformat=dos +:e! XXUnix +:w! XXtt11 +:e! XXDos +:w! XXtt12 +:e! XXMac +:w! XXtt13 +:bwipe XXUnix XXDos XXMac +:set fileformat=mac +:e! XXUnix +:w! XXtt21 +:e! XXDos +:w! XXtt22 +:e! XXMac +:w! XXtt23 +:bwipe XXUnix XXDos XXMac +:" +:" try reading and writing with 'fileformats' set to one format +:set fileformats=unix +:e! XXUxDsMc +:w! XXtt31 +:bwipe XXUxDsMc +:set fileformats=dos +:e! XXUxDsMc +:w! XXtt32 +:bwipe XXUxDsMc +:set fileformats=mac +:e! XXUxDsMc +:w! XXtt33 +:bwipe XXUxDsMc +:" +:" try reading and writing with 'fileformats' set to two formats +:set fileformats=unix,dos +:e! XXUxDsMc +:w! XXtt41 +:bwipe XXUxDsMc +:e! XXUxMac +:w! XXtt42 +:bwipe XXUxMac +:e! XXDosMac +:w! XXtt43 +:bwipe XXDosMac +:set fileformats=unix,mac +:e! XXUxDs +:w! XXtt51 +:bwipe XXUxDs +:e! XXUxDsMc +:w! XXtt52 +:bwipe XXUxDsMc +:e! XXDosMac +:w! XXtt53 +:bwipe XXDosMac +:set fileformats=dos,mac +:e! XXUxDs +:w! XXtt61 +:bwipe XXUxDs +:e! XXUxMac +:w! XXtt62 +:bwipe XXUxMac +:e! XXUxDsMc +:w! XXtt63 +:bwipe XXUxDsMc +:" +:" try reading and writing with 'fileformats' set to three formats +:set fileformats=unix,dos,mac +:e! XXUxDsMc +:w! XXtt71 +:bwipe XXUxDsMc +:set fileformats=mac,dos,unix +:e! XXUxDsMc +:w! XXtt81 +:bwipe XXUxDsMc +:" try with 'binary' set +:set fileformats=mac,unix,dos +:set binary +:e! XXUxDsMc +:w! XXtt91 +:bwipe XXUxDsMc +:set fileformats=mac +:e! XXUxDsMc +:w! XXtt92 +:bwipe XXUxDsMc +:set fileformats=dos +:e! XXUxDsMc +:w! XXtt93 +:" +:" Append "END" to each file so that we can see what the last written char was. +:set fileformat=unix nobin +ggdGaEND:w >>XXtt01 +:w >>XXtt02 +:w >>XXtt11 +:w >>XXtt12 +:w >>XXtt13 +:w >>XXtt21 +:w >>XXtt22 +:w >>XXtt23 +:w >>XXtt31 +:w >>XXtt32 +:w >>XXtt33 +:w >>XXtt41 +:w >>XXtt42 +:w >>XXtt43 +:w >>XXtt51 +:w >>XXtt52 +:w >>XXtt53 +:w >>XXtt61 +:w >>XXtt62 +:w >>XXtt63 +:w >>XXtt71 +:w >>XXtt81 +:w >>XXtt91 +:w >>XXtt92 +:w >>XXtt93 +:" +:" Concatenate the results. +:" Make fileformat of test.out the native fileformat. +:" Add a newline at the end. +:set binary +:e! test.out +:$r XXtt01 +:$r XXtt02 +Go1:$r XXtt11 +:$r XXtt12 +:$r XXtt13 +Go2:$r XXtt21 +:$r XXtt22 +:$r XXtt23 +Go3:$r XXtt31 +:$r XXtt32 +:$r XXtt33 +Go4:$r XXtt41 +:$r XXtt42 +:$r XXtt43 +Go5:$r XXtt51 +:$r XXtt52 +:$r XXtt53 +Go6:$r XXtt61 +:$r XXtt62 +:$r XXtt63 +Go7:$r XXtt71 +Go8:$r XXtt81 +Go9:$r XXtt91 +:$r XXtt92 +:$r XXtt93 +Go10:$r XXUnix +:set nobinary ff& +:w +:qa! +ENDTEST + +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 + +unix +unix +eof + +dos
+dos
+eof + +mac
mac
diff --git a/src/nvim/testdir/test30.ok b/src/nvim/testdir/test30.ok new file mode 100644 index 0000000000..380ce67061 --- /dev/null +++ b/src/nvim/testdir/test30.ok @@ -0,0 +1,121 @@ +unix +unix +dos
+dos
+END +mac
mac
+END +1 +unix
+unix
+END +dos
+dos
+END +mac
mac
+END +2 +unix +unix +
END +dos
+dos
+
END +mac
mac
END +3 +unix +unix +dos
+dos
+mac
mac
+END +unix
+unix
+dos
+dos
+mac
mac
+END +unix +unix +dos
+dos
+mac
mac
END +4 +unix +unix +dos
+dos
+mac
mac
+END +unix +unix +mac
mac
+END +dos
+dos
+mac
mac
+END +5 +unix +unix +dos
+dos
+END +unix +unix +dos
+dos
+mac
mac
+END +dos
+dos
+mac
mac
END +6 +unix
+unix
+dos
+dos
+END +unix
+unix
+mac
mac
+END +unix
+unix
+dos
+dos
+mac
mac
+END +7 +unix +unix +dos
+dos
+mac
mac
+END +8 +unix +unix +dos
+dos
+mac
mac
+END +9 +unix +unix +dos
+dos
+mac
mac
END +unix +unix +dos
+dos
+mac
mac
END +unix +unix +dos
+dos
+mac
mac
END +10 +unix +unix diff --git a/src/nvim/testdir/test31.in b/src/nvim/testdir/test31.in new file mode 100644 index 0000000000..7dc2334781 --- /dev/null +++ b/src/nvim/testdir/test31.in @@ -0,0 +1,75 @@ +Test for commands that close windows and/or buffers: +:quit +:close +:hide +:only +:sall +:all +:ball +:buf +:edit + +STARTTEST +:so tiny.vim +GA 1:$w! Xtest1 +$r2:$w! Xtest2 +$r3:$w! Xtest3 +:n! Xtest1 Xtest2 +A 1:set hidden +:" test for working :n when hidden set; write "testtext 2" +:n +:w! test.out +:" test for failing :rew when hidden not set; write "testtext 2 2" +:set nohidden +A 2:rew +:w >>test.out +:" test for working :rew when hidden set; write "testtext 1 1" +:set hidden +:rew +:w >>test.out +:" test for :all keeping a buffer when it's modified; write "testtext 1 1 1" +:set nohidden +A 1:sp +:n Xtest2 Xtest3 +:all +:1wincmd w +:w >>test.out +:" test abandoning changed buffer, should be unloaded even when 'hidden' set +:" write "testtext 2 2" twice +:set hidden +A 1:q! +:w >>test.out +:unhide +:w >>test.out +:" test ":hide" hides anyway when 'hidden' not set; write "testtext 3" +:set nohidden +A 2:hide +:w >>test.out +:" test ":edit" failing in modified buffer when 'hidden' not set +:" write "testtext 3 3" +A 3:e Xtest1 +:w >>test.out +:" test ":edit" working in modified buffer when 'hidden' set; write "testtext 1" +:set hidden +:e Xtest1 +:w >>test.out +:" test ":close" not hiding when 'hidden' not set in modified buffer; +:" write "testtext 3 3 3" +:sp Xtest3 +:set nohidden +A 3:close +:w >>test.out +:" test ":close!" does hide when 'hidden' not set in modified buffer; +:" write "testtext 1" +A 3:close! +:w >>test.out +:set nohidden +:" test ":all!" hides changed buffer; write "testtext 2 2 2" +:sp Xtest4 +GA 4:all! +:1wincmd w +:w >>test.out +:qa! +ENDTEST + +testtext diff --git a/src/nvim/testdir/test31.ok b/src/nvim/testdir/test31.ok new file mode 100644 index 0000000000..185bdc768e --- /dev/null +++ b/src/nvim/testdir/test31.ok @@ -0,0 +1,12 @@ +testtext 2 +testtext 2 2 +testtext 1 1 +testtext 1 1 1 +testtext 2 2 +testtext 2 2 +testtext 3 +testtext 3 3 +testtext 1 +testtext 3 3 3 +testtext 1 +testtext 2 2 2 diff --git a/src/nvim/testdir/test32.in b/src/nvim/testdir/test32.in new file mode 100644 index 0000000000..6b399fa6c6 --- /dev/null +++ b/src/nvim/testdir/test32.in @@ -0,0 +1,60 @@ +Test for insert expansion + +:se cpt=.,w +* add-expands (word from next line) from other window +* add-expands (current buffer first) +* Local expansion, ends in an empty line (unless it becomes a global expansion) +* starts Local and switches to global add-expansion +:se cpt=.,w,i +* i-add-expands and switches to local +* add-expands lines (it would end in an empty line if it didn't ignored it self) +:se cpt=kXtestfile +* checks k-expansion, and file expansion (use Xtest11 instead of test11, +* because TEST11.OUT may match first on DOS) +:se cpt=w +* checks make_cyclic in other window +:se cpt=u nohid +* checks unloaded buffer expansion +* checks adding mode abortion +:se cpt=t,d +* tag expansion, define add-expansion interrupted +* t-expansion + +STARTTEST +:so small.vim +:se nocp viminfo+=nviminfo cpt=.,w ff=unix | $-2,$w!Xtestfile | set ff& +:se cot= +nO#include "Xtestfile" +ru +O + + +:se cpt=.,w,i +kOM + +:se cpt=kXtestfile +:w Xtest11.one +:w Xtest11.two +OIXA +:" use CTRL-X CTRL-F to complete Xtest11.one, remove it and then use +:" CTRL-X CTRL-F again to verify this doesn't cause trouble. +OXddk +:se cpt=w +OST +:se cpt=u nohid +oOEN +unl +:se cpt=t,d def=^\\k* tags=Xtestfile notagbsearch +O +a +:wq! test.out +ENDTEST + +start of testfile +run1 +run2 +end of testfile + +test11 36Gepeto /Tag/ +asd test11file 36G +Makefile to run diff --git a/src/nvim/testdir/test32.ok b/src/nvim/testdir/test32.ok new file mode 100644 index 0000000000..afc4463fac --- /dev/null +++ b/src/nvim/testdir/test32.ok @@ -0,0 +1,15 @@ +#include "Xtestfile" +run1 run3 +run3 run3 + +Makefile to run3 +Makefile to run3 +Makefile to run3 +Xtest11.two +STARTTEST +ENDTEST +unless +test11file 36Gepeto /Tag/ asd +asd +run1 run2 + diff --git a/src/nvim/testdir/test33.in b/src/nvim/testdir/test33.in new file mode 100644 index 0000000000..5644760402 --- /dev/null +++ b/src/nvim/testdir/test33.in @@ -0,0 +1,34 @@ +Test for 'lisp' +If the lisp feature is not enabled, this will fail! + +STARTTEST +:so small.vim +:set lisp +/^(defun +=G:/^(defun/,$w! test.out +:q! +ENDTEST + +(defun html-file (base) +(format nil "~(~A~).html" base)) + +(defmacro page (name title &rest body) +(let ((ti (gensym))) +`(with-open-file (*standard-output* +(html-file ,name) +:direction :output +:if-exists :supersede) +(let ((,ti ,title)) +(as title ,ti) +(with center +(as h2 (string-upcase ,ti))) +(brs 3) +,@body)))) + +;;; Utilities for generating links + +(defmacro with-link (dest &rest body) +`(progn +(format t "<a href=\"~A\">" (html-file ,dest)) +,@body +(princ "</a>"))) diff --git a/src/nvim/testdir/test33.ok b/src/nvim/testdir/test33.ok new file mode 100644 index 0000000000..cd1d87a14b --- /dev/null +++ b/src/nvim/testdir/test33.ok @@ -0,0 +1,23 @@ +(defun html-file (base) + (format nil "~(~A~).html" base)) + +(defmacro page (name title &rest body) + (let ((ti (gensym))) + `(with-open-file (*standard-output* + (html-file ,name) + :direction :output + :if-exists :supersede) + (let ((,ti ,title)) + (as title ,ti) + (with center + (as h2 (string-upcase ,ti))) + (brs 3) + ,@body)))) + +;;; Utilities for generating links + +(defmacro with-link (dest &rest body) + `(progn + (format t "<a href=\"~A\">" (html-file ,dest)) + ,@body + (princ "</a>"))) diff --git a/src/nvim/testdir/test34.in b/src/nvim/testdir/test34.in new file mode 100644 index 0000000000..71ee5f63b2 --- /dev/null +++ b/src/nvim/testdir/test34.in @@ -0,0 +1,87 @@ +Test for user functions. +Also test an <expr> mapping calling a function. +Also test that a builtin function cannot be replaced. +Also test for regression when calling arbitrary expression. + +STARTTEST +:so small.vim +:function Table(title, ...) +: let ret = a:title +: let idx = 1 +: while idx <= a:0 +: exe "let ret = ret . a:" . idx +: let idx = idx + 1 +: endwhile +: return ret +:endfunction +:function Compute(n1, n2, divname) +: if a:n2 == 0 +: return "fail" +: endif +: exe "let g:" . a:divname . " = ". a:n1 / a:n2 +: return "ok" +:endfunction +:func Expr1() +: normal! v +: return "111" +:endfunc +:func Expr2() +: call search('XX', 'b') +: return "222" +:endfunc +:func ListItem() +: let g:counter += 1 +: return g:counter . '. ' +:endfunc +:func ListReset() +: let g:counter = 0 +: return '' +:endfunc +:func FuncWithRef(a) +: unlet g:FuncRef +: return a:a +:endfunc +:let g:FuncRef=function("FuncWithRef") +:let counter = 0 +:inoremap <expr> ( ListItem() +:inoremap <expr> [ ListReset() +:imap <expr> + Expr1() +:imap <expr> * Expr2() +:let retval = "nop" +/^here +C=Table("xxx", 4, "asdf") + =Compute(45, 0, "retval") + =retval + =Compute(45, 5, "retval") + =retval + =g:FuncRef(333) + +XX+-XX +---*--- +(one +(two +[(one again:call append(line('$'), max([1, 2, 3])) +:call extend(g:, {'max': function('min')}) +:call append(line('$'), max([1, 2, 3])) +:try +: " Regression: the first line below used to throw ?E110: Missing ')'? +: " Second is here just to prove that this line is correct when not skipping +: " rhs of &&. +: $put =(0&&(function('tr'))(1, 2, 3)) +: $put =(1&&(function('tr'))(1, 2, 3)) +:catch +: $put ='!!! Unexpected exception:' +: $put =v:exception +:endtry +:$-9,$w! test.out +:delfunc Table +:delfunc Compute +:delfunc Expr1 +:delfunc Expr2 +:delfunc ListItem +:delfunc ListReset +:unlet retval counter +:q! +ENDTEST + +here diff --git a/src/nvim/testdir/test34.ok b/src/nvim/testdir/test34.ok new file mode 100644 index 0000000000..97995de80e --- /dev/null +++ b/src/nvim/testdir/test34.ok @@ -0,0 +1,10 @@ +xxx4asdf fail nop ok 9 333 +XX111-XX +---222--- +1. one +2. two +1. one again +3 +3 +0 +1 diff --git a/src/nvim/testdir/test35.in b/src/nvim/testdir/test35.in new file mode 100644 index 0000000000..ba97911a1d --- /dev/null +++ b/src/nvim/testdir/test35.in @@ -0,0 +1,21 @@ +Test Ctrl-A and Ctrl-X, which increment and decrement decimal, hexadecimal, +and octal numbers. + +STARTTEST +/^start-here +:set nrformats=octal,hex +j102ll64128$ +:set nrformats=octal +0102l2w65129blx6lD +:set nrformats=hex +0101l257Txldt +:set nrformats= +0200l100w78k +:$-3,$wq! test.out +ENDTEST + +start-here +100 0x100 077 0 +100 0x100 077 +100 0x100 077 0xfF 0xFf +100 0x100 077 diff --git a/src/nvim/testdir/test35.ok b/src/nvim/testdir/test35.ok new file mode 100644 index 0000000000..093ad958ac --- /dev/null +++ b/src/nvim/testdir/test35.ok @@ -0,0 +1,4 @@ +0 0x0ff 0000 -1 +0 1x100 0777777 +-1 0x0 078 0xFE 0xfe +-100 -100x100 000 diff --git a/src/nvim/testdir/test36.in b/src/nvim/testdir/test36.in new file mode 100644 index 0000000000..8cdb5262bd --- /dev/null +++ b/src/nvim/testdir/test36.in @@ -0,0 +1,105 @@ +Test character classes in regexp using regexpengine 0, 1, 2. + +STARTTEST +/^start-here/+1 +Y:s/\%#=0\d//g +p:s/\%#=1\d//g +p:s/\%#=2\d//g +p:s/\%#=0[0-9]//g +p:s/\%#=1[0-9]//g +p:s/\%#=2[0-9]//g +p:s/\%#=0\D//g +p:s/\%#=1\D//g +p:s/\%#=2\D//g +p:s/\%#=0[^0-9]//g +p:s/\%#=1[^0-9]//g +p:s/\%#=2[^0-9]//g +p:s/\%#=0\o//g +p:s/\%#=1\o//g +p:s/\%#=2\o//g +p:s/\%#=0[0-7]//g +p:s/\%#=1[0-7]//g +p:s/\%#=2[0-7]//g +p:s/\%#=0\O//g +p:s/\%#=1\O//g +p:s/\%#=2\O//g +p:s/\%#=0[^0-7]//g +p:s/\%#=1[^0-7]//g +p:s/\%#=2[^0-7]//g +p:s/\%#=0\x//g +p:s/\%#=1\x//g +p:s/\%#=2\x//g +p:s/\%#=0[0-9A-Fa-f]//g +p:s/\%#=1[0-9A-Fa-f]//g +p:s/\%#=2[0-9A-Fa-f]//g +p:s/\%#=0\X//g +p:s/\%#=1\X//g +p:s/\%#=2\X//g +p:s/\%#=0[^0-9A-Fa-f]//g +p:s/\%#=1[^0-9A-Fa-f]//g +p:s/\%#=2[^0-9A-Fa-f]//g +p:s/\%#=0\w//g +p:s/\%#=1\w//g +p:s/\%#=2\w//g +p:s/\%#=0[0-9A-Za-z_]//g +p:s/\%#=1[0-9A-Za-z_]//g +p:s/\%#=2[0-9A-Za-z_]//g +p:s/\%#=0\W//g +p:s/\%#=1\W//g +p:s/\%#=2\W//g +p:s/\%#=0[^0-9A-Za-z_]//g +p:s/\%#=1[^0-9A-Za-z_]//g +p:s/\%#=2[^0-9A-Za-z_]//g +p:s/\%#=0\h//g +p:s/\%#=1\h//g +p:s/\%#=2\h//g +p:s/\%#=0[A-Za-z_]//g +p:s/\%#=1[A-Za-z_]//g +p:s/\%#=2[A-Za-z_]//g +p:s/\%#=0\H//g +p:s/\%#=1\H//g +p:s/\%#=2\H//g +p:s/\%#=0[^A-Za-z_]//g +p:s/\%#=1[^A-Za-z_]//g +p:s/\%#=2[^A-Za-z_]//g +p:s/\%#=0\a//g +p:s/\%#=1\a//g +p:s/\%#=2\a//g +p:s/\%#=0[A-Za-z]//g +p:s/\%#=1[A-Za-z]//g +p:s/\%#=2[A-Za-z]//g +p:s/\%#=0\A//g +p:s/\%#=1\A//g +p:s/\%#=2\A//g +p:s/\%#=0[^A-Za-z]//g +p:s/\%#=1[^A-Za-z]//g +p:s/\%#=2[^A-Za-z]//g +p:s/\%#=0\l//g +p:s/\%#=1\l//g +p:s/\%#=2\l//g +p:s/\%#=0[a-z]//g +p:s/\%#=1[a-z]//g +p:s/\%#=2[a-z]//g +p:s/\%#=0\L//g +p:s/\%#=1\L//g +p:s/\%#=2\L//g +p:s/\%#=0[^a-z]//g +p:s/\%#=1[^a-z]//g +p:s/\%#=2[^a-z]//g +p:s/\%#=0\u//g +p:s/\%#=1\u//g +p:s/\%#=2\u//g +p:s/\%#=0[A-Z]//g +p:s/\%#=1[A-Z]//g +p:s/\%#=2[A-Z]//g +p:s/\%#=0\U//g +p:s/\%#=1\U//g +p:s/\%#=2\U//g +p:s/\%#=0[^A-Z]//g +p:s/\%#=1[^A-Z]//g +p:s/\%#=2[^A-Z]//g +:/^start-here/+1,$wq! test.out +ENDTEST + +start-here +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ diff --git a/src/nvim/testdir/test36.ok b/src/nvim/testdir/test36.ok new file mode 100644 index 0000000000..f72a74b2b7 --- /dev/null +++ b/src/nvim/testdir/test36.ok @@ -0,0 +1,96 @@ +
!"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +0123456789 +0123456789 +0123456789 +0123456789 +0123456789 +0123456789 +
!"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +01234567 +01234567 +01234567 +01234567 +01234567 +01234567 +
!"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~ +
!"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~ +
!"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~ +
!"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~ +
!"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~ +
!"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~ +0123456789ABCDEFabcdef +0123456789ABCDEFabcdef +0123456789ABCDEFabcdef +0123456789ABCDEFabcdef +0123456789ABCDEFabcdef +0123456789ABCDEFabcdef +
!"#$%&'()#+'-./:;<=>?@[\]^`{|}~ +
!"#$%&'()#+'-./:;<=>?@[\]^`{|}~ +
!"#$%&'()#+'-./:;<=>?@[\]^`{|}~ +
!"#$%&'()#+'-./:;<=>?@[\]^`{|}~ +
!"#$%&'()#+'-./:;<=>?@[\]^`{|}~ +
!"#$%&'()#+'-./:;<=>?@[\]^`{|}~ +0123456789ABCDEFGHIXYZ_abcdefghiwxyz +0123456789ABCDEFGHIXYZ_abcdefghiwxyz +0123456789ABCDEFGHIXYZ_abcdefghiwxyz +0123456789ABCDEFGHIXYZ_abcdefghiwxyz +0123456789ABCDEFGHIXYZ_abcdefghiwxyz +0123456789ABCDEFGHIXYZ_abcdefghiwxyz +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~ +ABCDEFGHIXYZ_abcdefghiwxyz +ABCDEFGHIXYZ_abcdefghiwxyz +ABCDEFGHIXYZ_abcdefghiwxyz +ABCDEFGHIXYZ_abcdefghiwxyz +ABCDEFGHIXYZ_abcdefghiwxyz +ABCDEFGHIXYZ_abcdefghiwxyz +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~ +ABCDEFGHIXYZabcdefghiwxyz +ABCDEFGHIXYZabcdefghiwxyz +ABCDEFGHIXYZabcdefghiwxyz +ABCDEFGHIXYZabcdefghiwxyz +ABCDEFGHIXYZabcdefghiwxyz +ABCDEFGHIXYZabcdefghiwxyz +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~ +abcdefghiwxyz +abcdefghiwxyz +abcdefghiwxyz +abcdefghiwxyz +abcdefghiwxyz +abcdefghiwxyz +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~ +ABCDEFGHIXYZ +ABCDEFGHIXYZ +ABCDEFGHIXYZ +ABCDEFGHIXYZ +ABCDEFGHIXYZ +ABCDEFGHIXYZ diff --git a/src/nvim/testdir/test37.in b/src/nvim/testdir/test37.in new file mode 100644 index 0000000000..8ca1125793 --- /dev/null +++ b/src/nvim/testdir/test37.in @@ -0,0 +1,116 @@ +Test for 'scrollbind'. <eralston@computer.org> Do not add a line below! +STARTTEST +:so small.vim +:set noscrollbind +:set scrollopt=ver,jump +:set scrolloff=2 +:set nowrap +:set noequalalways +:set splitbelow +:" TEST using two windows open to one buffer, one extra empty window +:split +:new +t: +:resize 8 +/^start of window 1$/ +zt: +:set scrollbind +j: +:resize 7 +/^start of window 2$/ +zt: +:set scrollbind +:" -- start of tests -- +:" TEST scrolling down +L5jHyybpr0tHyybpr1tL6jHyybpr2kHyybpr3: +:" TEST scrolling up +tH4kjHtHyybpr4kHyybpr5k3ktHjHyybpr6tHyybpr7: +:" TEST horizontal scrolling +:set scrollopt+=hor +gg"zyyG"zpGt015zly$bp"zpGky$bp"zpG: +k10jH7zhg0y$bp"zpGtHg0y$bp"zpG: +:set scrollopt-=hor +:" ****** tests using two different buffers ***** +tj: +:close +t: +:set noscrollbind +:/^start of window 2$/,/^end of window 2$/y +:new +tj4"zpGp: +t/^start of window 1$/ +zt: +:set scrollbind +j: +/^start of window 2$/ +zt: +:set scrollbind +:" -- start of tests -- +:" TEST scrolling down +L5jHyybpr0tHyybpr1tL6jHyybpr2kHyybpr3: +:" TEST scrolling up +tH4kjHtHyybpr4kHyybpr5k3ktHjHyybpr6tHyybpr7: +:" TEST horizontal scrolling +:set scrollopt+=hor +gg"zyyG"zpGt015zly$bp"zpGky$bp"zpG: +k10jH7zhg0y$bp"zpGtHg0y$bp"zpG: +:set scrollopt-=hor +:" TEST syncbind +t:set noscb +ggLj:set noscb +ggL:set scb +t:set scb +GjG:syncbind +HktHjHyybptyybp: +t:set noscb +ggLj:set noscb +ggL:set scb +t:set scb +tGjGt:syncbind +HkjHtHyybptjyybp: +tH3kjHtHyybptjyybp: +:" ***** done with tests ***** +:w! test.out " Write contents of this file +:qa! +ENDTEST + + +start of window 1 +. line 01 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 01 +. line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02 +. line 03 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 03 +. line 04 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 04 +. line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05 +. line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06 +. line 07 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 07 +. line 08 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 08 +. line 09 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 09 +. line 10 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 10 +. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11 +. line 12 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 12 +. line 13 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 13 +. line 14 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 14 +. line 15 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 15 +end of window 1 + + +start of window 2 +. line 01 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 01 +. line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02 +. line 03 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 03 +. line 04 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 04 +. line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05 +. line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06 +. line 07 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 07 +. line 08 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 08 +. line 09 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 09 +. line 10 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 10 +. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12 +. line 13 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 13 +. line 14 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 14 +. line 15 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 15 +. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16 +end of window 2 + +end of test37.in (please don't delete this line) diff --git a/src/nvim/testdir/test37.ok b/src/nvim/testdir/test37.ok new file mode 100644 index 0000000000..d0b74853b3 --- /dev/null +++ b/src/nvim/testdir/test37.ok @@ -0,0 +1,33 @@ + +0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05 +1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05 +2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11 +3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06 +5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06 +6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02 +7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02 +56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02 +UTSRQPONMLKJIHGREDCBA9876543210 02 +. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11 + +0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05 +1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05 +2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11 +3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06 +5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06 +6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02 +7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02 +56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02 +UTSRQPONMLKJIHGREDCBA9876543210 02 +. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11 + +. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16 +:set scrollbind +:set scrollbind +. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16 +j: +. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12 diff --git a/src/nvim/testdir/test38.in b/src/nvim/testdir/test38.in new file mode 100644 index 0000000000..3e0236251b --- /dev/null +++ b/src/nvim/testdir/test38.in @@ -0,0 +1,35 @@ + +Test Virtual replace mode. + +STARTTEST +:so small.vim +:" make sure that backspace works, no matter what termcap is used +:set t_kD=x7f t_kb=x08 +ggdGa +abcdefghi +jk lmn + opq rst +uvwxyz +gg:set ai +:set bs=2 +gR0 1 +A +BCDEFGHIJ + KL +MNO +PQRG:ka +o0 +abcdefghi +jk lmn + opq rst +uvwxyz +'ajgR0 1 +A +BCDEFGHIJ + KL +MNO +PQR:$ +iab cdefghi jkl0gRAB......CDEFGHI.Jo: +iabcdefghijklmnopqrst0gRAB IJKLMNO QR:wq! test.out +ENDTEST + diff --git a/src/nvim/testdir/test38.ok b/src/nvim/testdir/test38.ok new file mode 100644 index 0000000000..e10209667b --- /dev/null +++ b/src/nvim/testdir/test38.ok @@ -0,0 +1,13 @@ + 1 + A + BCDEFGHIJ + KL + MNO + PQR + 1 +abcdefghi +jk lmn + opq rst +uvwxyz +AB......CDEFGHI.Jkl +AB IJKLMNO QRst diff --git a/src/nvim/testdir/test39.in b/src/nvim/testdir/test39.in new file mode 100644 index 0000000000..c1e1cc49a6 --- /dev/null +++ b/src/nvim/testdir/test39.in @@ -0,0 +1,93 @@ + +Test Visual block mode commands +And test "U" in Visual mode, also on German sharp S. + +STARTTEST +:so small.vim +:so mbyte.vim +:" This only works when 'encoding' is "latin1", don't depend on the environment +:set enc=latin1 +/^abcde +:" Test shift-right of a block +jlllljj>wlljlll> +:" Test shift-left of a block +G$hhhhkk< +:" Test block-insert +GklkkkIxyz +:" Test block-replace +Gllllkkklllrq +:" Test block-change +G$khhhhhkkcmno +:$-4,$w! test.out +:" Test block-insert using cursor keys for movement +/^aaaa/ +:exe ":norm! l\<C-V>jjjlllI\<Right>\<Right> \<Esc>" +:/^aa/,/^$/w >> test.out +:" Test for Visual block was created with the last <C-v>$ +/^A23$/ +:exe ":norm! l\<C-V>j$Aab\<Esc>" +:.,/^$/w >> test.out +:" Test for Visual block was created with the middle <C-v>$ (1) +/^B23$/ +:exe ":norm! l\<C-V>j$hAab\<Esc>" +:.,/^$/w >> test.out +:" Test for Visual block was created with the middle <C-v>$ (2) +/^C23$/ +:exe ":norm! l\<C-V>j$hhAab\<Esc>" +:.,/^$/w >> test.out +:" Test for Visual block insert when virtualedit=all +:set ve=all +:/\t\tline +:exe ":norm! 07l\<C-V>jjIx\<Esc>" +:set ve= +:.,/^$/w >> test.out +:" gUe must uppercase a whole word, also when changes to SS +Gothe youtueuu endYpk0wgUe +:" gUfx must uppercase until x, inclusive. +O- youtuexu -0fogUfx +:" VU must uppercase a whole line +YpkVU +:" same, when it's the last line in the buffer +YPGi111VUddP +:" Uppercase two lines +Oblah di +doh dutVkUj +:" Uppercase part of two lines +ddppi333k0i222fyllvjfuUk +:" visual replace using Enter or NL +G3o1234567892k05l2jr
G3o987652k02l2jr
+G3o1234567892k05l2jr +G3o987652k02l2jr +:" +:" Test cursor position. When ve=block and Visual block mode and $gj +:set ve=block +:exe ":norm! 2k\<C-V>$gj\<Esc>" +:let cpos=getpos("'>") +:$put ='col:'.cpos[2].' off:'.cpos[3] +:/^the/,$w >> test.out +:qa! +ENDTEST + + line1 + line2 + line3 + +aaaaaa +bbbbbb +cccccc +dddddd + +A23 +4567 + +B23 +4567 + +C23 +4567 + +abcdefghijklm +abcdefghijklm +abcdefghijklm +abcdefghijklm +abcdefghijklm diff --git a/src/nvim/testdir/test39.ok b/src/nvim/testdir/test39.ok Binary files differnew file mode 100644 index 0000000000..ef7a2c6442 --- /dev/null +++ b/src/nvim/testdir/test39.ok diff --git a/src/nvim/testdir/test4.in b/src/nvim/testdir/test4.in new file mode 100644 index 0000000000..4aa2fe5a86 --- /dev/null +++ b/src/nvim/testdir/test4.in @@ -0,0 +1,31 @@ +Test for autocommand that changes current buffer on BufEnter event. +Check if modelines are interpreted for the correct buffer. + +STARTTEST +:so small.vim +:set nocompatible viminfo+=nviminfo +:au BufEnter Xxx brew +/start of +:.,/end of/w! Xxx " write test file Xxx +:set ai modeline modelines=3 +:sp Xxx " split to Xxx, autocmd will do :brew +G?this is a +othis should be auto-indented +: " Append text with autoindent to this file +:au! BufEnter Xxx +:buf Xxx " go to Xxx, no autocmd anymore +G?this is a +othis should be in column 1:wq " append text without autoindent to Xxx +G:r Xxx " include Xxx in the current file +:?startstart?,$w! test.out +:qa! +ENDTEST + +startstart +start of test file Xxx +vim: set noai : + this is a test + this is a test + this is a test + this is a test +end of test file Xxx diff --git a/src/nvim/testdir/test4.ok b/src/nvim/testdir/test4.ok new file mode 100644 index 0000000000..dffecda4d2 --- /dev/null +++ b/src/nvim/testdir/test4.ok @@ -0,0 +1,17 @@ +startstart +start of test file Xxx +vim: set noai : + this is a test + this is a test + this is a test + this is a test + this should be auto-indented +end of test file Xxx +start of test file Xxx +vim: set noai : + this is a test + this is a test + this is a test + this is a test +this should be in column 1 +end of test file Xxx diff --git a/src/nvim/testdir/test40.in b/src/nvim/testdir/test40.in new file mode 100644 index 0000000000..d92a18f3d0 --- /dev/null +++ b/src/nvim/testdir/test40.in @@ -0,0 +1,63 @@ +Test for "*Cmd" autocommands + +STARTTEST +:so small.vim +:/^start/,$w! Xxx " write lines below to Xxx +:au BufReadCmd XtestA 0r Xxx|$del +:e XtestA " will read text of Xxd instead +:au BufWriteCmd XtestA call append(line("$"), "write") +:w " will append a line to the file +:r XtestA " should not read anything +: " now we have: +: " 1 start of Xxx +: " 2 test40 +: " 3 end of Xxx +: " 4 write +:au FileReadCmd XtestB '[r Xxx +:2r XtestB " will read Xxx below line 2 instead +: " 1 start of Xxx +: " 2 test40 +: " 3 start of Xxx +: " 4 test40 +: " 5 end of Xxx +: " 6 end of Xxx +: " 7 write +:au FileWriteCmd XtestC '[,']copy $ +4GA1 +:4,5w XtestC " will copy lines 4 and 5 to the end +:r XtestC " should not read anything +: " 1 start of Xxx +: " 2 test40 +: " 3 start of Xxx +: " 4 test401 +: " 5 end of Xxx +: " 6 end of Xxx +: " 7 write +: " 8 test401 +: " 9 end of Xxx +:au FILEAppendCmd XtestD '[,']w! test.out +:w >>XtestD " will write all lines to test.out +:$r XtestD " should not read anything +:$w >>test.out " append "end of Xxx" to test.out +:au BufReadCmd XtestE 0r test.out|$del +:sp XtestE " split window with test.out +5Goasdf:" +:au BufWriteCmd XtestE w! test.out +:wall " will write other window to test.out +: " 1 start of Xxx +: " 2 test40 +: " 3 start of Xxx +: " 4 test401 +: " 5 end of Xxx +: " 6 asdf +: " 7 end of Xxx +: " 8 write +: " 9 test401 +: " 10 end of Xxx +: " 11 end of Xxx +:qa! +ENDTEST + +start of Xxx + test40 +end of Xxx diff --git a/src/nvim/testdir/test40.ok b/src/nvim/testdir/test40.ok new file mode 100644 index 0000000000..b6501394f9 --- /dev/null +++ b/src/nvim/testdir/test40.ok @@ -0,0 +1,11 @@ +start of Xxx + test40 +start of Xxx + test401 +end of Xxx +asdf +end of Xxx +write + test401 +end of Xxx +end of Xxx diff --git a/src/nvim/testdir/test41.in b/src/nvim/testdir/test41.in new file mode 100644 index 0000000000..2d294cae09 --- /dev/null +++ b/src/nvim/testdir/test41.in @@ -0,0 +1,24 @@ +Test for writing and reading a file of over 100 Kbyte + +1 line: "This is the start" +3001 lines: "This is the leader" +1 line: "This is the middle" +3001 lines: "This is the trailer" +1 line: "This is the end" + +STARTTEST +:%d +aThis is the start +This is the leader +This is the middle +This is the trailer +This is the endkY3000p2GY3000p +:w! Xtest +:%d +:e! Xtest +:.w! test.out +3003G:.w >>test.out +6005G:.w >>test.out +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test41.ok b/src/nvim/testdir/test41.ok new file mode 100644 index 0000000000..988e5f24b4 --- /dev/null +++ b/src/nvim/testdir/test41.ok @@ -0,0 +1,3 @@ +This is the start +This is the middle +This is the end diff --git a/src/nvim/testdir/test42.in b/src/nvim/testdir/test42.in Binary files differnew file mode 100644 index 0000000000..c35569a76c --- /dev/null +++ b/src/nvim/testdir/test42.in diff --git a/src/nvim/testdir/test42.ok b/src/nvim/testdir/test42.ok Binary files differnew file mode 100644 index 0000000000..183430d71c --- /dev/null +++ b/src/nvim/testdir/test42.ok diff --git a/src/nvim/testdir/test43.in b/src/nvim/testdir/test43.in new file mode 100644 index 0000000000..7c545073da --- /dev/null +++ b/src/nvim/testdir/test43.in @@ -0,0 +1,34 @@ +Tests for regexp with various magic settings. + +STARTTEST +:so small.vim +:set nocompatible viminfo+=nviminfo +/^1 +/a*b\{2}c\+/e +x/\Md\*e\{2}f\+/e +x:set nomagic +/g\*h\{2}i\+/e +x/\mj*k\{2}l\+/e +x/\vm*n{2}o+/e +x/\V^aa$ +x:set magic +/\v(a)(b)\2\1\1/e +x/\V[ab]\(\[xy]\)\1 +x:$ +:set undolevels=100 +dv?bar? +Yup:" +:?^1?,$w! test.out +:qa! +ENDTEST + +1 a aa abb abbccc +2 d dd dee deefff +3 g gg ghh ghhiii +4 j jj jkk jkklll +5 m mm mnn mnnooo +6 x ^aa$ x +7 (a)(b) abbaa +8 axx [ab]xx +9 foobar + diff --git a/src/nvim/testdir/test43.ok b/src/nvim/testdir/test43.ok new file mode 100644 index 0000000000..0b37a6a61e --- /dev/null +++ b/src/nvim/testdir/test43.ok @@ -0,0 +1,11 @@ +1 a aa abb abbcc +2 d dd dee deeff +3 g gg ghh ghhii +4 j jj jkk jkkll +5 m mm mnn mnnoo +6 x aa$ x +7 (a)(b) abba +8 axx ab]xx +9 foobar +9 foo + diff --git a/src/nvim/testdir/test44.in b/src/nvim/testdir/test44.in new file mode 100644 index 0000000000..87de1b95a4 --- /dev/null +++ b/src/nvim/testdir/test44.in @@ -0,0 +1,68 @@ +Tests for regexp with multi-byte encoding and various magic settings. +Test matchstr() with a count and multi-byte chars. +See test99 for exactly the same test with re=2. + +STARTTEST +:so mbyte.vim +:set nocompatible encoding=utf-8 termencoding=latin1 viminfo+=nviminfo +:set re=1 +/^1 +/a*b\{2}c\+/e +x/\Md\*e\{2}f\+/e +x:set nomagic +/g\*h\{2}i\+/e +x/\mj*k\{2}l\+/e +x/\vm*n{2}o+/e +x/\V^aa$ +x:set magic +/\v(a)(b)\2\1\1/e +x/\V[ab]\(\[xy]\)\1 +x:" Now search for multi-byte without composing char +/ม +x:" Now search for multi-byte with composing char +/ม่ +x:" find word by change of word class +/ち\<カヨ\>は +x:" Test \%u, [\u] and friends +/\%u20ac +x/[\u4f7f\u5929]\+ +x/\%U12345678 +x/[\U1234abcd\u1234\uabcd] +x/\%d21879b +x/ [[=A=]]* [[=B=]]* [[=C=]]* [[=D=]]* [[=E=]]* [[=F=]]* [[=G=]]* [[=H=]]* [[=I=]]* [[=J=]]* [[=K=]]* [[=L=]]* [[=M=]]* [[=N=]]* [[=O=]]* [[=P=]]* [[=Q=]]* [[=R=]]* [[=S=]]* [[=T=]]* [[=U=]]* [[=V=]]* [[=W=]]* [[=X=]]* [[=Y=]]* [[=Z=]]*/e +x/ [[=a=]]* [[=b=]]* [[=c=]]* [[=d=]]* [[=e=]]* [[=f=]]* [[=g=]]* [[=h=]]* [[=i=]]* [[=j=]]* [[=k=]]* [[=l=]]* [[=m=]]* [[=n=]]* [[=o=]]* [[=p=]]* [[=q=]]* [[=r=]]* [[=s=]]* [[=t=]]* [[=u=]]* [[=v=]]* [[=w=]]* [[=x=]]* [[=y=]]* [[=z=]]*/e +x:" Test backwards search from a multi-byte char +/x +x?. +x:let @w=':%s#comb[i]nations#œ̄ṣ́m̥̄ᾱ̆́#g' +:@w +:?^1?,$w! test.out +:e! test.out +G:put =matchstr(\"אבגד\", \".\", 0, 2) " ב +:put =matchstr(\"אבגד\", \"..\", 0, 2) " בג +:put =matchstr(\"אבגד\", \".\", 0, 0) " א +:put =matchstr(\"אבגד\", \".\", 4, -1) " ג +:w! +:qa! +ENDTEST + +1 a aa abb abbccc +2 d dd dee deefff +3 g gg ghh ghhiii +4 j jj jkk jkklll +5 m mm mnn mnnooo +6 x ^aa$ x +7 (a)(b) abbaa +8 axx [ab]xx +9 หม่x อมx +a อมx หม่x +b ちカヨは +c x ¬€x +d 天使x +e y +f z +g a啷bb +h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐẔ +i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑẕ +j 0123❤x +k combinations diff --git a/src/nvim/testdir/test44.ok b/src/nvim/testdir/test44.ok new file mode 100644 index 0000000000..0bd0b8ab73 --- /dev/null +++ b/src/nvim/testdir/test44.ok @@ -0,0 +1,24 @@ +1 a aa abb abbcc +2 d dd dee deeff +3 g gg ghh ghhii +4 j jj jkk jkkll +5 m mm mnn mnnoo +6 x aa$ x +7 (a)(b) abba +8 axx ab]xx +9 หม่x อx +a อมx หx +b カヨは +c x ¬x +d 使x +e y +f z +g abb +h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐ +i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑ +j 012❤ +k œ̄ṣ́m̥̄ᾱ̆́ +ב +בג +א +ג diff --git a/src/nvim/testdir/test45.in b/src/nvim/testdir/test45.in new file mode 100644 index 0000000000..e5af5073d9 --- /dev/null +++ b/src/nvim/testdir/test45.in @@ -0,0 +1,80 @@ +Tests for folding. vim: set ft=vim : + +STARTTEST +:so small.vim +:" We also need the +syntax feature here. +:if !has("syntax") + e! test.ok + w! test.out + qa! +:endif +:" basic test if a fold can be created, opened, moving to the end and closed +/^1 +zf2j:call append("$", "manual " . getline(foldclosed("."))) +zo:call append("$", foldclosed(".")) +]z:call append("$", getline(".")) +zc:call append("$", getline(foldclosed("."))) +:" test folding with markers. +:set fdm=marker fdl=1 fdc=3 +/^5 +:call append("$", "marker " . foldlevel(".")) +[z:call append("$", foldlevel(".")) +jo{{ r{jj:call append("$", foldlevel(".")) +kYpj:call append("$", foldlevel(".")) +:" test folding with indent +:set fdm=indent sw=2 +/^2 b +i jI :call append("$", "indent " . foldlevel(".")) +k:call append("$", foldlevel(".")) +:" test syntax folding +:set fdm=syntax fdl=0 +:syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3 +:syn region Fd1 start="ee" end="ff" fold contained +:syn region Fd2 start="gg" end="hh" fold contained +:syn region Fd3 start="commentstart" end="commentend" fold contained +Gzk:call append("$", "folding " . getline(".")) +k:call append("$", getline(".")) +jAcommentstart Acommentend:set fdl=1 +3j:call append("$", getline(".")) +:set fdl=0 +zOj:call append("$", getline(".")) +:" test expression folding +:fun Flvl() + let l = getline(v:lnum) + if l =~ "bb$" + return 2 + elseif l =~ "gg$" + return "s1" + elseif l =~ "ii$" + return ">2" + elseif l =~ "kk$" + return "0" + endif + return "=" +endfun +:set fdm=expr fde=Flvl() +/bb$ +:call append("$", "expr " . foldlevel(".")) +/hh$ +:call append("$", foldlevel(".")) +/ii$ +:call append("$", foldlevel(".")) +/kk$ +:call append("$", foldlevel(".")) +:/^last/+1,$w! test.out +:delfun Flvl +:qa! +ENDTEST + +1 aa +2 bb +3 cc +4 dd {{{ +5 ee {{{ }}} +6 ff }}} +7 gg +8 hh +9 ii +a jj +b kk +last diff --git a/src/nvim/testdir/test45.ok b/src/nvim/testdir/test45.ok new file mode 100644 index 0000000000..f04996e337 --- /dev/null +++ b/src/nvim/testdir/test45.ok @@ -0,0 +1,18 @@ +manual 1 aa +-1 +3 cc +1 aa +marker 2 +1 +1 +0 +indent 2 +1 +folding 9 ii + 3 cc +7 gg +8 hh +expr 2 +1 +2 +0 diff --git a/src/nvim/testdir/test46.in b/src/nvim/testdir/test46.in new file mode 100644 index 0000000000..9a9db74d62 --- /dev/null +++ b/src/nvim/testdir/test46.in @@ -0,0 +1,27 @@ +Tests for multi-line regexps with ":s". vim: set ft=vim : + +STARTTEST +:" test if replacing a line break works with a back reference +:/^1/,/^2/s/\n\(.\)/ \1/ +:" test if inserting a line break works with a back reference +:/^3/,/^4/s/\(.\)$/\r\1/ +:" test if replacing a line break with another line break works +:/^5/,/^6/s/\(\_d\{3}\)/x\1x/ +:/^1/,$w! test.out +:qa! +ENDTEST + +1 aa +bb +cc +2 dd +ee +3 ef +gh +4 ij +5 a8 +8b c9 +9d +6 e7 +77f +xxxxx diff --git a/src/nvim/testdir/test46.ok b/src/nvim/testdir/test46.ok new file mode 100644 index 0000000000..71b353df1d --- /dev/null +++ b/src/nvim/testdir/test46.ok @@ -0,0 +1,13 @@ +1 aa bb cc 2 dd ee +3 e +f +g +h +4 i +j +5 ax8 +8xb cx9 +9xd +6 ex7 +7x7f +xxxxx diff --git a/src/nvim/testdir/test47.in b/src/nvim/testdir/test47.in new file mode 100644 index 0000000000..13ad82462f --- /dev/null +++ b/src/nvim/testdir/test47.in @@ -0,0 +1,62 @@ +Tests for vertical splits and filler lines in diff mode + +STARTTEST +:so small.vim +:" Disable the title to avoid xterm keeping the wrong one. +:set notitle noicon +/^1 +yG:new +pkdd:w! Xtest +ddGpkkrXoxxx:w! Xtest2 +:file Nop +ggoyyyjjjozzzz +:vert diffsplit Xtest +:vert diffsplit Xtest2 +:" jump to second window for a moment to have filler line appear at start of +:" first window +ggpgg:let one = winline() +j:let one = one . "-" . winline() +j:let one = one . "-" . winline() +j:let one = one . "-" . winline() +j:let one = one . "-" . winline() +j:let one = one . "-" . winline() +gg:let two = winline() +j:let two = two . "-" . winline() +j:let two = two . "-" . winline() +j:let two = two . "-" . winline() +j:let two = two . "-" . winline() +gg:let three = winline() +j:let three = three . "-" . winline() +j:let three = three . "-" . winline() +j:let three = three . "-" . winline() +j:let three = three . "-" . winline() +j:let three = three . "-" . winline() +j:let three = three . "-" . winline() +:call append("$", one) +:call append("$", two) +:call append("$", three) +:$-2,$w! test.out +:" Test that diffing shows correct filler lines +:diffoff! +:windo :bw! +:enew +:put =range(4,10) +:1d _ +:vnew +:put =range(1,10) +:1d _ +:windo :diffthis +:wincmd h +:let w0=line('w0') +:enew +:put =w0 +:.w >> test.out +:unlet! one two three w0 +:qa! +ENDTEST + +1 aa +2 bb +3 cc +4 dd +5 ee diff --git a/src/nvim/testdir/test47.ok b/src/nvim/testdir/test47.ok new file mode 100644 index 0000000000..b1cba92b1c --- /dev/null +++ b/src/nvim/testdir/test47.ok @@ -0,0 +1,4 @@ +2-4-5-6-8-9 +1-2-4-5-8 +2-3-4-5-6-7-8 +1 diff --git a/src/nvim/testdir/test48.in b/src/nvim/testdir/test48.in new file mode 100644 index 0000000000..48f4abbf75 --- /dev/null +++ b/src/nvim/testdir/test48.in @@ -0,0 +1,78 @@ +This is a test of 'virtualedit'. + +STARTTEST +:so small.vim +:set noswf +:set ve=all +-dgg +:" +:" Insert "keyword keyw", ESC, C CTRL-N, shows "keyword ykeyword". +:" Repeating CTRL-N fixes it. (Mary Ellen Foster) +2/w +C +:" +:" Using "C" then then <CR> moves the last remaining character to the next +:" line. (Mary Ellen Foster) +j^/are +C
are belong to vim +:" +:" When past the end of a line that ends in a single character "b" skips +:" that word. +^$15lbC7 +:" +:" Make sure 'i' works +$4li<-- should be 3 ' ' +:" +:" Make sure 'C' works +$4lC<-- should be 3 ' ' +:" +:" Make sure 'a' works +$4la<-- should be 4 ' ' +:" +:" Make sure 'A' works +$4lA<-- should be 0 ' ' +:" +:" Make sure 'D' works +$4lDi<-- 'D' should be intact +:" +:" Test for yank bug reported by Mark Waggoner. +:set ve=block +^2w3jyGp +:" +:" Test "r" beyond the end of the line +:set ve=all +/^"r" +$5lrxa<-- should be 'x' +:" +:" Test to make sure 'x' can delete control characters +:set display=uhex +^xxxxxxi[This line should contain only the text between the brackets.] +:set display= +:" +:" Test for ^Y/^E due to bad w_virtcol value, reported by +:" Roy <royl@netropolis.net>. +^O3li4li4li <-- should show the name of a noted text editor +^o4li4li4li <-- and its version number-dd +:" +:" Test for yanking and pasting using the small delete register +gg/^foo +dewve"-p +:wq! test.out +ENDTEST +foo, bar +keyword keyw +all your base are belong to us +1 2 3 4 5 6 +'i' +'C' +'a' +'A' +'D' +this is a test +this is a test +this is a test +"r" +ab
sd +abcv6efi.him0kl + + diff --git a/src/nvim/testdir/test48.ok b/src/nvim/testdir/test48.ok new file mode 100644 index 0000000000..334cb5a29c --- /dev/null +++ b/src/nvim/testdir/test48.ok @@ -0,0 +1,22 @@ +, foo +keyword keyword +all your base +are belong to vim +1 2 3 4 5 7 +'i' <-- should be 3 ' ' +'C' <-- should be 3 ' ' +'a' <-- should be 4 ' ' +'A'<-- should be 0 ' ' +'D' <-- 'D' should be intact +this is a test +this is a test +this is a test +"r" x<-- should be 'x' +[This line should contain only the text between the brackets.] + v i m <-- should show the name of a noted text editor + 6 . 0 <-- and its version number + +a +a +a + diff --git a/src/nvim/testdir/test49.in b/src/nvim/testdir/test49.in new file mode 100644 index 0000000000..bd6cb4cad7 --- /dev/null +++ b/src/nvim/testdir/test49.in @@ -0,0 +1,30 @@ +This is a test of the script language. + +If after adding a new test, the test output doesn't appear properly in +test49.failed, try to add one ore more "G"s at the line ending in "test.out" + +STARTTEST +:so small.vim +:se nocp nomore viminfo+=nviminfo +:lang mess C +:so test49.vim +GGGGGGGGGGGGGG"rp:.-,$w! test.out +:" +:" make valgrind happy +:redir => funclist +:silent func +:redir END +:for line in split(funclist, "\n") +: let name = matchstr(line, 'function \zs[A-Z]\w*\ze(') +: if name != '' +: exe "delfunc " . name +: endif +:endfor +:for v in keys(g:) +: silent! exe "unlet " . v +:endfor +:unlet v +:qa! +ENDTEST + +Results of test49.vim: diff --git a/src/nvim/testdir/test49.ok b/src/nvim/testdir/test49.ok new file mode 100644 index 0000000000..bf1ceed9af --- /dev/null +++ b/src/nvim/testdir/test49.ok @@ -0,0 +1,99 @@ +Results of test49.vim: +*** Test 1: OK (34695) +*** Test 2: OK (34695) +*** Test 3: OK (1384648195) +*** Test 4: OK (32883) +*** Test 5: OK (32883) +*** Test 6: OK (603978947) +*** Test 7: OK (90563) +*** Test 8: OK (562493431) +*** Test 9: OK (363) +*** Test 10: OK (559615) +*** Test 11: OK (2049) +*** Test 12: OK (352256) +*** Test 13: OK (145) +*** Test 14: OK (42413) +*** Test 15: OK (42413) +*** Test 16: OK (8722) +*** Test 17: OK (285127993) +*** Test 18: OK (67224583) +*** Test 19: OK (69275973) +*** Test 20: OK (1874575085) +*** Test 21: OK (147932225) +*** Test 22: OK (4161) +*** Test 23: OK (49) +*** Test 24: OK (41) +*** Test 25: OK (260177811) +*** Test 26: OK (1681500476) +*** Test 27: OK (1996459) +*** Test 28: OK (1996459) +*** Test 29: OK (170428555) +*** Test 30: OK (190905173) +*** Test 31: OK (190905173) +*** Test 32: OK (354833067) +--- Test 33: sum = 178275600 (ok) +*** Test 33: OK (1216907538) +*** Test 34: OK (2146584868) +*** Test 35: OK (2146584868) +*** Test 36: OK (1071644672) +*** Test 37: OK (1071644672) +*** Test 38: OK (357908480) +*** Test 39: OK (357908480) +*** Test 40: OK (357908480) +*** Test 41: OK (3076095) +*** Test 42: OK (1505155949) +*** Test 43: OK (1157763329) +*** Test 44: OK (1031761407) +*** Test 45: OK (1157763329) +*** Test 46: OK (739407) +*** Test 47: OK (371213935) +*** Test 48: OK (756255461) +*** Test 49: OK (179000669) +*** Test 50: OK (363550045) +*** Test 51: OK (40744667) +*** Test 52: OK (1247112011) +*** Test 53: OK (131071) +*** Test 54: OK (2047) +*** Test 55: OK (1023) +*** Test 56: OK (511) +*** Test 57: OK (2147450880) +*** Test 58: OK (624945) +*** Test 59: OK (2038431743) +*** Test 60: OK (311511339) +*** Test 61: OK (374889517) +*** Test 62: OK (286331153) +*** Test 63: OK (236978127) +*** Test 64: OK (1499645335) +*** Test 65: OK (70187) +*** Test 66: OK (5464) +*** Test 67: OK (212514423) +*** Test 68: OK (212514423) +*** Test 69: OK (8995471) +*** Test 70: OK (69544277) +*** Test 71: OK (34886997) +*** Test 72: OK (1789569365) +*** Test 73: OK (9032615) +*** Test 74: OK (224907669) +*** Test 75: OK (2000403408) +*** Test 76: OK (1610087935) +*** Test 77: OK (1388671) +*** Test 78: OK (134217728) +*** Test 79: OK (70288929) +*** Test 80: OK (17895765) +*** Test 81: OK (387) +*** Test 82: OK (8454401) +*** Test 83: OK (2835) +*** Test 84: OK (934782101) +*** Test 85: OK (198689) +--- Test 86: No Crash for vimgrep on BufUnload +*** Test 86: OK (0) +--- Test 87: 3 +--- Test 87: 5 +--- Test 87: abcdefghijk +--- Test 87: Successfully executed funcref Add2 +*** Test 87: OK (0) +--- Test 88: All tests were run with throwing exceptions on error. + The $VIMNOERRTHROW control is not configured. +--- Test 88: All tests were run with throwing exceptions on interrupt. + The $VIMNOINTTHROW control is not configured. +*** Test 88: OK (50443995) diff --git a/src/nvim/testdir/test49.vim b/src/nvim/testdir/test49.vim new file mode 100644 index 0000000000..21c2a0c582 --- /dev/null +++ b/src/nvim/testdir/test49.vim @@ -0,0 +1,9852 @@ +" Vim script language tests +" Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com> +" Last Change: 2013 Jun 06 + +"------------------------------------------------------------------------------- +" Test environment {{{1 +"------------------------------------------------------------------------------- + + +" Adding new tests easily. {{{2 +" +" Writing new tests is eased considerably with the following functions and +" abbreviations (see "Commands for recording the execution path", "Automatic +" argument generation"). +" +" To get the abbreviations, execute the command +" +" :let test49_set_env = 1 | source test49.vim +" +" To get them always (from src/testdir), put a line +" +" au! BufRead test49.vim let test49_set_env = 1 | source test49.vim +" +" into the local .vimrc file in the src/testdir directory. +" +if exists("test49_set_env") && test49_set_env + + " Automatic argument generation for the test environment commands. + + function! Xsum() + let addend = substitute(getline("."), '^.*"\s*X:\s*\|^.*', '', "") + " Evaluate arithmetic expression. + if addend != "" + exec "let g:Xsum = g:Xsum + " . addend + endif + endfunction + + function! Xcheck() + let g:Xsum=0 + ?XpathINIT?,.call Xsum() + exec "norm A " + return g:Xsum + endfunction + + iab Xcheck Xcheck<Space><C-R>=Xcheck()<CR><C-O>x + + function! Xcomment(num) + let str = "" + let tabwidth = &sts ? &sts : &ts + let tabs = (48+tabwidth - a:num - virtcol(".")) / tabwidth + while tabs > 0 + let str = str . "\t" + let tabs = tabs - 1 + endwhile + let str = str . '" X:' + return str + endfunction + + function! Xloop() + let back = line(".") . "|norm" . virtcol(".") . "|" + norm 0 + let last = search('X\(loop\|path\)INIT\|Xloop\>', "bW") + exec back + let theline = getline(last) + if theline =~ 'X\(loop\|path\)INIT' + let num = 1 + else + let num = 2 * substitute(theline, '.*Xloop\s*\(\d\+\).*', '\1', "") + endif + ?X\(loop\|path\)INIT? + \s/\(XloopINIT!\=\s*\d\+\s\+\)\@<=\(\d\+\)/\=2*submatch(2)/ + exec back + exec "norm a " + return num . Xcomment(strlen(num)) + endfunction + + iab Xloop Xloop<Space><C-R>=Xloop()<CR><C-O>x + + function! Xpath(loopinit) + let back = line(".") . "|norm" . virtcol(".") . "|" + norm 0 + let last = search('XpathINIT\|Xpath\>\|XloopINIT', "bW") + exec back + let theline = getline(last) + if theline =~ 'XpathINIT' + let num = 1 + elseif theline =~ 'Xpath\>' + let num = 2 * substitute(theline, '.*Xpath\s*\(\d\+\).*', '\1', "") + else + let pattern = '.*XloopINIT!\=\s*\(\d\+\)\s*\(\d\+\).*' + let num = substitute(theline, pattern, '\1', "") + let factor = substitute(theline, pattern, '\2', "") + " The "<C-O>x" from the "Xpath" iab and the character triggering its + " expansion are in the input buffer. Save and clear typeahead so + " that it is not read away by the call to "input()" below. Restore + " afterwards. + call inputsave() + let loops = input("Number of iterations in previous loop? ") + call inputrestore() + while (loops > 0) + let num = num * factor + let loops = loops - 1 + endwhile + endif + exec "norm a " + if a:loopinit + return num . " 1" + endif + return num . Xcomment(strlen(num)) + endfunction + + iab Xpath Xpath<Space><C-R>=Xpath(0)<CR><C-O>x + iab XloopINIT XloopINIT<Space><C-R>=Xpath(1)<CR><C-O>x + + " Also useful (see ExtraVim below): + aug ExtraVim + au! + au BufEnter <sfile> syn region ExtraVim + \ start=+^if\s\+ExtraVim(.*)+ end=+^endif+ + \ transparent keepend + au BufEnter <sfile> syn match ExtraComment /^"/ + \ contained containedin=ExtraVim + au BufEnter <sfile> hi link ExtraComment vimComment + aug END + + aug Xpath + au BufEnter <sfile> syn keyword Xpath + \ XpathINIT Xpath XloopINIT Xloop XloopNEXT Xcheck Xout + au BufEnter <sfile> hi link Xpath Special + aug END + + do BufEnter <sfile> + + " Do not execute the tests when sourcing this file for getting the functions + " and abbreviations above, which are intended for easily adding new test + " cases; they are not needed for test execution. Unlet the variable + " controlling this so that an explicit ":source" command for this file will + " execute the tests. + unlet test49_set_env + finish + +endif + + +" Commands for recording the execution path. {{{2 +" +" The Xpath/Xloop commands can be used for computing the eXecution path by +" adding (different) powers of 2 from those script lines, for which the +" execution should be checked. Xloop provides different addends for each +" execution of a loop. Permitted values are 2^0 to 2^30, so that 31 execution +" points (multiply counted inside loops) can be tested. +" +" Note that the arguments of the following commands can be generated +" automatically, see below. +" +" Usage: {{{3 +" +" - Use XpathINIT at the beginning of the test. +" +" - Use Xpath to check if a line is executed. +" Argument: power of 2 (decimal). +" +" - To check multiple execution of loops use Xloop for automatically +" computing Xpath values: +" +" - Use XloopINIT before the loop. +" Two arguments: +" - the first Xpath value (power of 2) to be used (Xnext), +" - factor for computing a new Xnext value when reexecuting a loop +" (by a ":continue" or ":endwhile"); this should be 2^n where +" n is the number of Xloop commands inside the loop. +" If XloopINIT! is used, the first execution of XloopNEXT is +" a no-operation. +" +" - Use Xloop inside the loop: +" One argument: +" The argument and the Xnext value are multiplied to build the +" next Xpath value. No new Xnext value is prepared. The argument +" should be 2^(n-1) for the nth Xloop command inside the loop. +" If the loop has only one Xloop command, the argument can be +" ommitted (default: 1). +" +" - Use XloopNEXT before ":continue" and ":endwhile". This computes a new +" Xnext value for the next execution of the loop by multiplying the old +" one with the factor specified in the XloopINIT command. No Argument. +" Alternatively, when XloopINIT! is used, a single XloopNEXT at the +" beginning of the loop can be used. +" +" Nested loops are not supported. +" +" - Use Xcheck at end of each test. It prints the test number, the expected +" execution path value, the test result ("OK" or "FAIL"), and, if the tests +" fails, the actual execution path. +" One argument: +" Expected Xpath/Xloop sum for the correct execution path. +" In order that this value can be computed automatically, do the +" following: For each line in the test with an Xpath and Xloop +" command, add a comment starting with "X:" and specifying an +" expression that evaluates to the value contributed by this line to +" the correct execution path. (For copying an Xpath argument of at +" least two digits into the comment, press <C-P>.) At the end of the +" test, just type "Xcheck" and press <Esc>. +" +" - In order to add additional information to the test output file, use the +" Xout command. Argument(s) like ":echo". +" +" Automatic argument generation: {{{3 +" +" The arguments of the Xpath, XloopINIT, Xloop, and Xcheck commands can be +" generated automatically, so that new tests can easily be written without +" mental arithmetic. The Xcheck argument is computed from the "X:" comments +" of the preceding Xpath and Xloop commands. See the commands and +" abbreviations at the beginning of this file. +" +" Implementation: {{{3 +" XpathINIT, Xpath, XloopINIT, Xloop, XloopNEXT, Xcheck, Xout. +" +" The variants for existing g:ExtraVimResult are needed when executing a script +" in an extra Vim process, see ExtraVim below. + +" EXTRA_VIM_START - do not change or remove this line. + +com! XpathINIT let g:Xpath = 0 + +if exists("g:ExtraVimResult") + com! -count -bar Xpath exec "!echo <count> >>" . g:ExtraVimResult +else + com! -count -bar Xpath let g:Xpath = g:Xpath + <count> +endif + +com! -count -nargs=1 -bang + \ XloopINIT let g:Xnext = <count> | + \ let g:Xfactor = <args> | + \ let g:Xskip = strlen("<bang>") + +if exists("g:ExtraVimResult") + com! -count=1 -bar Xloop exec "!echo " . (g:Xnext * <count>) . " >>" . + \ g:ExtraVimResult +else + com! -count=1 -bar Xloop let g:Xpath = g:Xpath + g:Xnext * <count> +endif + +com! XloopNEXT let g:Xnext = g:Xnext * + \ (g:Xskip ? 1 : g:Xfactor) | + \ let g:Xskip = 0 + +let @r = "" +let Xtest = 1 +com! -count Xcheck let Xresult = "*** Test " . + \ (Xtest<10?" ":Xtest<100?" ":"") . + \ Xtest . ": " . ( + \ (Xpath==<count>) ? "OK (".Xpath.")" : + \ "FAIL (".Xpath." instead of <count>)" + \ ) | + \ let @R = Xresult . "\n" | + \ echo Xresult | + \ let Xtest = Xtest + 1 + +if exists("g:ExtraVimResult") + com! -nargs=+ Xoutq exec "!echo @R:'" . + \ substitute(substitute(<q-args>, + \ "'", '&\\&&', "g"), "\n", "@NL@", "g") + \ . "' >>" . g:ExtraVimResult +else + com! -nargs=+ Xoutq let @R = "--- Test " . + \ (g:Xtest<10?" ":g:Xtest<100?" ":"") . + \ g:Xtest . ": " . substitute(<q-args>, + \ "\n", "&\t ", "g") . "\n" +endif +com! -nargs=+ Xout exec 'Xoutq' <args> + +" Switch off storing of lines for undoing changes. Speeds things up a little. +set undolevels=-1 + +" EXTRA_VIM_STOP - do not change or remove this line. + + +" ExtraVim() - Run a script file in an extra Vim process. {{{2 +" +" This is useful for testing immediate abortion of the script processing due to +" an error in a command dynamically enclosed by a :try/:tryend region or when an +" exception is thrown but not caught or when an interrupt occurs. It can also +" be used for testing :finish. +" +" An interrupt location can be specified by an "INTERRUPT" comment. A number +" telling how often this location is reached (in a loop or in several function +" calls) should be specified as argument. When missing, once per script +" invocation or function call is assumed. INTERRUPT locations are tested by +" setting a breakpoint in that line and using the ">quit" debug command when +" the breakpoint is reached. A function for which an INTERRUPT location is +" specified must be defined before calling it (or executing it as a script by +" using ExecAsScript below). +" +" This function is only called in normal modus ("g:ExtraVimResult" undefined). +" +" Tests to be executed as an extra script should be written as follows: +" +" column 1 column 1 +" | | +" v v +" +" XpathINIT XpathINIT +" if ExtraVim() if ExtraVim() +" ... " ... +" ... " ... +" endif endif +" Xcheck <number> Xcheck <number> +" +" Double quotes in column 1 are removed before the script is executed. +" They should be used if the test has unbalanced conditionals (:if/:endif, +" :while:/endwhile, :try/:endtry) or for a line with a syntax error. The +" extra script may use Xpath, XloopINIT, Xloop, XloopNEXT, and Xout as usual. +" +" A file name may be specified as argument. All messages of the extra Vim +" process are then redirected to the file. An existing file is overwritten. +" +let ExtraVimCount = 0 +let ExtraVimBase = expand("<sfile>") +let ExtraVimTestEnv = "" +" +function! ExtraVim(...) + " Count how often this function is called. + let g:ExtraVimCount = g:ExtraVimCount + 1 + + " Disable folds to prevent that the ranges in the ":write" commands below + " are extended up to the end of a closed fold. This also speeds things up + " considerably. + set nofoldenable + + " Open a buffer for this test script and copy the test environment to + " a temporary file. Take account of parts relevant for the extra script + " execution only. + let current_buffnr = bufnr("%") + execute "view +1" g:ExtraVimBase + if g:ExtraVimCount == 1 + let g:ExtraVimTestEnv = tempname() + execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w" + \ g:ExtraVimTestEnv "|']+" + execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>" + \ g:ExtraVimTestEnv "|']+" + execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>" + \ g:ExtraVimTestEnv "|']+" + execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>" + \ g:ExtraVimTestEnv "|']+" + endif + + " Start the extra Vim script with a ":source" command for the test + " environment. The source line number where the extra script will be + " appended, needs to be passed as variable "ExtraVimBegin" to the script. + let extra_script = tempname() + exec "!echo 'source " . g:ExtraVimTestEnv . "' >" . extra_script + let extra_begin = 1 + + " Starting behind the test environment, skip over the first g:ExtraVimCount + " occurrences of "if ExtraVim()" and copy the following lines up to the + " matching "endif" to the extra Vim script. + execute "/E" . "ND_OF_TEST_ENVIRONMENT/" + exec 'norm ' . g:ExtraVimCount . '/^\s*if\s\+ExtraVim(.*)/+' . "\n" + execute ".,/^endif/-write >>" . extra_script + + " Open a buffer for the extra Vim script, delete all ^", and write the + " script if was actually modified. + execute "edit +" . (extra_begin + 1) extra_script + ,$s/^"//e + update + + " Count the INTERRUPTs and build the breakpoint and quit commands. + let breakpoints = "" + let debug_quits = "" + let in_func = 0 + exec extra_begin + while search( + \ '"\s*INTERRUPT\h\@!\|^\s*fu\%[nction]\>!\=\s*\%(\u\|s:\)\w*\s*(\|' + \ . '^\s*\\\|^\s*endf\%[unction]\>\|' + \ . '\%(^\s*fu\%[nction]!\=\s*\)\@<!\%(\u\|s:\)\w*\s*(\|' + \ . 'ExecAsScript\s\+\%(\u\|s:\)\w*', + \ "W") > 0 + let theline = getline(".") + if theline =~ '^\s*fu' + " Function definition. + let in_func = 1 + let func_start = line(".") + let func_name = substitute(theline, + \ '^\s*fu\%[nction]!\=\s*\(\%(\u\|s:\)\w*\).*', '\1', "") + elseif theline =~ '^\s*endf' + " End of function definition. + let in_func = 0 + else + let finding = substitute(theline, '.*\(\%' . col(".") . 'c.*\)', + \ '\1', "") + if finding =~ '^"\s*INTERRUPT\h\@!' + " Interrupt comment. Compose as many quit commands as + " specified. + let cnt = substitute(finding, + \ '^"\s*INTERRUPT\s*\(\d*\).*$', '\1', "") + let quits = "" + while cnt > 0 + " Use "\r" rather than "\n" to separate the quit commands. + " "\r" is not interpreted as command separator by the ":!" + " command below but works to separate commands in the + " external vim. + let quits = quits . "q\r" + let cnt = cnt - 1 + endwhile + if in_func + " Add the function breakpoint and note the number of quits + " to be used, if specified, or one for every call else. + let breakpoints = breakpoints . " -c 'breakadd func " . + \ (line(".") - func_start) . " " . + \ func_name . "'" + if quits != "" + let debug_quits = debug_quits . quits + elseif !exists("quits{func_name}") + let quits{func_name} = "q\r" + else + let quits{func_name} = quits{func_name} . "q\r" + endif + else + " Add the file breakpoint and the quits to be used for it. + let breakpoints = breakpoints . " -c 'breakadd file " . + \ line(".") . " " . extra_script . "'" + if quits == "" + let quits = "q\r" + endif + let debug_quits = debug_quits . quits + endif + else + " Add the quits to be used for calling the function or executing + " it as script file. + if finding =~ '^ExecAsScript' + " Sourcing function as script. + let finding = substitute(finding, + \ '^ExecAsScript\s\+\(\%(\u\|s:\)\w*\).*', '\1', "") + else + " Function call. + let finding = substitute(finding, + \ '^\(\%(\u\|s:\)\w*\).*', '\1', "") + endif + if exists("quits{finding}") + let debug_quits = debug_quits . quits{finding} + endif + endif + endif + endwhile + + " Close the buffer for the script and create an (empty) resultfile. + bwipeout + let resultfile = tempname() + exec "!>" . resultfile + + " Run the script in an extra vim. Switch to extra modus by passing the + " resultfile in ExtraVimResult. Redirect messages to the file specified as + " argument if any. Use ":debuggreedy" so that the commands provided on the + " pipe are consumed at the debug prompt. Use "-N" to enable command-line + " continuation ("C" in 'cpo'). Add "nviminfo" to 'viminfo' to avoid + " messing up the user's viminfo file. + let redirect = a:0 ? + \ " -c 'au VimLeave * redir END' -c 'redir\\! >" . a:1 . "'" : "" + exec "!echo '" . debug_quits . "q' | ../../build/bin/nvim -u NONE -N -Xes" . redirect . + \ " -c 'debuggreedy|set viminfo+=nviminfo'" . + \ " -c 'let ExtraVimBegin = " . extra_begin . "'" . + \ " -c 'let ExtraVimResult = \"" . resultfile . "\"'" . breakpoints . + \ " -S " . extra_script + + " Build the resulting sum for resultfile and add it to g:Xpath. Add Xout + " information provided by the extra Vim process to the test output. + let sum = 0 + exec "edit" resultfile + let line = 1 + while line <= line("$") + let theline = getline(line) + if theline =~ '^@R:' + exec 'Xout "' . substitute(substitute( + \ escape(escape(theline, '"'), '\"'), + \ '^@R:', '', ""), '@NL@', "\n", "g") . '"' + else + let sum = sum + getline(line) + endif + let line = line + 1 + endwhile + bwipeout + let g:Xpath = g:Xpath + sum + + " Delete the extra script and the resultfile. + call delete(extra_script) + call delete(resultfile) + + " Switch back to the buffer that was active when this function was entered. + exec "buffer" current_buffnr + + " Return 0. This protects extra scripts from being run in the main Vim + " process. + return 0 +endfunction + + +" ExtraVimThrowpoint() - Relative throwpoint in ExtraVim script {{{2 +" +" Evaluates v:throwpoint and returns the throwpoint relative to the beginning of +" an ExtraVim script as passed by ExtraVim() in ExtraVimBegin. +" +" EXTRA_VIM_START - do not change or remove this line. +function! ExtraVimThrowpoint() + if !exists("g:ExtraVimBegin") + Xout "ExtraVimThrowpoint() used outside ExtraVim() script." + return v:throwpoint + endif + + if v:throwpoint =~ '^function\>' + return v:throwpoint + endif + + return "line " . + \ (substitute(v:throwpoint, '.*, line ', '', "") - g:ExtraVimBegin) . + \ " of ExtraVim() script" +endfunction +" EXTRA_VIM_STOP - do not change or remove this line. + + +" MakeScript() - Make a script file from a function. {{{2 +" +" Create a script that consists of the body of the function a:funcname. +" Replace any ":return" by a ":finish", any argument variable by a global +" variable, and and every ":call" by a ":source" for the next following argument +" in the variable argument list. This function is useful if similar tests are +" to be made for a ":return" from a function call or a ":finish" in a script +" file. +" +" In order to execute a function specifying an INTERRUPT location (see ExtraVim) +" as a script file, use ExecAsScript below. +" +" EXTRA_VIM_START - do not change or remove this line. +function! MakeScript(funcname, ...) + let script = tempname() + execute "redir! >" . script + execute "function" a:funcname + redir END + execute "edit" script + " Delete the "function" and the "endfunction" lines. Do not include the + " word "function" in the pattern since it might be translated if LANG is + " set. When MakeScript() is being debugged, this deletes also the debugging + " output of its line 3 and 4. + exec '1,/.*' . a:funcname . '(.*)/d' + /^\d*\s*endfunction\>/,$d + %s/^\d*//e + %s/return/finish/e + %s/\<a:\(\h\w*\)/g:\1/ge + normal gg0 + let cnt = 0 + while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0 + let cnt = cnt + 1 + s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/ + endwhile + g/^\s*$/d + write + bwipeout + return script +endfunction +" EXTRA_VIM_STOP - do not change or remove this line. + + +" ExecAsScript - Source a temporary script made from a function. {{{2 +" +" Make a temporary script file from the function a:funcname, ":source" it, and +" delete it afterwards. +" +" When inside ":if ExtraVim()", add a file breakpoint for each INTERRUPT +" location specified in the function. +" +" EXTRA_VIM_START - do not change or remove this line. +function! ExecAsScript(funcname) + " Make a script from the function passed as argument. + let script = MakeScript(a:funcname) + + " When running in an extra Vim process, add a file breakpoint for each + " function breakpoint set when the extra Vim process was invoked by + " ExtraVim(). + if exists("g:ExtraVimResult") + let bplist = tempname() + execute "redir! >" . bplist + breaklist + redir END + execute "edit" bplist + " Get the line number from the function breakpoint. Works also when + " LANG is set. + execute 'v/^\s*\d\+\s\+func\s\+' . a:funcname . '\s.*/d' + %s/^\s*\d\+\s\+func\s\+\%(\u\|s:\)\w*\s\D*\(\d*\).*/\1/e + let cnt = 0 + while cnt < line("$") + let cnt = cnt + 1 + if getline(cnt) != "" + execute "breakadd file" getline(cnt) script + endif + endwhile + bwipeout! + call delete(bplist) + endif + + " Source and delete the script. + exec "source" script + call delete(script) +endfunction + +com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>) +" EXTRA_VIM_STOP - do not change or remove this line. + + +" END_OF_TEST_ENVIRONMENT - do not change or remove this line. + + +"------------------------------------------------------------------------------- +" Test 1: :endwhile in function {{{1 +" +" Detect if a broken loop is (incorrectly) reactivated by the +" :endwhile. Use a :return to prevent an endless loop, and make +" this test first to get a meaningful result on an error before other +" tests will hang. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + Xpath 1 " X: 1 + let first = 1 + XloopINIT 2 8 + while 1 + Xloop 1 " X: 2 + 0 * 16 + if first + Xloop 2 " X: 4 + 0 * 32 + let first = 0 + XloopNEXT + break + else + Xloop 4 " X: 0 + 0 * 64 + return + endif + endwhile +endfunction + +call F() +Xpath 128 " X: 128 + +function! G() + Xpath 256 " X: 256 + 0 * 2048 + let first = 1 + XloopINIT 512 8 + while 1 + Xloop 1 " X: 512 + 0 * 4096 + if first + Xloop 2 " X: 1024 + 0 * 8192 + let first = 0 + XloopNEXT + break + else + Xloop 4 " X: 0 + 0 * 16384 + return + endif + if 1 " unmatched :if + endwhile +endfunction + +call G() +Xpath 32768 " X: 32768 + +Xcheck 34695 + +" Leave F and G for execution as scripts in the next test. + + +"------------------------------------------------------------------------------- +" Test 2: :endwhile in script {{{1 +" +" Detect if a broken loop is (incorrectly) reactivated by the +" :endwhile. Use a :finish to prevent an endless loop, and place +" this test before others that might hang to get a meaningful result +" on an error. +" +" This test executes the bodies of the functions F and G from the +" previous test as script files (:return replaced by :finish). +"------------------------------------------------------------------------------- + +XpathINIT + +ExecAsScript F " X: 1 + 2 + 4 +Xpath 128 " X: 128 + +ExecAsScript G " X: 256 + 512 + 1024 +Xpath 32768 " X: 32768 + +unlet first +delfunction F +delfunction G + +Xcheck 34695 + + +"------------------------------------------------------------------------------- +" Test 3: :if, :elseif, :while, :continue, :break {{{1 +"------------------------------------------------------------------------------- + +XpathINIT +if 1 + Xpath 1 " X: 1 + let loops = 3 + XloopINIT 2 512 + while loops > -1 " main loop: loops == 3, 2, 1 (which breaks) + if loops <= 0 + let break_err = 1 + let loops = -1 + else " 3: 2: 1: + Xloop 1 " X: 2 + 2*512 + 2*512*512 + endif + if (loops == 2) + while loops == 2 " dummy loop + Xloop 2 " X: 4*512 + let loops = loops - 1 + continue " stop dummy loop + Xloop 4 " X: 0 + endwhile + XloopNEXT + continue " continue main loop + Xloop 8 " X: 0 + elseif (loops == 1) + let p = 1 + while p " dummy loop + Xloop 16 " X: 32*512*512 + let p = 0 + break " break dummy loop + Xloop 32 " X: 0 + endwhile + Xloop 64 " X: 128*512*512 + unlet p + break " break main loop + Xloop 128 " X: 0 + endif + if (loops > 0) + Xloop 256 " X: 512 + endif + while loops == 3 " dummy loop + let loops = loops - 1 + endwhile " end dummy loop + XloopNEXT + endwhile " end main loop + Xpath 268435456 " X: 1024*512*512 +else + Xpath 536870912 " X: 0 +endif +Xpath 1073741824 " X: 4096*512*512 +if exists("break_err") + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + unlet break_err +endif + +unlet loops + +Xcheck 1384648195 + + +"------------------------------------------------------------------------------- +" Test 4: :return {{{1 +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + if 1 + Xpath 1 " X: 1 + let loops = 3 + XloopINIT 2 16 + while loops > 0 " 3: 2: 1: + Xloop 1 " X: 2 + 2*16 + 0*16*16 + if (loops == 2) + Xloop 2 " X: 4*16 + return + Xloop 4 " X: 0 + endif + Xloop 8 " X: 16 + let loops = loops - 1 + XloopNEXT + endwhile + Xpath 8192 " X: 0 + else + Xpath 16384 " X: 0 + endif +endfunction + +call F() +Xpath 32768 " X: 8*16*16*16 + +Xcheck 32883 + +" Leave F for execution as a script in the next test. + + +"------------------------------------------------------------------------------- +" Test 5: :finish {{{1 +" +" This test executes the body of the function F from the previous test +" as a script file (:return replaced by :finish). +"------------------------------------------------------------------------------- + +XpathINIT + +ExecAsScript F " X: 1 + 2 + 2*16 + 4*16 + 16 +Xpath 32768 " X: 32768 + +unlet loops +delfunction F + +Xcheck 32883 + + +"------------------------------------------------------------------------------- +" Test 6: Defining functions in :while loops {{{1 +" +" Functions can be defined inside other functions. An inner function +" gets defined when the outer function is executed. Functions may +" also be defined inside while loops. Expressions in braces for +" defining the function name are allowed. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + " The command CALL collects the argument of all its invocations in "calls" + " when used from a function (that is, when the global variable "calls" needs + " the "g:" prefix). This is to check that the function code is skipped when + " the function is defined. For inner functions, do so only if the outer + " function is not being executed. + " + let calls = "" + com! -nargs=1 CALL + \ if !exists("calls") && !exists("outer") | + \ let g:calls = g:calls . <args> | + \ endif + + + XloopINIT! 1 16 + + let i = 0 + while i < 3 + + XloopNEXT + let i = i + 1 + + if i == 1 + Xloop 1 " X: 1 + function! F1(arg) + CALL a:arg + let outer = 1 + + XloopINIT! 4096 4 + let j = 0 + while j < 1 + XloopNEXT + Xloop 1 " X: 4096 + let j = j + 1 + function! G1(arg) + CALL a:arg + endfunction + Xloop 2 " X: 8192 + endwhile + endfunction + Xloop 2 " X: 2 + + continue + endif + + Xloop 4 " X: 4 * (16 + 256) + function! F{i}(i, arg) + CALL a:arg + let outer = 1 + + XloopINIT! 16384 4 + if a:i == 3 + XloopNEXT + XloopNEXT + XloopNEXT + endif + let k = 0 + while k < 3 + XloopNEXT + Xloop 1 " X: 16384*(1+4+16+64+256+1024) + let k = k + 1 + function! G{a:i}{k}(arg) + CALL a:arg + endfunction + Xloop 2 " X: 32768*(1+4+16+64+256+1024) + endwhile + endfunction + Xloop 8 " X: 8 * (16 + 256) + + endwhile + + if exists("*G1") + Xpath 67108864 " X: 0 + endif + if exists("*F1") + call F1("F1") + if exists("*G1") + call G1("G1") + endif + endif + + if exists("G21") || exists("G21") || exists("G21") + Xpath 134217728 " X: 0 + endif + if exists("*F2") + call F2(2, "F2") + if exists("*G21") + call G21("G21") + endif + if exists("*G22") + call G22("G22") + endif + if exists("*G23") + call G23("G23") + endif + endif + + if exists("G31") || exists("G31") || exists("G31") + Xpath 268435456 " X: 0 + endif + if exists("*F3") + call F3(3, "F3") + if exists("*G31") + call G31("G31") + endif + if exists("*G32") + call G32("G32") + endif + if exists("*G33") + call G33("G33") + endif + endif + + Xpath 536870912 " X: 536870912 + + if calls != "F1G1F2G21G22G23F3G31G32G33" + Xpath 1073741824 " X: 0 + Xout "calls is" calls + endif + + delfunction F1 + delfunction G1 + delfunction F2 + delfunction G21 + delfunction G22 + delfunction G23 + delfunction G31 + delfunction G32 + delfunction G33 + +endif + +Xcheck 603978947 + + +"------------------------------------------------------------------------------- +" Test 7: Continuing on errors outside functions {{{1 +" +" On an error outside a function, the script processing continues +" at the line following the outermost :endif or :endwhile. When not +" inside an :if or :while, the script processing continues at the next +" line. +"------------------------------------------------------------------------------- + +XpathINIT + +if 1 + Xpath 1 " X: 1 + while 1 + Xpath 2 " X: 2 + asdf + Xpath 4 " X: 0 + break + endwhile | Xpath 8 " X: 0 + Xpath 16 " X: 0 +endif | Xpath 32 " X: 0 +Xpath 64 " X: 64 + +while 1 + Xpath 128 " X: 128 + if 1 + Xpath 256 " X: 256 + asdf + Xpath 512 " X: 0 + endif | Xpath 1024 " X: 0 + Xpath 2048 " X: 0 + break +endwhile | Xpath 4096 " X: 0 +Xpath 8192 " X: 8192 + +asdf +Xpath 16384 " X: 16384 + +asdf | Xpath 32768 " X: 0 +Xpath 65536 " X: 65536 + +Xcheck 90563 + + +"------------------------------------------------------------------------------- +" Test 8: Aborting and continuing on errors inside functions {{{1 +" +" On an error inside a function without the "abort" attribute, the +" script processing continues at the next line (unless the error was +" in a :return command). On an error inside a function with the +" "abort" attribute, the function is aborted and the script processing +" continues after the function call; the value -1 is returned then. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + if 1 + Xpath 1 " X: 1 + while 1 + Xpath 2 " X: 2 + asdf + Xpath 4 " X: 4 + asdf | Xpath 8 " X: 0 + Xpath 16 " X: 16 + break + endwhile + Xpath 32 " X: 32 + endif | Xpath 64 " X: 64 + Xpath 128 " X: 128 + + while 1 + Xpath 256 " X: 256 + if 1 + Xpath 512 " X: 512 + asdf + Xpath 1024 " X: 1024 + asdf | Xpath 2048 " X: 0 + Xpath 4096 " X: 4096 + endif + Xpath 8192 " X: 8192 + break + endwhile | Xpath 16384 " X: 16384 + Xpath 32768 " X: 32768 + + return novar " returns (default return value 0) + Xpath 65536 " X: 0 + return 1 " not reached +endfunction + +function! G() abort + if 1 + Xpath 131072 " X: 131072 + while 1 + Xpath 262144 " X: 262144 + asdf " returns -1 + Xpath 524288 " X: 0 + break + endwhile + Xpath 1048576 " X: 0 + endif | Xpath 2097152 " X: 0 + Xpath Xpath 4194304 " X: 0 + + return -4 " not reached +endfunction + +function! H() abort + while 1 + Xpath 8388608 " X: 8388608 + if 1 + Xpath 16777216 " X: 16777216 + asdf " returns -1 + Xpath 33554432 " X: 0 + endif + Xpath 67108864 " X: 0 + break + endwhile | Xpath 134217728 " X: 0 + Xpath 268435456 " X: 0 + + return -4 " not reached +endfunction + +" Aborted functions (G and H) return -1. +let sum = (F() + 1) - 4*G() - 8*H() +Xpath 536870912 " X: 536870912 +if sum != 13 + Xpath 1073741824 " X: 0 + Xout "sum is" sum +endif + +unlet sum +delfunction F +delfunction G +delfunction H + +Xcheck 562493431 + + +"------------------------------------------------------------------------------- +" Test 9: Continuing after aborted functions {{{1 +" +" When a function with the "abort" attribute is aborted due to an +" error, the next function back in the call hierarchy without an +" "abort" attribute continues; the value -1 is returned then. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() abort + Xpath 1 " X: 1 + let result = G() " not aborted + Xpath 2 " X: 2 + if result != 2 + Xpath 4 " X: 0 + endif + return 1 +endfunction + +function! G() " no abort attribute + Xpath 8 " X: 8 + if H() != -1 " aborted + Xpath 16 " X: 0 + endif + Xpath 32 " X: 32 + return 2 +endfunction + +function! H() abort + Xpath 64 " X: 64 + call I() " aborted + Xpath 128 " X: 0 + return 4 +endfunction + +function! I() abort + Xpath 256 " X: 256 + asdf " error + Xpath 512 " X: 0 + return 8 +endfunction + +if F() != 1 + Xpath 1024 " X: 0 +endif + +delfunction F +delfunction G +delfunction H +delfunction I + +Xcheck 363 + + +"------------------------------------------------------------------------------- +" Test 10: :if, :elseif, :while argument parsing {{{1 +" +" A '"' or '|' in an argument expression must not be mixed up with +" a comment or a next command after a bar. Parsing errors should +" be recognized. +"------------------------------------------------------------------------------- + +XpathINIT + +function! MSG(enr, emsg) + let english = v:lang == "C" || v:lang =~ '^[Ee]n' + if a:enr == "" + Xout "TODO: Add message number for:" a:emsg + let v:errmsg = ":" . v:errmsg + endif + let match = 1 + if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) + let match = 0 + if v:errmsg == "" + Xout "Message missing." + else + let v:errmsg = escape(v:errmsg, '"') + Xout "Unexpected message:" v:errmsg + endif + endif + return match +endfunction + +if 1 || strlen("\"") | Xpath 1 " X: 1 + Xpath 2 " X: 2 +endif +Xpath 4 " X: 4 + +if 0 +elseif 1 || strlen("\"") | Xpath 8 " X: 8 + Xpath 16 " X: 16 +endif +Xpath 32 " X: 32 + +while 1 || strlen("\"") | Xpath 64 " X: 64 + Xpath 128 " X: 128 + break +endwhile +Xpath 256 " X: 256 + +let v:errmsg = "" +if 1 ||| strlen("\"") | Xpath 512 " X: 0 + Xpath 1024 " X: 0 +endif +Xpath 2048 " X: 2048 +if !MSG('E15', "Invalid expression") + Xpath 4096 " X: 0 +endif + +let v:errmsg = "" +if 0 +elseif 1 ||| strlen("\"") | Xpath 8192 " X: 0 + Xpath 16384 " X: 0 +endif +Xpath 32768 " X: 32768 +if !MSG('E15', "Invalid expression") + Xpath 65536 " X: 0 +endif + +let v:errmsg = "" +while 1 ||| strlen("\"") | Xpath 131072 " X: 0 + Xpath 262144 " X: 0 + break +endwhile +Xpath 524288 " X: 524288 +if !MSG('E15', "Invalid expression") + Xpath 1048576 " X: 0 +endif + +delfunction MSG + +Xcheck 559615 + + +"------------------------------------------------------------------------------- +" Test 11: :if, :elseif, :while argument evaluation after abort {{{1 +" +" When code is skipped over due to an error, the boolean argument to +" an :if, :elseif, or :while must not be evaluated. +"------------------------------------------------------------------------------- + +XpathINIT + +let calls = 0 + +function! P(num) + let g:calls = g:calls + a:num " side effect on call + return 0 +endfunction + +if 1 + Xpath 1 " X: 1 + asdf " error + Xpath 2 " X: 0 + if P(1) " should not be called + Xpath 4 " X: 0 + elseif !P(2) " should not be called + Xpath 8 " X: 0 + else + Xpath 16 " X: 0 + endif + Xpath 32 " X: 0 + while P(4) " should not be called + Xpath 64 " X: 0 + endwhile + Xpath 128 " X: 0 +endif + +if calls % 2 + Xpath 256 " X: 0 +endif +if (calls/2) % 2 + Xpath 512 " X: 0 +endif +if (calls/4) % 2 + Xpath 1024 " X: 0 +endif +Xpath 2048 " X: 2048 + +unlet calls +delfunction P + +Xcheck 2049 + + +"------------------------------------------------------------------------------- +" Test 12: Expressions in braces in skipped code {{{1 +" +" In code skipped over due to an error or inactive conditional, +" an expression in braces as part of a variable or function name +" should not be evaluated. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT 1 8 + +function! NULL() + Xloop 1 " X: 0 + return 0 +endfunction + +function! ZERO() + Xloop 2 " X: 0 + return 0 +endfunction + +function! F0() + Xloop 4 " X: 0 +endfunction + +function! F1(arg) + Xpath 4096 " X: 0 +endfunction + +let V0 = 1 + +Xpath 8192 " X: 8192 +echo 0 ? F{NULL() + V{ZERO()}}() : 1 +XloopNEXT + +Xpath 16384 " X: 16384 +if 0 + Xpath 32768 " X: 0 + call F{NULL() + V{ZERO()}}() +endif +XloopNEXT + +Xpath 65536 " X: 65536 +if 1 + asdf " error + Xpath 131072 " X: 0 + call F1(F{NULL() + V{ZERO()}}()) +endif +XloopNEXT + +Xpath 262144 " X: 262144 +if 1 + asdf " error + Xpath 524288 " X: 0 + call F{NULL() + V{ZERO()}}() +endif + +Xcheck 352256 + + +"------------------------------------------------------------------------------- +" Test 13: Failure in argument evaluation for :while {{{1 +" +" A failure in the expression evaluation for the condition of a :while +" causes the whole :while loop until the matching :endwhile being +" ignored. Continuation is at the next following line. +"------------------------------------------------------------------------------- + +XpathINIT + +Xpath 1 " X: 1 +while asdf + Xpath 2 " X: 0 + while 1 + Xpath 4 " X: 0 + break + endwhile + Xpath 8 " X: 0 + break +endwhile +Xpath 16 " X: 16 + +while asdf | Xpath 32 | endwhile | Xpath 64 " X: 0 +Xpath 128 " X: 128 + +Xcheck 145 + + +"------------------------------------------------------------------------------- +" Test 14: Failure in argument evaluation for :if {{{1 +" +" A failure in the expression evaluation for the condition of an :if +" does not cause the corresponding :else or :endif being matched to +" a previous :if/:elseif. Neither of both branches of the failed :if +" are executed. +"------------------------------------------------------------------------------- + +XpathINIT +XloopINIT 1 256 + +function! F() + Xloop 1 " X: 1 + 256 * 1 + let x = 0 + if x " false + Xloop 2 " X: 0 + 256 * 0 + elseif !x " always true + Xloop 4 " X: 4 + 256 * 4 + let x = 1 + if g:boolvar " possibly undefined + Xloop 8 " X: 8 + 256 * 0 + else + Xloop 16 " X: 0 + 256 * 0 + endif + Xloop 32 " X: 32 + 256 * 32 + elseif x " never executed + Xloop 64 " X: 0 + 256 * 0 + endif + Xloop 128 " X: 128 + 256 * 128 +endfunction + +let boolvar = 1 +call F() + +XloopNEXT +unlet boolvar +call F() + +delfunction F + +Xcheck 42413 + + +"------------------------------------------------------------------------------- +" Test 15: Failure in argument evaluation for :if (bar) {{{1 +" +" Like previous test, except that the failing :if ... | ... | :endif +" is in a single line. +"------------------------------------------------------------------------------- + +XpathINIT +XloopINIT 1 256 + +function! F() + Xloop 1 " X: 1 + 256 * 1 + let x = 0 + if x " false + Xloop 2 " X: 0 + 256 * 0 + elseif !x " always true + Xloop 4 " X: 4 + 256 * 4 + let x = 1 + if g:boolvar | Xloop 8 | else | Xloop 16 | endif " X: 8 + Xloop 32 " X: 32 + 256 * 32 + elseif x " never executed + Xloop 64 " X: 0 + 256 * 0 + endif + Xloop 128 " X: 128 + 256 * 128 +endfunction + +let boolvar = 1 +call F() + +XloopNEXT +unlet boolvar +call F() + +delfunction F + +Xcheck 42413 + + +"------------------------------------------------------------------------------- +" Test 16: Double :else or :elseif after :else {{{1 +" +" Multiple :elses or an :elseif after an :else are forbidden. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() abort + if 0 + Xpath 1 " X: 0 + else + Xpath 2 " X: 2 + else " aborts function + Xpath 4 " X: 0 + endif +endfunction + +function! G() abort + if 0 + Xpath 8 " X: 0 + else + Xpath 16 " X: 16 + elseif 1 " aborts function + Xpath 32 " X: 0 + else + Xpath 64 " X: 0 + endif +endfunction + +function! H() abort + if 0 + Xpath 128 " X: 0 + elseif 0 + Xpath 256 " X: 0 + else + Xpath 512 " X: 512 + else " aborts function + Xpath 1024 " X: 0 + endif +endfunction + +function! I() abort + if 0 + Xpath 2048 " X: 0 + elseif 0 + Xpath 4096 " X: 0 + else + Xpath 8192 " X: 8192 + elseif 1 " aborts function + Xpath 16384 " X: 0 + else + Xpath 32768 " X: 0 + endif +endfunction + +call F() +call G() +call H() +call I() + +delfunction F +delfunction G +delfunction H +delfunction I + +Xcheck 8722 + + +"------------------------------------------------------------------------------- +" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1 +" +" The :while/:endwhile takes precedence in nesting over an unclosed +" :if or an unopened :endif. +"------------------------------------------------------------------------------- + +XpathINIT + +function! MSG(enr, emsg) + let english = v:lang == "C" || v:lang =~ '^[Ee]n' + if a:enr == "" + Xout "TODO: Add message number for:" a:emsg + let v:errmsg = ":" . v:errmsg + endif + let match = 1 + if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) + let match = 0 + if v:errmsg == "" + Xout "Message missing." + else + let v:errmsg = escape(v:errmsg, '"') + Xout "Unexpected message:" v:errmsg + endif + endif + return match +endfunction + +let messages = "" + +" While loops inside a function are continued on error. +function! F() + let v:errmsg = "" + XloopINIT 1 16 + let loops = 3 + while loops > 0 + let loops = loops - 1 " 2: 1: 0: + Xloop 1 " X: 1 + 1*16 + 1*16*16 + if (loops == 1) + Xloop 2 " X: 2*16 + XloopNEXT + continue + elseif (loops == 0) + Xloop 4 " X: 4*16*16 + break + elseif 1 + Xloop 8 " X: 8 + XloopNEXT + " endif missing! + endwhile " :endwhile after :if 1 + Xpath 4096 " X: 16*16*16 + if MSG('E171', "Missing :endif") + let g:messages = g:messages . "A" + endif + + let v:errmsg = "" + XloopINIT! 8192 4 + let loops = 2 + while loops > 0 " 2: 1: + XloopNEXT + let loops = loops - 1 + Xloop 1 " X: 8192 + 8192*4 + if 0 + Xloop 2 " X: 0 + " endif missing + endwhile " :endwhile after :if 0 + Xpath 131072 " X: 8192*4*4 + if MSG('E171', "Missing :endif") + let g:messages = g:messages . "B" + endif + + let v:errmsg = "" + XloopINIT 262144 4 + let loops = 2 + while loops > 0 " 2: 1: + let loops = loops - 1 + Xloop 1 " X: 262144 + 262144 * 4 + " if missing! + endif " :endif without :if in while + Xloop 2 " X: 524288 + 524288 * 4 + XloopNEXT + endwhile + Xpath 4194304 " X: 262144*4*4 + if MSG('E580', ":endif without :if") + let g:messages = g:messages . "C" + endif +endfunction + +call F() + +" Error continuation outside a function is at the outermost :endwhile or :endif. +let v:errmsg = "" +XloopINIT! 8388608 4 +let loops = 2 +while loops > 0 " 2: 1: + XloopNEXT + let loops = loops - 1 + Xloop 1 " X: 8388608 + 0 * 4 + if 0 + Xloop 2 " X: 0 + " endif missing! Following :endwhile fails. +endwhile | Xpath 134217728 " X: 0 +Xpath 268435456 " X: 2*8388608*4*4 +if MSG('E171', "Missing :endif") + let messages = g:messages . "D" +endif + +if messages != "ABCD" + Xpath 536870912 " X: 0 + Xout "messages is" messages "instead of ABCD" +endif + +unlet loops messages +delfunction F +delfunction MSG + +Xcheck 285127993 + + +"------------------------------------------------------------------------------- +" Test 18: Interrupt (Ctrl-C pressed) {{{1 +" +" On an interrupt, the script processing is terminated immediately. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + if 1 + Xpath 1 " X: 1 + while 1 + Xpath 2 " X: 2 + if 1 + Xpath 4 " X: 4 + "INTERRUPT + Xpath 8 " X: 0 + break + finish + endif | Xpath 16 " X: 0 + Xpath 32 " X: 0 + endwhile | Xpath 64 " X: 0 + Xpath 128 " X: 0 + endif | Xpath 256 " X: 0 + Xpath 512 " X: 0 +endif + +if ExtraVim() + try + Xpath 1024 " X: 1024 + "INTERRUPT + Xpath 2048 " X: 0 + endtry | Xpath 4096 " X: 0 + Xpath 8192 " X: 0 +endif + +if ExtraVim() + function! F() + if 1 + Xpath 16384 " X: 16384 + while 1 + Xpath 32768 " X: 32768 + if 1 + Xpath 65536 " X: 65536 + "INTERRUPT + Xpath 131072 " X: 0 + break + return + endif | Xpath 262144 " X: 0 + Xpath Xpath 524288 " X: 0 + endwhile | Xpath 1048576 " X: 0 + Xpath Xpath 2097152 " X: 0 + endif | Xpath Xpath 4194304 " X: 0 + Xpath Xpath 8388608 " X: 0 + endfunction + + call F() | Xpath 16777216 " X: 0 + Xpath 33554432 " X: 0 +endif + +if ExtraVim() + function! G() + try + Xpath 67108864 " X: 67108864 + "INTERRUPT + Xpath 134217728 " X: 0 + endtry | Xpath 268435456 " X: 0 + Xpath 536870912 " X: 0 + endfunction + + call G() | Xpath 1073741824 " X: 0 + " The Xpath command does not accept 2^31 (negative); display explicitly: + exec "!echo 2147483648 >>" . g:ExtraVimResult + " X: 0 +endif + +Xcheck 67224583 + + +"------------------------------------------------------------------------------- +" Test 19: Aborting on errors inside :try/:endtry {{{1 +" +" An error in a command dynamically enclosed in a :try/:endtry region +" aborts script processing immediately. It does not matter whether +" the failing command is outside or inside a function and whether a +" function has an "abort" attribute. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + function! F() abort + Xpath 1 " X: 1 + asdf + Xpath 2 " X: 0 + endfunction + + try + Xpath 4 " X: 4 + call F() + Xpath 8 " X: 0 + endtry | Xpath 16 " X: 0 + Xpath 32 " X: 0 +endif + +if ExtraVim() + function! G() + Xpath 64 " X: 64 + asdf + Xpath 128 " X: 0 + endfunction + + try + Xpath 256 " X: 256 + call G() + Xpath 512 " X: 0 + endtry | Xpath 1024 " X: 0 + Xpath 2048 " X: 0 +endif + +if ExtraVim() + try + Xpath 4096 " X: 4096 + asdf + Xpath 8192 " X: 0 + endtry | Xpath 16384 " X: 0 + Xpath 32768 " X: 0 +endif + +if ExtraVim() + if 1 + try + Xpath 65536 " X: 65536 + asdf + Xpath 131072 " X: 0 + endtry | Xpath 262144 " X: 0 + endif | Xpath 524288 " X: 0 + Xpath 1048576 " X: 0 +endif + +if ExtraVim() + let p = 1 + while p + let p = 0 + try + Xpath 2097152 " X: 2097152 + asdf + Xpath 4194304 " X: 0 + endtry | Xpath 8388608 " X: 0 + endwhile | Xpath 16777216 " X: 0 + Xpath 33554432 " X: 0 +endif + +if ExtraVim() + let p = 1 + while p + let p = 0 +" try + Xpath 67108864 " X: 67108864 + endwhile | Xpath 134217728 " X: 0 + Xpath 268435456 " X: 0 +endif + +Xcheck 69275973 +"------------------------------------------------------------------------------- +" Test 20: Aborting on errors after :try/:endtry {{{1 +" +" When an error occurs after the last active :try/:endtry region has +" been left, termination behavior is as if no :try/:endtry has been +" seen. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + let p = 1 + while p + let p = 0 + try + Xpath 1 " X: 1 + endtry + asdf + endwhile | Xpath 2 " X: 0 + Xpath 4 " X: 4 +endif + +if ExtraVim() + while 1 + try + Xpath 8 " X: 8 + break + Xpath 16 " X: 0 + endtry + endwhile + Xpath 32 " X: 32 + asdf + Xpath 64 " X: 64 +endif + +if ExtraVim() + while 1 + try + Xpath 128 " X: 128 + break + Xpath 256 " X: 0 + finally + Xpath 512 " X: 512 + endtry + endwhile + Xpath 1024 " X: 1024 + asdf + Xpath 2048 " X: 2048 +endif + +if ExtraVim() + while 1 + try + Xpath 4096 " X: 4096 + finally + Xpath 8192 " X: 8192 + break + Xpath 16384 " X: 0 + endtry + endwhile + Xpath 32768 " X: 32768 + asdf + Xpath 65536 " X: 65536 +endif + +if ExtraVim() + let p = 1 + while p + let p = 0 + try + Xpath 131072 " X: 131072 + continue + Xpath 262144 " X: 0 + endtry + endwhile + Xpath 524288 " X: 524288 + asdf + Xpath 1048576 " X: 1048576 +endif + +if ExtraVim() + let p = 1 + while p + let p = 0 + try + Xpath 2097152 " X: 2097152 + continue + Xpath 4194304 " X: 0 + finally + Xpath 8388608 " X: 8388608 + endtry + endwhile + Xpath 16777216 " X: 16777216 + asdf + Xpath 33554432 " X: 33554432 +endif + +if ExtraVim() + let p = 1 + while p + let p = 0 + try + Xpath 67108864 " X: 67108864 + finally + Xpath 134217728 " X: 134217728 + continue + Xpath 268435456 " X: 0 + endtry + endwhile + Xpath 536870912 " X: 536870912 + asdf + Xpath 1073741824 " X: 1073741824 +endif + +Xcheck 1874575085 + + +"------------------------------------------------------------------------------- +" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1 +" +" If a :try conditional stays inactive due to a preceding :continue, +" :break, :return, or :finish, its :finally clause should not be +" executed. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + function F() + let loops = 2 + XloopINIT! 1 256 + while loops > 0 + XloopNEXT + let loops = loops - 1 + try + if loops == 1 + Xloop 1 " X: 1 + continue + Xloop 2 " X: 0 + elseif loops == 0 + Xloop 4 " X: 4*256 + break + Xloop 8 " X: 0 + endif + + try " inactive + Xloop 16 " X: 0 + finally + Xloop 32 " X: 0 + endtry + finally + Xloop 64 " X: 64 + 64*256 + endtry + Xloop 128 " X: 0 + endwhile + + try + Xpath 65536 " X: 65536 + return + Xpath 131072 " X: 0 + try " inactive + Xpath 262144 " X: 0 + finally + Xpath 524288 " X: 0 + endtry + finally + Xpath 1048576 " X: 1048576 + endtry + Xpath 2097152 " X: 0 + endfunction + + try + Xpath 4194304 " X: 4194304 + call F() + Xpath 8388608 " X: 8388608 + finish + Xpath 16777216 " X: 0 + try " inactive + Xpath 33554432 " X: 0 + finally + Xpath 67108864 " X: 0 + endtry + finally + Xpath 134217728 " X: 134217728 + endtry + Xpath 268435456 " X: 0 +endif + +Xcheck 147932225 + + +"------------------------------------------------------------------------------- +" Test 22: :finally for a :try after an error/interrupt/:throw {{{1 +" +" If a :try conditional stays inactive due to a preceding error or +" interrupt or :throw, its :finally clause should not be executed. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + function! Error() + try + asdf " aborting error, triggering error exception + endtry + endfunction + + Xpath 1 " X: 1 + call Error() + Xpath 2 " X: 0 + + if 1 " not active due to error + try " not active since :if inactive + Xpath 4 " X: 0 + finally + Xpath 8 " X: 0 + endtry + endif + + try " not active due to error + Xpath 16 " X: 0 + finally + Xpath 32 " X: 0 + endtry +endif + +if ExtraVim() + function! Interrupt() + try + "INTERRUPT " triggering interrupt exception + endtry + endfunction + + Xpath 64 " X: 64 + call Interrupt() + Xpath 128 " X: 0 + + if 1 " not active due to interrupt + try " not active since :if inactive + Xpath 256 " X: 0 + finally + Xpath 512 " X: 0 + endtry + endif + + try " not active due to interrupt + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 0 + endtry +endif + +if ExtraVim() + function! Throw() + throw "xyz" + endfunction + + Xpath 4096 " X: 4096 + call Throw() + Xpath 8192 " X: 0 + + if 1 " not active due to :throw + try " not active since :if inactive + Xpath 16384 " X: 0 + finally + Xpath 32768 " X: 0 + endtry + endif + + try " not active due to :throw + Xpath 65536 " X: 0 + finally + Xpath 131072 " X: 0 + endtry +endif + +Xcheck 4161 + + +"------------------------------------------------------------------------------- +" Test 23: :catch clauses for a :try after a :throw {{{1 +" +" If a :try conditional stays inactive due to a preceding :throw, +" none of its :catch clauses should be executed. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + try + Xpath 1 " X: 1 + throw "xyz" + Xpath 2 " X: 0 + + if 1 " not active due to :throw + try " not active since :if inactive + Xpath 4 " X: 0 + catch /xyz/ + Xpath 8 " X: 0 + endtry + endif + catch /xyz/ + Xpath 16 " X: 16 + endtry + + Xpath 32 " X: 32 + throw "abc" + Xpath 64 " X: 0 + + try " not active due to :throw + Xpath 128 " X: 0 + catch /abc/ + Xpath 256 " X: 0 + endtry +endif + +Xcheck 49 + + +"------------------------------------------------------------------------------- +" Test 24: :endtry for a :try after a :throw {{{1 +" +" If a :try conditional stays inactive due to a preceding :throw, +" its :endtry should not rethrow the exception to the next surrounding +" active :try conditional. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + try " try 1 + try " try 2 + Xpath 1 " X: 1 + throw "xyz" " makes try 2 inactive + Xpath 2 " X: 0 + + try " try 3 + Xpath 4 " X: 0 + endtry " no rethrow to try 1 + catch /xyz/ " should catch although try 2 inactive + Xpath 8 " X: 8 + endtry + catch /xyz/ " try 1 active, but exception already caught + Xpath 16 " X: 0 + endtry + Xpath 32 " X: 32 +endif + +Xcheck 41 + + +"------------------------------------------------------------------------------- +" Test 25: Executing :finally clauses on normal control flow {{{1 +" +" Control flow in a :try conditional should always fall through to its +" :finally clause. A :finally clause of a :try conditional inside an +" inactive conditional should never be executed. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + let loops = 3 + XloopINIT 1 256 + while loops > 0 " 3: 2: 1: + Xloop 1 " X: 1 + 1*256 + 1*256*256 + if loops >= 2 + try + Xloop 2 " X: 2 + 2*256 + if loops == 2 + try + Xloop 4 " X: 4*256 + finally + Xloop 8 " X: 8*256 + endtry + endif + finally + Xloop 16 " X: 16 + 16*256 + if loops == 2 + try + Xloop 32 " X: 32*256 + finally + Xloop 64 " X: 64*256 + endtry + endif + endtry + endif + Xloop 128 " X: 128 + 128*256 + 128*256*256 + let loops = loops - 1 + XloopNEXT + endwhile + Xpath 16777216 " X: 16777216 +endfunction + +if 1 + try + Xpath 33554432 " X: 33554432 + call F() + Xpath 67108864 " X: 67108864 + finally + Xpath 134217728 " X: 134217728 + endtry +else + try + Xpath 268435456 " X: 0 + finally + Xpath 536870912 " X: 0 + endtry +endif + +delfunction F + +Xcheck 260177811 + + +"------------------------------------------------------------------------------- +" Test 26: Executing :finally clauses after :continue or :break {{{1 +" +" For a :continue or :break dynamically enclosed in a :try/:endtry +" region inside the next surrounding :while/:endwhile, if the +" :continue/:break is before the :finally, the :finally clause is +" executed first. If the :continue/:break is after the :finally, the +" :finally clause is broken (like an :if/:endif region). +"------------------------------------------------------------------------------- + +XpathINIT + +try + let loops = 3 + XloopINIT! 1 32 + while loops > 0 + XloopNEXT + try + try + if loops == 2 " 3: 2: 1: + Xloop 1 " X: 1*32 + let loops = loops - 1 + continue + elseif loops == 1 + Xloop 2 " X: 2*32*32 + break + finish + endif + Xloop 4 " X: 4 + endtry + finally + Xloop 8 " X: 8 + 8*32 + 8*32*32 + endtry + Xloop 16 " X: 16 + let loops = loops - 1 + endwhile + Xpath 32768 " X: 32768 +finally + Xpath 65536 " X: 65536 + let loops = 3 + XloopINIT 131072 16 + while loops > 0 + try + finally + try + if loops == 2 + Xloop 1 " X: 131072*16 + let loops = loops - 1 + XloopNEXT + continue + elseif loops == 1 + Xloop 2 " X: 131072*2*16*16 + break + finish + endif + endtry + Xloop 4 " X: 131072*4 + endtry + Xloop 8 " X: 131072*8 + let loops = loops - 1 + XloopNEXT + endwhile + Xpath 536870912 " X: 536870912 +endtry +Xpath 1073741824 " X: 1073741824 + +unlet loops + +Xcheck 1681500476 + + +"------------------------------------------------------------------------------- +" Test 27: Executing :finally clauses after :return {{{1 +" +" For a :return command dynamically enclosed in a :try/:endtry region, +" :finally clauses are executed and the called function is ended. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + try + Xpath 1 " X: 1 + try + Xpath 2 " X: 2 + return + Xpath 4 " X: 0 + finally + Xpath 8 " X: 8 + endtry + Xpath 16 " X: 0 + finally + Xpath 32 " X: 32 + endtry + Xpath 64 " X: 0 +endfunction + +function! G() + try + Xpath 128 " X: 128 + return + Xpath 256 " X: 0 + finally + Xpath 512 " X: 512 + call F() + Xpath 1024 " X: 1024 + endtry + Xpath 2048 " X: 0 +endfunction + +function! H() + try + Xpath 4096 " X: 4096 + call G() + Xpath 8192 " X: 8192 + finally + Xpath 16384 " X: 16384 + return + Xpath 32768 " X: 0 + endtry + Xpath 65536 " X: 0 +endfunction + +try + Xpath 131072 " X: 131072 + call H() + Xpath 262144 " X: 262144 +finally + Xpath 524288 " X: 524288 +endtry +Xpath 1048576 " X: 1048576 + +Xcheck 1996459 + +" Leave F, G, and H for execution as scripts in the next test. + + +"------------------------------------------------------------------------------- +" Test 28: Executing :finally clauses after :finish {{{1 +" +" For a :finish command dynamically enclosed in a :try/:endtry region, +" :finally clauses are executed and the sourced file is finished. +" +" This test executes the bodies of the functions F, G, and H from the +" previous test as script files (:return replaced by :finish). +"------------------------------------------------------------------------------- + +XpathINIT + +let scriptF = MakeScript("F") " X: 1 + 2 + 8 + 32 +let scriptG = MakeScript("G", scriptF) " X: 128 + 512 + 1024 +let scriptH = MakeScript("H", scriptG) " X: 4096 + 8192 + 16384 + +try + Xpath 131072 " X: 131072 + exec "source" scriptH + Xpath 262144 " X: 262144 +finally + Xpath 524288 " X: 524288 +endtry +Xpath 1048576 " X: 1048576 + +call delete(scriptF) +call delete(scriptG) +call delete(scriptH) +unlet scriptF scriptG scriptH +delfunction F +delfunction G +delfunction H + +Xcheck 1996459 + + +"------------------------------------------------------------------------------- +" Test 29: Executing :finally clauses on errors {{{1 +" +" After an error in a command dynamically enclosed in a :try/:endtry +" region, :finally clauses are executed and the script processing is +" terminated. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + function! F() + while 1 + try + Xpath 1 " X: 1 + while 1 + try + Xpath 2 " X: 2 + asdf " error + Xpath 4 " X: 0 + finally + Xpath 8 " X: 8 + endtry | Xpath 16 " X: 0 + Xpath 32 " X: 0 + break + endwhile + Xpath 64 " X: 0 + finally + Xpath 128 " X: 128 + endtry | Xpath 256 " X: 0 + Xpath 512 " X: 0 + break + endwhile + Xpath 1024 " X: 0 + endfunction + + while 1 + try + Xpath 2048 " X: 2048 + while 1 + call F() + Xpath 4096 " X: 0 + break + endwhile | Xpath 8192 " X: 0 + Xpath 16384 " X: 0 + finally + Xpath 32768 " X: 32768 + endtry | Xpath 65536 " X: 0 + endwhile | Xpath 131072 " X: 0 + Xpath 262144 " X: 0 +endif + +if ExtraVim() + function! G() abort + if 1 + try + Xpath 524288 " X: 524288 + asdf " error + Xpath 1048576 " X: 0 + finally + Xpath 2097152 " X: 2097152 + endtry | Xpath 4194304 " X: 0 + endif | Xpath 8388608 " X: 0 + Xpath 16777216 " X: 0 + endfunction + + if 1 + try + Xpath 33554432 " X: 33554432 + call G() + Xpath 67108864 " X: 0 + finally + Xpath 134217728 " X: 134217728 + endtry | Xpath 268435456 " X: 0 + endif | Xpath 536870912 " X: 0 + Xpath 1073741824 " X: 0 +endif + +Xcheck 170428555 + + +"------------------------------------------------------------------------------- +" Test 30: Executing :finally clauses on interrupt {{{1 +" +" After an interrupt in a command dynamically enclosed in +" a :try/:endtry region, :finally clauses are executed and the +" script processing is terminated. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + XloopINIT 1 16 + + function! F() + try + Xloop 1 " X: 1 + 1*16 + "INTERRUPT + Xloop 2 " X: 0 + finally + Xloop 4 " X: 4 + 4*16 + endtry + Xloop 8 " X: 0 + endfunction + + try + Xpath 256 " X: 256 + try + Xpath 512 " X: 512 + "INTERRUPT + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + try + Xpath 4096 " X: 4096 + try + Xpath 8192 " X: 8192 + finally + Xpath 16384 " X: 16384 + try + Xpath 32768 " X: 32768 + "INTERRUPT + Xpath 65536 " X: 0 + endtry + Xpath 131072 " X: 0 + endtry + Xpath 262144 " X: 0 + endtry + Xpath 524288 " X: 0 + endtry + Xpath 1048576 " X: 0 + finally + Xpath 2097152 " X: 2097152 + try + Xpath 4194304 " X: 4194304 + call F() + Xpath 8388608 " X: 0 + finally + Xpath 16777216 " X: 16777216 + try + Xpath 33554432 " X: 33554432 + XloopNEXT + ExecAsScript F + Xpath 67108864 " X: 0 + finally + Xpath 134217728 " X: 134217728 + endtry + Xpath 268435456 " X: 0 + endtry + Xpath 536870912 " X: 0 + endtry + Xpath 1073741824 " X: 0 +endif + +Xcheck 190905173 + + +"------------------------------------------------------------------------------- +" Test 31: Executing :finally clauses after :throw {{{1 +" +" After a :throw dynamically enclosed in a :try/:endtry region, +" :finally clauses are executed and the script processing is +" terminated. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + XloopINIT 1 16 + + function! F() + try + Xloop 1 " X: 1 + 1*16 + throw "exception" + Xloop 2 " X: 0 + finally + Xloop 4 " X: 4 + 4*16 + endtry + Xloop 8 " X: 0 + endfunction + + try + Xpath 256 " X: 256 + try + Xpath 512 " X: 512 + throw "exception" + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + try + Xpath 4096 " X: 4096 + try + Xpath 8192 " X: 8192 + finally + Xpath 16384 " X: 16384 + try + Xpath 32768 " X: 32768 + throw "exception" + Xpath 65536 " X: 0 + endtry + Xpath 131072 " X: 0 + endtry + Xpath 262144 " X: 0 + endtry + Xpath 524288 " X: 0 + endtry + Xpath 1048576 " X: 0 + finally + Xpath 2097152 " X: 2097152 + try + Xpath 4194304 " X: 4194304 + call F() + Xpath 8388608 " X: 0 + finally + Xpath 16777216 " X: 16777216 + try + Xpath 33554432 " X: 33554432 + XloopNEXT + ExecAsScript F + Xpath 67108864 " X: 0 + finally + Xpath 134217728 " X: 134217728 + endtry + Xpath 268435456 " X: 0 + endtry + Xpath 536870912 " X: 0 + endtry + Xpath 1073741824 " X: 0 +endif + +Xcheck 190905173 + + +"------------------------------------------------------------------------------- +" Test 32: Remembering the :return value on :finally {{{1 +" +" If a :finally clause is executed due to a :return specifying +" a value, this is the value visible to the caller if not overwritten +" by a new :return in the :finally clause. A :return without a value +" in the :finally clause overwrites with value 0. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + try + Xpath 1 " X: 1 + try + Xpath 2 " X: 2 + return "ABCD" + Xpath 4 " X: 0 + finally + Xpath 8 " X: 8 + endtry + Xpath 16 " X: 0 + finally + Xpath 32 " X: 32 + endtry + Xpath 64 " X: 0 +endfunction + +function! G() + try + Xpath 128 " X: 128 + return 8 + Xpath 256 " X: 0 + finally + Xpath 512 " X: 512 + return 16 + strlen(F()) + Xpath 1024 " X: 0 + endtry + Xpath 2048 " X: 0 +endfunction + +function! H() + try + Xpath 4096 " X: 4096 + return 32 + Xpath 8192 " X: 0 + finally + Xpath 16384 " X: 16384 + return + Xpath 32768 " X: 0 + endtry + Xpath 65536 " X: 0 +endfunction + +function! I() + try + Xpath 131072 " X: 131072 + finally + Xpath 262144 " X: 262144 + return G() + H() + 64 + Xpath 524288 " X: 0 + endtry + Xpath 1048576 " X: 0 +endfunction + +let retcode = I() +Xpath 2097152 " X: 2097152 + +if retcode < 0 + Xpath 4194304 " X: 0 +endif +if retcode % 4 + Xpath 8388608 " X: 0 +endif +if (retcode/4) % 2 + Xpath 16777216 " X: 16777216 +endif +if (retcode/8) % 2 + Xpath 33554432 " X: 0 +endif +if (retcode/16) % 2 + Xpath 67108864 " X: 67108864 +endif +if (retcode/32) % 2 + Xpath 134217728 " X: 0 +endif +if (retcode/64) % 2 + Xpath 268435456 " X: 268435456 +endif +if retcode/128 + Xpath 536870912 " X: 0 +endif + +unlet retcode +delfunction F +delfunction G +delfunction H +delfunction I + +Xcheck 354833067 + + +"------------------------------------------------------------------------------- +" Test 33: :return under :execute or user command and :finally {{{1 +" +" A :return command may be executed under an ":execute" or from +" a user command. Executing of :finally clauses and passing through +" the return code works also then. +"------------------------------------------------------------------------------- +XpathINIT + +command! -nargs=? RETURN + \ try | return <args> | finally | return <args> * 2 | endtry + +function! F() + try + RETURN 8 + Xpath 1 " X: 0 + finally + Xpath 2 " X: 2 + endtry + Xpath 4 " X: 0 +endfunction + +function! G() + try + RETURN 32 + Xpath 8 " X: 0 + finally + Xpath 16 " X: 16 + RETURN 128 + Xpath 32 " X: 0 + endtry + Xpath 64 " X: 0 +endfunction + +function! H() + try + execute "try | return 512 | finally | return 1024 | endtry" + Xpath 128 " X: 0 + finally + Xpath 256 " X: 256 + endtry + Xpath 512 " X: 0 +endfunction + +function! I() + try + execute "try | return 2048 | finally | return 4096 | endtry" + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + execute "try | return 8192 | finally | return 16384 | endtry" + Xpath 4096 " X: 0 + endtry + Xpath 8192 " X: 0 +endfunction + +function! J() + try + RETURN 32768 + Xpath 16384 " X: 0 + finally + Xpath 32768 " X: 32768 + return + Xpath 65536 " X: 0 + endtry + Xpath 131072 " X: 0 +endfunction + +function! K() + try + execute "try | return 131072 | finally | return 262144 | endtry" + Xpath 262144 " X: 0 + finally + Xpath 524288 " X: 524288 + execute "try | return 524288 | finally | return | endtry" + Xpath 1048576 " X: 0 + endtry + Xpath 2097152 " X: 0 +endfunction + +function! L() + try + return + Xpath 4194304 " X: 0 + finally + Xpath 8388608 " X: 8388608 + RETURN 1048576 + Xpath 16777216 " X: 0 + endtry + Xpath 33554432 " X: 0 +endfunction + +function! M() + try + return + Xpath 67108864 " X: 0 + finally + Xpath 134217728 " X: 134217728 + execute "try | return 4194304 | finally | return 8388608 | endtry" + Xpath 268435456 " X: 0 + endtry + Xpath 536870912 " X: 0 +endfunction + +function! N() + RETURN 16777216 +endfunction + +function! O() + execute "try | return 67108864 | finally | return 134217728 | endtry" +endfunction + +let sum = F() + G() + H() + I() + J() + K() + L() + M() +let expected = 16 + 256 + 1024 + 16384 + 0 + 0 + 2097152 + 8388608 +let sum = sum + N() + O() +let expected = expected + 33554432 + 134217728 + +if sum == expected + Xout "sum = " . sum . " (ok)" +else + Xout "sum = " . sum . ", expected: " . expected +endif + +Xpath 1073741824 " X: 1073741824 + +if sum != expected + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 +endif + +unlet sum expected +delfunction F +delfunction G +delfunction H +delfunction I +delfunction J +delfunction K +delfunction L +delfunction M +delfunction N +delfunction O + +Xcheck 1216907538 + + +"------------------------------------------------------------------------------- +" Test 34: :finally reason discarded by :continue {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :continue in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 8 + + function! C(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + continue " discards jump that caused the :finally + Xloop 1 " X: 0 + endtry + Xloop 2 " X: 0 + elseif loop == 2 + Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144) + endif + endwhile + endfunction + + call C("continue") + Xpath 2097152 " X: 2097152 + call C("break") + Xpath 4194304 " X: 4194304 + call C("return") + Xpath 8388608 " X: 8388608 + let g:jump = "finish" + ExecAsScript C + unlet g:jump + Xpath 16777216 " X: 16777216 + try + call C("error") + Xpath 33554432 " X: 33554432 + finally + Xpath 67108864 " X: 67108864 + try + call C("interrupt") + Xpath 134217728 " X: 134217728 + finally + Xpath 268435456 " X: 268435456 + call C("throw") + Xpath 536870912 " X: 536870912 + endtry + endtry + Xpath 1073741824 " X: 1073741824 + + delfunction C + +endif + +Xcheck 2146584868 + + +"------------------------------------------------------------------------------- +" Test 35: :finally reason discarded by :break {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :break in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 8 + + function! B(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + break " discards jump that caused the :finally + Xloop 1 " X: 0 + endtry + elseif loop == 2 + Xloop 2 " X: 0 + endif + endwhile + Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144) + endfunction + + call B("continue") + Xpath 2097152 " X: 2097152 + call B("break") + Xpath 4194304 " X: 4194304 + call B("return") + Xpath 8388608 " X: 8388608 + let g:jump = "finish" + ExecAsScript B + unlet g:jump + Xpath 16777216 " X: 16777216 + try + call B("error") + Xpath 33554432 " X: 33554432 + finally + Xpath 67108864 " X: 67108864 + try + call B("interrupt") + Xpath 134217728 " X: 134217728 + finally + Xpath 268435456 " X: 268435456 + call B("throw") + Xpath 536870912 " X: 536870912 + endtry + endtry + Xpath 1073741824 " X: 1073741824 + + delfunction B + +endif + +Xcheck 2146584868 + + +"------------------------------------------------------------------------------- +" Test 36: :finally reason discarded by :return {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :return in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 8 + + function! R(jump, retval) abort + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + return a:retval " discards jump that caused the :finally + Xloop 1 " X: 0 + endtry + elseif loop == 2 + Xloop 2 " X: 0 + endif + endwhile + Xloop 4 " X: 0 + endfunction + + let sum = -R("continue", -8) + Xpath 2097152 " X: 2097152 + let sum = sum - R("break", -16) + Xpath 4194304 " X: 4194304 + let sum = sum - R("return", -32) + Xpath 8388608 " X: 8388608 + try + let sum = sum - R("error", -64) + Xpath 16777216 " X: 16777216 + finally + Xpath 33554432 " X: 33554432 + try + let sum = sum - R("interrupt", -128) + Xpath 67108864 " X: 67108864 + finally + Xpath 134217728 " X: 134217728 + let sum = sum - R("throw", -256) + Xpath 268435456 " X: 268435456 + endtry + endtry + Xpath 536870912 " X: 536870912 + + let expected = 8 + 16 + 32 + 64 + 128 + 256 + if sum != expected + Xpath 1073741824 " X: 0 + Xout "sum =" . sum . ", expected: " . expected + endif + + unlet sum expected + delfunction R + +endif + +Xcheck 1071644672 + + +"------------------------------------------------------------------------------- +" Test 37: :finally reason discarded by :finish {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :finish in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 8 + + function! F(jump) " not executed as function, transformed to a script + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "finish" + finish + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + finish " discards jump that caused the :finally + Xloop 1 " X: 0 + endtry + elseif loop == 2 + Xloop 2 " X: 0 + endif + endwhile + Xloop 4 " X: 0 + endfunction + + let scriptF = MakeScript("F") + delfunction F + + let g:jump = "continue" + exec "source" scriptF + Xpath 2097152 " X: 2097152 + let g:jump = "break" + exec "source" scriptF + Xpath 4194304 " X: 4194304 + let g:jump = "finish" + exec "source" scriptF + Xpath 8388608 " X: 8388608 + try + let g:jump = "error" + exec "source" scriptF + Xpath 16777216 " X: 16777216 + finally + Xpath 33554432 " X: 33554432 + try + let g:jump = "interrupt" + exec "source" scriptF + Xpath 67108864 " X: 67108864 + finally + Xpath 134217728 " X: 134217728 + try + let g:jump = "throw" + exec "source" scriptF + Xpath 268435456 " X: 268435456 + finally + Xpath 536870912 " X: 536870912 + endtry + endtry + endtry + unlet g:jump + + call delete(scriptF) + unlet scriptF + +endif + +Xcheck 1071644672 + + +"------------------------------------------------------------------------------- +" Test 38: :finally reason discarded by an error {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by an error in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 4 + + function! E(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + asdf " error; discards jump that caused the :finally + endtry + elseif loop == 2 + Xloop 1 " X: 0 + endif + endwhile + Xloop 2 " X: 0 + endfunction + + try + Xpath 16384 " X: 16384 + call E("continue") + Xpath 32768 " X: 0 + finally + try + Xpath 65536 " X: 65536 + call E("break") + Xpath 131072 " X: 0 + finally + try + Xpath 262144 " X: 262144 + call E("return") + Xpath 524288 " X: 0 + finally + try + Xpath 1048576 " X: 1048576 + let g:jump = "finish" + ExecAsScript E + Xpath 2097152 " X: 0 + finally + unlet g:jump + try + Xpath 4194304 " X: 4194304 + call E("error") + Xpath 8388608 " X: 0 + finally + try + Xpath 16777216 " X: 16777216 + call E("interrupt") + Xpath 33554432 " X: 0 + finally + try + Xpath 67108864 " X: 67108864 + call E("throw") + Xpath 134217728 " X: 0 + finally + Xpath 268435456 " X: 268435456 + delfunction E + endtry + endtry + endtry + endtry + endtry + endtry + endtry + Xpath 536870912 " X: 0 + +endif + +Xcheck 357908480 + + +"------------------------------------------------------------------------------- +" Test 39: :finally reason discarded by an interrupt {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by an interrupt in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 4 + + function! I(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + "INTERRUPT - discards jump that caused the :finally + let dummy = 0 + endtry + elseif loop == 2 + Xloop 1 " X: 0 + endif + endwhile + Xloop 2 " X: 0 + endfunction + + try + Xpath 16384 " X: 16384 + call I("continue") + Xpath 32768 " X: 0 + finally + try + Xpath 65536 " X: 65536 + call I("break") + Xpath 131072 " X: 0 + finally + try + Xpath 262144 " X: 262144 + call I("return") + Xpath 524288 " X: 0 + finally + try + Xpath 1048576 " X: 1048576 + let g:jump = "finish" + ExecAsScript I + Xpath 2097152 " X: 0 + finally + unlet g:jump + try + Xpath 4194304 " X: 4194304 + call I("error") + Xpath 8388608 " X: 0 + finally + try + Xpath 16777216 " X: 16777216 + call I("interrupt") + Xpath 33554432 " X: 0 + finally + try + Xpath 67108864 " X: 67108864 + call I("throw") + Xpath 134217728 " X: 0 + finally + Xpath 268435456 " X: 268435456 + delfunction I + endtry + endtry + endtry + endtry + endtry + endtry + endtry + Xpath 536870912 " X: 0 + +endif + +Xcheck 357908480 + + +"------------------------------------------------------------------------------- +" Test 40: :finally reason discarded by :throw {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :throw in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 4 + + function! T(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + throw "xyz" " discards jump that caused the :finally + endtry + elseif loop == 2 + Xloop 1 " X: 0 + endif + endwhile + Xloop 2 " X: 0 + endfunction + + try + Xpath 16384 " X: 16384 + call T("continue") + Xpath 32768 " X: 0 + finally + try + Xpath 65536 " X: 65536 + call T("break") + Xpath 131072 " X: 0 + finally + try + Xpath 262144 " X: 262144 + call T("return") + Xpath 524288 " X: 0 + finally + try + Xpath 1048576 " X: 1048576 + let g:jump = "finish" + ExecAsScript T + Xpath 2097152 " X: 0 + finally + unlet g:jump + try + Xpath 4194304 " X: 4194304 + call T("error") + Xpath 8388608 " X: 0 + finally + try + Xpath 16777216 " X: 16777216 + call T("interrupt") + Xpath 33554432 " X: 0 + finally + try + Xpath 67108864 " X: 67108864 + call T("throw") + Xpath 134217728 " X: 0 + finally + Xpath 268435456 " X: 268435456 + delfunction T + endtry + endtry + endtry + endtry + endtry + endtry + endtry + Xpath 536870912 " X: 0 + +endif + +Xcheck 357908480 + + +"------------------------------------------------------------------------------- +" Test 41: Skipped :throw finding next command {{{1 +" +" A :throw in an inactive conditional must not hide a following +" command. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + Xpath 1 " X: 1 + if 0 | throw "never" | endif | Xpath 2 " X: 2 + Xpath 4 " X: 4 +endfunction + +function! G() + Xpath 8 " X: 8 + while 0 | throw "never" | endwhile | Xpath 16 " X: 16 + Xpath 32 " X: 32 +endfunction + +function H() + Xpath 64 " X: 64 + if 0 | try | throw "never" | endtry | endif | Xpath 128 " X: 128 + Xpath 256 " X: 256 +endfunction + +Xpath 512 " X: 512 + +try + Xpath 1024 " X: 1024 + call F() + Xpath 2048 " X: 2048 +catch /.*/ + Xpath 4096 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 8192 " X: 8192 + +try + Xpath 16384 " X: 16384 + call G() + Xpath 32768 " X: 32768 +catch /.*/ + Xpath 65536 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 131072 " X: 131072 + +try + Xpath 262144 " X: 262144 + call H() + Xpath 524288 " X: 524288 +catch /.*/ + Xpath 1048576 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 2097152 " X: 2097152 + +delfunction F +delfunction G +delfunction H + +Xcheck 3076095 + + +"------------------------------------------------------------------------------- +" Test 42: Catching number and string exceptions {{{1 +" +" When a number is thrown, it is converted to a string exception. +" Numbers and strings may be caught by specifying a regular exception +" as argument to the :catch command. +"------------------------------------------------------------------------------- + +XpathINIT + +try + + try + Xpath 1 " X: 1 + throw 4711 + Xpath 2 " X: 0 + catch /4711/ + Xpath 4 " X: 4 + endtry + + try + Xpath 8 " X: 8 + throw 4711 + Xpath 16 " X: 0 + catch /^4711$/ + Xpath 32 " X: 32 + endtry + + try + Xpath 64 " X: 64 + throw 4711 + Xpath 128 " X: 0 + catch /\d/ + Xpath 256 " X: 256 + endtry + + try + Xpath 512 " X: 512 + throw 4711 + Xpath 1024 " X: 0 + catch /^\d\+$/ + Xpath 2048 " X: 2048 + endtry + + try + Xpath 4096 " X: 4096 + throw "arrgh" + Xpath 8192 " X: 0 + catch /arrgh/ + Xpath 16384 " X: 16384 + endtry + + try + Xpath 32768 " X: 32768 + throw "arrgh" + Xpath 65536 " X: 0 + catch /^arrgh$/ + Xpath 131072 " X: 131072 + endtry + + try + Xpath 262144 " X: 262144 + throw "arrgh" + Xpath 524288 " X: 0 + catch /\l/ + Xpath 1048576 " X: 1048576 + endtry + + try + Xpath 2097152 " X: 2097152 + throw "arrgh" + Xpath 4194304 " X: 0 + catch /^\l\+$/ + Xpath 8388608 " X: 8388608 + endtry + + try + try + Xpath 16777216 " X: 16777216 + throw "ARRGH" + Xpath 33554432 " X: 0 + catch /^arrgh$/ + Xpath 67108864 " X: 0 + endtry + catch /^\carrgh$/ + Xpath 134217728 " X: 134217728 + endtry + + try + Xpath 268435456 " X: 268435456 + throw "" + Xpath 536870912 " X: 0 + catch /^$/ + Xpath 1073741824 " X: 1073741824 + endtry + +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xcheck 1505155949 + + +"------------------------------------------------------------------------------- +" Test 43: Selecting the correct :catch clause {{{1 +" +" When an exception is thrown and there are multiple :catch clauses, +" the first matching one is taken. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT 1 1024 +let loops = 3 +while loops > 0 + try + if loops == 3 + Xloop 1 " X: 1 + throw "a" + Xloop 2 " X: 0 + elseif loops == 2 + Xloop 4 " X: 4*1024 + throw "ab" + Xloop 8 " X: 0 + elseif loops == 1 + Xloop 16 " X: 16*1024*1024 + throw "abc" + Xloop 32 " X: 0 + endif + catch /abc/ + Xloop 64 " X: 64*1024*1024 + catch /ab/ + Xloop 128 " X: 128*1024 + catch /.*/ + Xloop 256 " X: 256 + catch /a/ + Xloop 512 " X: 0 + endtry + + let loops = loops - 1 + XloopNEXT +endwhile +Xpath 1073741824 " X: 1073741824 + +unlet loops + +Xcheck 1157763329 + + +"------------------------------------------------------------------------------- +" Test 44: Missing or empty :catch patterns {{{1 +" +" A missing or empty :catch pattern means the same as /.*/, that is, +" catches everything. To catch only empty exceptions, /^$/ must be +" used. A :catch with missing, empty, or /.*/ argument also works +" when followed by another command separated by a bar on the same +" line. :catch patterns cannot be specified between ||. But other +" pattern separators can be used instead of //. +"------------------------------------------------------------------------------- + +XpathINIT + +try + try + Xpath 1 " X: 1 + throw "" + catch /^$/ + Xpath 2 " X: 2 + endtry + + try + Xpath 4 " X: 4 + throw "" + catch /.*/ + Xpath 8 " X: 8 + endtry + + try + Xpath 16 " X: 16 + throw "" + catch // + Xpath 32 " X: 32 + endtry + + try + Xpath 64 " X: 64 + throw "" + catch + Xpath 128 " X: 128 + endtry + + try + Xpath 256 " X: 256 + throw "oops" + catch /^$/ + Xpath 512 " X: 0 + catch /.*/ + Xpath 1024 " X: 1024 + endtry + + try + Xpath 2048 " X: 2048 + throw "arrgh" + catch /^$/ + Xpath 4096 " X: 0 + catch // + Xpath 8192 " X: 8192 + endtry + + try + Xpath 16384 " X: 16384 + throw "brrr" + catch /^$/ + Xpath 32768 " X: 0 + catch + Xpath 65536 " X: 65536 + endtry + + try | Xpath 131072 | throw "x" | catch /.*/ | Xpath 262144 | endtry + " X: 131072 + 262144 + + try | Xpath 524288 | throw "y" | catch // | Xpath 1048576 | endtry + " X: 524288 + 1048576 + + while 1 + try + let caught = 0 + let v:errmsg = "" + " Extra try level: if ":catch" without arguments below raises + " a syntax error because it misinterprets the "Xpath" as a pattern, + " let it be caught by the ":catch /.*/" below. + try + try | Xpath 2097152 | throw "z" | catch | Xpath 4194304 | : + endtry " X: 2097152 + 4194304 + endtry + catch /.*/ + let caught = 1 + Xout v:exception "in" v:throwpoint + finally + if $VIMNOERRTHROW && v:errmsg != "" + Xout v:errmsg + endif + if caught || $VIMNOERRTHROW && v:errmsg != "" + Xpath 8388608 " X: 0 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + let cologne = 4711 + try + try + Xpath 16777216 " X: 16777216 + throw "throw cologne" + " Next lines catches all and throws 4711: + catch |throw cologne| + Xpath 33554432 " X: 0 + endtry + catch /4711/ + Xpath 67108864 " X: 67108864 + endtry + + try + Xpath 134217728 " X: 134217728 + throw "plus" + catch +plus+ + Xpath 268435456 " X: 268435456 + endtry + + Xpath 536870912 " X: 536870912 +catch /.*/ + Xpath 1073741824 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +unlet! caught cologne + +Xcheck 1031761407 + + +"------------------------------------------------------------------------------- +" Test 45: Catching exceptions from nested :try blocks {{{1 +" +" When :try blocks are nested, an exception is caught by the innermost +" try conditional that has a matching :catch clause. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT 1 1024 +let loops = 3 +while loops > 0 + try + try + try + try + if loops == 3 + Xloop 1 " X: 1 + throw "a" + Xloop 2 " X: 0 + elseif loops == 2 + Xloop 4 " X: 4*1024 + throw "ab" + Xloop 8 " X: 0 + elseif loops == 1 + Xloop 16 " X: 16*1024*1024 + throw "abc" + Xloop 32 " X: 0 + endif + catch /abc/ + Xloop 64 " X: 64*1024*1024 + endtry + catch /ab/ + Xloop 128 " X: 128*1024 + endtry + catch /.*/ + Xloop 256 " X: 256 + endtry + catch /a/ + Xloop 512 " X: 0 + endtry + + let loops = loops - 1 + XloopNEXT +endwhile +Xpath 1073741824 " X: 1073741824 + +unlet loops + +Xcheck 1157763329 + + +"------------------------------------------------------------------------------- +" Test 46: Executing :finally after a :throw in nested :try {{{1 +" +" When an exception is thrown from within nested :try blocks, the +" :finally clauses of the non-catching try conditionals should be +" executed before the matching :catch of the next surrounding :try +" gets the control. If this also has a :finally clause, it is +" executed afterwards. +"------------------------------------------------------------------------------- + +XpathINIT + +let sum = 0 + +try + Xpath 1 " X: 1 + try + Xpath 2 " X: 2 + try + Xpath 4 " X: 4 + try + Xpath 8 " X: 8 + throw "ABC" + Xpath 16 " X: 0 + catch /xyz/ + Xpath 32 " X: 0 + finally + Xpath 64 " X: 64 + if sum != 0 + Xpath 128 " X: 0 + endif + let sum = sum + 1 + endtry + Xpath 256 " X: 0 + catch /123/ + Xpath 512 " X: 0 + catch /321/ + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + if sum != 1 + Xpath 4096 " X: 0 + endif + let sum = sum + 2 + endtry + Xpath 8192 " X: 0 + finally + Xpath 16384 " X: 16384 + if sum != 3 + Xpath 32768 " X: 0 + endif + let sum = sum + 4 + endtry + Xpath 65536 " X: 0 +catch /ABC/ + Xpath 131072 " X: 131072 + if sum != 7 + Xpath 262144 " X: 0 + endif + let sum = sum + 8 +finally + Xpath 524288 " X: 524288 + if sum != 15 + Xpath 1048576 " X: 0 + endif + let sum = sum + 16 +endtry +Xpath 65536 " X: 65536 +if sum != 31 + Xpath 131072 " X: 0 +endif + +unlet sum + +Xcheck 739407 + + +"------------------------------------------------------------------------------- +" Test 47: Throwing exceptions from a :catch clause {{{1 +" +" When an exception is thrown from a :catch clause, it should not be +" caught by a :catch of the same :try conditional. After executing +" the :finally clause (if present), surrounding try conditionals +" should be checked for a matching :catch. +"------------------------------------------------------------------------------- + +XpathINIT + +Xpath 1 " X: 1 +try + Xpath 2 " X: 2 + try + Xpath 4 " X: 4 + try + Xpath 8 " X: 8 + throw "x1" + Xpath 16 " X: 0 + catch /x1/ + Xpath 32 " X: 32 + try + Xpath 64 " X: 64 + throw "x2" + Xpath 128 " X: 0 + catch /x1/ + Xpath 256 " X: 0 + catch /x2/ + Xpath 512 " X: 512 + try + Xpath 1024 " X: 1024 + throw "x3" + Xpath 2048 " X: 0 + catch /x1/ + Xpath 4096 " X: 0 + catch /x2/ + Xpath 8192 " X: 0 + finally + Xpath 16384 " X: 16384 + endtry + Xpath 32768 " X: 0 + catch /x3/ + Xpath 65536 " X: 0 + endtry + Xpath 131072 " X: 0 + catch /x1/ + Xpath 262144 " X: 0 + catch /x2/ + Xpath 524288 " X: 0 + catch /x3/ + Xpath 1048576 " X: 0 + finally + Xpath 2097152 " X: 2097152 + endtry + Xpath 4194304 " X: 0 + catch /x1/ + Xpath 8388608 " X: 0 + catch /x2/ + Xpath 16777216 " X: 0 + catch /x3/ + Xpath 33554432 " X: 33554432 + endtry + Xpath 67108864 " X: 67108864 +catch /.*/ + Xpath 134217728 " X: 0 + Xout v:exception "in" v:throwpoint +endtry +Xpath 268435456 " X: 268435456 + +Xcheck 371213935 + + +"------------------------------------------------------------------------------- +" Test 48: Throwing exceptions from a :finally clause {{{1 +" +" When an exception is thrown from a :finally clause, it should not be +" caught by a :catch of the same :try conditional. Surrounding try +" conditionals should be checked for a matching :catch. A previously +" thrown exception is discarded. +"------------------------------------------------------------------------------- + +XpathINIT + +try + + try + try + Xpath 1 " X: 1 + catch /x1/ + Xpath 2 " X: 0 + finally + Xpath 4 " X: 4 + throw "x1" + Xpath 8 " X: 0 + endtry + Xpath 16 " X: 0 + catch /x1/ + Xpath 32 " X: 32 + endtry + Xpath 64 " X: 64 + + try + try + Xpath 128 " X: 128 + throw "x2" + Xpath 256 " X: 0 + catch /x2/ + Xpath 512 " X: 512 + catch /x3/ + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + throw "x3" + Xpath 4096 " X: 0 + endtry + Xpath 8192 " X: 0 + catch /x2/ + Xpath 16384 " X: 0 + catch /x3/ + Xpath 32768 " X: 32768 + endtry + Xpath 65536 " X: 65536 + + try + try + try + Xpath 131072 " X: 131072 + throw "x4" + Xpath 262144 " X: 0 + catch /x5/ + Xpath 524288 " X: 0 + finally + Xpath 1048576 " X: 1048576 + throw "x5" " discards "x4" + Xpath 2097152 " X: 0 + endtry + Xpath 4194304 " X: 0 + catch /x4/ + Xpath 8388608 " X: 0 + finally + Xpath 16777216 " X: 16777216 + endtry + Xpath 33554432 " X: 0 + catch /x5/ + Xpath 67108864 " X: 67108864 + endtry + Xpath 134217728 " X: 134217728 + +catch /.*/ + Xpath 268435456 " X: 0 + Xout v:exception "in" v:throwpoint +endtry +Xpath 536870912 " X: 536870912 + +Xcheck 756255461 + + +"------------------------------------------------------------------------------- +" Test 49: Throwing exceptions across functions {{{1 +" +" When an exception is thrown but not caught inside a function, the +" caller is checked for a matching :catch clause. +"------------------------------------------------------------------------------- + +XpathINIT + +function! C() + try + Xpath 1 " X: 1 + throw "arrgh" + Xpath 2 " X: 0 + catch /arrgh/ + Xpath 4 " X: 4 + endtry + Xpath 8 " X: 8 +endfunction + +XloopINIT! 16 16 + +function! T1() + XloopNEXT + try + Xloop 1 " X: 16 + 16*16 + throw "arrgh" + Xloop 2 " X: 0 + finally + Xloop 4 " X: 64 + 64*16 + endtry + Xloop 8 " X: 0 +endfunction + +function! T2() + try + Xpath 4096 " X: 4096 + call T1() + Xpath 8192 " X: 0 + finally + Xpath 16384 " X: 16384 + endtry + Xpath 32768 " X: 0 +endfunction + +try + Xpath 65536 " X: 65536 + call C() " throw and catch + Xpath 131072 " X: 131072 +catch /.*/ + Xpath 262144 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +try + Xpath 524288 " X: 524288 + call T1() " throw, one level + Xpath 1048576 " X: 0 +catch /arrgh/ + Xpath 2097152 " X: 2097152 +catch /.*/ + Xpath 4194304 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +try + Xpath 8388608 " X: 8388608 + call T2() " throw, two levels + Xpath 16777216 " X: 0 +catch /arrgh/ + Xpath 33554432 " X: 33554432 +catch /.*/ + Xpath 67108864 " X: 0 + Xout v:exception "in" v:throwpoint +endtry +Xpath 134217728 " X: 134217728 + +Xcheck 179000669 + +" Leave C, T1, and T2 for execution as scripts in the next test. + + +"------------------------------------------------------------------------------- +" Test 50: Throwing exceptions across script files {{{1 +" +" When an exception is thrown but not caught inside a script file, +" the sourcing script or function is checked for a matching :catch +" clause. +" +" This test executes the bodies of the functions C, T1, and T2 from +" the previous test as script files (:return replaced by :finish). +"------------------------------------------------------------------------------- + +XpathINIT + +let scriptC = MakeScript("C") " X: 1 + 4 + 8 +delfunction C + +XloopINIT! 16 16 + +let scriptT1 = MakeScript("T1") " X: 16 + 64 + 16*16 + 64*16 +delfunction T1 + +let scriptT2 = MakeScript("T2", scriptT1) " X: 4096 + 16384 +delfunction T2 + +function! F() + try + Xpath 65536 " X: 65536 + exec "source" g:scriptC + Xpath 131072 " X: 131072 + catch /.*/ + Xpath 262144 " X: 0 + Xout v:exception "in" v:throwpoint + endtry + + try + Xpath 524288 " X: 524288 + exec "source" g:scriptT1 + Xpath 1048576 " X: 0 + catch /arrgh/ + Xpath 2097152 " X: 2097152 + catch /.*/ + Xpath 4194304 " X: 0 + Xout v:exception "in" v:throwpoint + endtry +endfunction + +try + Xpath 8388608 " X: 8388608 + call F() + Xpath 16777216 " X: 16777216 + exec "source" scriptT2 + Xpath 33554432 " X: 0 +catch /arrgh/ + Xpath 67108864 " X: 67108864 +catch /.*/ + Xpath 134217728 " X: 0 + Xout v:exception "in" v:throwpoint +endtry +Xpath 268435456 " X: 268435456 + +call delete(scriptC) +call delete(scriptT1) +call delete(scriptT2) +unlet scriptC scriptT1 scriptT2 +delfunction F + +Xcheck 363550045 + + +"------------------------------------------------------------------------------- +" Test 51: Throwing exceptions across :execute and user commands {{{1 +" +" A :throw command may be executed under an ":execute" or from +" a user command. +"------------------------------------------------------------------------------- + +XpathINIT + +command! -nargs=? THROW1 throw <args> | throw 1 +command! -nargs=? THROW2 try | throw <args> | endtry | throw 2 +command! -nargs=? THROW3 try | throw 3 | catch /3/ | throw <args> | endtry +command! -nargs=? THROW4 try | throw 4 | finally | throw <args> | endtry + +try + + try + try + Xpath 1 " X: 1 + THROW1 "A" + catch /A/ + Xpath 2 " X: 2 + endtry + catch /1/ + Xpath 4 " X: 0 + endtry + + try + try + Xpath 8 " X: 8 + THROW2 "B" + catch /B/ + Xpath 16 " X: 16 + endtry + catch /2/ + Xpath 32 " X: 0 + endtry + + try + try + Xpath 64 " X: 64 + THROW3 "C" + catch /C/ + Xpath 128 " X: 128 + endtry + catch /3/ + Xpath 256 " X: 0 + endtry + + try + try + Xpath 512 " X: 512 + THROW4 "D" + catch /D/ + Xpath 1024 " X: 1024 + endtry + catch /4/ + Xpath 2048 " X: 0 + endtry + + try + try + Xpath 4096 " X: 4096 + execute 'throw "E" | throw 5' + catch /E/ + Xpath 8192 " X: 8192 + endtry + catch /5/ + Xpath 16384 " X: 0 + endtry + + try + try + Xpath 32768 " X: 32768 + execute 'try | throw "F" | endtry | throw 6' + catch /F/ + Xpath 65536 " X: 65536 + endtry + catch /6/ + Xpath 131072 " X: 0 + endtry + + try + try + Xpath 262144 " X: 262144 + execute'try | throw 7 | catch /7/ | throw "G" | endtry' + catch /G/ + Xpath 524288 " X: 524288 + endtry + catch /7/ + Xpath 1048576 " X: 0 + endtry + + try + try + Xpath 2097152 " X: 2097152 + execute 'try | throw 8 | finally | throw "H" | endtry' + catch /H/ + Xpath 4194304 " X: 4194304 + endtry + catch /8/ + Xpath 8388608 " X: 0 + endtry + +catch /.*/ + Xpath 16777216 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 33554432 " X: 33554432 + +delcommand THROW1 +delcommand THROW2 +delcommand THROW3 +delcommand THROW4 + +Xcheck 40744667 + + +"------------------------------------------------------------------------------- +" Test 52: Uncaught exceptions {{{1 +" +" When an exception is thrown but not caught, an error message is +" displayed when the script is terminated. In case of an interrupt +" or error exception, the normal interrupt or error message(s) are +" displayed. +"------------------------------------------------------------------------------- + +XpathINIT + +let msgfile = tempname() + +function! MESSAGES(...) + try + exec "edit" g:msgfile + catch /^Vim(edit):/ + return 0 + endtry + + let english = v:lang == "C" || v:lang =~ '^[Ee]n' + let match = 1 + norm gg + + let num = a:0 / 2 + let cnt = 1 + while cnt <= num + let enr = a:{2*cnt - 1} + let emsg= a:{2*cnt} + let cnt = cnt + 1 + + if enr == "" + Xout "TODO: Add message number for:" emsg + elseif enr == "INT" + let enr = "" + endif + if enr == "" && !english + continue + endif + let pattern = (enr != "") ? enr . ':.*' : '' + if english + let pattern = pattern . emsg + endif + if !search(pattern, "W") + let match = 0 + Xout "No match for:" pattern + endif + norm $ + endwhile + + bwipeout! + return match +endfunction + +if ExtraVim(msgfile) + Xpath 1 " X: 1 + throw "arrgh" +endif + +Xpath 2 " X: 2 +if !MESSAGES('E605', "Exception not caught") + Xpath 4 " X: 0 +endif + +if ExtraVim(msgfile) + try + Xpath 8 " X: 8 + throw "oops" + catch /arrgh/ + Xpath 16 " X: 0 + endtry + Xpath 32 " X: 0 +endif + +Xpath 64 " X: 64 +if !MESSAGES('E605', "Exception not caught") + Xpath 128 " X: 0 +endif + +if ExtraVim(msgfile) + function! T() + throw "brrr" + endfunction + + try + Xpath 256 " X: 256 + throw "arrgh" + catch /.*/ + Xpath 512 " X: 512 + call T() + endtry + Xpath 1024 " X: 0 +endif + +Xpath 2048 " X: 2048 +if !MESSAGES('E605', "Exception not caught") + Xpath 4096 " X: 0 +endif + +if ExtraVim(msgfile) + try + Xpath 8192 " X: 8192 + throw "arrgh" + finally + Xpath 16384 " X: 16384 + throw "brrr" + endtry + Xpath 32768 " X: 0 +endif + +Xpath 65536 " X: 65536 +if !MESSAGES('E605', "Exception not caught") + Xpath 131072 " X: 0 +endif + +if ExtraVim(msgfile) + try + Xpath 262144 " X: 262144 + "INTERRUPT + endtry + Xpath 524288 " X: 0 +endif + +Xpath 1048576 " X: 1048576 +if !MESSAGES('INT', "Interrupted") + Xpath 2097152 " X: 0 +endif + +if ExtraVim(msgfile) + try + Xpath 4194304 " X: 4194304 + let x = novar " error E121/E15; exception: E121 + catch /E15:/ " should not catch + Xpath 8388608 " X: 0 + endtry + Xpath 16777216 " X: 0 +endif + +Xpath 33554432 " X: 33554432 +if !MESSAGES('E121', "Undefined variable", 'E15', "Invalid expression") + Xpath 67108864 " X: 0 +endif + +if ExtraVim(msgfile) + try + Xpath 134217728 " X: 134217728 +" unlet novar # " error E108/E488; exception: E488 + catch /E108:/ " should not catch + Xpath 268435456 " X: 0 + endtry + Xpath 536870912 " X: 0 +endif + +Xpath 1073741824 " X: 1073741824 +if !MESSAGES('E108', "No such variable", 'E488', "Trailing characters") + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 +endif + +call delete(msgfile) +unlet msgfile + +Xcheck 1247112011 + +" Leave MESSAGES() for the next tests. + + +"------------------------------------------------------------------------------- +" Test 53: Nesting errors: :endif/:else/:elseif {{{1 +" +" For nesting errors of :if conditionals the correct error messages +" should be given. +" +" This test reuses the function MESSAGES() from the previous test. +" This functions checks the messages in g:msgfile. +"------------------------------------------------------------------------------- + +XpathINIT + +let msgfile = tempname() + +if ExtraVim(msgfile) +" endif +endif +if MESSAGES('E580', ":endif without :if") + Xpath 1 " X: 1 +endif + +if ExtraVim(msgfile) +" while 1 +" endif +" endwhile +endif +if MESSAGES('E580', ":endif without :if") + Xpath 2 " X: 2 +endif + +if ExtraVim(msgfile) +" try +" finally +" endif +" endtry +endif +if MESSAGES('E580', ":endif without :if") + Xpath 4 " X: 4 +endif + +if ExtraVim(msgfile) +" try +" endif +" endtry +endif +if MESSAGES('E580', ":endif without :if") + Xpath 8 " X: 8 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" endif +" endtry +endif +if MESSAGES('E580', ":endif without :if") + Xpath 16 " X: 16 +endif + +if ExtraVim(msgfile) +" else +endif +if MESSAGES('E581', ":else without :if") + Xpath 32 " X: 32 +endif + +if ExtraVim(msgfile) +" while 1 +" else +" endwhile +endif +if MESSAGES('E581', ":else without :if") + Xpath 64 " X: 64 +endif + +if ExtraVim(msgfile) +" try +" finally +" else +" endtry +endif +if MESSAGES('E581', ":else without :if") + Xpath 128 " X: 128 +endif + +if ExtraVim(msgfile) +" try +" else +" endtry +endif +if MESSAGES('E581', ":else without :if") + Xpath 256 " X: 256 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" else +" endtry +endif +if MESSAGES('E581', ":else without :if") + Xpath 512 " X: 512 +endif + +if ExtraVim(msgfile) +" elseif +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 1024 " X: 1024 +endif + +if ExtraVim(msgfile) +" while 1 +" elseif +" endwhile +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 2048 " X: 2048 +endif + +if ExtraVim(msgfile) +" try +" finally +" elseif +" endtry +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 4096 " X: 4096 +endif + +if ExtraVim(msgfile) +" try +" elseif +" endtry +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 8192 " X: 8192 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" elseif +" endtry +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 16384 " X: 16384 +endif + +if ExtraVim(msgfile) +" if 1 +" else +" else +" endif +endif +if MESSAGES('E583', "multiple :else") + Xpath 32768 " X: 32768 +endif + +if ExtraVim(msgfile) +" if 1 +" else +" elseif 1 +" endif +endif +if MESSAGES('E584', ":elseif after :else") + Xpath 65536 " X: 65536 +endif + +call delete(msgfile) +unlet msgfile + +Xcheck 131071 + +" Leave MESSAGES() for the next test. + + +"------------------------------------------------------------------------------- +" Test 54: Nesting errors: :while/:endwhile {{{1 +" +" For nesting errors of :while conditionals the correct error messages +" should be given. +" +" This test reuses the function MESSAGES() from the previous test. +" This functions checks the messages in g:msgfile. +"------------------------------------------------------------------------------- + +XpathINIT + +let msgfile = tempname() + +if ExtraVim(msgfile) +" endwhile +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 1 " X: 1 +endif + +if ExtraVim(msgfile) +" if 1 +" endwhile +" endif +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 2 " X: 2 +endif + +if ExtraVim(msgfile) +" while 1 +" if 1 +" endwhile +endif +if MESSAGES('E171', "Missing :endif") + Xpath 4 " X: 4 +endif + +if ExtraVim(msgfile) +" try +" finally +" endwhile +" endtry +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 8 " X: 8 +endif + +if ExtraVim(msgfile) +" while 1 +" try +" finally +" endwhile +endif +if MESSAGES('E600', "Missing :endtry") + Xpath 16 " X: 16 +endif + +if ExtraVim(msgfile) +" while 1 +" if 1 +" try +" finally +" endwhile +endif +if MESSAGES('E600', "Missing :endtry") + Xpath 32 " X: 32 +endif + +if ExtraVim(msgfile) +" while 1 +" try +" finally +" if 1 +" endwhile +endif +if MESSAGES('E171', "Missing :endif") + Xpath 64 " X: 64 +endif + +if ExtraVim(msgfile) +" try +" endwhile +" endtry +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 128 " X: 128 +endif + +if ExtraVim(msgfile) +" while 1 +" try +" endwhile +" endtry +" endwhile +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 256 " X: 256 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" endwhile +" endtry +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 512 " X: 512 +endif + +if ExtraVim(msgfile) +" while 1 +" try +" throw "a" +" catch /a/ +" endwhile +" endtry +" endwhile +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 1024 " X: 1024 +endif + + +call delete(msgfile) +unlet msgfile + +Xcheck 2047 + +" Leave MESSAGES() for the next test. + + +"------------------------------------------------------------------------------- +" Test 55: Nesting errors: :continue/:break {{{1 +" +" For nesting errors of :continue and :break commands the correct +" error messages should be given. +" +" This test reuses the function MESSAGES() from the previous test. +" This functions checks the messages in g:msgfile. +"------------------------------------------------------------------------------- + +XpathINIT + +let msgfile = tempname() + +if ExtraVim(msgfile) +" continue +endif +if MESSAGES('E586', ":continue without :while") + Xpath 1 " X: 1 +endif + +if ExtraVim(msgfile) +" if 1 +" continue +" endif +endif +if MESSAGES('E586', ":continue without :while") + Xpath 2 " X: 2 +endif + +if ExtraVim(msgfile) +" try +" finally +" continue +" endtry +endif +if MESSAGES('E586', ":continue without :while") + Xpath 4 " X: 4 +endif + +if ExtraVim(msgfile) +" try +" continue +" endtry +endif +if MESSAGES('E586', ":continue without :while") + Xpath 8 " X: 8 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" continue +" endtry +endif +if MESSAGES('E586', ":continue without :while") + Xpath 16 " X: 16 +endif + +if ExtraVim(msgfile) +" break +endif +if MESSAGES('E587', ":break without :while") + Xpath 32 " X: 32 +endif + +if ExtraVim(msgfile) +" if 1 +" break +" endif +endif +if MESSAGES('E587', ":break without :while") + Xpath 64 " X: 64 +endif + +if ExtraVim(msgfile) +" try +" finally +" break +" endtry +endif +if MESSAGES('E587', ":break without :while") + Xpath 128 " X: 128 +endif + +if ExtraVim(msgfile) +" try +" break +" endtry +endif +if MESSAGES('E587', ":break without :while") + Xpath 256 " X: 256 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" break +" endtry +endif +if MESSAGES('E587', ":break without :while") + Xpath 512 " X: 512 +endif + +call delete(msgfile) +unlet msgfile + +Xcheck 1023 + +" Leave MESSAGES() for the next test. + + +"------------------------------------------------------------------------------- +" Test 56: Nesting errors: :endtry {{{1 +" +" For nesting errors of :try conditionals the correct error messages +" should be given. +" +" This test reuses the function MESSAGES() from the previous test. +" This functions checks the messages in g:msgfile. +"------------------------------------------------------------------------------- + +XpathINIT + +let msgfile = tempname() + +if ExtraVim(msgfile) +" endtry +endif +if MESSAGES('E602', ":endtry without :try") + Xpath 1 " X: 1 +endif + +if ExtraVim(msgfile) +" if 1 +" endtry +" endif +endif +if MESSAGES('E602', ":endtry without :try") + Xpath 2 " X: 2 +endif + +if ExtraVim(msgfile) +" while 1 +" endtry +" endwhile +endif +if MESSAGES('E602', ":endtry without :try") + Xpath 4 " X: 4 +endif + +if ExtraVim(msgfile) +" try +" if 1 +" endtry +endif +if MESSAGES('E171', "Missing :endif") + Xpath 8 " X: 8 +endif + +if ExtraVim(msgfile) +" try +" while 1 +" endtry +endif +if MESSAGES('E170', "Missing :endwhile") + Xpath 16 " X: 16 +endif + +if ExtraVim(msgfile) +" try +" finally +" if 1 +" endtry +endif +if MESSAGES('E171', "Missing :endif") + Xpath 32 " X: 32 +endif + +if ExtraVim(msgfile) +" try +" finally +" while 1 +" endtry +endif +if MESSAGES('E170', "Missing :endwhile") + Xpath 64 " X: 64 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" if 1 +" endtry +endif +if MESSAGES('E171', "Missing :endif") + Xpath 128 " X: 128 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" while 1 +" endtry +endif +if MESSAGES('E170', "Missing :endwhile") + Xpath 256 " X: 256 +endif + +call delete(msgfile) +unlet msgfile + +delfunction MESSAGES + +Xcheck 511 + + +"------------------------------------------------------------------------------- +" Test 57: v:exception and v:throwpoint for user exceptions {{{1 +" +" v:exception evaluates to the value of the exception that was caught +" most recently and is not finished. (A caught exception is finished +" when the next ":catch", ":finally", or ":endtry" is reached.) +" v:throwpoint evaluates to the script/function name and line number +" where that exception has been thrown. +"------------------------------------------------------------------------------- + +XpathINIT + +function! FuncException() + let g:exception = v:exception +endfunction + +function! FuncThrowpoint() + let g:throwpoint = v:throwpoint +endfunction + +let scriptException = MakeScript("FuncException") +let scriptThrowPoint = MakeScript("FuncThrowpoint") + +command! CmdException let g:exception = v:exception +command! CmdThrowpoint let g:throwpoint = v:throwpoint + +XloopINIT! 1 2 + +function! CHECK(n, exception, throwname, throwline) + XloopNEXT + let error = 0 + if v:exception != a:exception + Xout a:n.": v:exception is" v:exception "instead of" a:exception + let error = 1 + endif + if v:throwpoint !~ a:throwname + let name = escape(a:throwname, '\') + Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name + let error = 1 + endif + if v:throwpoint !~ a:throwline + let line = escape(a:throwline, '\') + Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line + let error = 1 + endif + if error + Xloop 1 " X: 0 + endif +endfunction + +function! T(arg, line) + if a:line == 2 + throw a:arg " in line 2 + elseif a:line == 4 + throw a:arg " in line 4 + elseif a:line == 6 + throw a:arg " in line 6 + elseif a:line == 8 + throw a:arg " in line 8 + endif +endfunction + +function! G(arg, line) + call T(a:arg, a:line) +endfunction + +function! F(arg, line) + call G(a:arg, a:line) +endfunction + +let scriptT = MakeScript("T") +let scriptG = MakeScript("G", scriptT) +let scriptF = MakeScript("F", scriptG) + +try + Xpath 32768 " X: 32768 + call F("oops", 2) +catch /.*/ + Xpath 65536 " X: 65536 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(1, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + exec "let exception = v:exception" + exec "let throwpoint = v:throwpoint" + call CHECK(2, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + CmdException + CmdThrowpoint + call CHECK(3, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + call FuncException() + call FuncThrowpoint() + call CHECK(4, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + exec "source" scriptException + exec "source" scriptThrowPoint + call CHECK(5, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + try + Xpath 131072 " X: 131072 + call G("arrgh", 4) + catch /.*/ + Xpath 262144 " X: 262144 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(6, "arrgh", '\<G\.\.T\>', '\<4\>') + try + Xpath 524288 " X: 524288 + let g:arg = "autsch" + let g:line = 6 + exec "source" scriptF + catch /.*/ + Xpath 1048576 " X: 1048576 + let exception = v:exception + let throwpoint = v:throwpoint + " Symbolic links in tempname()s are not resolved, whereas resolving + " is done for v:throwpoint. Resolve the temporary file name for + " scriptT, so that it can be matched against v:throwpoint. + call CHECK(7, "autsch", resolve(scriptT), '\<6\>') + finally + Xpath 2097152 " X: 2097152 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(8, "arrgh", '\<G\.\.T\>', '\<4\>') + try + Xpath 4194304 " X: 4194304 + let g:arg = "brrrr" + let g:line = 8 + exec "source" scriptG + catch /.*/ + Xpath 8388608 " X: 8388608 + let exception = v:exception + let throwpoint = v:throwpoint + " Resolve scriptT for matching it against v:throwpoint. + call CHECK(9, "brrrr", resolve(scriptT), '\<8\>') + finally + Xpath 16777216 " X: 16777216 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(10, "arrgh", '\<G\.\.T\>', '\<4\>') + endtry + Xpath 33554432 " X: 33554432 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(11, "arrgh", '\<G\.\.T\>', '\<4\>') + endtry + Xpath 67108864 " X: 67108864 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(12, "arrgh", '\<G\.\.T\>', '\<4\>') + finally + Xpath 134217728 " X: 134217728 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(13, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + endtry + Xpath 268435456 " X: 268435456 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(14, "oops", '\<F\.\.G\.\.T\>', '\<2\>') +finally + Xpath 536870912 " X: 536870912 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(15, "", '^$', '^$') +endtry + +Xpath 1073741824 " X: 1073741824 + +unlet exception throwpoint +delfunction FuncException +delfunction FuncThrowpoint +call delete(scriptException) +call delete(scriptThrowPoint) +unlet scriptException scriptThrowPoint +delcommand CmdException +delcommand CmdThrowpoint +delfunction T +delfunction G +delfunction F +call delete(scriptT) +call delete(scriptG) +call delete(scriptF) +unlet scriptT scriptG scriptF + +Xcheck 2147450880 + + +"------------------------------------------------------------------------------- +" +" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1 +" +" v:exception and v:throwpoint work also for error and interrupt +" exceptions. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + function! T(line) + if a:line == 2 + delfunction T " error (function in use) in line 2 + elseif a:line == 4 + let dummy = 0 " INTERRUPT1 - interrupt in line 4 + endif + endfunction + + while 1 + try + Xpath 1 " X: 1 + let caught = 0 + call T(2) + catch /.*/ + let caught = 1 + if v:exception !~ 'Vim(delfunction):' + Xpath 2 " X: 0 + endif + if v:throwpoint !~ '\<T\>' + Xpath 4 " X: 0 + endif + if v:throwpoint !~ '\<2\>' + Xpath 8 " X: 0 + endif + finally + Xpath 16 " X: 16 + if caught || $VIMNOERRTHROW + Xpath 32 " X: 32 + endif + if v:exception != "" + Xpath 64 " X: 0 + endif + if v:throwpoint != "" + Xpath 128 " X: 0 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + Xpath 256 " X: 256 + if v:exception != "" + Xpath 512 " X: 0 + endif + if v:throwpoint != "" + Xpath 1024 " X: 0 + endif + + while 1 + try + Xpath 2048 " X: 2048 + let caught = 0 + call T(4) + catch /.*/ + let caught = 1 + if v:exception != 'Vim:Interrupt' + Xpath 4096 " X: 0 + endif + if v:throwpoint !~ '\<T\>' + Xpath 8192 " X: 0 + endif + if v:throwpoint !~ '\<4\>' + Xpath 16384 " X: 0 + endif + finally + Xpath 32768 " X: 32768 + if caught || $VIMNOINTTHROW + Xpath 65536 " X: 65536 + endif + if v:exception != "" + Xpath 131072 " X: 0 + endif + if v:throwpoint != "" + Xpath 262144 " X: 0 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + Xpath 524288 " X: 524288 + if v:exception != "" + Xpath 1048576 " X: 0 + endif + if v:throwpoint != "" + Xpath 2097152 " X: 0 + endif + +endif + +Xcheck 624945 + + +"------------------------------------------------------------------------------- +" +" Test 59: v:exception and v:throwpoint when discarding exceptions {{{1 +" +" When a :catch clause is left by a ":break" etc or an error or +" interrupt exception, v:exception and v:throwpoint are reset. They +" are not affected by an exception that is discarded before being +" caught. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 2 + + let sfile = expand("<sfile>") + + function! LineNumber() + return substitute(substitute(v:throwpoint, g:sfile, '', ""), + \ '\D*\(\d*\).*', '\1', "") + endfunction + + command! -nargs=1 SetLineNumber + \ try | throw "line" | catch /.*/ | let <args> = LineNumber() | endtry + + " Check v:exception/v:throwpoint against second/fourth parameter if + " specified, check for being empty else. + function! CHECK(n, ...) + XloopNEXT + let exception = a:0 != 0 ? a:1 : "" " second parameter (optional) + let emsg = a:0 != 0 ? a:2 : "" " third parameter (optional) + let line = a:0 != 0 ? a:3 : 0 " fourth parameter (optional) + let error = 0 + if emsg != "" + " exception is the error number, emsg the English error message text + if exception !~ '^E\d\+$' + Xout "TODO: Add message number for:" emsg + elseif v:lang == "C" || v:lang =~ '^[Ee]n' + if exception == "E492" && emsg == "Not an editor command" + let exception = '^Vim:' . exception . ': ' . emsg + else + let exception = '^Vim(\a\+):' . exception . ': ' . emsg + endif + else + if exception == "E492" + let exception = '^Vim:' . exception + else + let exception = '^Vim(\a\+):' . exception + endif + endif + endif + if exception == "" && v:exception != "" + Xout a:n.": v:exception is set:" v:exception + let error = 1 + elseif exception != "" && v:exception !~ exception + Xout a:n.": v:exception (".v:exception.") does not match" exception + let error = 1 + endif + if line == 0 && v:throwpoint != "" + Xout a:n.": v:throwpoint is set:" v:throwpoint + let error = 1 + elseif line != 0 && v:throwpoint !~ '\<' . line . '\>' + Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line + let error = 1 + endif + if !error + Xloop 1 " X: 2097151 + endif + endfunction + + while 1 + try + throw "x1" + catch /.*/ + break + endtry + endwhile + call CHECK(1) + + while 1 + try + throw "x2" + catch /.*/ + break + finally + call CHECK(2) + endtry + break + endwhile + call CHECK(3) + + while 1 + try + let errcaught = 0 + try + try + throw "x3" + catch /.*/ + SetLineNumber line_before_error + asdf + endtry + catch /.*/ + let errcaught = 1 + call CHECK(4, 'E492', "Not an editor command", + \ line_before_error + 1) + endtry + finally + if !errcaught && $VIMNOERRTHROW + call CHECK(4) + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + call CHECK(5) + + Xpath 2097152 " X: 2097152 + + while 1 + try + let intcaught = 0 + try + try + throw "x4" + catch /.*/ + SetLineNumber two_lines_before_interrupt + "INTERRUPT + let dummy = 0 + endtry + catch /.*/ + let intcaught = 1 + call CHECK(6, "Vim:Interrupt", '', + \ two_lines_before_interrupt + 2) + endtry + finally + if !intcaught && $VIMNOINTTHROW + call CHECK(6) + endif + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + call CHECK(7) + + Xpath 4194304 " X: 4194304 + + while 1 + try + let errcaught = 0 + try + try +" if 1 + SetLineNumber line_before_throw + throw "x5" + " missing endif + catch /.*/ + Xpath 8388608 " X: 0 + endtry + catch /.*/ + let errcaught = 1 + call CHECK(8, 'E171', "Missing :endif", line_before_throw + 3) + endtry + finally + if !errcaught && $VIMNOERRTHROW + call CHECK(8) + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + call CHECK(9) + + Xpath 16777216 " X: 16777216 + + try + while 1 + try + throw "x6" + finally + break + endtry + break + endwhile + catch /.*/ + Xpath 33554432 " X: 0 + endtry + call CHECK(10) + + try + while 1 + try + throw "x7" + finally + break + endtry + break + endwhile + catch /.*/ + Xpath 67108864 " X: 0 + finally + call CHECK(11) + endtry + call CHECK(12) + + while 1 + try + let errcaught = 0 + try + try + throw "x8" + finally + SetLineNumber line_before_error + asdf + endtry + catch /.*/ + let errcaught = 1 + call CHECK(13, 'E492', "Not an editor command", + \ line_before_error + 1) + endtry + finally + if !errcaught && $VIMNOERRTHROW + call CHECK(13) + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + call CHECK(14) + + Xpath 134217728 " X: 134217728 + + while 1 + try + let intcaught = 0 + try + try + throw "x9" + finally + SetLineNumber two_lines_before_interrupt + "INTERRUPT + endtry + catch /.*/ + let intcaught = 1 + call CHECK(15, "Vim:Interrupt", '', + \ two_lines_before_interrupt + 2) + endtry + finally + if !intcaught && $VIMNOINTTHROW + call CHECK(15) + endif + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + call CHECK(16) + + Xpath 268435456 " X: 268435456 + + while 1 + try + let errcaught = 0 + try + try +" if 1 + SetLineNumber line_before_throw + throw "x10" + " missing endif + finally + call CHECK(17) + endtry + catch /.*/ + let errcaught = 1 + call CHECK(18, 'E171', "Missing :endif", line_before_throw + 3) + endtry + finally + if !errcaught && $VIMNOERRTHROW + call CHECK(18) + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + call CHECK(19) + + Xpath 536870912 " X: 536870912 + + while 1 + try + let errcaught = 0 + try + try +" if 1 + SetLineNumber line_before_throw + throw "x11" + " missing endif + endtry + catch /.*/ + let errcaught = 1 + call CHECK(20, 'E171', "Missing :endif", line_before_throw + 3) + endtry + finally + if !errcaught && $VIMNOERRTHROW + call CHECK(20) + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + call CHECK(21) + + Xpath 1073741824 " X: 1073741824 + +endif + +Xcheck 2038431743 + + +"------------------------------------------------------------------------------- +" +" Test 60: (Re)throwing v:exception; :echoerr. {{{1 +" +" A user exception can be rethrown after catching by throwing +" v:exception. An error or interrupt exception cannot be rethrown +" because Vim exceptions cannot be faked. A Vim exception using the +" value of v:exception can, however, be triggered by the :echoerr +" command. +"------------------------------------------------------------------------------- + +XpathINIT + +try + try + Xpath 1 " X: 1 + throw "oops" + catch /oops/ + Xpath 2 " X: 2 + throw v:exception " rethrow user exception + catch /.*/ + Xpath 4 " X: 0 + endtry +catch /^oops$/ " catches rethrown user exception + Xpath 8 " X: 8 +catch /.*/ + Xpath 16 " X: 0 +endtry + +function! F() + try + let caught = 0 + try + Xpath 32 " X: 32 + write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e + Xpath 64 " X: 0 + Xout "did_emsg was reset before executing " . + \ "BufWritePost autocommands." + catch /^Vim(write):/ + let caught = 1 + throw v:exception " throw error: cannot fake Vim exception + catch /.*/ + Xpath 128 " X: 0 + finally + Xpath 256 " X: 256 + if !caught && !$VIMNOERRTHROW + Xpath 512 " X: 0 + endif + endtry + catch /^Vim(throw):/ " catches throw error + let caught = caught + 1 + catch /.*/ + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + if caught != 2 + if !caught && !$VIMNOERRTHROW + Xpath 4096 " X: 0 + elseif caught + Xpath 8192 " X: 0 + endif + return | " discard error for $VIMNOERRTHROW + endif + endtry +endfunction + +call F() +delfunction F + +function! G() + try + let caught = 0 + try + Xpath 16384 " X: 16384 + asdf + catch /^Vim/ " catch error exception + let caught = 1 + " Trigger Vim error exception with value specified after :echoerr + let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "") + echoerr value + catch /.*/ + Xpath 32768 " X: 0 + finally + Xpath 65536 " X: 65536 + if !caught + if !$VIMNOERRTHROW + Xpath 131072 " X: 0 + else + let value = "Error" + echoerr value + endif + endif + endtry + catch /^Vim(echoerr):/ + let caught = caught + 1 + if v:exception !~ value + Xpath 262144 " X: 0 + endif + catch /.*/ + Xpath 524288 " X: 0 + finally + Xpath 1048576 " X: 1048576 + if caught != 2 + if !caught && !$VIMNOERRTHROW + Xpath 2097152 " X: 0 + elseif caught + Xpath 4194304 " X: 0 + endif + return | " discard error for $VIMNOERRTHROW + endif + endtry +endfunction + +call G() +delfunction G + +unlet! value caught + +if ExtraVim() + try + let errcaught = 0 + try + Xpath 8388608 " X: 8388608 + let intcaught = 0 + "INTERRUPT + catch /^Vim:/ " catch interrupt exception + let intcaught = 1 + " Trigger Vim error exception with value specified after :echoerr + echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "") + catch /.*/ + Xpath 16777216 " X: 0 + finally + Xpath 33554432 " X: 33554432 + if !intcaught + if !$VIMNOINTTHROW + Xpath 67108864 " X: 0 + else + echoerr "Interrupt" + endif + endif + endtry + catch /^Vim(echoerr):/ + let errcaught = 1 + if v:exception !~ "Interrupt" + Xpath 134217728 " X: 0 + endif + finally + Xpath 268435456 " X: 268435456 + if !errcaught && !$VIMNOERRTHROW + Xpath 536870912 " X: 0 + endif + endtry +endif + +Xcheck 311511339 + + +"------------------------------------------------------------------------------- +" Test 61: Catching interrupt exceptions {{{1 +" +" When an interrupt occurs inside a :try/:endtry region, an +" interrupt exception is thrown and can be caught. Its value is +" "Vim:Interrupt". If the interrupt occurs after an error or a :throw +" but before a matching :catch is reached, all following :catches of +" that try block are ignored, but the interrupt exception can be +" caught by the next surrounding try conditional. An interrupt is +" ignored when there is a previous interrupt that has not been caught +" or causes a :finally clause to be executed. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + while 1 + try + try + Xpath 1 " X: 1 + let caught = 0 + "INTERRUPT + Xpath 2 " X: 0 + catch /^Vim:Interrupt$/ + let caught = 1 + finally + Xpath 4 " X: 4 + if caught || $VIMNOINTTHROW + Xpath 8 " X: 8 + endif + endtry + catch /.*/ + Xpath 16 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + + while 1 + try + try + let caught = 0 + try + Xpath 32 " X: 32 + asdf + Xpath 64 " X: 0 + catch /do_not_catch/ + Xpath 128 " X: 0 + catch /.*/ "INTERRUPT - throw interrupt if !$VIMNOERRTHROW + Xpath 256 " X: 0 + catch /.*/ + Xpath 512 " X: 0 + finally "INTERRUPT - throw interrupt if $VIMNOERRTHROW + Xpath 1024 " X: 1024 + endtry + catch /^Vim:Interrupt$/ + let caught = 1 + finally + Xpath 2048 " X: 2048 + if caught || $VIMNOINTTHROW + Xpath 4096 " X: 4096 + endif + endtry + catch /.*/ + Xpath 8192 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + + while 1 + try + try + let caught = 0 + try + Xpath 16384 " X: 16384 + throw "x" + Xpath 32768 " X: 0 + catch /do_not_catch/ + Xpath 65536 " X: 0 + catch /x/ "INTERRUPT + Xpath 131072 " X: 0 + catch /.*/ + Xpath 262144 " X: 0 + endtry + catch /^Vim:Interrupt$/ + let caught = 1 + finally + Xpath 524288 " X: 524288 + if caught || $VIMNOINTTHROW + Xpath 1048576 " X: 1048576 + endif + endtry + catch /.*/ + Xpath 2097152 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + + while 1 + try + let caught = 0 + try + Xpath 4194304 " X: 4194304 + "INTERRUPT + Xpath 8388608 " X: 0 + catch /do_not_catch/ "INTERRUPT + Xpath 16777216 " X: 0 + catch /^Vim:Interrupt$/ + let caught = 1 + finally + Xpath 33554432 " X: 33554432 + if caught || $VIMNOINTTHROW + Xpath 67108864 " X: 67108864 + endif + endtry + catch /.*/ + Xpath 134217728 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + + Xpath 268435456 " X: 268435456 + +endif + +Xcheck 374889517 + + +"------------------------------------------------------------------------------- +" Test 62: Catching error exceptions {{{1 +" +" An error inside a :try/:endtry region is converted to an exception +" and can be caught. The error exception has a "Vim(cmdname):" prefix +" where cmdname is the name of the failing command, or a "Vim:" prefix +" if no command name is known. The "Vim" prefixes cannot be faked. +"------------------------------------------------------------------------------- + +XpathINIT + +function! MSG(enr, emsg) + let english = v:lang == "C" || v:lang =~ '^[Ee]n' + if a:enr == "" + Xout "TODO: Add message number for:" a:emsg + let v:errmsg = ":" . v:errmsg + endif + let match = 1 + if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) + let match = 0 + if v:errmsg == "" + Xout "Message missing." + else + let v:errmsg = escape(v:errmsg, '"') + Xout "Unexpected message:" v:errmsg + endif + endif + return match +endfunction + +while 1 + try + try + let caught = 0 + unlet novar + catch /^Vim(unlet):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "") + finally + Xpath 1 " X: 1 + if !caught && !$VIMNOERRTHROW + Xpath 2 " X: 0 + endif + if !MSG('E108', "No such variable") + Xpath 4 " X: 0 + endif + endtry + catch /.*/ + Xpath 8 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let caught = 0 + throw novar " error in :throw + catch /^Vim(throw):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "") + finally + Xpath 16 " X: 16 + if !caught && !$VIMNOERRTHROW + Xpath 32 " X: 0 + endif + if caught ? !MSG('E121', "Undefined variable") + \ : !MSG('E15', "Invalid expression") + Xpath 64 " X: 0 + endif + endtry + catch /.*/ + Xpath 128 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let caught = 0 + throw "Vim:faked" " error: cannot fake Vim exception + catch /^Vim(throw):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "") + finally + Xpath 256 " X: 256 + if !caught && !$VIMNOERRTHROW + Xpath 512 " X: 0 + endif + if !MSG('E608', "Cannot :throw exceptions with 'Vim' prefix") + Xpath 1024 " X: 0 + endif + endtry + catch /.*/ + Xpath 2048 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +function! F() + while 1 + " Missing :endwhile +endfunction + +while 1 + try + try + let caught = 0 + call F() + catch /^Vim(endfunction):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "") + finally + Xpath 4096 " X: 4096 + if !caught && !$VIMNOERRTHROW + Xpath 8192 " X: 0 + endif + if !MSG('E170', "Missing :endwhile") + Xpath 16384 " X: 0 + endif + endtry + catch /.*/ + Xpath 32768 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let caught = 0 + ExecAsScript F + catch /^Vim:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim:', '', "") + finally + Xpath 65536 " X: 65536 + if !caught && !$VIMNOERRTHROW + Xpath 131072 " X: 0 + endif + if !MSG('E170', "Missing :endwhile") + Xpath 262144 " X: 0 + endif + endtry + catch /.*/ + Xpath 524288 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +function! G() + call G() +endfunction + +while 1 + try + let mfd_save = &mfd + set mfd=3 + try + let caught = 0 + call G() + catch /^Vim(call):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(call):', '', "") + finally + Xpath 1048576 " X: 1048576 + if !caught && !$VIMNOERRTHROW + Xpath 2097152 " X: 0 + endif + if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'") + Xpath 4194304 " X: 0 + endif + endtry + catch /.*/ + Xpath 8388608 " X: 0 + Xout v:exception "in" v:throwpoint + finally + let &mfd = mfd_save + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +function! H() + return H() +endfunction + +while 1 + try + let mfd_save = &mfd + set mfd=3 + try + let caught = 0 + call H() + catch /^Vim(return):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(return):', '', "") + finally + Xpath 16777216 " X: 16777216 + if !caught && !$VIMNOERRTHROW + Xpath 33554432 " X: 0 + endif + if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'") + Xpath 67108864 " X: 0 + endif + endtry + catch /.*/ + Xpath 134217728 " X: 0 + Xout v:exception "in" v:throwpoint + finally + let &mfd = mfd_save + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +unlet! caught mfd_save +delfunction F +delfunction G +delfunction H +Xpath 268435456 " X: 268435456 + +Xcheck 286331153 + +" Leave MSG() for the next test. + + +"------------------------------------------------------------------------------- +" Test 63: Suppressing error exceptions by :silent!. {{{1 +" +" A :silent! command inside a :try/:endtry region suppresses the +" conversion of errors to an exception and the immediate abortion on +" error. When the commands executed by the :silent! themselves open +" a new :try/:endtry region, conversion of errors to exception and +" immediate abortion is switched on again - until the next :silent! +" etc. The :silent! has the effect of setting v:errmsg to the error +" message text (without displaying it) and continuing with the next +" script line. +" +" When a command triggering autocommands is executed by :silent! +" inside a :try/:endtry, the autocommand execution is not suppressed +" on error. +" +" This test reuses the function MSG() from the previous test. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT! 1 4 + +let taken = "" + +function! S(n) abort + XloopNEXT + let g:taken = g:taken . "E" . a:n + let v:errmsg = "" + exec "asdf" . a:n + + " Check that ":silent!" continues: + Xloop 1 + + " Check that ":silent!" sets "v:errmsg": + if MSG('E492', "Not an editor command") + Xloop 2 + endif +endfunction + +function! Foo() + while 1 + try + try + let caught = 0 + " This is not silent: + call S(3) " X: 0 * 16 + catch /^Vim:/ + let caught = 1 + let errmsg3 = substitute(v:exception, '^Vim:', '', "") + silent! call S(4) " X: 3 * 64 + finally + if !caught + let errmsg3 = v:errmsg + " Do call S(4) here if not executed in :catch. + silent! call S(4) + endif + Xpath 1048576 " X: 1048576 + if !caught && !$VIMNOERRTHROW + Xpath 2097152 " X: 0 + endif + let v:errmsg = errmsg3 + if !MSG('E492', "Not an editor command") + Xpath 4194304 " X: 0 + endif + silent! call S(5) " X: 3 * 256 + " Break out of try conditionals that cover ":silent!". This also + " discards the aborting error when $VIMNOERRTHROW is non-zero. + break + endtry + catch /.*/ + Xpath 8388608 " X: 0 + Xout v:exception "in" v:throwpoint + endtry + endwhile + " This is a double ":silent!" (see caller). + silent! call S(6) " X: 3 * 1024 +endfunction + +function! Bar() + try + silent! call S(2) " X: 3 * 4 + " X: 3 * 4096 + silent! execute "call Foo() | call S(7)" + silent! call S(8) " X: 3 * 16384 + endtry " normal end of try cond that covers ":silent!" + " This has a ":silent!" from the caller: + call S(9) " X: 3 * 65536 +endfunction + +silent! call S(1) " X: 3 * 1 +silent! call Bar() +silent! call S(10) " X: 3 * 262144 + +let expected = "E1E2E3E4E5E6E7E8E9E10" +if taken != expected + Xpath 16777216 " X: 0 + Xout "'taken' is" taken "instead of" expected +endif + +augroup TMP + autocmd BufWritePost * Xpath 33554432 " X: 33554432 +augroup END + +Xpath 67108864 " X: 67108864 +write /i/m/p/o/s/s/i/b/l/e +Xpath 134217728 " X: 134217728 + +autocmd! TMP +unlet! caught errmsg3 taken expected +delfunction S +delfunction Foo +delfunction Bar +delfunction MSG + +Xcheck 236978127 + + +"------------------------------------------------------------------------------- +" Test 64: Error exceptions after error, interrupt or :throw {{{1 +" +" When an error occurs after an interrupt or a :throw but before +" a matching :catch is reached, all following :catches of that try +" block are ignored, but the error exception can be caught by the next +" surrounding try conditional. Any previous error exception is +" discarded. An error is ignored when there is a previous error that +" has not been caught. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + while 1 + try + try + Xpath 1 " X: 1 + let caught = 0 + while 1 +" if 1 + " Missing :endif + endwhile " throw error exception + catch /^Vim(/ + let caught = 1 + finally + Xpath 2 " X: 2 + if caught || $VIMNOERRTHROW + Xpath 4 " X: 4 + endif + endtry + catch /.*/ + Xpath 8 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + try + Xpath 16 " X: 16 + let caught = 0 + try +" if 1 + " Missing :endif + catch /.*/ " throw error exception + Xpath 32 " X: 0 + catch /.*/ + Xpath 64 " X: 0 + endtry + catch /^Vim(/ + let caught = 1 + finally + Xpath 128 " X: 128 + if caught || $VIMNOERRTHROW + Xpath 256 " X: 256 + endif + endtry + catch /.*/ + Xpath 512 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + try + let caught = 0 + try + Xpath 1024 " X: 1024 + "INTERRUPT + catch /do_not_catch/ + Xpath 2048 " X: 0 +" if 1 + " Missing :endif + catch /.*/ " throw error exception + Xpath 4096 " X: 0 + catch /.*/ + Xpath 8192 " X: 0 + endtry + catch /^Vim(/ + let caught = 1 + finally + Xpath 16384 " X: 16384 + if caught || $VIMNOERRTHROW + Xpath 32768 " X: 32768 + endif + endtry + catch /.*/ + Xpath 65536 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + try + let caught = 0 + try + Xpath 131072 " X: 131072 + throw "x" + catch /do_not_catch/ + Xpath 262144 " X: 0 +" if 1 + " Missing :endif + catch /x/ " throw error exception + Xpath 524288 " X: 0 + catch /.*/ + Xpath 1048576 " X: 0 + endtry + catch /^Vim(/ + let caught = 1 + finally + Xpath 2097152 " X: 2097152 + if caught || $VIMNOERRTHROW + Xpath 4194304 " X: 4194304 + endif + endtry + catch /.*/ + Xpath 8388608 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + try + let caught = 0 + Xpath 16777216 " X: 16777216 +" endif " :endif without :if; throw error exception +" if 1 + " Missing :endif + catch /do_not_catch/ " ignore new error + Xpath 33554432 " X: 0 + catch /^Vim(endif):/ + let caught = 1 + catch /^Vim(/ + Xpath 67108864 " X: 0 + finally + Xpath 134217728 " X: 134217728 + if caught || $VIMNOERRTHROW + Xpath 268435456 " X: 268435456 + endif + endtry + catch /.*/ + Xpath 536870912 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + Xpath 1073741824 " X: 1073741824 + +endif + +Xcheck 1499645335 + + +"------------------------------------------------------------------------------- +" Test 65: Errors in the /pattern/ argument of a :catch {{{1 +" +" On an error in the /pattern/ argument of a :catch, the :catch does +" not match. Any following :catches of the same :try/:endtry don't +" match either. Finally clauses are executed. +"------------------------------------------------------------------------------- + +XpathINIT + +function! MSG(enr, emsg) + let english = v:lang == "C" || v:lang =~ '^[Ee]n' + if a:enr == "" + Xout "TODO: Add message number for:" a:emsg + let v:errmsg = ":" . v:errmsg + endif + let match = 1 + if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) + let match = 0 + if v:errmsg == "" + Xout "Message missing." + else + let v:errmsg = escape(v:errmsg, '"') + Xout "Unexpected message:" v:errmsg + endif + endif + return match +endfunction + +try + try + Xpath 1 " X: 1 + throw "oops" + catch /^oops$/ + Xpath 2 " X: 2 + catch /\)/ " not checked; exception has already been caught + Xpath 4 " X: 0 + endtry + Xpath 8 " X: 8 +catch /.*/ + Xpath 16 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +function! F() + try + let caught = 0 + try + try + Xpath 32 " X: 32 + throw "ab" + catch /abc/ " does not catch + Xpath 64 " X: 0 + catch /\)/ " error; discards exception + Xpath 128 " X: 0 + catch /.*/ " not checked + Xpath 256 " X: 0 + finally + Xpath 512 " X: 512 + endtry + Xpath 1024 " X: 0 + catch /^ab$/ " checked, but original exception is discarded + Xpath 2048 " X: 0 + catch /^Vim(catch):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(catch):', '', "") + finally + Xpath 4096 " X: 4096 + if !caught && !$VIMNOERRTHROW + Xpath 8192 " X: 0 + endif + if caught ? !MSG('E55', 'Unmatched \\)') + \ : !MSG('E475', "Invalid argument") + Xpath 16384 " X: 0 + endif + if !caught + return | " discard error + endif + endtry + catch /.*/ + Xpath 32768 " X: 0 + Xout v:exception "in" v:throwpoint + endtry +endfunction + +call F() +Xpath 65536 " X: 65536 + +delfunction MSG +delfunction F +unlet! caught + +Xcheck 70187 + + +"------------------------------------------------------------------------------- +" Test 66: Stop range :call on error, interrupt, or :throw {{{1 +" +" When a function which is multiply called for a range since it +" doesn't handle the range itself has an error in a command +" dynamically enclosed by :try/:endtry or gets an interrupt or +" executes a :throw, no more calls for the remaining lines in the +" range are made. On an error in a command not dynamically enclosed +" by :try/:endtry, the function is executed again for the remaining +" lines in the range. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + let file = tempname() + exec "edit" file + + insert +line 1 +line 2 +line 3 +. + + XloopINIT! 1 2 + + let taken = "" + let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)" + + function! F(reason, n) abort + let g:taken = g:taken . "F" . a:n . + \ substitute(a:reason, '\(\l\).*', '\u\1', "") . + \ "(" . line(".") . ")" + + if a:reason == "error" + asdf + elseif a:reason == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:reason == "throw" + throw "xyz" + elseif a:reason == "aborting error" + XloopNEXT + if g:taken != g:expected + Xloop 1 " X: 0 + Xout "'taken' is" g:taken "instead of" g:expected + endif + try + bwipeout! + call delete(file) + asdf + endtry + endif + endfunction + + function! G(reason, n) + let g:taken = g:taken . "G" . a:n . + \ substitute(a:reason, '\(\l\).*', '\u\1', "") + 1,3call F(a:reason, a:n) + endfunction + + Xpath 8 " X: 8 + call G("error", 1) + try + Xpath 16 " X: 16 + try + call G("error", 2) + Xpath 32 " X: 0 + finally + Xpath 64 " X: 64 + try + call G("interrupt", 3) + Xpath 128 " X: 0 + finally + Xpath 256 " X: 256 + try + call G("throw", 4) + Xpath 512 " X: 0 + endtry + endtry + endtry + catch /xyz/ + Xpath 1024 " X: 1024 + catch /.*/ + Xpath 2048 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + Xpath 4096 " X: 4096 + call G("aborting error", 5) + Xpath 8192 " X: 0 + Xout "'taken' is" taken "instead of" expected + +endif + +Xcheck 5464 + + +"------------------------------------------------------------------------------- +" Test 67: :throw across :call command {{{1 +" +" On a call command, an exception might be thrown when evaluating the +" function name, during evaluation of the arguments, or when the +" function is being executed. The exception can be caught by the +" caller. +"------------------------------------------------------------------------------- + +XpathINIT + +function! THROW(x, n) + if a:n == 1 + Xpath 1 " X: 1 + elseif a:n == 2 + Xpath 2 " X: 2 + elseif a:n == 3 + Xpath 4 " X: 4 + endif + throw a:x +endfunction + +function! NAME(x, n) + if a:n == 1 + Xpath 8 " X: 0 + elseif a:n == 2 + Xpath 16 " X: 16 + elseif a:n == 3 + Xpath 32 " X: 32 + elseif a:n == 4 + Xpath 64 " X: 64 + endif + return a:x +endfunction + +function! ARG(x, n) + if a:n == 1 + Xpath 128 " X: 0 + elseif a:n == 2 + Xpath 256 " X: 0 + elseif a:n == 3 + Xpath 512 " X: 512 + elseif a:n == 4 + Xpath 1024 " X: 1024 + endif + return a:x +endfunction + +function! F(x, n) + if a:n == 2 + Xpath 2048 " X: 0 + elseif a:n == 4 + Xpath 4096 " X: 4096 + endif +endfunction + +while 1 + try + let error = 0 + let v:errmsg = "" + + while 1 + try + Xpath 8192 " X: 8192 + call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1) + Xpath 16384 " X: 0 + catch /^name$/ + Xpath 32768 " X: 32768 + catch /.*/ + let error = 1 + Xout "1:" v:exception "in" v:throwpoint + finally + if !error && $VIMNOERRTHROW && v:errmsg != "" + let error = 1 + Xout "1:" v:errmsg + endif + if error + Xpath 65536 " X: 0 + endif + let error = 0 + let v:errmsg = "" + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + Xpath 131072 " X: 131072 + call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2) + Xpath 262144 " X: 0 + catch /^arg$/ + Xpath 524288 " X: 524288 + catch /.*/ + let error = 1 + Xout "2:" v:exception "in" v:throwpoint + finally + if !error && $VIMNOERRTHROW && v:errmsg != "" + let error = 1 + Xout "2:" v:errmsg + endif + if error + Xpath 1048576 " X: 0 + endif + let error = 0 + let v:errmsg = "" + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + Xpath 2097152 " X: 2097152 + call {NAME("THROW", 3)}(ARG("call", 3), 3) + Xpath 4194304 " X: 0 + catch /^call$/ + Xpath 8388608 " X: 8388608 + catch /^0$/ " default return value + Xpath 16777216 " X: 0 + Xout "3:" v:throwpoint + catch /.*/ + let error = 1 + Xout "3:" v:exception "in" v:throwpoint + finally + if !error && $VIMNOERRTHROW && v:errmsg != "" + let error = 1 + Xout "3:" v:errmsg + endif + if error + Xpath 33554432 " X: 0 + endif + let error = 0 + let v:errmsg = "" + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + Xpath 67108864 " X: 67108864 + call {NAME("F", 4)}(ARG(4711, 4), 4) + Xpath 134217728 " X: 134217728 + catch /.*/ + let error = 1 + Xout "4:" v:exception "in" v:throwpoint + finally + if !error && $VIMNOERRTHROW && v:errmsg != "" + let error = 1 + Xout "4:" v:errmsg + endif + if error + Xpath 268435456 " X: 0 + endif + let error = 0 + let v:errmsg = "" + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + catch /^0$/ " default return value + Xpath 536870912 " X: 0 + Xout v:throwpoint + catch /.*/ + let error = 1 + Xout v:exception "in" v:throwpoint + finally + if !error && $VIMNOERRTHROW && v:errmsg != "" + let error = 1 + Xout v:errmsg + endif + if error + Xpath 1073741824 " X: 0 + endif + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +unlet error +delfunction F + +Xcheck 212514423 + +" Leave THROW(), NAME(), and ARG() for the next test. + + +"------------------------------------------------------------------------------- +" Test 68: :throw across function calls in expressions {{{1 +" +" On a function call within an expression, an exception might be +" thrown when evaluating the function name, during evaluation of the +" arguments, or when the function is being executed. The exception +" can be caught by the caller. +" +" This test reuses the functions THROW(), NAME(), and ARG() from the +" previous test. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F(x, n) + if a:n == 2 + Xpath 2048 " X: 0 + elseif a:n == 4 + Xpath 4096 " X: 4096 + endif + return a:x +endfunction + +unlet! var1 var2 var3 var4 + +while 1 + try + let error = 0 + let v:errmsg = "" + + while 1 + try + Xpath 8192 " X: 8192 + let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1) + Xpath 16384 " X: 0 + catch /^name$/ + Xpath 32768 " X: 32768 + catch /.*/ + let error = 1 + Xout "1:" v:exception "in" v:throwpoint + finally + if !error && $VIMNOERRTHROW && v:errmsg != "" + let error = 1 + Xout "1:" v:errmsg + endif + if error + Xpath 65536 " X: 0 + endif + let error = 0 + let v:errmsg = "" + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + Xpath 131072 " X: 131072 + let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2) + Xpath 262144 " X: 0 + catch /^arg$/ + Xpath 524288 " X: 524288 + catch /.*/ + let error = 1 + Xout "2:" v:exception "in" v:throwpoint + finally + if !error && $VIMNOERRTHROW && v:errmsg != "" + let error = 1 + Xout "2:" v:errmsg + endif + if error + Xpath 1048576 " X: 0 + endif + let error = 0 + let v:errmsg = "" + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + Xpath 2097152 " X: 2097152 + let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3) + Xpath 4194304 " X: 0 + catch /^call$/ + Xpath 8388608 " X: 8388608 + catch /^0$/ " default return value + Xpath 16777216 " X: 0 + Xout "3:" v:throwpoint + catch /.*/ + let error = 1 + Xout "3:" v:exception "in" v:throwpoint + finally + if !error && $VIMNOERRTHROW && v:errmsg != "" + let error = 1 + Xout "3:" v:errmsg + endif + if error + Xpath 33554432 " X: 0 + endif + let error = 0 + let v:errmsg = "" + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + Xpath 67108864 " X: 67108864 + let var4 = {NAME("F", 4)}(ARG(4711, 4), 4) + Xpath 134217728 " X: 134217728 + catch /.*/ + let error = 1 + Xout "4:" v:exception "in" v:throwpoint + finally + if !error && $VIMNOERRTHROW && v:errmsg != "" + let error = 1 + Xout "4:" v:errmsg + endif + if error + Xpath 268435456 " X: 0 + endif + let error = 0 + let v:errmsg = "" + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + catch /^0$/ " default return value + Xpath 536870912 " X: 0 + Xout v:throwpoint + catch /.*/ + let error = 1 + Xout v:exception "in" v:throwpoint + finally + if !error && $VIMNOERRTHROW && v:errmsg != "" + let error = 1 + Xout v:errmsg + endif + if error + Xpath 1073741824 " X: 0 + endif + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +if exists("var1") || exists("var2") || exists("var3") || + \ !exists("var4") || var4 != 4711 + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + if exists("var1") + Xout "var1 =" var1 + endif + if exists("var2") + Xout "var2 =" var2 + endif + if exists("var3") + Xout "var3 =" var3 + endif + if !exists("var4") + Xout "var4 unset" + elseif var4 != 4711 + Xout "var4 =" var4 + endif +endif + +unlet! error var1 var2 var3 var4 +delfunction THROW +delfunction NAME +delfunction ARG +delfunction F + +Xcheck 212514423 + + +"------------------------------------------------------------------------------- +" Test 69: :throw across :if, :elseif, :while {{{1 +" +" On an :if, :elseif, or :while command, an exception might be thrown +" during evaluation of the expression to test. The exception can be +" caught by the script. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT! 1 2 + +function! THROW(x) + XloopNEXT + Xloop 1 " X: 1 + 2 + 4 + throw a:x +endfunction + +try + + try + Xpath 8 " X: 8 + if 4711 == THROW("if") + 111 + Xpath 16 " X: 0 + else + Xpath 32 " X: 0 + endif + Xpath 64 " X: 0 + catch /^if$/ + Xpath 128 " X: 128 + catch /.*/ + Xpath 256 " X: 0 + Xout "if:" v:exception "in" v:throwpoint + endtry + + try + Xpath 512 " X: 512 + if 4711 == 4 + 7 + 1 + 1 + Xpath 1024 " X: 0 + elseif 4711 == THROW("elseif") + 222 + Xpath 2048 " X: 0 + else + Xpath 4096 " X: 0 + endif + Xpath 8192 " X: 0 + catch /^elseif$/ + Xpath 16384 " X: 16384 + catch /.*/ + Xpath 32768 " X: 0 + Xout "elseif:" v:exception "in" v:throwpoint + endtry + + try + Xpath 65536 " X: 65536 + while 4711 == THROW("while") + 4711 + Xpath 131072 " X: 0 + break + endwhile + Xpath 262144 " X: 0 + catch /^while$/ + Xpath 524288 " X: 524288 + catch /.*/ + Xpath 1048576 " X: 0 + Xout "while:" v:exception "in" v:throwpoint + endtry + +catch /^0$/ " default return value + Xpath 2097152 " X: 0 + Xout v:throwpoint +catch /.*/ + Xout v:exception "in" v:throwpoint + Xpath 4194304 " X: 0 +endtry + +Xpath 8388608 " X: 8388608 + +delfunction THROW + +Xcheck 8995471 + + +"------------------------------------------------------------------------------- +" Test 70: :throw across :return or :throw {{{1 +" +" On a :return or :throw command, an exception might be thrown during +" evaluation of the expression to return or throw, respectively. The +" exception can be caught by the script. +"------------------------------------------------------------------------------- + +XpathINIT + +let taken = "" + +function! THROW(x, n) + let g:taken = g:taken . "T" . a:n + throw a:x +endfunction + +function! F(x, y, n) + let g:taken = g:taken . "F" . a:n + return a:x + THROW(a:y, a:n) +endfunction + +function! G(x, y, n) + let g:taken = g:taken . "G" . a:n + throw a:x . THROW(a:y, a:n) + return a:x +endfunction + +try + try + Xpath 1 " X: 1 + call F(4711, "return", 1) + Xpath 2 " X: 0 + catch /^return$/ + Xpath 4 " X: 4 + catch /.*/ + Xpath 8 " X: 0 + Xout "return:" v:exception "in" v:throwpoint + endtry + + try + Xpath 16 " X: 16 + let var = F(4712, "return-var", 2) + Xpath 32 " X: 0 + catch /^return-var$/ + Xpath 64 " X: 64 + catch /.*/ + Xpath 128 " X: 0 + Xout "return-var:" v:exception "in" v:throwpoint + finally + unlet! var + endtry + + try + Xpath 256 " X: 256 + throw "except1" . THROW("throw1", 3) + Xpath 512 " X: 0 + catch /^except1/ + Xpath 1024 " X: 0 + catch /^throw1$/ + Xpath 2048 " X: 2048 + catch /.*/ + Xpath 4096 " X: 0 + Xout "throw1:" v:exception "in" v:throwpoint + endtry + + try + Xpath 8192 " X: 8192 + call G("except2", "throw2", 4) + Xpath 16384 " X: 0 + catch /^except2/ + Xpath 32768 " X: 0 + catch /^throw2$/ + Xpath 65536 " X: 65536 + catch /.*/ + Xpath 131072 " X: 0 + Xout "throw2:" v:exception "in" v:throwpoint + endtry + + try + Xpath 262144 " X: 262144 + let var = G("except3", "throw3", 5) + Xpath 524288 " X: 0 + catch /^except3/ + Xpath 1048576 " X: 0 + catch /^throw3$/ + Xpath 2097152 " X: 2097152 + catch /.*/ + Xpath 4194304 " X: 0 + Xout "throw3:" v:exception "in" v:throwpoint + finally + unlet! var + endtry + + let expected = "F1T1F2T2T3G4T4G5T5" + if taken != expected + Xpath 8388608 " X: 0 + Xout "'taken' is" taken "instead of" expected + endif + +catch /^0$/ " default return value + Xpath 16777216 " X: 0 + Xout v:throwpoint +catch /.*/ + Xpath 33554432 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 67108864 " X: 67108864 + +unlet taken expected +delfunction THROW +delfunction F +delfunction G + +Xcheck 69544277 + + +"------------------------------------------------------------------------------- +" Test 71: :throw across :echo variants and :execute {{{1 +" +" On an :echo, :echon, :echomsg, :echoerr, or :execute command, an +" exception might be thrown during evaluation of the arguments to +" be displayed or executed as a command, respectively. Any following +" arguments are not evaluated, then. The exception can be caught by +" the script. +"------------------------------------------------------------------------------- + +XpathINIT + +let taken = "" + +function! THROW(x, n) + let g:taken = g:taken . "T" . a:n + throw a:x +endfunction + +function! F(n) + let g:taken = g:taken . "F" . a:n + return "F" . a:n +endfunction + +try + try + Xpath 1 " X: 1 + echo "echo" . THROW("echo-except", 1) F(1) + Xpath 2 " X: 0 + catch /^echo-except$/ + Xpath 4 " X: 4 + catch /.*/ + Xpath 8 " X: 0 + Xout "echo:" v:exception "in" v:throwpoint + endtry + + try + Xpath 16 " X: 16 + echon "echon" . THROW("echon-except", 2) F(2) + Xpath 32 " X: 0 + catch /^echon-except$/ + Xpath 64 " X: 64 + catch /.*/ + Xpath 128 " X: 0 + Xout "echon:" v:exception "in" v:throwpoint + endtry + + try + Xpath 256 " X: 256 + echomsg "echomsg" . THROW("echomsg-except", 3) F(3) + Xpath 512 " X: 0 + catch /^echomsg-except$/ + Xpath 1024 " X: 1024 + catch /.*/ + Xpath 2048 " X: 0 + Xout "echomsg:" v:exception "in" v:throwpoint + endtry + + try + Xpath 4096 " X: 4096 + echoerr "echoerr" . THROW("echoerr-except", 4) F(4) + Xpath 8192 " X: 0 + catch /^echoerr-except$/ + Xpath 16384 " X: 16384 + catch /Vim/ + Xpath 32768 " X: 0 + catch /echoerr/ + Xpath 65536 " X: 0 + catch /.*/ + Xpath 131072 " X: 0 + Xout "echoerr:" v:exception "in" v:throwpoint + endtry + + try + Xpath 262144 " X: 262144 + execute "echo 'execute" . THROW("execute-except", 5) F(5) "'" + Xpath 524288 " X: 0 + catch /^execute-except$/ + Xpath 1048576 " X: 1048576 + catch /.*/ + Xpath 2097152 " X: 0 + Xout "execute:" v:exception "in" v:throwpoint + endtry + + let expected = "T1T2T3T4T5" + if taken != expected + Xpath 4194304 " X: 0 + Xout "'taken' is" taken "instead of" expected + endif + +catch /^0$/ " default return value + Xpath 8388608 " X: 0 + Xout v:throwpoint +catch /.*/ + Xpath 16777216 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 33554432 " X: 33554432 + +unlet taken expected +delfunction THROW +delfunction F + +Xcheck 34886997 + + +"------------------------------------------------------------------------------- +" Test 72: :throw across :let or :unlet {{{1 +" +" On a :let command, an exception might be thrown during evaluation +" of the expression to assign. On an :let or :unlet command, the +" evaluation of the name of the variable to be assigned or list or +" deleted, respectively, may throw an exception. Any following +" arguments are not evaluated, then. The exception can be caught by +" the script. +"------------------------------------------------------------------------------- + +XpathINIT + +let throwcount = 0 + +function! THROW(x) + let g:throwcount = g:throwcount + 1 + throw a:x +endfunction + +try + try + let $VAR = "old_value" + Xpath 1 " X: 1 + let $VAR = "let(" . THROW("var") . ")" + Xpath 2 " X: 0 + catch /^var$/ + Xpath 4 " X: 4 + finally + if $VAR != "old_value" + Xpath 8 " X: 0 + endif + endtry + + try + let @a = "old_value" + Xpath 16 " X: 16 + let @a = "let(" . THROW("reg") . ")" + Xpath 32 " X: 0 + catch /^reg$/ + try + Xpath 64 " X: 64 + let @A = "let(" . THROW("REG") . ")" + Xpath 128 " X: 0 + catch /^REG$/ + Xpath 256 " X: 256 + endtry + finally + if @a != "old_value" + Xpath 512 " X: 0 + endif + if @A != "old_value" + Xpath 1024 " X: 0 + endif + endtry + + try + let saved_gpath = &g:path + let saved_lpath = &l:path + Xpath 2048 " X: 2048 + let &path = "let(" . THROW("opt") . ")" + Xpath 4096 " X: 0 + catch /^opt$/ + try + Xpath 8192 " X: 8192 + let &g:path = "let(" . THROW("gopt") . ")" + Xpath 16384 " X: 0 + catch /^gopt$/ + try + Xpath 32768 " X: 32768 + let &l:path = "let(" . THROW("lopt") . ")" + Xpath 65536 " X: 0 + catch /^lopt$/ + Xpath 131072 " X: 131072 + endtry + endtry + finally + if &g:path != saved_gpath || &l:path != saved_lpath + Xpath 262144 " X: 0 + endif + let &g:path = saved_gpath + let &l:path = saved_lpath + endtry + + unlet! var1 var2 var3 + + try + Xpath 524288 " X: 524288 + let var1 = "let(" . THROW("var1") . ")" + Xpath 1048576 " X: 0 + catch /^var1$/ + Xpath 2097152 " X: 2097152 + finally + if exists("var1") + Xpath 4194304 " X: 0 + endif + endtry + + try + let var2 = "old_value" + Xpath 8388608 " X: 8388608 + let var2 = "let(" . THROW("var2"). ")" + Xpath 16777216 " X: 0 + catch /^var2$/ + Xpath 33554432 " X: 33554432 + finally + if var2 != "old_value" + Xpath 67108864 " X: 0 + endif + endtry + + try + Xpath 134217728 " X: 134217728 + let var{THROW("var3")} = 4711 + Xpath 268435456 " X: 0 + catch /^var3$/ + Xpath 536870912 " X: 536870912 + endtry + + let addpath = "" + + function ADDPATH(p) + let g:addpath = g:addpath . a:p + endfunction + + try + call ADDPATH("T1") + let var{THROW("var4")} var{ADDPATH("T2")} | call ADDPATH("T3") + call ADDPATH("T4") + catch /^var4$/ + call ADDPATH("T5") + endtry + + try + call ADDPATH("T6") + unlet var{THROW("var5")} var{ADDPATH("T7")} | call ADDPATH("T8") + call ADDPATH("T9") + catch /^var5$/ + call ADDPATH("T10") + endtry + + if addpath != "T1T5T6T10" || throwcount != 11 + throw "addpath: " . addpath . ", throwcount: " . throwcount + endif + + Xpath 1073741824 " X: 1073741824 + +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +unlet! var1 var2 var3 addpath throwcount +delfunction THROW + +Xcheck 1789569365 + + +"------------------------------------------------------------------------------- +" Test 73: :throw across :function, :delfunction {{{1 +" +" The :function and :delfunction commands may cause an expression +" specified in braces to be evaluated. During evaluation, an +" exception might be thrown. The exception can be caught by the +" script. +"------------------------------------------------------------------------------- + +XpathINIT + +let taken = "" + +function! THROW(x, n) + let g:taken = g:taken . "T" . a:n + throw a:x +endfunction + +function! EXPR(x, n) + let g:taken = g:taken . "E" . a:n + if a:n % 2 == 0 + call THROW(a:x, a:n) + endif + return 2 - a:n % 2 +endfunction + +try + try + " Define function. + Xpath 1 " X: 1 + function! F0() + endfunction + Xpath 2 " X: 2 + function! F{EXPR("function-def-ok", 1)}() + endfunction + Xpath 4 " X: 4 + function! F{EXPR("function-def", 2)}() + endfunction + Xpath 8 " X: 0 + catch /^function-def-ok$/ + Xpath 16 " X: 0 + catch /^function-def$/ + Xpath 32 " X: 32 + catch /.*/ + Xpath 64 " X: 0 + Xout "def:" v:exception "in" v:throwpoint + endtry + + try + " List function. + Xpath 128 " X: 128 + function F0 + Xpath 256 " X: 256 + function F{EXPR("function-lst-ok", 3)} + Xpath 512 " X: 512 + function F{EXPR("function-lst", 4)} + Xpath 1024 " X: 0 + catch /^function-lst-ok$/ + Xpath 2048 " X: 0 + catch /^function-lst$/ + Xpath 4096 " X: 4096 + catch /.*/ + Xpath 8192 " X: 0 + Xout "lst:" v:exception "in" v:throwpoint + endtry + + try + " Delete function + Xpath 16384 " X: 16384 + delfunction F0 + Xpath 32768 " X: 32768 + delfunction F{EXPR("function-del-ok", 5)} + Xpath 65536 " X: 65536 + delfunction F{EXPR("function-del", 6)} + Xpath 131072 " X: 0 + catch /^function-del-ok$/ + Xpath 262144 " X: 0 + catch /^function-del$/ + Xpath 524288 " X: 524288 + catch /.*/ + Xpath 1048576 " X: 0 + Xout "del:" v:exception "in" v:throwpoint + endtry + + let expected = "E1E2T2E3E4T4E5E6T6" + if taken != expected + Xpath 2097152 " X: 0 + Xout "'taken' is" taken "instead of" expected + endif + +catch /.*/ + Xpath 4194304 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 8388608 " X: 8388608 + +unlet taken expected +delfunction THROW +delfunction EXPR + +Xcheck 9032615 + + +"------------------------------------------------------------------------------- +" Test 74: :throw across builtin functions and commands {{{1 +" +" Some functions like exists(), searchpair() take expression +" arguments, other functions or commands like substitute() or +" :substitute cause an expression (specified in the regular +" expression) to be evaluated. During evaluation an exception +" might be thrown. The exception can be caught by the script. +"------------------------------------------------------------------------------- + +XpathINIT + +let taken = "" + +function! THROW(x, n) + let g:taken = g:taken . "T" . a:n + throw a:x +endfunction + +function! EXPR(x, n) + let g:taken = g:taken . "E" . a:n + call THROW(a:x . a:n, a:n) + return "EXPR" +endfunction + +function! SKIP(x, n) + let g:taken = g:taken . "S" . a:n . "(" . line(".") + let theline = getline(".") + if theline =~ "skip" + let g:taken = g:taken . "s)" + return 1 + elseif theline =~ "throw" + let g:taken = g:taken . "t)" + call THROW(a:x . a:n, a:n) + else + let g:taken = g:taken . ")" + return 0 + endif +endfunction + +function! SUBST(x, n) + let g:taken = g:taken . "U" . a:n . "(" . line(".") + let theline = getline(".") + if theline =~ "not" " SUBST() should not be called for this line + let g:taken = g:taken . "n)" + call THROW(a:x . a:n, a:n) + elseif theline =~ "throw" + let g:taken = g:taken . "t)" + call THROW(a:x . a:n, a:n) + else + let g:taken = g:taken . ")" + return "replaced" + endif +endfunction + +try + try + Xpath 1 " X: 1 + let result = exists('*{EXPR("exists", 1)}') + Xpath 2 " X: 0 + catch /^exists1$/ + Xpath 4 " X: 4 + try + let result = exists('{EXPR("exists", 2)}') + Xpath 8 " X: 0 + catch /^exists2$/ + Xpath 16 " X: 16 + catch /.*/ + Xpath 32 " X: 0 + Xout "exists2:" v:exception "in" v:throwpoint + endtry + catch /.*/ + Xpath 64 " X: 0 + Xout "exists1:" v:exception "in" v:throwpoint + endtry + + try + let file = tempname() + exec "edit" file + insert +begin + xx +middle 3 + xx +middle 5 skip + xx +middle 7 throw + xx +end +. + normal! gg + Xpath 128 " X: 128 + let result = + \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 3)') + Xpath 256 " X: 256 + let result = + \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 4)') + Xpath 512 " X: 0 + let result = + \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 5)') + Xpath 1024 " X: 0 + catch /^searchpair[35]$/ + Xpath 2048 " X: 0 + catch /^searchpair4$/ + Xpath 4096 " X: 4096 + catch /.*/ + Xpath 8192 " X: 0 + Xout "searchpair:" v:exception "in" v:throwpoint + finally + bwipeout! + call delete(file) + endtry + + try + let file = tempname() + exec "edit" file + insert +subst 1 +subst 2 +not +subst 4 +subst throw +subst 6 +. + normal! gg + Xpath 16384 " X: 16384 + 1,2substitute/subst/\=SUBST("substitute", 6)/ + try + Xpath 32768 " X: 32768 + try + let v:errmsg = "" + 3substitute/subst/\=SUBST("substitute", 7)/ + finally + if v:errmsg != "" + " If exceptions are not thrown on errors, fake the error + " exception in order to get the same execution path. + throw "faked Vim(substitute)" + endif + endtry + catch /Vim(substitute)/ " Pattern not found ('e' flag missing) + Xpath 65536 " X: 65536 + 3substitute/subst/\=SUBST("substitute", 8)/e + Xpath 131072 " X: 131072 + endtry + Xpath 262144 " X: 262144 + 4,6substitute/subst/\=SUBST("substitute", 9)/ + Xpath 524288 " X: 0 + catch /^substitute[678]/ + Xpath 1048576 " X: 0 + catch /^substitute9/ + Xpath 2097152 " X: 2097152 + finally + bwipeout! + call delete(file) + endtry + + try + Xpath 4194304 " X: 4194304 + let var = substitute("sub", "sub", '\=THROW("substitute()y", 10)', '') + Xpath 8388608 " X: 0 + catch /substitute()y/ + Xpath 16777216 " X: 16777216 + catch /.*/ + Xpath 33554432 " X: 0 + Xout "substitute()y:" v:exception "in" v:throwpoint + endtry + + try + Xpath 67108864 " X: 67108864 + let var = substitute("not", "sub", '\=THROW("substitute()n", 11)', '') + Xpath 134217728 " X: 134217728 + catch /substitute()n/ + Xpath 268435456 " X: 0 + catch /.*/ + Xpath 536870912 " X: 0 + Xout "substitute()n:" v:exception "in" v:throwpoint + endtry + + let expected = "E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10" + if taken != expected + Xpath 1073741824 " X: 0 + Xout "'taken' is" taken "instead of" expected + endif + +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +unlet result var taken expected +delfunction THROW +delfunction EXPR +delfunction SKIP +delfunction SUBST + +Xcheck 224907669 + + +"------------------------------------------------------------------------------- +" Test 75: Errors in builtin functions. {{{1 +" +" On an error in a builtin function called inside a :try/:endtry +" region, the evaluation of the expression calling that function and +" the command containing that expression are abandoned. The error can +" be caught as an exception. +" +" A simple :call of the builtin function is a trivial case. If the +" builtin function is called in the argument list of another function, +" no further arguments are evaluated, and the other function is not +" executed. If the builtin function is called from the argument of +" a :return command, the :return command is not executed. If the +" builtin function is called from the argument of a :throw command, +" the :throw command is not executed. The evaluation of the +" expression calling the builtin function is abandoned. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F1(arg1) + Xpath 1 " X: 0 +endfunction + +function! F2(arg1, arg2) + Xpath 2 " X: 0 +endfunction + +function! G() + Xpath 4 " X: 0 +endfunction + +function! H() + Xpath 8 " X: 0 +endfunction + +function! R() + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 16 " X: 16 + return append(1, "s") + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 32 " X: 0 + finally + Xpath 64 " X: 64 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 128 " X: 128 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + Xpath 256 " X: 256 +endfunction + +try + set noma " let append() fail with "E21" + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 512 " X: 512 + call append(1, "s") + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 4096 " X: 4096 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 8192 " X: 8192 + call F1('x' . append(1, "s")) + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 16384 " X: 0 + finally + Xpath 32768 " X: 32768 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 65536 " X: 65536 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 131072 " X: 131072 + call F2('x' . append(1, "s"), G()) + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 262144 " X: 0 + finally + Xpath 524288 " X: 524288 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 1048576 " X: 1048576 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + call R() + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 2097152 " X: 2097152 + throw "T" . append(1, "s") + catch /E21/ + let caught = 1 + catch /^T.*/ + Xpath 4194304 " X: 0 + catch /.*/ + Xpath 8388608 " X: 0 + finally + Xpath 16777216 " X: 16777216 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 33554432 " X: 33554432 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 67108864 " X: 67108864 + let x = "a" + let x = x . "b" . append(1, "s") . H() + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 134217728 " X: 0 + finally + Xpath 268435456 " X: 268435456 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 536870912 " X: 536870912 + endif + if x == "a" + Xpath 1073741824 " X: 1073741824 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout v:exception "in" v:throwpoint +finally + set ma& +endtry + +unlet! caught x +delfunction F1 +delfunction F2 +delfunction G +delfunction H +delfunction R + +Xcheck 2000403408 + + +"------------------------------------------------------------------------------- +" Test 76: Errors, interrupts, :throw during expression evaluation {{{1 +" +" When a function call made during expression evaluation is aborted +" due to an error inside a :try/:endtry region or due to an interrupt +" or a :throw, the expression evaluation is aborted as well. No +" message is displayed for the cancelled expression evaluation. On an +" error not inside :try/:endtry, the expression evaluation continues. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + let taken = "" + + function! ERR(n) + let g:taken = g:taken . "E" . a:n + asdf + endfunction + + function! ERRabort(n) abort + let g:taken = g:taken . "A" . a:n + asdf + endfunction " returns -1; may cause follow-up msg for illegal var/func name + + function! WRAP(n, arg) + let g:taken = g:taken . "W" . a:n + let g:saved_errmsg = v:errmsg + return arg + endfunction + + function! INT(n) + let g:taken = g:taken . "I" . a:n + "INTERRUPT9 + let dummy = 0 + endfunction + + function! THR(n) + let g:taken = g:taken . "T" . a:n + throw "should not be caught" + endfunction + + function! CONT(n) + let g:taken = g:taken . "C" . a:n + endfunction + + function! MSG(n) + let g:taken = g:taken . "M" . a:n + let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg + let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf" + if errmsg !~ msgptn + let g:taken = g:taken . "x" + Xout "Expr" a:n.": Unexpected message:" v:errmsg + endif + let v:errmsg = "" + let g:saved_errmsg = "" + endfunction + + let v:errmsg = "" + + try + let t = 1 + XloopINIT 1 2 + while t <= 9 + Xloop 1 " X: 511 + try + if t == 1 + let v{ERR(t) + CONT(t)} = 0 + elseif t == 2 + let v{ERR(t) + CONT(t)} + elseif t == 3 + let var = exists('v{ERR(t) + CONT(t)}') + elseif t == 4 + unlet v{ERR(t) + CONT(t)} + elseif t == 5 + function F{ERR(t) + CONT(t)}() + endfunction + elseif t == 6 + function F{ERR(t) + CONT(t)} + elseif t == 7 + let var = exists('*F{ERR(t) + CONT(t)}') + elseif t == 8 + delfunction F{ERR(t) + CONT(t)} + elseif t == 9 + let var = ERR(t) + CONT(t) + endif + catch /asdf/ + " v:errmsg is not set when the error message is converted to an + " exception. Set it to the original error message. + let v:errmsg = substitute(v:exception, '^Vim:', '', "") + catch /^Vim\((\a\+)\)\=:/ + " An error exception has been thrown after the original error. + let v:errmsg = "" + finally + call MSG(t) + let t = t + 1 + XloopNEXT + continue " discard an aborting error + endtry + endwhile + catch /.*/ + Xpath 512 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + + try + let t = 10 + XloopINIT 1024 2 + while t <= 18 + Xloop 1 " X: 1024 * 511 + try + if t == 10 + let v{INT(t) + CONT(t)} = 0 + elseif t == 11 + let v{INT(t) + CONT(t)} + elseif t == 12 + let var = exists('v{INT(t) + CONT(t)}') + elseif t == 13 + unlet v{INT(t) + CONT(t)} + elseif t == 14 + function F{INT(t) + CONT(t)}() + endfunction + elseif t == 15 + function F{INT(t) + CONT(t)} + elseif t == 16 + let var = exists('*F{INT(t) + CONT(t)}') + elseif t == 17 + delfunction F{INT(t) + CONT(t)} + elseif t == 18 + let var = INT(t) + CONT(t) + endif + catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/ + " An error exception has been triggered after the interrupt. + let v:errmsg = substitute(v:exception, + \ '^Vim\((\a\+)\)\=:', '', "") + finally + call MSG(t) + let t = t + 1 + XloopNEXT + continue " discard interrupt + endtry + endwhile + catch /.*/ + Xpath 524288 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + + try + let t = 19 + XloopINIT 1048576 2 + while t <= 27 + Xloop 1 " X: 1048576 * 511 + try + if t == 19 + let v{THR(t) + CONT(t)} = 0 + elseif t == 20 + let v{THR(t) + CONT(t)} + elseif t == 21 + let var = exists('v{THR(t) + CONT(t)}') + elseif t == 22 + unlet v{THR(t) + CONT(t)} + elseif t == 23 + function F{THR(t) + CONT(t)}() + endfunction + elseif t == 24 + function F{THR(t) + CONT(t)} + elseif t == 25 + let var = exists('*F{THR(t) + CONT(t)}') + elseif t == 26 + delfunction F{THR(t) + CONT(t)} + elseif t == 27 + let var = THR(t) + CONT(t) + endif + catch /^Vim\((\a\+)\)\=:/ + " An error exception has been triggered after the :throw. + let v:errmsg = substitute(v:exception, + \ '^Vim\((\a\+)\)\=:', '', "") + finally + call MSG(t) + let t = t + 1 + XloopNEXT + continue " discard exception + endtry + endwhile + catch /.*/ + Xpath 536870912 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + + let v{ERR(28) + CONT(28)} = 0 + call MSG(28) + let v{ERR(29) + CONT(29)} + call MSG(29) + let var = exists('v{ERR(30) + CONT(30)}') + call MSG(30) + unlet v{ERR(31) + CONT(31)} + call MSG(31) + function F{ERR(32) + CONT(32)}() + endfunction + call MSG(32) + function F{ERR(33) + CONT(33)} + call MSG(33) + let var = exists('*F{ERR(34) + CONT(34)}') + call MSG(34) + delfunction F{ERR(35) + CONT(35)} + call MSG(35) + let var = ERR(36) + CONT(36) + call MSG(36) + + let saved_errmsg = "" + + let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0 + call MSG(37) + let v{WRAP(38, ERRabort(38)) + CONT(38)} + call MSG(38) + let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}') + call MSG(39) + unlet v{WRAP(40, ERRabort(40)) + CONT(40)} + call MSG(40) + function F{WRAP(41, ERRabort(41)) + CONT(41)}() + endfunction + call MSG(41) + function F{WRAP(42, ERRabort(42)) + CONT(42)} + call MSG(42) + let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}') + call MSG(43) + delfunction F{WRAP(44, ERRabort(44)) + CONT(44)} + call MSG(44) + let var = ERRabort(45) + CONT(45) + call MSG(45) + + Xpath 1073741824 " X: 1073741824 + + let expected = "" + \ . "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9" + \ . "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18" + \ . "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27" + \ . "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33" + \ . "E34C34M34E35C35M35E36C36M36" + \ . "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41" + \ . "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45" + + if taken != expected + " The Xpath command does not accept 2^31 (negative); display explicitly: + exec "!echo 2147483648 >>" . g:ExtraVimResult + " X: 0 + Xout "'taken' is" taken "instead of" expected + if substitute(taken, + \ '\(.*\)E3C3M3x\(.*\)E30C30M30x\(.*\)A39C39M39x\(.*\)', + \ '\1E3M3\2E30C30M30\3A39C39M39\4', + \ "") == expected + Xout "Is ++emsg_skip for var with expr_start non-NULL" + \ "in f_exists ok?" + endif + endif + + unlet! v var saved_errmsg taken expected + call delete(WA_t5) + call delete(WA_t14) + call delete(WA_t23) + unlet! WA_t5 WA_t14 WA_t23 + delfunction WA_t5 + delfunction WA_t14 + delfunction WA_t23 + +endif + +Xcheck 1610087935 + + +"------------------------------------------------------------------------------- +" Test 77: Errors, interrupts, :throw in name{brace-expression} {{{1 +" +" When a function call made during evaluation of an expression in +" braces as part of a function name after ":function" is aborted due +" to an error inside a :try/:endtry region or due to an interrupt or +" a :throw, the expression evaluation is aborted as well, and the +" function definition is ignored, skipping all commands to the +" ":endfunction". On an error not inside :try/:endtry, the expression +" evaluation continues and the function gets defined, and can be +" called and deleted. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT 1 4 + +function! ERR() abort + Xloop 1 " X: 1 + 4 + 16 + 64 + asdf +endfunction " returns -1 + +function! OK() + Xloop 2 " X: 2 * (1 + 4 + 16) + let v:errmsg = "" + return 0 +endfunction + +let v:errmsg = "" + +Xpath 4096 " X: 4096 +function! F{1 + ERR() + OK()}(arg) + " F0 should be defined. + if exists("a:arg") && a:arg == "calling" + Xpath 8192 " X: 8192 + else + Xpath 16384 " X: 0 + endif +endfunction +if v:errmsg != "" + Xpath 32768 " X: 0 +endif +XloopNEXT + +Xpath 65536 " X: 65536 +call F{1 + ERR() + OK()}("calling") +if v:errmsg != "" + Xpath 131072 " X: 0 +endif +XloopNEXT + +Xpath 262144 " X: 262144 +delfunction F{1 + ERR() + OK()} +if v:errmsg != "" + Xpath 524288 " X: 0 +endif +XloopNEXT + +try + while 1 + let caught = 0 + try + Xpath 1048576 " X: 1048576 + function! G{1 + ERR() + OK()}(arg) + " G0 should not be defined, and the function body should be + " skipped. + if exists("a:arg") && a:arg == "calling" + Xpath 2097152 " X: 0 + else + Xpath 4194304 " X: 0 + endif + " Use an unmatched ":finally" to check whether the body is + " skipped when an error occurs in ERR(). This works whether or + " not the exception is converted to an exception. + finally + Xpath 8388608 " X: 0 + Xout "Body of G{1 + ERR() + OK()}() not skipped" + " Discard the aborting error or exception, and break the + " while loop. + break + " End the try conditional and start a new one to avoid + " ":catch after :finally" errors. + endtry + try + Xpath 16777216 " X: 0 + endfunction + + " When the function was not defined, this won't be reached - whether + " the body was skipped or not. When the function was defined, it + " can be called and deleted here. + Xpath 33554432 " X: 0 + Xout "G0() has been defined" + XloopNEXT + try + call G{1 + ERR() + OK()}("calling") + catch /.*/ + Xpath 67108864 " X: 0 + endtry + Xpath 134217728 " X: 0 + XloopNEXT + try + delfunction G{1 + ERR() + OK()} + catch /.*/ + Xpath 268435456 " X: 0 + endtry + catch /asdf/ + " Jumped to when the function is not defined and the body is + " skipped. + let caught = 1 + catch /.*/ + Xpath 536870912 " X: 0 + finally + if !caught && !$VIMNOERRTHROW + Xpath 1073741824 " X: 0 + endif + break " discard error for $VIMNOERRTHROW + endtry " jumped to when the body is not skipped + endwhile +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout "Body of G{1 + ERR() + OK()}() not skipped, exception caught" + Xout v:exception "in" v:throwpoint +endtry + +Xcheck 1388671 + + +"------------------------------------------------------------------------------- +" Test 78: Messages on parsing errors in expression evaluation {{{1 +" +" When an expression evaluation detects a parsing error, an error +" message is given and converted to an exception, and the expression +" evaluation is aborted. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + let taken = "" + + function! F(n) + let g:taken = g:taken . "F" . a:n + endfunction + + function! MSG(n, enr, emsg) + let g:taken = g:taken . "M" . a:n + let english = v:lang == "C" || v:lang =~ '^[Ee]n' + if a:enr == "" + Xout "TODO: Add message number for:" a:emsg + let v:errmsg = ":" . v:errmsg + endif + if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) + if v:errmsg == "" + Xout "Expr" a:n.": Message missing." + let g:taken = g:taken . "x" + else + let v:errmsg = escape(v:errmsg, '"') + Xout "Expr" a:n.": Unexpected message:" v:errmsg + Xout "Expected: " . a:enr . ': ' . a:emsg + let g:taken = g:taken . "X" + endif + endif + endfunction + + function! CONT(n) + let g:taken = g:taken . "C" . a:n + endfunction + + let v:errmsg = "" + XloopINIT 1 2 + + try + let t = 1 + while t <= 14 + let g:taken = g:taken . "T" . t + let v:errmsg = "" + try + let caught = 0 + if t == 1 + let v{novar + CONT(t)} = 0 + elseif t == 2 + let v{novar + CONT(t)} + elseif t == 3 + let var = exists('v{novar + CONT(t)}') + elseif t == 4 + unlet v{novar + CONT(t)} + elseif t == 5 + function F{novar + CONT(t)}() + endfunction + elseif t == 6 + function F{novar + CONT(t)} + elseif t == 7 + let var = exists('*F{novar + CONT(t)}') + elseif t == 8 + delfunction F{novar + CONT(t)} + elseif t == 9 + echo novar + CONT(t) + elseif t == 10 + echo v{novar + CONT(t)} + elseif t == 11 + echo F{novar + CONT(t)} + elseif t == 12 + let var = novar + CONT(t) + elseif t == 13 + let var = v{novar + CONT(t)} + elseif t == 14 + let var = F{novar + CONT(t)}() + endif + catch /^Vim\((\a\+)\)\=:/ + " v:errmsg is not set when the error message is converted to an + " exception. Set it to the original error message. + let v:errmsg = substitute(v:exception, + \ '^Vim\((\a\+)\)\=:', '', "") + let caught = 1 + finally + if t <= 8 && t != 3 && t != 7 + call MSG(t, 'E475', 'Invalid argument\>') + else + if !caught " no error exceptions ($VIMNOERRTHROW set) + call MSG(t, 'E15', "Invalid expression") + else + call MSG(t, 'E121', "Undefined variable") + endif + endif + let t = t + 1 + XloopNEXT + continue " discard an aborting error + endtry + endwhile + catch /.*/ + Xloop 1 " X: 0 + Xout t.":" v:exception "in" ExtraVimThrowpoint() + endtry + + function! T(n, expr, enr, emsg) + try + let g:taken = g:taken . "T" . a:n + let v:errmsg = "" + try + let caught = 0 + execute "let var = " . a:expr + catch /^Vim\((\a\+)\)\=:/ + " v:errmsg is not set when the error message is converted to an + " exception. Set it to the original error message. + let v:errmsg = substitute(v:exception, + \ '^Vim\((\a\+)\)\=:', '', "") + let caught = 1 + finally + if !caught " no error exceptions ($VIMNOERRTHROW set) + call MSG(a:n, 'E15', "Invalid expression") + else + call MSG(a:n, a:enr, a:emsg) + endif + XloopNEXT + " Discard an aborting error: + return + endtry + catch /.*/ + Xloop 1 " X: 0 + Xout a:n.":" v:exception "in" ExtraVimThrowpoint() + endtry + endfunction + + call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function") + call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments") + call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments") + call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments") + call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'") + call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'") + call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression") + call T(22, '1 2 + CONT(22)', 'E15', "Invalid expression") + call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'") + call T(24, '("abc) + CONT(24)', 'E114', "Missing quote") + call T(25, "('abc) + CONT(25)", 'E115', "Missing quote") + call T(26, '& + CONT(26)', 'E112', "Option name missing") + call T(27, '&asdf + CONT(27)', 'E113', "Unknown option") + + Xpath 134217728 " X: 134217728 + + let expected = "" + \ . "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14" + \ . "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25" + \ . "T26M26T27M27" + + if taken != expected + Xpath 268435456 " X: 0 + Xout "'taken' is" taken "instead of" expected + if substitute(taken, '\(.*\)T3M3x\(.*\)', '\1T3M3\2', "") == expected + Xout "Is ++emsg_skip for var with expr_start non-NULL" + \ "in f_exists ok?" + endif + endif + + unlet! var caught taken expected + call delete(WA_t5) + unlet! WA_t5 + delfunction WA_t5 + +endif + +Xcheck 134217728 + + +"------------------------------------------------------------------------------- +" Test 79: Throwing one of several errors for the same command {{{1 +" +" When several errors appear in a row (for instance during expression +" evaluation), the first as the most specific one is used when +" throwing an error exception. If, however, a syntax error is +" detected afterwards, this one is used for the error exception. +" On a syntax error, the next command is not executed, on a normal +" error, however, it is (relevant only in a function without the +" "abort" flag). v:errmsg is not set. +" +" If throwing error exceptions is configured off, v:errmsg is always +" set to the latest error message, that is, to the more general +" message or the syntax error, respectively. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT 1 2 + +function! NEXT(cmd) + exec a:cmd . " | Xloop 1" +endfunction + +call NEXT('echo novar') " X: 1 * 1 (checks nextcmd) +XloopNEXT +call NEXT('let novar #') " X: 0 * 2 (skips nextcmd) +XloopNEXT +call NEXT('unlet novar #') " X: 0 * 4 (skips nextcmd) +XloopNEXT +call NEXT('let {novar}') " X: 0 * 8 (skips nextcmd) +XloopNEXT +call NEXT('unlet{ novar}') " X: 0 * 16 (skips nextcmd) + +function! EXEC(cmd) + exec a:cmd +endfunction + +function! MATCH(expected, msg, enr, emsg) + let msg = a:msg + if a:enr == "" + Xout "TODO: Add message number for:" a:emsg + let msg = ":" . msg + endif + let english = v:lang == "C" || v:lang =~ '^[Ee]n' + if msg !~ '^'.a:enr.':' || (english && msg !~ a:emsg) + let match = 0 + if a:expected " no match although expected + if a:msg == "" + Xout "Message missing." + else + let msg = escape(msg, '"') + Xout "Unexpected message:" msg + Xout "Expected:" a:enr . ": " . a:emsg + endif + endif + else + let match = 1 + if !a:expected " match although not expected + let msg = escape(msg, '"') + Xout "Unexpected message:" msg + Xout "Expected none." + endif + endif + return match +endfunction + +try + + while 1 " dummy loop + try + let v:errmsg = "" + let caught = 0 + let thrmsg = "" + call EXEC('echo novar') " normal error + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xpath 32 " X: 32 + if !caught + if !$VIMNOERRTHROW + Xpath 64 " X: 0 + endif + elseif !MATCH(1, thrmsg, 'E121', "Undefined variable") + \ || v:errmsg != "" + Xpath 128 " X: 0 + endif + if !caught && !MATCH(1, v:errmsg, 'E15', "Invalid expression") + Xpath 256 " X: 0 + endif + break " discard error if $VIMNOERRTHROW == 1 + endtry + endwhile + + Xpath 512 " X: 512 + let cmd = "let" + XloopINIT 1024 32 + while cmd != "" + try + let v:errmsg = "" + let caught = 0 + let thrmsg = "" + call EXEC(cmd . ' novar #') " normal plus syntax error + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xloop 1 " X: 1024 * (1 + 32) + if !caught + if !$VIMNOERRTHROW + Xloop 2 " X: 0 + endif + else + if cmd == "let" + let match = MATCH(0, thrmsg, 'E121', "Undefined variable") + elseif cmd == "unlet" + let match = MATCH(0, thrmsg, 'E108', "No such variable") + endif + if match " normal error + Xloop 4 " X: 0 + endif + if !MATCH(1, thrmsg, 'E488', "Trailing characters") + \|| v:errmsg != "" + " syntax error + Xloop 8 " X: 0 + endif + endif + if !caught && !MATCH(1, v:errmsg, 'E488', "Trailing characters") + " last error + Xloop 16 " X: 0 + endif + if cmd == "let" + let cmd = "unlet" + else + let cmd = "" + endif + XloopNEXT + continue " discard error if $VIMNOERRTHROW == 1 + endtry + endwhile + + Xpath 1048576 " X: 1048576 + let cmd = "let" + XloopINIT 2097152 32 + while cmd != "" + try + let v:errmsg = "" + let caught = 0 + let thrmsg = "" + call EXEC(cmd . ' {novar}') " normal plus syntax error + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xloop 1 " X: 2097152 * (1 + 32) + if !caught + if !$VIMNOERRTHROW + Xloop 2 " X: 0 + endif + else + if MATCH(0, thrmsg, 'E121', "Undefined variable") " normal error + Xloop 4 " X: 0 + endif + if !MATCH(1, thrmsg, 'E475', 'Invalid argument\>') + \ || v:errmsg != "" " syntax error + Xloop 8 " X: 0 + endif + endif + if !caught && !MATCH(1, v:errmsg, 'E475', 'Invalid argument\>') + " last error + Xloop 16 " X: 0 + endif + if cmd == "let" + let cmd = "unlet" + else + let cmd = "" + endif + XloopNEXT + continue " discard error if $VIMNOERRTHROW == 1 + endtry + endwhile + +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +unlet! next_command thrmsg match +delfunction NEXT +delfunction EXEC +delfunction MATCH + +Xcheck 70288929 + + +"------------------------------------------------------------------------------- +" Test 80: Syntax error in expression for illegal :elseif {{{1 +" +" If there is a syntax error in the expression after an illegal +" :elseif, an error message is given (or an error exception thrown) +" for the illegal :elseif rather than the expression error. +"------------------------------------------------------------------------------- + +XpathINIT + +function! MSG(enr, emsg) + let english = v:lang == "C" || v:lang =~ '^[Ee]n' + if a:enr == "" + Xout "TODO: Add message number for:" a:emsg + let v:errmsg = ":" . v:errmsg + endif + let match = 1 + if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) + let match = 0 + if v:errmsg == "" + Xout "Message missing." + else + let v:errmsg = escape(v:errmsg, '"') + Xout "Unexpected message:" v:errmsg + endif + endif + return match +endfunction + +let v:errmsg = "" +if 0 +else +elseif 1 ||| 2 +endif +Xpath 1 " X: 1 +if !MSG('E584', ":elseif after :else") + Xpath 2 " X: 0 +endif + +let v:errmsg = "" +if 1 +else +elseif 1 ||| 2 +endif +Xpath 4 " X: 4 +if !MSG('E584', ":elseif after :else") + Xpath 8 " X: 0 +endif + +let v:errmsg = "" +elseif 1 ||| 2 +Xpath 16 " X: 16 +if !MSG('E582', ":elseif without :if") + Xpath 32 " X: 0 +endif + +let v:errmsg = "" +while 1 + elseif 1 ||| 2 +endwhile +Xpath 64 " X: 64 +if !MSG('E582', ":elseif without :if") + Xpath 128 " X: 0 +endif + +while 1 + try + try + let v:errmsg = "" + let caught = 0 + if 0 + else + elseif 1 ||| 2 + endif + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xpath 256 " X: 256 + if !caught && !$VIMNOERRTHROW + Xpath 512 " X: 0 + endif + if !MSG('E584', ":elseif after :else") + Xpath 1024 " X: 0 + endif + endtry + catch /.*/ + Xpath 2048 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let v:errmsg = "" + let caught = 0 + if 1 + else + elseif 1 ||| 2 + endif + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xpath 4096 " X: 4096 + if !caught && !$VIMNOERRTHROW + Xpath 8192 " X: 0 + endif + if !MSG('E584', ":elseif after :else") + Xpath 16384 " X: 0 + endif + endtry + catch /.*/ + Xpath 32768 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let v:errmsg = "" + let caught = 0 + elseif 1 ||| 2 + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xpath 65536 " X: 65536 + if !caught && !$VIMNOERRTHROW + Xpath 131072 " X: 0 + endif + if !MSG('E582', ":elseif without :if") + Xpath 262144 " X: 0 + endif + endtry + catch /.*/ + Xpath 524288 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let v:errmsg = "" + let caught = 0 + while 1 + elseif 1 ||| 2 + endwhile + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xpath 1048576 " X: 1048576 + if !caught && !$VIMNOERRTHROW + Xpath 2097152 " X: 0 + endif + if !MSG('E582', ":elseif without :if") + Xpath 4194304 " X: 0 + endif + endtry + catch /.*/ + Xpath 8388608 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +Xpath 16777216 " X: 16777216 + +unlet! caught +delfunction MSG + +Xcheck 17895765 + + +"------------------------------------------------------------------------------- +" Test 81: Discarding exceptions after an error or interrupt {{{1 +" +" When an exception is thrown from inside a :try conditional without +" :catch and :finally clauses and an error or interrupt occurs before +" the :endtry is reached, the exception is discarded. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + try + Xpath 1 " X: 1 + try + Xpath 2 " X: 2 + throw "arrgh" + Xpath 4 " X: 0 +" if 1 + Xpath 8 " X: 0 + " error after :throw: missing :endif + endtry + Xpath 16 " X: 0 + catch /arrgh/ + Xpath 32 " X: 0 + endtry + Xpath 64 " X: 0 +endif + +if ExtraVim() + try + Xpath 128 " X: 128 + try + Xpath 256 " X: 256 + throw "arrgh" + Xpath 512 " X: 0 + endtry " INTERRUPT + Xpath 1024 " X: 0 + catch /arrgh/ + Xpath 2048 " X: 0 + endtry + Xpath 4096 " X: 0 +endif + +Xcheck 387 + + +"------------------------------------------------------------------------------- +" Test 82: Ignoring :catch clauses after an error or interrupt {{{1 +" +" When an exception is thrown and an error or interrupt occurs before +" the matching :catch clause is reached, the exception is discarded +" and the :catch clause is ignored (also for the error or interrupt +" exception being thrown then). +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + try + try + Xpath 1 " X: 1 + throw "arrgh" + Xpath 2 " X: 0 +" if 1 + Xpath 4 " X: 0 + " error after :throw: missing :endif + catch /.*/ + Xpath 8 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + catch /.*/ + Xpath 16 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + Xpath 32 " X: 0 + catch /arrgh/ + Xpath 64 " X: 0 + endtry + Xpath 128 " X: 0 +endif + +if ExtraVim() + function! E() + try + try + Xpath 256 " X: 256 + throw "arrgh" + Xpath 512 " X: 0 +" if 1 + Xpath 1024 " X: 0 + " error after :throw: missing :endif + catch /.*/ + Xpath 2048 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + catch /.*/ + Xpath 4096 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + Xpath 8192 " X: 0 + catch /arrgh/ + Xpath 16384 " X: 0 + endtry + endfunction + + call E() + Xpath 32768 " X: 0 +endif + +if ExtraVim() + try + try + Xpath 65536 " X: 65536 + throw "arrgh" + Xpath 131072 " X: 0 + catch /.*/ "INTERRUPT + Xpath 262144 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + catch /.*/ + Xpath 524288 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + Xpath 1048576 " X: 0 + catch /arrgh/ + Xpath 2097152 " X: 0 + endtry + Xpath 4194304 " X: 0 +endif + +if ExtraVim() + function I() + try + try + Xpath 8388608 " X: 8388608 + throw "arrgh" + Xpath 16777216 " X: 0 + catch /.*/ "INTERRUPT + Xpath 33554432 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + catch /.*/ + Xpath 67108864 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + Xpath 134217728 " X: 0 + catch /arrgh/ + Xpath 268435456 " X: 0 + endtry + endfunction + + call I() + Xpath 536870912 " X: 0 +endif + +Xcheck 8454401 + + +"------------------------------------------------------------------------------- +" Test 83: Executing :finally clauses after an error or interrupt {{{1 +" +" When an exception is thrown and an error or interrupt occurs before +" the :finally of the innermost :try is reached, the exception is +" discarded and the :finally clause is executed. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + try + Xpath 1 " X: 1 + try + Xpath 2 " X: 2 + throw "arrgh" + Xpath 4 " X: 0 +" if 1 + Xpath 8 " X: 0 + " error after :throw: missing :endif + finally + Xpath 16 " X: 16 + endtry + Xpath 32 " X: 0 + catch /arrgh/ + Xpath 64 " X: 0 + endtry + Xpath 128 " X: 0 +endif + +if ExtraVim() + try + Xpath 256 " X: 256 + try + Xpath 512 " X: 512 + throw "arrgh" + Xpath 1024 " X: 0 + finally "INTERRUPT + Xpath 2048 " X: 2048 + endtry + Xpath 4096 " X: 0 + catch /arrgh/ + Xpath 8192 " X: 0 + endtry + Xpath 16384 " X: 0 +endif + +Xcheck 2835 + + +"------------------------------------------------------------------------------- +" Test 84: Exceptions in autocommand sequences. {{{1 +" +" When an exception occurs in a sequence of autocommands for +" a specific event, the rest of the sequence is not executed. The +" command that triggered the autocommand execution aborts, and the +" exception is propagated to the caller. +" +" For the FuncUndefined event under a function call expression or +" :call command, the function is not executed, even when it has +" been defined by the autocommands before the exception occurred. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + function! INT() + "INTERRUPT + let dummy = 0 + endfunction + + aug TMP + autocmd! + + autocmd User x1 Xpath 1 " X: 1 + autocmd User x1 throw "x1" + autocmd User x1 Xpath 2 " X: 0 + + autocmd User x2 Xpath 4 " X: 4 + autocmd User x2 asdf + autocmd User x2 Xpath 8 " X: 0 + + autocmd User x3 Xpath 16 " X: 16 + autocmd User x3 call INT() + autocmd User x3 Xpath 32 " X: 0 + + autocmd FuncUndefined U1 function! U1() + autocmd FuncUndefined U1 Xpath 64 " X: 0 + autocmd FuncUndefined U1 endfunction + autocmd FuncUndefined U1 Xpath 128 " X: 128 + autocmd FuncUndefined U1 throw "U1" + autocmd FuncUndefined U1 Xpath 256 " X: 0 + + autocmd FuncUndefined U2 function! U2() + autocmd FuncUndefined U2 Xpath 512 " X: 0 + autocmd FuncUndefined U2 endfunction + autocmd FuncUndefined U2 Xpath 1024 " X: 1024 + autocmd FuncUndefined U2 ASDF + autocmd FuncUndefined U2 Xpath 2048 " X: 0 + + autocmd FuncUndefined U3 function! U3() + autocmd FuncUndefined U3 Xpath 4096 " X: 0 + autocmd FuncUndefined U3 endfunction + autocmd FuncUndefined U3 Xpath 8192 " X: 8192 + autocmd FuncUndefined U3 call INT() + autocmd FuncUndefined U3 Xpath 16384 " X: 0 + aug END + + try + try + Xpath 32768 " X: 32768 + doautocmd User x1 + catch /x1/ + Xpath 65536 " X: 65536 + endtry + + while 1 + try + Xpath 131072 " X: 131072 + let caught = 0 + doautocmd User x2 + catch /asdf/ + let caught = 1 + finally + Xpath 262144 " X: 262144 + if !caught && !$VIMNOERRTHROW + Xpath 524288 " X: 0 + " Propagate uncaught error exception, + else + " ... but break loop for caught error exception, + " or discard error and break loop if $VIMNOERRTHROW + break + endif + endtry + endwhile + + while 1 + try + Xpath 1048576 " X: 1048576 + let caught = 0 + doautocmd User x3 + catch /Vim:Interrupt/ + let caught = 1 + finally + Xpath 2097152 " X: 2097152 + if !caught && !$VIMNOINTTHROW + Xpath 4194304 " X: 0 + " Propagate uncaught interrupt exception, + else + " ... but break loop for caught interrupt exception, + " or discard interrupt and break loop if $VIMNOINTTHROW + break + endif + endtry + endwhile + + if exists("*U1") | delfunction U1 | endif + if exists("*U2") | delfunction U2 | endif + if exists("*U3") | delfunction U3 | endif + + try + Xpath 8388608 " X: 8388608 + call U1() + catch /U1/ + Xpath 16777216 " X: 16777216 + endtry + + while 1 + try + Xpath 33554432 " X: 33554432 + let caught = 0 + call U2() + catch /ASDF/ + let caught = 1 + finally + Xpath 67108864 " X: 67108864 + if !caught && !$VIMNOERRTHROW + Xpath 134217728 " X: 0 + " Propagate uncaught error exception, + else + " ... but break loop for caught error exception, + " or discard error and break loop if $VIMNOERRTHROW + break + endif + endtry + endwhile + + while 1 + try + Xpath 268435456 " X: 268435456 + let caught = 0 + call U3() + catch /Vim:Interrupt/ + let caught = 1 + finally + Xpath 536870912 " X: 536870912 + if !caught && !$VIMNOINTTHROW + Xpath 1073741824 " X: 0 + " Propagate uncaught interrupt exception, + else + " ... but break loop for caught interrupt exception, + " or discard interrupt and break loop if $VIMNOINTTHROW + break + endif + endtry + endwhile + catch /.*/ + " The Xpath command does not accept 2^31 (negative); display explicitly: + exec "!echo 2147483648 >>" . g:ExtraVimResult + Xout "Caught" v:exception "in" v:throwpoint + endtry + + unlet caught + delfunction INT + delfunction U1 + delfunction U2 + delfunction U3 + au! TMP + aug! TMP +endif + +Xcheck 934782101 + + +"------------------------------------------------------------------------------- +" Test 85: Error exceptions in autocommands for I/O command events {{{1 +" +" When an I/O command is inside :try/:endtry, autocommands to be +" executed after it should be skipped on an error (exception) in the +" command itself or in autocommands to be executed before the command. +" In the latter case, the I/O command should not be executed either. +" Example 1: BufWritePre, :write, BufWritePost +" Example 2: FileReadPre, :read, FileReadPost. +"------------------------------------------------------------------------------- + +XpathINIT + +function! MSG(enr, emsg) + let english = v:lang == "C" || v:lang =~ '^[Ee]n' + if a:enr == "" + Xout "TODO: Add message number for:" a:emsg + let v:errmsg = ":" . v:errmsg + endif + let match = 1 + if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) + let match = 0 + if v:errmsg == "" + Xout "Message missing." + else + let v:errmsg = escape(v:errmsg, '"') + Xout "Unexpected message:" v:errmsg + endif + endif + return match +endfunction + +" Remove the autocommands for the events specified as arguments in all used +" autogroups. +function! Delete_autocommands(...) + let augfile = tempname() + while 1 + try + exec "redir >" . augfile + aug + redir END + exec "edit" augfile + g/^$/d + norm G$ + let wrap = "w" + while search('\%( \|^\)\@<=.\{-}\%( \)\@=', wrap) > 0 + let wrap = "W" + exec "norm y/ \n" + let argno = 1 + while argno <= a:0 + exec "au!" escape(@", " ") a:{argno} + let argno = argno + 1 + endwhile + endwhile + catch /.*/ + finally + bwipeout! + call delete(augfile) + break " discard errors for $VIMNOERRTHROW + endtry + endwhile +endfunction + +call Delete_autocommands("BufWritePre", "BufWritePost") + +while 1 + try + try + let post = 0 + aug TMP + au! BufWritePost * let post = 1 + aug END + let caught = 0 + write /n/o/n/e/x/i/s/t/e/n/t + catch /^Vim(write):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(write):', '', "") + finally + Xpath 1 " X: 1 + if !caught && !$VIMNOERRTHROW + Xpath 2 " X: 0 + endif + let v:errmsg = substitute(v:errmsg, '^"/n/o/n/e/x/i/s/t/e/n/t" ', + \ '', "") + if !MSG('E212', "Can't open file for writing") + Xpath 4 " X: 0 + endif + if post + Xpath 8 " X: 0 + Xout "BufWritePost commands executed after write error" + endif + au! TMP + aug! TMP + endtry + catch /.*/ + Xpath 16 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let post = 0 + aug TMP + au! BufWritePre * asdf + au! BufWritePost * let post = 1 + aug END + let tmpfile = tempname() + let caught = 0 + exec "write" tmpfile + catch /^Vim\((write)\)\=:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim\((write)\)\=:', '', "") + finally + Xpath 32 " X: 32 + if !caught && !$VIMNOERRTHROW + Xpath 64 " X: 0 + endif + let v:errmsg = substitute(v:errmsg, '^"'.tmpfile.'" ', '', "") + if !MSG('E492', "Not an editor command") + Xpath 128 " X: 0 + endif + if filereadable(tmpfile) + Xpath 256 " X: 0 + Xout ":write command not suppressed after BufWritePre error" + endif + if post + Xpath 512 " X: 0 + Xout "BufWritePost commands executed after BufWritePre error" + endif + au! TMP + aug! TMP + endtry + catch /.*/ + Xpath 1024 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +call delete(tmpfile) + +call Delete_autocommands("BufWritePre", "BufWritePost", + \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost") + +while 1 + try + try + let post = 0 + aug TMP + au! FileReadPost * let post = 1 + aug END + let caught = 0 + read /n/o/n/e/x/i/s/t/e/n/t + catch /^Vim(read):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(read):', '', "") + finally + Xpath 2048 " X: 2048 + if !caught && !$VIMNOERRTHROW + Xpath 4096 " X: 0 + endif + let v:errmsg = substitute(v:errmsg, ' /n/o/n/e/x/i/s/t/e/n/t$', + \ '', "") + if !MSG('E484', "Can't open file") + Xpath 8192 " X: 0 + endif + if post + Xpath 16384 " X: 0 + Xout "FileReadPost commands executed after write error" + endif + au! TMP + aug! TMP + endtry + catch /.*/ + Xpath 32768 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + let infile = tempname() + let tmpfile = tempname() + exec "!echo XYZ >" . infile + exec "edit" tmpfile + try + Xpath 65536 " X: 65536 + try + let post = 0 + aug TMP + au! FileReadPre * asdf + au! FileReadPost * let post = 1 + aug END + let caught = 0 + exec "0read" infile + catch /^Vim\((read)\)\=:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim\((read)\)\=:', '', + \ "") + finally + Xpath 131072 " X: 131072 + if !caught && !$VIMNOERRTHROW + Xpath 262144 " X: 0 + endif + let v:errmsg = substitute(v:errmsg, ' '.infile.'$', '', "") + if !MSG('E492', "Not an editor command") + Xpath 524288 " X: 0 + endif + if getline("1") == "XYZ" + Xpath 1048576 " X: 0 + Xout ":read command not suppressed after FileReadPre error" + endif + if post + Xpath 2097152 " X: 0 + Xout "FileReadPost commands executed after " . + \ "FileReadPre error" + endif + au! TMP + aug! TMP + endtry + finally + bwipeout! + endtry + catch /.*/ + Xpath 4194304 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +call delete(infile) +call delete(tmpfile) +unlet! caught post infile tmpfile +delfunction MSG +delfunction Delete_autocommands + +Xcheck 198689 + +"------------------------------------------------------------------------------- +" Test 86: setloclist crash {{{1 +" +" Executing a setloclist() on BufUnload shouldn't crash Vim +"------------------------------------------------------------------------------- + +func F + au BufUnload * :call setloclist(0, [{'bufnr':1, 'lnum':1, 'col':1, 'text': 'tango down'}]) + + :lvimgrep /.*/ *.mak +endfunc + +XpathINIT + +ExecAsScript F + +delfunction F +Xout "No Crash for vimgrep on BufUnload" +Xcheck 0 + +"------------------------------------------------------------------------------- +" Test 87 using (expr) ? funcref : funcref {{{1 +" +" Vim needs to correctly parse the funcref and even when it does +" not execute the funcref, it needs to consume the trailing () +"------------------------------------------------------------------------------- + +XpathINIT + +func Add2(x1, x2) + return a:x1 + a:x2 +endfu + +func GetStr() + return "abcdefghijklmnopqrstuvwxyp" +endfu + +echo function('Add2')(2,3) + +Xout 1 ? function('Add2')(1,2) : function('Add2')(2,3) +Xout 0 ? function('Add2')(1,2) : function('Add2')(2,3) +" Make sure, GetStr() still works. +Xout GetStr()[0:10] + + +delfunction GetStr +delfunction Add2 +Xout "Successfully executed funcref Add2" + +Xcheck 0 + +"------------------------------------------------------------------------------- +" Test 88: $VIMNOERRTHROW and $VIMNOINTTHROW support {{{1 +" +" It is possible to configure Vim for throwing exceptions on error +" or interrupt, controlled by variables $VIMNOERRTHROW and +" $VIMNOINTTHROW. This is just for increasing the number of tests. +" All tests here should run for all four combinations of setting +" these variables to 0 or 1. The variables are intended for the +" development phase only. In the final release, Vim should be +" configured to always use error and interrupt exceptions. +" +" The test result is "OK", +" +" - if the $VIMNOERRTHROW and the $VIMNOINTTHROW control are not +" configured and exceptions are thrown on error and on +" interrupt. +" +" - if the $VIMNOERRTHROW or the $VIMNOINTTHROW control is +" configured and works as intended. +" +" What actually happens, is shown in the test output. +" +" Otherwise, the test result is "FAIL", and the test output describes +" the problem. +" +" IMPORTANT: This must be the last test because it sets $VIMNOERRTHROW and +" $VIMNOINTTHROW. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + function! ThrowOnError() + XloopNEXT + let caught = 0 + try + Xloop 1 " X: 1 + 8 + 64 + asdf + catch /.*/ + let caught = 1 " error exception caught + finally + Xloop 2 " X: 2 + 16 + 128 + return caught " discard aborting error + endtry + Xloop 4 " X: 0 + endfunction + + let quits_skipped = 0 + + function! ThrowOnInterrupt() + XloopNEXT + let caught = 0 + try + Xloop 1 " X: (1 + 8 + 64) * 512 + "INTERRUPT3 + let dummy = 0 + let g:quits_skipped = g:quits_skipped + 1 + catch /.*/ + let caught = 1 " interrupt exception caught + finally + Xloop 2 " X: (2 + 16 + 128) * 512 + return caught " discard interrupt + endtry + Xloop 4 " X: 0 + endfunction + + function! CheckThrow(Type) + execute 'return ThrowOn' . a:Type . '()' + endfunction + + function! CheckConfiguration(type) " type is "error" or "interrupt" + + let type = a:type + let Type = substitute(type, '.*', '\u&', "") + let VAR = '$VIMNO' . substitute(type, '\(...\).*', '\U\1', "") . 'THROW' + + if type == "error" + XloopINIT! 1 8 + elseif type == "interrupt" + XloopINIT! 512 8 + endif + + exec 'let requested_for_tests = exists(VAR) && ' . VAR . ' == 0' + exec 'let suppressed_for_tests = ' . VAR . ' != 0' + let used_in_tests = CheckThrow(Type) + + exec 'let ' . VAR . ' = 0' + let request_works = CheckThrow(Type) + + exec 'let ' . VAR . ' = 1' + let suppress_works = !CheckThrow(Type) + + if type == "error" + XloopINIT! 262144 8 + elseif type == "interrupt" + XloopINIT! 2097152 8 + + if g:quits_skipped != 0 + Xloop 1 " X: 0*2097152 + Xout "Test environment error. Interrupt breakpoints skipped: " + \ . g:quits_skipped . ".\n" + \ . "Cannot check whether interrupt exceptions are thrown." + return + endif + endif + + let failure = + \ !suppressed_for_tests && !used_in_tests + \ || !request_works + + let contradiction = + \ used_in_tests + \ ? suppressed_for_tests && !request_works + \ : !suppressed_for_tests + + if failure + " Failure in configuration. + Xloop 2 " X: 0 * 2* (262144 + 2097152) + elseif contradiction + " Failure in test logic. Should not happen. + Xloop 4 " X: 0 * 4 * (262144 + 2097152) + endif + + let var_control_configured = + \ request_works != used_in_tests + \ || suppress_works == used_in_tests + + let var_control_not_configured = + \ requested_for_tests || suppressed_for_tests + \ ? request_works && !suppress_works + \ : request_works == used_in_tests + \ && suppress_works != used_in_tests + + let with = used_in_tests ? "with" : "without" + + let set = suppressed_for_tests ? "non-zero" : + \ requested_for_tests ? "0" : "unset" + + let although = contradiction && !var_control_not_configured + \ ? ",\nalthough " + \ : ".\n" + + let output = "All tests were run " . with . " throwing exceptions on " + \ . type . although + + if !var_control_not_configured + let output = output . VAR . " was " . set . "." + + if !request_works && !requested_for_tests + let output = output . + \ "\n" . Type . " exceptions are not thrown when " . VAR . + \ " is\nset to 0." + endif + + if !suppress_works && (!used_in_tests || + \ !request_works && + \ !requested_for_tests && !suppressed_for_tests) + let output = output . + \ "\n" . Type . " exceptions are thrown when " . VAR . + \ " is set to 1." + endif + + if !failure && var_control_configured + let output = output . + \ "\nRun tests also with " . substitute(VAR, '^\$', '', "") + \ . "=" . used_in_tests . "." + \ . "\nThis is for testing in the development phase only." + \ . " Remove the \n" + \ . VAR . " control in the final release." + endif + else + let output = output . + \ "The " . VAR . " control is not configured." + endif + + Xout output + endfunction + + call CheckConfiguration("error") + Xpath 16777216 " X: 16777216 + call CheckConfiguration("interrupt") + Xpath 33554432 " X: 33554432 +endif + +Xcheck 50443995 + +" IMPORTANT: No test should be added after this test because it changes +" $VIMNOERRTHROW and $VIMNOINTTHROW. + + +"------------------------------------------------------------------------------- +" Modelines {{{1 +" vim: ts=8 sw=4 tw=80 fdm=marker +" vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "") +"------------------------------------------------------------------------------- diff --git a/src/nvim/testdir/test5.in b/src/nvim/testdir/test5.in new file mode 100644 index 0000000000..e19e20d59b --- /dev/null +++ b/src/nvim/testdir/test5.in @@ -0,0 +1,29 @@ +Test for autocommand that deletes the current buffer on BufLeave event. +Also test deleting the last buffer, should give a new, empty buffer. + +STARTTEST +:so small.vim +:au BufLeave Xxx bwipe +/start of +:.,/end of/w! Xxx " write test file Xxx +:sp Xxx " split to Xxx +:bwipe " delete buffer Xxx, now we're back here +G?this is a +othis is some more text +: " Append some text to this file +:?start?,$w! test.out " Write current file contents +:bwipe test.out " delete alternate buffer +:au bufleave test5.in bwipe +:bwipe! " delete current buffer, get an empty one +ithis is another test line:w >>test.out +: " append an extra line to the output file +:qa! +ENDTEST + +start of test file Xxx +vim: set noai : + this is a test + this is a test + this is a test + this is a test +end of test file Xxx diff --git a/src/nvim/testdir/test5.ok b/src/nvim/testdir/test5.ok new file mode 100644 index 0000000000..6743060794 --- /dev/null +++ b/src/nvim/testdir/test5.ok @@ -0,0 +1,9 @@ +start of test file Xxx +vim: set noai : + this is a test + this is a test + this is a test + this is a test +this is some more text +end of test file Xxx +this is another test line diff --git a/src/nvim/testdir/test50.in b/src/nvim/testdir/test50.in new file mode 100644 index 0000000000..0cbf4bf6d6 --- /dev/null +++ b/src/nvim/testdir/test50.in @@ -0,0 +1,90 @@ +Test for shortpathname ':8' extension. +Only for use on Win32 systems! + +STARTTEST +:so small.vim +:fun! TestIt(file, bits, expected) + let res=fnamemodify(a:file,a:bits) + if a:expected == '' + echo "'".a:file."'->(".a:bits.")->'".res."'" + else + if substitute(res,'/','\\', 'g') != substitute( a:expected, '/','\\', 'g') + echo "FAILED: '".a:file."'->(".a:bits.")->'".res."'" + echo "Expected: '".a:expected."'" + else + echo "OK" + endif + endif +endfun +:fun! MakeDir( dirname ) + "exe '!mkdir '.substitute(a:dirname,'/','\\','g') + call system('mkdir '.substitute(a:dirname,'/','\\','g')) +endfun +:fun! RMDir( dirname) + "exe '!rmdir '.substitute(a:dirname,'/','\\','g') + call system('rmdir '.substitute(a:dirname,'/','\\','g')) +endfun +:fun! MakeFile( filename) + "exe '!copy nul '.substitute(a:filename,'/','\\','g') + call system('copy nul '.substitute(a:filename,'/','\\','g')) +endfun +:fun! TestColonEight() + redir! >test.out + " This could change for CygWin to //cygdrive/c + let dir1='c:/x.x.y' + if filereadable(dir1) || isdirectory(dir1) + echo "FATAL: '".dir1."' exists, cannot run test" + return + endif + let file1=dir1.'/zz.y.txt' + let nofile1=dir1.'/z.y.txt' + let dir2=dir1.'/VimIsTheGreatestSinceSlicedBread' + let file2=dir2.'/z.txt' + let nofile2=dir2.'/zz.txt' + call MakeDir( dir1 ) + let resdir1 = substitute(fnamemodify(dir1, ':p:8'), '\\$', '', '') + if resdir1 !~ '\V\^c:/XX\x\x\x\x~1.Y\$' + echo "FATAL: unexpected short name: " . resdir1 + echo "INFO: please report your OS to vim-dev" + return + endif + let resfile1=resdir1.'/ZZY~1.TXT' + let resnofile1=resdir1.'/z.y.txt' + let resdir2=resdir1.'/VIMIST~1' + let resfile2=resdir2.'/z.txt' + let resnofile2=resdir2.'/zz.txt' + call MakeDir( dir2 ) + call MakeFile( file1 ) + call MakeFile( file2 ) + call TestIt(file1, ':p:8', resfile1) + call TestIt(nofile1, ':p:8', resnofile1) + call TestIt(file2, ':p:8', resfile2) + call TestIt(nofile2, ':p:8', resnofile2) + call TestIt(nofile2, ':p:8:h', fnamemodify(resnofile2,':h')) + exe 'cd '.dir1 + call TestIt(file1, ':.:8', strpart(resfile1,strlen(resdir1)+1)) + call TestIt(nofile1, ':.:8', strpart(resnofile1,strlen(resdir1)+1)) + call TestIt(file2, ':.:8', strpart(resfile2,strlen(resdir1)+1)) + call TestIt(nofile2, ':.:8', strpart(resnofile2,strlen(resdir1)+1)) + let $HOME=dir1 + call TestIt(file1, ':~:8', '~'.strpart(resfile1,strlen(resdir1))) + call TestIt(nofile1, ':~:8', '~'.strpart(resnofile1,strlen(resdir1))) + call TestIt(file2, ':~:8', '~'.strpart(resfile2,strlen(resdir1))) + call TestIt(nofile2, ':~:8', '~'.strpart(resnofile2,strlen(resdir1))) + cd c:/ + call delete( file2 ) + call delete( file1 ) + call RMDir( dir2 ) + call RMDir( dir1 ) + echo + redir END +endfun +:let dir = getcwd() +:call TestColonEight() +:exe "cd " . dir +:edit! test.out +:set ff=dos +:w +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test50.ok b/src/nvim/testdir/test50.ok new file mode 100644 index 0000000000..91ef1d6604 --- /dev/null +++ b/src/nvim/testdir/test50.ok @@ -0,0 +1,14 @@ + +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK diff --git a/src/nvim/testdir/test51.in b/src/nvim/testdir/test51.in new file mode 100644 index 0000000000..b4f45d1f75 --- /dev/null +++ b/src/nvim/testdir/test51.in @@ -0,0 +1,36 @@ +Tests for ":highlight". vim: set ft=vim : + +STARTTEST +:so small.vim +:" basic test if ":highlight" doesn't crash +:highlight +:hi Search +:" test setting colors. +:" test clearing one color and all doesn't generate error or warning +:hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan +:hi Group2 term= cterm= +:hi Group3 term=underline cterm=bold +:redir! >test.out +:hi NewGroup +:hi Group2 +:hi Group3 +:hi clear NewGroup +:hi NewGroup +:hi Group2 +:hi Group2 NONE +:hi Group2 +:hi clear +:hi Group3 +:hi Crash term='asdf +:redir END +:" filter ctermfg and ctermbg, the numbers depend on the terminal +:e test.out +:%s/ctermfg=\d*/ctermfg=2/ +:%s/ctermbg=\d*/ctermbg=3/ +:" filter out possibly translated error message +:%s/E475: [^:]*:/E475:/ +:" fix the fileformat +:set ff& +:wq! +ENDTEST + diff --git a/src/nvim/testdir/test51.ok b/src/nvim/testdir/test51.ok new file mode 100644 index 0000000000..be9ff7862c --- /dev/null +++ b/src/nvim/testdir/test51.ok @@ -0,0 +1,20 @@ + + +NewGroup xxx term=bold cterm=italic ctermfg=2 ctermbg=3 + +Group2 xxx cleared + +Group3 xxx term=underline cterm=bold + + +NewGroup xxx cleared + +Group2 xxx cleared + + +Group2 xxx cleared + + +Group3 xxx cleared + +E475: term='asdf diff --git a/src/nvim/testdir/test52.in b/src/nvim/testdir/test52.in new file mode 100644 index 0000000000..206b65a1f9 --- /dev/null +++ b/src/nvim/testdir/test52.in @@ -0,0 +1,65 @@ +Tests for reading and writing files with conversion for Win32. + +STARTTEST +:so mbyte.vim +:" make this a dummy test for non-Win32 systems +:if !has("win32") | e! test.ok | wq! test.out | endif +:" +:" write tests: +:" combine three values for 'encoding' with three values for 'fileencoding' +:" also write files for read tests +/^1 +:set encoding=utf-8 +:.w! ++enc=utf-8 test.out +:.w ++enc=cp1251 >>test.out +:.w ++enc=cp866 >>test.out +:.w! ++enc=utf-8 Xutf8 +/^2 +:set encoding=cp1251 +:.w ++enc=utf-8 >>test.out +:.w ++enc=cp1251 >>test.out +:.w ++enc=cp866 >>test.out +:.w! ++enc=cp1251 Xcp1251 +/^3 +:set encoding=cp866 +:.w ++enc=utf-8 >>test.out +:.w ++enc=cp1251 >>test.out +:.w ++enc=cp866 >>test.out +:.w! ++enc=cp866 Xcp866 +:" +:" read three 'fileencoding's with utf-8 'encoding' +:set encoding=utf-8 fencs=utf-8,cp1251 +:e Xutf8 +:.w ++enc=utf-8 >>test.out +:e Xcp1251 +:.w ++enc=utf-8 >>test.out +:set fencs=utf-8,cp866 +:e Xcp866 +:.w ++enc=utf-8 >>test.out +:" +:" read three 'fileencoding's with cp1251 'encoding' +:set encoding=utf-8 fencs=utf-8,cp1251 +:e Xutf8 +:.w ++enc=cp1251 >>test.out +:e Xcp1251 +:.w ++enc=cp1251 >>test.out +:set fencs=utf-8,cp866 +:e Xcp866 +:.w ++enc=cp1251 >>test.out +:" +:" read three 'fileencoding's with cp866 'encoding' +:set encoding=cp866 fencs=utf-8,cp1251 +:e Xutf8 +:.w ++enc=cp866 >>test.out +:e Xcp1251 +:.w ++enc=cp866 >>test.out +:set fencs=utf-8,cp866 +:e Xcp866 +:.w ++enc=cp866 >>test.out +:" +:qa! +ENDTEST + +1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +2 cp1251 text: Vim version 6.2. : 1970 Jan 01 +3 cp866 text: Vim version 6.2. : 1970 Jan 01 diff --git a/src/nvim/testdir/test52.ok b/src/nvim/testdir/test52.ok new file mode 100644 index 0000000000..90b516508d --- /dev/null +++ b/src/nvim/testdir/test52.ok @@ -0,0 +1,18 @@ +1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +1 utf-8 text: Vim version 6.2. : 1970 Jan 01 +1 utf-8 text: Vim version 6.2. : 1970 Jan 01 +2 cp1251 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +2 cp1251 text: Vim version 6.2. : 1970 Jan 01 +2 cp1251 text: Vim version 6.2. : 1970 Jan 01 +3 cp866 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +3 cp866 text: Vim version 6.2. : 1970 Jan 01 +3 cp866 text: Vim version 6.2. : 1970 Jan 01 +1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +2 cp1251 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +3 cp866 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +1 utf-8 text: Vim version 6.2. : 1970 Jan 01 +2 cp1251 text: Vim version 6.2. : 1970 Jan 01 +3 cp866 text: Vim version 6.2. : 1970 Jan 01 +1 utf-8 text: Vim version 6.2. : 1970 Jan 01 +2 cp1251 text: Vim version 6.2. : 1970 Jan 01 +3 cp866 text: Vim version 6.2. : 1970 Jan 01 diff --git a/src/nvim/testdir/test53.in b/src/nvim/testdir/test53.in new file mode 100644 index 0000000000..011c9ae39d --- /dev/null +++ b/src/nvim/testdir/test53.in @@ -0,0 +1,123 @@ +Tests for string and html text objects. vim: set ft=vim : + +Note that the end-of-line moves the cursor to the next test line. + +Also test match() and matchstr() + +Also test the gn command and repeating it. + +STARTTEST +:so small.vim +/^start:/ +da" +0va'a'rx +02f`da` +0fXdi" +03f'vi'ry +:set quoteescape=+*- +di` +$F"va"oha"i"rz +:" +/^<begin +jfXdit +0fXdit +fXdat +0fXdat +:" +:put =matchstr(\"abcd\", \".\", 0, 2) " b +:put =matchstr(\"abcd\", \"..\", 0, 2) " bc +:put =matchstr(\"abcd\", \".\", 2, 0) " c (zero and negative -> first match) +:put =matchstr(\"abcd\", \".\", 0, -1) " a +:put =match(\"abcd\", \".\", 0, 5) " -1 +:put =match(\"abcd\", \".\", 0, -1) " 0 +:put =match('abc', '.', 0, 1) " 0 +:put =match('abc', '.', 0, 2) " 1 +:put =match('abc', '.', 0, 3) " 2 +:put =match('abc', '.', 0, 4) " -1 +:put =match('abc', '.', 1, 1) " 1 +:put =match('abc', '.', 2, 1) " 2 +:put =match('abc', '.', 3, 1) " -1 +:put =match('abc', '$', 0, 1) " 3 +:put =match('abc', '$', 0, 2) " -1 +:put =match('abc', '$', 1, 1) " 3 +:put =match('abc', '$', 2, 1) " 3 +:put =match('abc', '$', 3, 1) " 3 +:put =match('abc', '$', 4, 1) " -1 +:put =match('abc', '\zs', 0, 1) " 0 +:put =match('abc', '\zs', 0, 2) " 1 +:put =match('abc', '\zs', 0, 3) " 2 +:put =match('abc', '\zs', 0, 4) " 3 +:put =match('abc', '\zs', 0, 5) " -1 +:put =match('abc', '\zs', 1, 1) " 1 +:put =match('abc', '\zs', 2, 1) " 2 +:put =match('abc', '\zs', 3, 1) " 3 +:put =match('abc', '\zs', 4, 1) " -1 +/^foobar +gncsearchmatch/one\_s*two\_s +:1 +gnd +/[a]bcdx +:1 +2gnd/join +/$ +0gnd +/\>\zs +0gnd/^ +gnd$h/\zs +gnd/[u]niquepattern/s +vlgnd +/mother +:set selection=exclusive +$cgNmongoose/i +cgnj +:" Make sure there is no other match y uppercase. +/x59 +gggnd +:" test repeating dgn +/^Johnny +ggdgn. +:" test repeating gUgn +/^Depp +gggUgn. +:/^start:/,/^end:/wq! test.out +ENDTEST + +start: "wo\"rd\\" foo +'foo' 'bar' 'piep' +bla bla `quote` blah +out " in "noXno" +"'" 'blah' rep 'buh' +bla `s*`d-`+++`l**` b`la +voo "nah" sdf " asdf" sdf " sdf" sd + +<begin> +-<b>asdf<i>Xasdf</i>asdf</b>- +-<b>asdX<i>a<i />sdf</i>asdf</b>- +-<b>asdf<i>Xasdf</i>asdf</b>- +-<b>asdX<i>as<b />df</i>asdf</b>- +</begin> +SEARCH: +foobar +one +two +abcdx | abcdx | abcdx +join +lines +zero width pattern +delete first and last chars +uniquepattern uniquepattern +my very excellent mother just served us nachos +for (i=0; i<=10; i++) +Y +text +Y +--1 +Johnny +--2 +Johnny +--3 +Depp +--4 +Depp +--5 +end: diff --git a/src/nvim/testdir/test53.ok b/src/nvim/testdir/test53.ok new file mode 100644 index 0000000000..d7ffa6bc51 --- /dev/null +++ b/src/nvim/testdir/test53.ok @@ -0,0 +1,64 @@ +start: foo +xxxxxxxxxxxx'piep' +bla bla blah +out " in "" +"'" 'blah'yyyyy'buh' +bla `` b`la +voo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzsd + +<begin> +-<b>asdf<i></i>asdf</b>- +-<b></b>- +-<b>asdfasdf</b>- +-- +</begin> +b +bc +c +a +-1 +0 +0 +1 +2 +-1 +1 +2 +-1 +3 +-1 +3 +3 +3 +-1 +0 +1 +2 +3 +-1 +1 +2 +3 +-1 +SEARCH: +searchmatch +abcdx | | abcdx +join lines +zerowidth pattern +elete first and last char + uniquepattern +my very excellent mongoose just served us nachos +for (j=0; i<=10; i++) + +text +Y +--1 + +--2 + +--3 +DEPP +--4 +DEPP +--5 +end: diff --git a/src/nvim/testdir/test54.in b/src/nvim/testdir/test54.in new file mode 100644 index 0000000000..9fc6537e08 --- /dev/null +++ b/src/nvim/testdir/test54.in @@ -0,0 +1,22 @@ +Some tests for buffer-local autocommands + +STARTTEST +:so small.vim +:e xx +:if has("vms") +: !del test.out.* +: au BufLeave <buffer> :!write sys$output "buffer-local autommand in %" > test.out +:else +: !rm -f test.out +: au BufLeave <buffer> :!echo buffer-local autommand in %>> test.out +:endif +:e somefile " here, autocommand for xx shall write test.out +: " but autocommand shall not apply to buffer named <buffer> +:bwipe xx " here, autocommand shall be auto-deleted +:e xx " nothing shall be written +:e somefile " nothing shall be written +:qa! +ENDTEST + +start of test file xx +end of test file xx diff --git a/src/nvim/testdir/test54.ok b/src/nvim/testdir/test54.ok new file mode 100644 index 0000000000..0fd1dc915b --- /dev/null +++ b/src/nvim/testdir/test54.ok @@ -0,0 +1 @@ +buffer-local autommand in xx diff --git a/src/nvim/testdir/test55.in b/src/nvim/testdir/test55.in new file mode 100644 index 0000000000..85a8063774 --- /dev/null +++ b/src/nvim/testdir/test55.in @@ -0,0 +1,404 @@ +Tests for List and Dictionary types. vim: set ft=vim : + +STARTTEST +:so small.vim +:fun Test(...) +:lang C +:" Creating List directly with different types +:let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},] +:$put =string(l) +:$put =string(l[-1]) +:$put =string(l[-4]) +:try +: $put =string(l[-5]) +:catch +: $put =v:exception[:14] +:endtry +:" List slices +:$put =string(l[:]) +:$put =string(l[1:]) +:$put =string(l[:-2]) +:$put =string(l[0:8]) +:$put =string(l[8:-1]) +:" +:" List identity +:let ll = l +:let lx = copy(l) +:try +: $put =(l == ll) . (l isnot ll) . (l is ll) . (l == lx) . (l is lx) . (l isnot lx) +:catch +: $put =v:exception +:endtry +:" +:" Creating Dictionary directly with different types +:let d = {001: 'asd', 'b': [1, 2, function('strlen')], -1: {'a': 1},} +:$put =string(d) . d.1 +:$put =string(sort(keys(d))) +:$put =string (values(d)) +:for [key, val] in items(d) +: $put =key . ':' . string(val) +: unlet key val +:endfor +:call extend (d, {3:33, 1:99}) +:call extend(d, {'b':'bbb', 'c':'ccc'}, "keep") +:try +: call extend(d, {3:333,4:444}, "error") +:catch +: $put =v:exception[:15] . v:exception[-1:-1] +:endtry +:$put =string(d) +:call filter(d, 'v:key =~ ''[ac391]''') +:$put =string(d) +:" +:" Dictionary identity +:let dd = d +:let dx = copy(d) +:try +: $put =(d == dd) . (d isnot dd) . (d is dd) . (d == dx) . (d is dx) . (d isnot dx) +:catch +: $put =v:exception +:endtry +:" +:" Changing var type should fail +:try +: let d = [] +:catch +: $put =v:exception[:14] . v:exception[-1:-1] +:endtry +:try +: let l = {} +:catch +: $put =v:exception[:14] . v:exception[-1:-1] +:endtry +:" +:" removing items with :unlet +:unlet l[2] +:$put =string(l) +:let l = range(8) +:try +:unlet l[:3] +:unlet l[1:] +:catch +:$put =v:exception +:endtry +:$put =string(l) +:" +:unlet d.c +:unlet d[-1] +:$put =string(d) +:" +:" removing items out of range: silently skip items that don't exist +let l = [0, 1, 2, 3] +:unlet l[2:1] +:$put =string(l) +let l = [0, 1, 2, 3] +:unlet l[2:2] +:$put =string(l) +let l = [0, 1, 2, 3] +:unlet l[2:3] +:$put =string(l) +let l = [0, 1, 2, 3] +:unlet l[2:4] +:$put =string(l) +let l = [0, 1, 2, 3] +:unlet l[2:5] +:$put =string(l) +let l = [0, 1, 2, 3] +:unlet l[-1:2] +:$put =string(l) +let l = [0, 1, 2, 3] +:unlet l[-2:2] +:$put =string(l) +let l = [0, 1, 2, 3] +:unlet l[-3:2] +:$put =string(l) +let l = [0, 1, 2, 3] +:unlet l[-4:2] +:$put =string(l) +let l = [0, 1, 2, 3] +:unlet l[-5:2] +:$put =string(l) +let l = [0, 1, 2, 3] +:unlet l[-6:2] +:$put =string(l) +:" +:" assignment to a list +:let l = [0, 1, 2, 3] +:let [va, vb] = l[2:3] +:$put =va +:$put =vb +:try +: let [va, vb] = l +:catch +: $put =v:exception[:14] +:endtry +:try +: let [va, vb] = l[1:1] +:catch +: $put =v:exception[:14] +:endtry +:" +:" manipulating a big Dictionary (hashtable.c has a border of 1000 entries) +:let d = {} +:for i in range(1500) +: let d[i] = 3000 - i +:endfor +:$put =d[0] . ' ' . d[100] . ' ' . d[999] . ' ' . d[1400] . ' ' . d[1499] +:try +: let n = d[1500] +:catch +: $put =substitute(v:exception, '\v(.{14}).*( \d{4}).*', '\1\2', '') +:endtry +:" lookup each items +:for i in range(1500) +: if d[i] != 3000 - i +: $put =d[i] +: endif +:endfor +: let i += 1 +:" delete even items +:while i >= 2 +: let i -= 2 +: unlet d[i] +:endwhile +:$put =get(d, 1500 - 100, 'NONE') . ' ' . d[1] +:" delete odd items, checking value, one intentionally wrong +:let d[33] = 999 +:let i = 1 +:while i < 1500 +: if d[i] != 3000 - i +: $put =i . '=' . d[i] +: else +: unlet d[i] +: endif +: let i += 2 +:endwhile +:$put =string(d) " must be almost empty now +:unlet d +:" +:" Dictionary function +:let dict = {} +:func dict.func(a) dict +: $put =a:a . len(self.data) +:endfunc +:let dict.data = [1,2,3] +:call dict.func("len: ") +:let x = dict.func("again: ") +:try +: let Fn = dict.func +: call Fn('xxx') +:catch +: $put =v:exception[:15] +:endtry +:" +:" Function in script-local List or Dict +:let g:dict = {} +:function g:dict.func() dict +: $put ='g:dict.func'.self.foo[1].self.foo[0]('asdf') +:endfunc +:let g:dict.foo = ['-', 2, 3] +:call insert(g:dict.foo, function('strlen')) +:call g:dict.func() +:" +:" Nasty: remove func from Dict that's being called (works) +:let d = {1:1} +:func d.func(a) +: return "a:". a:a +:endfunc +:$put =d.func(string(remove(d, 'func'))) +:" +:" Nasty: deepcopy() dict that refers to itself (fails when noref used) +:let d = {1:1, 2:2} +:let l = [4, d, 6] +:let d[3] = l +:let dc = deepcopy(d) +:try +: let dc = deepcopy(d, 1) +:catch +: $put =v:exception[:14] +:endtry +:let l2 = [0, l, l, 3] +:let l[1] = l2 +:let l3 = deepcopy(l2) +:$put ='same list: ' . (l3[1] is l3[2]) +:" +:" Locked variables +:for depth in range(5) +: $put ='depth is ' . depth +: for u in range(3) +: unlet l +: let l = [0, [1, [2, 3]], {4: 5, 6: {7: 8}}] +: exe "lockvar " . depth . " l" +: if u == 1 +: exe "unlockvar l" +: elseif u == 2 +: exe "unlockvar " . depth . " l" +: endif +: let ps = islocked("l").islocked("l[1]").islocked("l[1][1]").islocked("l[1][1][0]").'-'.islocked("l[2]").islocked("l[2]['6']").islocked("l[2]['6'][7]") +: $put =ps +: let ps = '' +: try +: let l[1][1][0] = 99 +: let ps .= 'p' +: catch +: let ps .= 'F' +: endtry +: try +: let l[1][1] = [99] +: let ps .= 'p' +: catch +: let ps .= 'F' +: endtry +: try +: let l[1] = [99] +: let ps .= 'p' +: catch +: let ps .= 'F' +: endtry +: try +: let l[2]['6'][7] = 99 +: let ps .= 'p' +: catch +: let ps .= 'F' +: endtry +: try +: let l[2][6] = {99: 99} +: let ps .= 'p' +: catch +: let ps .= 'F' +: endtry +: try +: let l[2] = {99: 99} +: let ps .= 'p' +: catch +: let ps .= 'F' +: endtry +: try +: let l = [99] +: let ps .= 'p' +: catch +: let ps .= 'F' +: endtry +: $put =ps +: endfor +:endfor +:" :lockvar/islocked() triggering script autoloading +:set rtp+=./sautest +:lockvar g:footest#x +:unlockvar g:footest#x +:$put ='locked g:footest#x:'.islocked('g:footest#x') +:$put ='exists g:footest#x:'.exists('g:footest#x') +:$put ='g:footest#x: '.g:footest#x +:" +:" a:000 function argument +:" first the tests that should fail +:try +: let a:000 = [1, 2] +:catch +: $put ='caught a:000' +:endtry +:try +: let a:000[0] = 9 +:catch +: $put ='caught a:000[0]' +:endtry +:try +: let a:000[2] = [9, 10] +:catch +: $put ='caught a:000[2]' +:endtry +:try +: let a:000[3] = {9: 10} +:catch +: $put ='caught a:000[3]' +:endtry +:" now the tests that should pass +:try +: let a:000[2][1] = 9 +: call extend(a:000[2], [5, 6]) +: let a:000[3][5] = 8 +: let a:000[3]['a'] = 12 +: $put =string(a:000) +:catch +: $put ='caught ' . v:exception +:endtry +:" +:" reverse(), sort(), uniq() +:let l = ['-0', 'A11', 2, 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 1.5] +:$put =string(uniq(copy(l))) +:$put =string(reverse(l)) +:$put =string(reverse(reverse(l))) +:$put =string(sort(l)) +:$put =string(reverse(sort(l))) +:$put =string(sort(reverse(sort(l)))) +:$put =string(uniq(sort(l))) +:" +:" splitting a string to a List +:$put =string(split(' aa bb ')) +:$put =string(split(' aa bb ', '\W\+', 0)) +:$put =string(split(' aa bb ', '\W\+', 1)) +:$put =string(split(' aa bb ', '\W', 1)) +:$put =string(split(':aa::bb:', ':', 0)) +:$put =string(split(':aa::bb:', ':', 1)) +:$put =string(split('aa,,bb, cc,', ',\s*', 1)) +:$put =string(split('abc', '\zs')) +:$put =string(split('abc', '\zs', 1)) +:" +:" compare recursively linked list and dict +:let l = [1, 2, 3, 4] +:let d = {'1': 1, '2': l, '3': 3} +:let l[1] = d +:$put =(l == l) +:$put =(d == d) +:$put =(l != deepcopy(l)) +:$put =(d != deepcopy(d)) +:" +:" compare complex recursively linked list and dict +:let l = [] +:call add(l, l) +:let dict4 = {"l": l} +:call add(dict4.l, dict4) +:let lcopy = deepcopy(l) +:let dict4copy = deepcopy(dict4) +:$put =(l == lcopy) +:$put =(dict4 == dict4copy) +:" +:" Pass the same List to extend() +:let l = [1, 2, 3, 4, 5] +:call extend(l, l) +:$put =string(l) +:" +:" Pass the same Dict to extend() +:let d = { 'a': {'b': 'B'}} +:call extend(d, d) +:$put =string(d) +:" +:" Pass the same Dict to extend() with "error" +:try +: call extend(d, d, "error") +:catch +: $put =v:exception[:15] . v:exception[-1:-1] +:endtry +:$put =string(d) +:endfun +:" +:call Test(1, 2, [3, 4], {5: 6}) " This may take a while +:" +:delfunc Test +:unlet dict +:call garbagecollect(1) +:" +:" test for patch 7.3.637 +:let a = 'No error caught' +:try|foldopen|catch|let a = matchstr(v:exception,'^[^ ]*')|endtry +o=a
:" +:lang C +:redir => a +:try|foobar|catch|let a = matchstr(v:exception,'^[^ ]*')|endtry +:redir END +o=a
:" +:" +:/^start:/,$wq! test.out +ENDTEST + +start: diff --git a/src/nvim/testdir/test55.ok b/src/nvim/testdir/test55.ok new file mode 100644 index 0000000000..be476e8e93 --- /dev/null +++ b/src/nvim/testdir/test55.ok @@ -0,0 +1,128 @@ +start: +[1, 'as''d', [1, 2, function('strlen')], {'a': 1}] +{'a': 1} +1 +Vim(put):E684: +[1, 'as''d', [1, 2, function('strlen')], {'a': 1}] +['as''d', [1, 2, function('strlen')], {'a': 1}] +[1, 'as''d', [1, 2, function('strlen')]] +[1, 'as''d', [1, 2, function('strlen')], {'a': 1}] +[] +101101 +{'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}}asd +['-1', '1', 'b'] +['asd', [1, 2, function('strlen')], {'a': 1}] +1:'asd' +b:[1, 2, function('strlen')] +-1:{'a': 1} +Vim(call):E737: 3 +{'c': 'ccc', '1': 99, 'b': [1, 2, function('strlen')], '3': 33, '-1': {'a': 1}} +{'c': 'ccc', '1': 99, '3': 33, '-1': {'a': 1}} +101101 +Vim(let):E706: d +Vim(let):E706: l +[1, 'as''d', {'a': 1}] +[4] +{'1': 99, '3': 33} +[0, 1, 2, 3] +[0, 1, 3] +[0, 1] +[0, 1] +[0, 1] +[0, 1, 2, 3] +[0, 1, 3] +[0, 3] +[3] +[3] +[3] +2 +3 +Vim(let):E687: +Vim(let):E688: +3000 2900 2001 1600 1501 +Vim(let):E716: 1500 +NONE 2999 +33=999 +{'33': 999} +len: 3 +again: 3 +Vim(call):E725: +g:dict.func-4 +a:function('3') +Vim(let):E698: +same list: 1 +depth is 0 +0000-000 +ppppppp +0000-000 +ppppppp +0000-000 +ppppppp +depth is 1 +1000-000 +ppppppF +0000-000 +ppppppp +0000-000 +ppppppp +depth is 2 +1100-100 +ppFppFF +0000-000 +ppppppp +0000-000 +ppppppp +depth is 3 +1110-110 +pFFpFFF +0010-010 +pFppFpp +0000-000 +ppppppp +depth is 4 +1111-111 +FFFFFFF +0011-011 +FFpFFpp +0000-000 +ppppppp +locked g:footest#x:-1 +exists g:footest#x:0 +g:footest#x: 1 +caught a:000 +caught a:000[0] +caught a:000[2] +caught a:000[3] +[1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}] +['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 1.5] +[1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0'] +[1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0'] +['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0, 1, 2]] +[[0, 1, 2], [0, 1, 2], 4, 2, 2, 1.5, 'xaaa', 'x8', 'foo6', 'foo', 'foo', 'A11', '-0'] +['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0, 1, 2]] +['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 4, [0, 1, 2]] +['aa', 'bb'] +['aa', 'bb'] +['', 'aa', 'bb', ''] +['', '', 'aa', '', 'bb', '', ''] +['aa', '', 'bb'] +['', 'aa', '', 'bb', ''] +['aa', '', 'bb', 'cc', ''] +['a', 'b', 'c'] +['', 'a', '', 'b', '', 'c', ''] +1 +1 +0 +0 +1 +1 +[1, 2, 3, 4, 5, 1, 2, 3, 4, 5] +{'a': {'b': 'B'}} +Vim(call):E737: a +{'a': {'b': 'B'}} +Vim(foldopen):E490: + + +Error detected while processing : +E492: Not an editor command: foobar|catch|let a = matchstr(v:exception,'^[^ ]*')|endtry + diff --git a/src/nvim/testdir/test56.in b/src/nvim/testdir/test56.in new file mode 100644 index 0000000000..311a6004ca --- /dev/null +++ b/src/nvim/testdir/test56.in @@ -0,0 +1,21 @@ +Test for script-local function. vim: set ft=vim : + +STARTTEST +:so small.vim +:" +:set nocp viminfo+=nviminfo +:/^start:/+1,/^end:/-1w! Xtest.vim +:source Xtest.vim +_x +:$-1,$wq! test.out +ENDTEST + +start: +fun <SID>DoLast() + call append(line('$'), "last line") +endfun +fun s:DoNothing() + call append(line('$'), "nothing line") +endfun +nnoremap <buffer> _x :call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr> +end: diff --git a/src/nvim/testdir/test56.ok b/src/nvim/testdir/test56.ok new file mode 100644 index 0000000000..f2b0d33c8b --- /dev/null +++ b/src/nvim/testdir/test56.ok @@ -0,0 +1,2 @@ +nothing line +last line diff --git a/src/nvim/testdir/test57.in b/src/nvim/testdir/test57.in new file mode 100644 index 0000000000..8d972e4a68 --- /dev/null +++ b/src/nvim/testdir/test57.in @@ -0,0 +1,500 @@ +Tests for :sort command. vim: set ft=vim : + +STARTTEST +:so small.vim +:" +:/^t01:/+1,/^t02/-1sort +:/^t02:/+1,/^t03/-1sort n +:/^t03:/+1,/^t04/-1sort x +:/^t04:/+1,/^t05/-1sort u +:/^t05:/+1,/^t06/-1sort! +:/^t06:/+1,/^t07/-1sort! n +:/^t07:/+1,/^t08/-1sort! u +:/^t08:/+1,/^t09/-1sort o +:/^t09:/+1,/^t10/-1sort! x +:/^t10:/+1,/^t11/-1sort/./ +:/^t11:/+1,/^t12/-1sort/../ +:/^t12:/+1,/^t13/-1sort/../u +:/^t13:/+1,/^t14/-1sort/./n +:/^t14:/+1,/^t15/-1sort/./r +:/^t15:/+1,/^t16/-1sort/../r +:/^t16:/+1,/^t17/-1sort/./rn +:/^t17:/+1,/^t18/-1sort/\d/ +:/^t18:/+1,/^t19/-1sort/\d/r +:/^t19:/+1,/^t20/-1sort/\d/n +:/^t20:/+1,/^t21/-1sort/\d/rn +:/^t21:/+1,/^t22/-1sort/\d\d/ +:/^t22:/+1,/^t23/-1sort/\d\d/n +:/^t23:/+1,/^t24/-1sort/\d\d/x +:/^t24:/+1,/^t25/-1sort/\d\d/r +:/^t25:/+1,/^t26/-1sort/\d\d/rn +:/^t26:/+1,/^t27/-1sort/\d\d/rx +:/^t27:/+1,/^t28/-1sort no +:/^t01:/,$wq! test.out +ENDTEST + +t01: alphebetical +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t02: numeric +abc +ab +a321 +a123 +a122 +a +x-22 +b321 +b123 + +c123d +-24 + 123b +c321d +0 +b322b +b321 +b321b + + +t03: hexadecimal +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t04: alpha, unique +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t05: alpha, reverse +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t06: numeric, reverse +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t07: unique, reverse +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t08: octal +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t09: reverse, hexadecimal +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t10: alpha, skip first character +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t11: alpha, skip first 2 characters +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t12: alpha, unique, skip first 2 characters +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t13: numeric, skip first character +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t14: alpha, sort on first character +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t15: alpha, sort on first 2 characters +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t16: numeric, sort on first character +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t17: alpha, skip past first digit +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t18: alpha, sort on first digit +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t19: numeric, skip past first digit +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t20: numeric, sort on first digit +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t21: alpha, skip past first 2 digits +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t22: numeric, skip past first 2 digits +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t23: hexadecimal, skip past first 2 digits +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t24: alpha, sort on first 2 digits +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t25: numeric, sort on first 2 digits +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t26: hexadecimal, sort on first 2 digits +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t27: wrong arguments +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t28: done + diff --git a/src/nvim/testdir/test57.ok b/src/nvim/testdir/test57.ok new file mode 100644 index 0000000000..aa3d373183 --- /dev/null +++ b/src/nvim/testdir/test57.ok @@ -0,0 +1,459 @@ +t01: alphebetical + + + 123b +a +a122 +a123 +a321 +ab +abc +b123 +b321 +b321 +b321b +b322b +c123d +c321d +t02: numeric +abc +ab +a + + + +-24 +x-22 +0 +a122 +a123 +b123 +c123d + 123b +a321 +b321 +c321d +b321 +b321b +b322b +t03: hexadecimal + + +a +ab +abc + 123b +a122 +a123 +a321 +b123 +b321 +b321 +b321b +b322b +c123d +c321d +t04: alpha, unique + + 123b +a +a122 +a123 +a321 +ab +abc +b123 +b321 +b321b +b322b +c123d +c321d +t05: alpha, reverse +c321d +c123d +b322b +b321b +b321 +b321 +b123 +abc +ab +a321 +a123 +a122 +a + 123b + + +t06: numeric, reverse +b322b +b321b +b321 +c321d +b321 +a321 + 123b +c123d +b123 +a123 +a122 + + +a +ab +abc +t07: unique, reverse +c321d +c123d +b322b +b321b +b321 +b123 +abc +ab +a321 +a123 +a122 +a + 123b + +t08: octal +abc +ab +a + + +a122 +a123 +b123 +c123d + 123b +a321 +b321 +c321d +b321 +b321b +b322b +t09: reverse, hexadecimal +c321d +c123d +b322b +b321b +b321 +b321 +b123 +a321 +a123 +a122 + 123b +abc +ab +a + + +t10: alpha, skip first character +a + + +a122 +a123 +b123 + 123b +c123d +a321 +b321 +b321 +b321b +c321d +b322b +ab +abc +t11: alpha, skip first 2 characters +ab +a + + +a321 +b321 +b321 +b321b +c321d +a122 +b322b +a123 +b123 + 123b +c123d +abc +t12: alpha, unique, skip first 2 characters +ab +a + +a321 +b321 +b321b +c321d +a122 +b322b +a123 +b123 + 123b +c123d +abc +t13: numeric, skip first character +abc +ab +a + + +a122 +a123 +b123 +c123d + 123b +a321 +b321 +c321d +b321 +b321b +b322b +t14: alpha, sort on first character + + + 123b +abc +ab +a +a321 +a123 +a122 +b321 +b123 +b322b +b321 +b321b +c123d +c321d +t15: alpha, sort on first 2 characters +a + + + 123b +a123 +a122 +a321 +abc +ab +b123 +b321 +b322b +b321 +b321b +c123d +c321d +t16: numeric, sort on first character +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t17: alpha, skip past first digit +abc +ab +a + + +a321 +b321 +b321 +b321b +c321d +a122 +b322b +a123 +b123 + 123b +c123d +t18: alpha, sort on first digit +abc +ab +a + + +a123 +a122 +b123 +c123d + 123b +a321 +b321 +c321d +b322b +b321 +b321b +t19: numeric, skip past first digit +abc +ab +a + + +a321 +b321 +c321d +b321 +b321b +a122 +b322b +a123 +b123 +c123d + 123b +t20: numeric, sort on first digit +abc +ab +a + + +a123 +a122 +b123 +c123d + 123b +a321 +b321 +c321d +b322b +b321 +b321b +t21: alpha, skip past first 2 digits +abc +ab +a + + +a321 +b321 +b321 +b321b +c321d +a122 +b322b +a123 +b123 + 123b +c123d +t22: numeric, skip past first 2 digits +abc +ab +a + + +a321 +b321 +c321d +b321 +b321b +a122 +b322b +a123 +b123 +c123d + 123b +t23: hexadecimal, skip past first 2 digits +abc +ab +a + + +a321 +b321 +b321 +a122 +a123 +b123 +b321b +c321d +b322b + 123b +c123d +t24: alpha, sort on first 2 digits +abc +ab +a + + +a123 +a122 +b123 +c123d + 123b +a321 +b321 +c321d +b322b +b321 +b321b +t25: numeric, sort on first 2 digits +abc +ab +a + + +a123 +a122 +b123 +c123d + 123b +a321 +b321 +c321d +b322b +b321 +b321b +t26: hexadecimal, sort on first 2 digits +abc +ab +a + + +a123 +a122 +b123 +c123d + 123b +a321 +b321 +c321d +b322b +b321 +b321b +t27: wrong arguments +abc +ab +a +a321 +a123 +a122 +b321 +b123 +c123d + 123b +c321d +b322b +b321 +b321b + + +t28: done + diff --git a/src/nvim/testdir/test58.in b/src/nvim/testdir/test58.in new file mode 100644 index 0000000000..cef1cfa1ba --- /dev/null +++ b/src/nvim/testdir/test58.in @@ -0,0 +1,639 @@ +Tests for spell checking. vim: set ft=vim : + +STARTTEST +:so small.vim +:" +:" Don't want to depend on the locale from the environment +:set enc=latin1 +:e! +:" +:" Check using z= in new buffer (crash fixed by patch 7.4a.028). +:set maxmem=512 spell +iasdz=:" +:" +:" Function to test .aff/.dic with list of good and bad words. +:func TestOne(aff, dic) + set spellfile= + $put ='' + $put ='test '. a:aff . '-' . a:dic + " Generate a .spl file from a .dic and .aff file. + exe '1;/^' . a:aff . 'affstart/+1,/^' . a:aff . 'affend/-1w! Xtest.aff' + exe '1;/^' . a:dic . 'dicstart/+1,/^' . a:dic . 'dicend/-1w! Xtest.dic' + mkspell! Xtest Xtest + " use that spell file + set spl=Xtest.latin1.spl spell + " list all valid words + spelldump + %yank + quit + $put + $put ='-------' + " find all bad words and suggestions for them + exe '1;/^' . a:aff . 'good:' + normal 0f:]s + let prevbad = '' + while 1 + let [bad, a] = spellbadword() + if bad == '' || bad == prevbad || bad == 'badend' + break + endif + let prevbad = bad + let lst = spellsuggest(bad, 3) + normal mm + $put =bad + $put =string(lst) + normal `m]s + endwhile +endfunc +:" +:call TestOne('1', '1') +:$put =soundfold('goobledygoook') +:$put =soundfold('koprnven') +:$put =soundfold('oeverloos gezwets edale') +:" +:" +:" and now with SAL instead of SOFO items; test automatic reloading +gg:/^affstart_sal/+1,/^affend_sal/-1w! Xtest.aff +:mkspell! Xtest Xtest +:$put =soundfold('goobledygoook') +:$put =soundfold('koprnven') +:$put =soundfold('oeverloos gezwets edale') +:" +:" also use an addition file +gg:/^addstart/+1,/^addend/-1w! Xtest.latin1.add +:mkspell! Xtest.latin1.add.spl Xtest.latin1.add +:set spellfile=Xtest.latin1.add +/^test2: +]s:let [str, a] = spellbadword() +:$put =str +:set spl=Xtest_us.latin1.spl +/^test2: +]smm:let [str, a] = spellbadword() +:$put =str +`m]s:let [str, a] = spellbadword() +:$put =str +:set spl=Xtest_gb.latin1.spl +/^test2: +]smm:let [str, a] = spellbadword() +:$put =str +`m]s:let [str, a] = spellbadword() +:$put =str +:set spl=Xtest_nz.latin1.spl +/^test2: +]smm:let [str, a] = spellbadword() +:$put =str +`m]s:let [str, a] = spellbadword() +:$put =str +:set spl=Xtest_ca.latin1.spl +/^test2: +]smm:let [str, a] = spellbadword() +:$put =str +`m]s:let [str, a] = spellbadword() +:$put =str +:unlet str a +:" +:" Postponed prefixes +:call TestOne('2', '1') +:" +:" Compound words +:call TestOne('3', '3') +:call TestOne('4', '4') +:call TestOne('5', '5') +:call TestOne('6', '6') +:call TestOne('7', '7') +:" +:" NOSLITSUGS +:call TestOne('8', '8') +:" +:" clean up for valgrind +:delfunc TestOne +:set spl= enc=latin1 +:" +gg:/^test output:/,$wq! test.out +ENDTEST + +1affstart +SET ISO8859-1 +TRY esianrtolcdugmphbyfvkwjkqxz-'ESIANRTOLCDUGMPHBYFVKWJKQXZ + +FOL +LOW +UPP + +SOFOFROM abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ +SOFOTO ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkeseeeeeeeceeeeeeeedneeeeeeeeeeepseeeeeeeeceeeeeeeedneeeeeeeeeeep? + +MIDWORD '- + +KEP = +RAR ? +BAD ! + +PFX I N 1 +PFX I 0 in . + +PFX O Y 1 +PFX O 0 out . + +SFX S Y 2 +SFX S 0 s [^s] +SFX S 0 es s + +SFX N N 3 +SFX N 0 en [^n] +SFX N 0 nen n +SFX N 0 n . + +REP 3 +REP g ch +REP ch g +REP svp s.v.p. + +MAP 9 +MAP a +MAP e +MAP i +MAP o +MAP u +MAP n +MAP c +MAP y +MAP s +1affend + +1good: wrong OK puts. Test the end +bad: inputs comment ok Ok. test dl end the +badend + +1dicstart +123456 +test/NO +# comment +wrong +Comment +OK +uk +put/ISO +the end +deol +dr +1dicend + +affstart_sal +SET ISO8859-1 +TRY esianrtolcdugmphbyfvkwjkqxz-'ESIANRTOLCDUGMPHBYFVKWJKQXZ + +FOL +LOW +UPP + +MIDWORD '- + +KEP = +RAR ? +BAD ! + +PFX I N 1 +PFX I 0 in . + +PFX O Y 1 +PFX O 0 out . + +SFX S Y 2 +SFX S 0 s [^s] +SFX S 0 es s + +SFX N N 3 +SFX N 0 en [^n] +SFX N 0 nen n +SFX N 0 n . + +REP 3 +REP g ch +REP ch g +REP svp s.v.p. + +MAP 9 +MAP a +MAP e +MAP i +MAP o +MAP u +MAP n +MAP c +MAP y +MAP s + +SAL AH(AEIOUY)-^ *H +SAL AR(AEIOUY)-^ *R +SAL A(HR)^ * +SAL A^ * +SAL AH(AEIOUY)- H +SAL AR(AEIOUY)- R +SAL A(HR) _ +SAL ^ * +SAL ^ * +SAL BB- _ +SAL B B +SAL CQ- _ +SAL CIA X +SAL CH X +SAL C(EIY)- S +SAL CK K +SAL COUGH^ KF +SAL CC< C +SAL C K +SAL DG(EIY) K +SAL DD- _ +SAL D T +SAL < E +SAL EH(AEIOUY)-^ *H +SAL ER(AEIOUY)-^ *R +SAL E(HR)^ * +SAL ENOUGH^$ *NF +SAL E^ * +SAL EH(AEIOUY)- H +SAL ER(AEIOUY)- R +SAL E(HR) _ +SAL FF- _ +SAL F F +SAL GN^ N +SAL GN$ N +SAL GNS$ NS +SAL GNED$ N +SAL GH(AEIOUY)- K +SAL GH _ +SAL GG9 K +SAL G K +SAL H H +SAL IH(AEIOUY)-^ *H +SAL IR(AEIOUY)-^ *R +SAL I(HR)^ * +SAL I^ * +SAL ING6 N +SAL IH(AEIOUY)- H +SAL IR(AEIOUY)- R +SAL I(HR) _ +SAL J K +SAL KN^ N +SAL KK- _ +SAL K K +SAL LAUGH^ LF +SAL LL- _ +SAL L L +SAL MB$ M +SAL MM M +SAL M M +SAL NN- _ +SAL N N +SAL OH(AEIOUY)-^ *H +SAL OR(AEIOUY)-^ *R +SAL O(HR)^ * +SAL O^ * +SAL OH(AEIOUY)- H +SAL OR(AEIOUY)- R +SAL O(HR) _ +SAL PH F +SAL PN^ N +SAL PP- _ +SAL P P +SAL Q K +SAL RH^ R +SAL ROUGH^ RF +SAL RR- _ +SAL R R +SAL SCH(EOU)- SK +SAL SC(IEY)- S +SAL SH X +SAL SI(AO)- X +SAL SS- _ +SAL S S +SAL TI(AO)- X +SAL TH @ +SAL TCH-- _ +SAL TOUGH^ TF +SAL TT- _ +SAL T T +SAL UH(AEIOUY)-^ *H +SAL UR(AEIOUY)-^ *R +SAL U(HR)^ * +SAL U^ * +SAL UH(AEIOUY)- H +SAL UR(AEIOUY)- R +SAL U(HR) _ +SAL V^ W +SAL V F +SAL WR^ R +SAL WH^ W +SAL W(AEIOU)- W +SAL X^ S +SAL X KS +SAL Y(AEIOU)- Y +SAL ZZ- _ +SAL Z S +affend_sal + +2affstart +SET ISO8859-1 + +FOL +LOW +UPP + +PFXPOSTPONE + +MIDWORD '- + +KEP = +RAR ? +BAD ! + +PFX I N 1 +PFX I 0 in . + +PFX O Y 1 +PFX O 0 out [a-z] + +SFX S Y 2 +SFX S 0 s [^s] +SFX S 0 es s + +SFX N N 3 +SFX N 0 en [^n] +SFX N 0 nen n +SFX N 0 n . + +REP 3 +REP g ch +REP ch g +REP svp s.v.p. + +MAP 9 +MAP a +MAP e +MAP i +MAP o +MAP u +MAP n +MAP c +MAP y +MAP s +2affend + +2good: puts +bad: inputs comment ok Ok end the. test dl +badend + +addstart +/regions=usgbnz +elequint/2 +elekwint/3 +addend + +test2: +elequint test elekwint test elekwent asdf + +Test rules for compounding. + +3affstart +SET ISO8859-1 + +COMPOUNDMIN 3 +COMPOUNDRULE m* +NEEDCOMPOUND x +3affend + +3dicstart +1234 +foo/m +bar/mx +m/m +la/mx +3dicend + +3good: foo m foobar foofoobar barfoo barbarfoo +bad: bar la foom barm mfoo mbar mm lala mla lam foola labar +badend + + +Tests for compounding. + +4affstart +SET ISO8859-1 + +FOL +LOW +UPP + +COMPOUNDRULE m+ +COMPOUNDRULE sm*e +COMPOUNDRULE sm+ +COMPOUNDMIN 3 +COMPOUNDWORDMAX 3 +COMPOUNDFORBIDFLAG t + +COMPOUNDSYLMAX 5 +SYLLABLE aeiouy/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui + +MAP 9 +MAP a +MAP e +MAP i +MAP o +MAP u +MAP n +MAP c +MAP y +MAP s + +NEEDAFFIX x + +PFXPOSTPONE + +MIDWORD '- + +SFX q N 1 +SFX q 0 -ok . + +SFX a Y 2 +SFX a 0 s . +SFX a 0 ize/t . + +PFX p N 1 +PFX p 0 pre . + +PFX P N 1 +PFX P 0 nou . +4affend + +4dicstart +1234 +word/mP +util/am +pro/xq +tomato/m +bork/mp +start/s +end/e +4dicend + +4good: word util bork prebork start end wordutil wordutils pro-ok + bork borkbork borkborkbork borkborkborkbork borkborkborkborkbork + tomato tomatotomato startend startword startwordword startwordend + startwordwordend startwordwordwordend prebork preborkbork + preborkborkbork + nouword +bad: wordutilize pro borkborkborkborkborkbork tomatotomatotomato + endstart endend startstart wordend wordstart + preborkprebork preborkpreborkbork + startwordwordwordwordend borkpreborkpreborkbork + utilsbork startnouword +badend + +Test affix flags with two characters + +5affstart +SET ISO8859-1 + +FLAG long + +NEEDAFFIX !! + +COMPOUNDRULE ssmm*ee + +NEEDCOMPOUND xx +COMPOUNDPERMITFLAG pp + +SFX 13 Y 1 +SFX 13 0 bork . + +SFX a1 Y 1 +SFX a1 0 a1 . + +SFX a Y 1 +SFX a 0 a . + +PFX zz Y 1 +PFX zz 0 pre/pp . + +PFX yy Y 1 +PFX yy 0 nou . +5affend + +5dicstart +1234 +foo/a1a!! +bar/zz13ee +start/ss +end/eeyy +middle/mmxx +5dicend + +5good: fooa1 fooa bar prebar barbork prebarbork startprebar + start end startend startmiddleend nouend +bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart + startprobar startnouend +badend + +6affstart +SET ISO8859-1 + +FLAG caplong + +NEEDAFFIX A! + +COMPOUNDRULE sMm*Ee + +NEEDCOMPOUND Xx + +COMPOUNDPERMITFLAG p + +SFX N3 Y 1 +SFX N3 0 bork . + +SFX A1 Y 1 +SFX A1 0 a1 . + +SFX A Y 1 +SFX A 0 a . + +PFX Zz Y 1 +PFX Zz 0 pre/p . +6affend + +6dicstart +1234 +mee/A1AA! +bar/ZzN3Ee +lead/s +end/Ee +middle/MmXx +6dicend + +6good: meea1 meea bar prebar barbork prebarbork leadprebar + lead end leadend leadmiddleend +bad: mee meea2 prabar probarbirk middle leadmiddle middleend endlead + leadprobar +badend + +7affstart +SET ISO8859-1 + +FLAG num + +NEEDAFFIX 9999 + +COMPOUNDRULE 2,77*123 + +NEEDCOMPOUND 1 +COMPOUNDPERMITFLAG 432 + +SFX 61003 Y 1 +SFX 61003 0 meat . + +SFX 391 Y 1 +SFX 391 0 a1 . + +SFX 111 Y 1 +SFX 111 0 a . + +PFX 17 Y 1 +PFX 17 0 pre/432 . +7affend + +7dicstart +1234 +mee/391,111,9999 +bar/17,61003,123 +lead/2 +tail/123 +middle/77,1 +7dicend + +7good: meea1 meea bar prebar barmeat prebarmeat leadprebar + lead tail leadtail leadmiddletail +bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead + leadprobar +badend + +Test NOSLITSUGS + +8affstart +SET ISO8859-1 + +NOSPLITSUGS +8affend + +8dicstart +1234 +foo +bar +faabar +8dicend + +8good: foo bar faabar +bad: foobar barfoo +badend + + +test output: diff --git a/src/nvim/testdir/test58.ok b/src/nvim/testdir/test58.ok new file mode 100644 index 0000000000..ce05c73322 --- /dev/null +++ b/src/nvim/testdir/test58.ok @@ -0,0 +1,283 @@ +test output: + +test 1-1 +# file: Xtest.latin1.spl +Comment +deol +dr +input +OK +output +outputs +outtest +put +puts +test +testen +testn +the end +uk +wrong +------- +bad +['put', 'uk', 'OK'] +inputs +['input', 'puts', 'outputs'] +comment +['Comment', 'outtest', 'the end'] +ok +['OK', 'uk', 'put'] +Ok +['OK', 'Uk', 'Put'] +test +['Test', 'testn', 'testen'] +dl +['deol', 'dr', 'test'] +end +['put', 'uk', 'test'] +the +['put', 'uk', 'test'] +gebletegek +kepereneven +everles gesvets etele +kbltykk +kprnfn +*fls kswts tl +elekwent +elequint +elekwint +elekwint +elekwent +elequint +elekwent +elequint +elekwint + +test 2-1 +# file: Xtest.latin1.spl +Comment +deol +dr +OK +put +input +output +puts +outputs +test +outtest +testen +testn +the end +uk +wrong +------- +bad +['put', 'uk', 'OK'] +inputs +['input', 'puts', 'outputs'] +comment +['Comment'] +ok +['OK', 'uk', 'put'] +Ok +['OK', 'Uk', 'Put'] +end +['put', 'uk', 'deol'] +the +['put', 'uk', 'test'] +test +['Test', 'testn', 'testen'] +dl +['deol', 'dr', 'test'] + +test 3-3 +# file: Xtest.latin1.spl +foo +m +------- +bad +['foo', 'm'] +bar +['barfoo', 'foobar', 'foo'] +la +['m', 'foo'] +foom +['foo m', 'foo', 'foofoo'] +barm +['barfoo', 'm', 'barbar'] +mfoo +['m foo', 'foo', 'foofoo'] +mbar +['foobar', 'barbar', 'm'] +mm +['m m', 'm'] +lala +[] +mla +['m', 'm m'] +lam +['m', 'm m'] +foola +['foo', 'foobar', 'foofoo'] +labar +['barbar', 'foobar'] + +test 4-4 +# file: Xtest.latin1.spl +bork +prebork +end +pro-ok +start +tomato +util +utilize +utils +word +nouword +------- +bad +['end', 'bork', 'word'] +wordutilize +['word utilize', 'wordutils', 'wordutil'] +pro +['bork', 'word', 'end'] +borkborkborkborkborkbork +['bork borkborkborkborkbork', 'borkbork borkborkborkbork', 'borkborkbork borkborkbork'] +tomatotomatotomato +['tomato tomatotomato', 'tomatotomato tomato', 'tomato tomato tomato'] +endstart +['end start', 'start'] +endend +['end end', 'end'] +startstart +['start start'] +wordend +['word end', 'word', 'wordword'] +wordstart +['word start', 'bork start'] +preborkprebork +['prebork prebork', 'preborkbork', 'preborkborkbork'] +preborkpreborkbork +['prebork preborkbork', 'preborkborkbork', 'preborkborkborkbork'] +startwordwordwordwordend +['startwordwordwordword end', 'startwordwordwordword', 'start wordwordwordword end'] +borkpreborkpreborkbork +['bork preborkpreborkbork', 'bork prebork preborkbork', 'bork preborkprebork bork'] +utilsbork +['utilbork', 'utils bork', 'util bork'] +startnouword +['start nouword', 'startword', 'startborkword'] + +test 5-5 +# file: Xtest.latin1.spl +bar +barbork +end +fooa1 +fooa +nouend +prebar +prebarbork +start +------- +bad +['bar', 'end', 'fooa1'] +foo +['fooa1', 'fooa', 'bar'] +fooa2 +['fooa1', 'fooa', 'bar'] +prabar +['prebar', 'bar', 'bar bar'] +probarbirk +['prebarbork'] +middle +[] +startmiddle +['startmiddleend', 'startmiddlebar'] +middleend +[] +endstart +['end start', 'start'] +startprobar +['startprebar', 'start prebar', 'startbar'] +startnouend +['start nouend', 'startend'] + +test 6-6 +# file: Xtest.latin1.spl +bar +barbork +end +lead +meea1 +meea +prebar +prebarbork +------- +bad +['bar', 'end', 'lead'] +mee +['meea1', 'meea', 'bar'] +meea2 +['meea1', 'meea', 'lead'] +prabar +['prebar', 'bar', 'leadbar'] +probarbirk +['prebarbork'] +middle +[] +leadmiddle +['leadmiddleend', 'leadmiddlebar'] +middleend +[] +endlead +['end lead', 'lead', 'end end'] +leadprobar +['leadprebar', 'lead prebar', 'leadbar'] + +test 7-7 +# file: Xtest.latin1.spl +bar +barmeat +lead +meea1 +meea +prebar +prebarmeat +tail +------- +bad +['bar', 'lead', 'tail'] +mee +['meea1', 'meea', 'bar'] +meea2 +['meea1', 'meea', 'lead'] +prabar +['prebar', 'bar', 'leadbar'] +probarmaat +['prebarmeat'] +middle +[] +leadmiddle +['leadmiddlebar'] +middletail +[] +taillead +['tail lead', 'tail'] +leadprobar +['leadprebar', 'lead prebar', 'leadbar'] + +test 8-8 +# file: Xtest.latin1.spl +bar +faabar +foo +------- +bad +['bar', 'foo'] +foobar +['faabar', 'foo bar', 'bar'] +barfoo +['bar foo', 'bar', 'foo'] diff --git a/src/nvim/testdir/test59.in b/src/nvim/testdir/test59.in new file mode 100644 index 0000000000..dcdb62b283 --- /dev/null +++ b/src/nvim/testdir/test59.in @@ -0,0 +1,626 @@ +Tests for spell checking with 'encoding' set to "utf-8". vim: set ft=vim : + +STARTTEST +:so small.vim +:so mbyte.vim +:" +:" Don't want to depend on the locale from the environment. The .aff and .dic +:" text is in latin1, the test text is utf-8. +:set enc=latin1 +:e! +:set enc=utf-8 +:set fenc= +:" +:" Function to test .aff/.dic with list of good and bad words. +:func TestOne(aff, dic) + set spellfile= + $put ='' + $put ='test '. a:aff . '-' . a:dic + " Generate a .spl file from a .dic and .aff file. + exe '1;/^' . a:aff . 'affstart/+1,/^' . a:aff . 'affend/-1w! Xtest.aff' + exe '1;/^' . a:dic . 'dicstart/+1,/^' . a:dic . 'dicend/-1w! Xtest.dic' + mkspell! Xtest Xtest + " use that spell file + set spl=Xtest.utf-8.spl spell + " list all valid words + spelldump + %yank + quit + $put + $put ='-------' + " find all bad words and suggestions for them + exe '1;/^' . a:aff . 'good:' + normal 0f:]s + let prevbad = '' + while 1 + let [bad, a] = spellbadword() + if bad == '' || bad == prevbad || bad == 'badend' + break + endif + let prevbad = bad + let lst = spellsuggest(bad, 3) + normal mm + $put =bad + $put =string(lst) + normal `m]s + endwhile +endfunc +:" +:call TestOne('1', '1') +:$put =soundfold('goobledygoook') +:$put =soundfold('kóopërÿnôven') +:$put =soundfold('oeverloos gezwets edale') +:" +:" +:" and now with SAL instead of SOFO items; test automatic reloading +gg:/^affstart_sal/+1,/^affend_sal/-1w! Xtest.aff +:mkspell! Xtest Xtest +:$put =soundfold('goobledygoook') +:$put =soundfold('kóopërÿnôven') +:$put =soundfold('oeverloos gezwets edale') +:" +:" also use an addition file +gg:/^addstart/+1,/^addend/-1w! Xtest.utf-8.add +:mkspell! Xtest.utf-8.add.spl Xtest.utf-8.add +:set spellfile=Xtest.utf-8.add +/^test2: +]s:let [str, a] = spellbadword() +:$put =str +:set spl=Xtest_us.utf-8.spl +/^test2: +]smm:let [str, a] = spellbadword() +:$put =str +`m]s:let [str, a] = spellbadword() +:$put =str +:set spl=Xtest_gb.utf-8.spl +/^test2: +]smm:let [str, a] = spellbadword() +:$put =str +`m]s:let [str, a] = spellbadword() +:$put =str +:set spl=Xtest_nz.utf-8.spl +/^test2: +]smm:let [str, a] = spellbadword() +:$put =str +`m]s:let [str, a] = spellbadword() +:$put =str +:set spl=Xtest_ca.utf-8.spl +/^test2: +]smm:let [str, a] = spellbadword() +:$put =str +`m]s:let [str, a] = spellbadword() +:$put =str +:unlet str a +:" +:" Postponed prefixes +:call TestOne('2', '1') +:" +:" Compound words +:call TestOne('3', '3') +:call TestOne('4', '4') +:call TestOne('5', '5') +:call TestOne('6', '6') +:call TestOne('7', '7') +:" +:" clean up for valgrind +:delfunc TestOne +:set spl= enc=latin1 +:" +gg:/^test output:/,$wq! test.out +ENDTEST + +1affstart +SET ISO8859-1 +TRY esianrtolcdugmphbyfvkwjkqxz-'ESIANRTOLCDUGMPHBYFVKWJKQXZ + +FOL +LOW +UPP + +SOFOFROM abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ +SOFOTO ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkeseeeeeeeceeeeeeeedneeeeeeeeeeepseeeeeeeeceeeeeeeedneeeeeeeeeeep? + +MIDWORD '- + +KEP = +RAR ? +BAD ! + +#NOSPLITSUGS + +PFX I N 1 +PFX I 0 in . + +PFX O Y 1 +PFX O 0 out . + +SFX S Y 2 +SFX S 0 s [^s] +SFX S 0 es s + +SFX N N 3 +SFX N 0 en [^n] +SFX N 0 nen n +SFX N 0 n . + +REP 3 +REP g ch +REP ch g +REP svp s.v.p. + +MAP 9 +MAP a +MAP e +MAP i +MAP o +MAP u +MAP n +MAP c +MAP y +MAP s +1affend + +affstart_sal +SET ISO8859-1 +TRY esianrtolcdugmphbyfvkwjkqxz-'ESIANRTOLCDUGMPHBYFVKWJKQXZ + +FOL +LOW +UPP + +MIDWORD '- + +KEP = +RAR ? +BAD ! + +#NOSPLITSUGS + +PFX I N 1 +PFX I 0 in . + +PFX O Y 1 +PFX O 0 out . + +SFX S Y 2 +SFX S 0 s [^s] +SFX S 0 es s + +SFX N N 3 +SFX N 0 en [^n] +SFX N 0 nen n +SFX N 0 n . + +REP 3 +REP g ch +REP ch g +REP svp s.v.p. + +MAP 9 +MAP a +MAP e +MAP i +MAP o +MAP u +MAP n +MAP c +MAP y +MAP s + +SAL AH(AEIOUY)-^ *H +SAL AR(AEIOUY)-^ *R +SAL A(HR)^ * +SAL A^ * +SAL AH(AEIOUY)- H +SAL AR(AEIOUY)- R +SAL A(HR) _ +SAL ^ * +SAL ^ * +SAL BB- _ +SAL B B +SAL CQ- _ +SAL CIA X +SAL CH X +SAL C(EIY)- S +SAL CK K +SAL COUGH^ KF +SAL CC< C +SAL C K +SAL DG(EIY) K +SAL DD- _ +SAL D T +SAL < E +SAL EH(AEIOUY)-^ *H +SAL ER(AEIOUY)-^ *R +SAL E(HR)^ * +SAL ENOUGH^$ *NF +SAL E^ * +SAL EH(AEIOUY)- H +SAL ER(AEIOUY)- R +SAL E(HR) _ +SAL FF- _ +SAL F F +SAL GN^ N +SAL GN$ N +SAL GNS$ NS +SAL GNED$ N +SAL GH(AEIOUY)- K +SAL GH _ +SAL GG9 K +SAL G K +SAL H H +SAL IH(AEIOUY)-^ *H +SAL IR(AEIOUY)-^ *R +SAL I(HR)^ * +SAL I^ * +SAL ING6 N +SAL IH(AEIOUY)- H +SAL IR(AEIOUY)- R +SAL I(HR) _ +SAL J K +SAL KN^ N +SAL KK- _ +SAL K K +SAL LAUGH^ LF +SAL LL- _ +SAL L L +SAL MB$ M +SAL MM M +SAL M M +SAL NN- _ +SAL N N +SAL OH(AEIOUY)-^ *H +SAL OR(AEIOUY)-^ *R +SAL O(HR)^ * +SAL O^ * +SAL OH(AEIOUY)- H +SAL OR(AEIOUY)- R +SAL O(HR) _ +SAL PH F +SAL PN^ N +SAL PP- _ +SAL P P +SAL Q K +SAL RH^ R +SAL ROUGH^ RF +SAL RR- _ +SAL R R +SAL SCH(EOU)- SK +SAL SC(IEY)- S +SAL SH X +SAL SI(AO)- X +SAL SS- _ +SAL S S +SAL TI(AO)- X +SAL TH @ +SAL TCH-- _ +SAL TOUGH^ TF +SAL TT- _ +SAL T T +SAL UH(AEIOUY)-^ *H +SAL UR(AEIOUY)-^ *R +SAL U(HR)^ * +SAL U^ * +SAL UH(AEIOUY)- H +SAL UR(AEIOUY)- R +SAL U(HR) _ +SAL V^ W +SAL V F +SAL WR^ R +SAL WH^ W +SAL W(AEIOU)- W +SAL X^ S +SAL X KS +SAL Y(AEIOU)- Y +SAL ZZ- _ +SAL Z S +affend_sal + +2affstart +SET ISO8859-1 + +FOL +LOW +UPP + +PFXPOSTPONE + +MIDWORD '- + +KEP = +RAR ? +BAD ! + +#NOSPLITSUGS + +PFX I N 1 +PFX I 0 in . + +PFX O Y 1 +PFX O 0 out [a-z] + +SFX S Y 2 +SFX S 0 s [^s] +SFX S 0 es s + +SFX N N 3 +SFX N 0 en [^n] +SFX N 0 nen n +SFX N 0 n . + +REP 3 +REP g ch +REP ch g +REP svp s.v.p. + +MAP 9 +MAP a +MAP e +MAP i +MAP o +MAP u +MAP n +MAP c +MAP y +MAP s +2affend + +1dicstart +123456 +test/NO +# comment +wrong +Comment +OK +uk +put/ISO +the end +deol +dr +1dicend + +addstart +/regions=usgbnz +elequint/2 +elekwint/3 +addend + +1good: wrong OK puts. Test the end +bad: inputs comment ok Ok. test déôl end the +badend + +2good: puts +bad: inputs comment ok Ok end the. test déôl +badend + +Test rules for compounding. + +3affstart +SET ISO8859-1 + +COMPOUNDMIN 3 +COMPOUNDRULE m* +NEEDCOMPOUND x +3affend + +3dicstart +1234 +foo/m +bar/mx +m/m +la/mx +3dicend + +3good: foo mï foobar foofoobar barfoo barbarfoo +bad: bar la foomï barmï mïfoo mïbar mïmï lala mïla lamï foola labar +badend + + +Tests for compounding. + +4affstart +SET ISO8859-1 + +FOL +LOW +UPP + +COMPOUNDRULE m+ +COMPOUNDRULE sm*e +COMPOUNDRULE sm+ +COMPOUNDMIN 3 +COMPOUNDWORDMAX 3 +COMPOUNDFORBIDFLAG t + +COMPOUNDSYLMAX 5 +SYLLABLE aeiouy/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui + +MAP 9 +MAP a +MAP e +MAP i +MAP o +MAP u +MAP n +MAP c +MAP y +MAP s + +NEEDAFFIX x + +PFXPOSTPONE + +MIDWORD '- + +SFX q N 1 +SFX q 0 -ok . + +SFX a Y 2 +SFX a 0 s . +SFX a 0 ize/t . + +PFX p N 1 +PFX p 0 pre . + +PFX P N 1 +PFX P 0 nou . +4affend + +4dicstart +1234 +word/mP +util/am +pro/xq +tomato/m +bork/mp +start/s +end/e +4dicend + +4good: word util bork prebork start end wordutil wordutils pro-ok + bork borkbork borkborkbork borkborkborkbork borkborkborkborkbork + tomato tomatotomato startend startword startwordword startwordend + startwordwordend startwordwordwordend prebork preborkbork + preborkborkbork + nouword +bad: wordutilize pro borkborkborkborkborkbork tomatotomatotomato + endstart endend startstart wordend wordstart + preborkprebork preborkpreborkbork + startwordwordwordwordend borkpreborkpreborkbork + utilsbork startnouword +badend + +test2: +elequint test elekwint test elekwent asdf + +Test affix flags with two characters + +5affstart +SET ISO8859-1 + +FLAG long + +NEEDAFFIX !! + +COMPOUNDRULE ssmm*ee + +NEEDCOMPOUND xx +COMPOUNDPERMITFLAG pp + +SFX 13 Y 1 +SFX 13 0 bork . + +SFX a1 Y 1 +SFX a1 0 a1 . + +SFX a Y 1 +SFX a 0 a . + +PFX zz Y 1 +PFX zz 0 pre/pp . + +PFX yy Y 1 +PFX yy 0 nou . +5affend + +5dicstart +1234 +foo/a1a!! +bar/zz13ee +start/ss +end/eeyy +middle/mmxx +5dicend + +5good: fooa1 fooaé bar prebar barbork prebarbork startprebar + start end startend startmiddleend nouend +bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart + startprobar startnouend +badend + +6affstart +SET ISO8859-1 + +FLAG caplong + +NEEDAFFIX A! + +COMPOUNDRULE sMm*Ee + +NEEDCOMPOUND Xx + +COMPOUNDPERMITFLAG p + +SFX N3 Y 1 +SFX N3 0 bork . + +SFX A1 Y 1 +SFX A1 0 a1 . + +SFX A Y 1 +SFX A 0 a . + +PFX Zz Y 1 +PFX Zz 0 pre/p . +6affend + +6dicstart +1234 +mee/A1AA! +bar/ZzN3Ee +lead/s +end/Ee +middle/MmXx +6dicend + +6good: meea1 meeaé bar prebar barbork prebarbork leadprebar + lead end leadend leadmiddleend +bad: mee meea2 prabar probarbirk middle leadmiddle middleend endlead + leadprobar +badend + +7affstart +SET ISO8859-1 + +FOL +LOW +UPP + +FLAG num + +NEEDAFFIX 9999 + +COMPOUNDRULE 2,77*123 + +NEEDCOMPOUND 1 +COMPOUNDPERMITFLAG 432 + +SFX 61003 Y 1 +SFX 61003 0 meat . + +SFX 391 Y 1 +SFX 391 0 a1 . + +SFX 111 Y 1 +SFX 111 0 a . + +PFX 17 Y 1 +PFX 17 0 pre/432 . +7affend + +7dicstart +1234 +mee/391,111,9999 +bar/17,61003,123 +lead/2 +tail/123 +middle/77,1 +7dicend + +7good: meea1 meeaé bar prebar barmeat prebarmeat leadprebar + lead tail leadtail leadmiddletail +bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead + leadprobar +badend + +test output: diff --git a/src/nvim/testdir/test59.ok b/src/nvim/testdir/test59.ok new file mode 100644 index 0000000000..931cdd9654 --- /dev/null +++ b/src/nvim/testdir/test59.ok @@ -0,0 +1,270 @@ +test output: + +test 1-1 +# file: Xtest.utf-8.spl +Comment +deol +déôr +input +OK +output +outputs +outtest +put +puts +test +testen +testn +the end +uk +wrong +------- +bad +['put', 'uk', 'OK'] +inputs +['input', 'puts', 'outputs'] +comment +['Comment', 'outtest', 'the end'] +ok +['OK', 'uk', 'put'] +Ok +['OK', 'Uk', 'Put'] +test +['Test', 'testn', 'testen'] +déôl +['deol', 'déôr', 'test'] +end +['put', 'uk', 'test'] +the +['put', 'uk', 'test'] +gebletegek +kepereneven +everles gesvets etele +kbltykk +kprnfn +*fls kswts tl +elekwent +elequint +elekwint +elekwint +elekwent +elequint +elekwent +elequint +elekwint + +test 2-1 +# file: Xtest.utf-8.spl +Comment +deol +déôr +OK +put +input +output +puts +outputs +test +outtest +testen +testn +the end +uk +wrong +------- +bad +['put', 'uk', 'OK'] +inputs +['input', 'puts', 'outputs'] +comment +['Comment'] +ok +['OK', 'uk', 'put'] +Ok +['OK', 'Uk', 'Put'] +end +['put', 'uk', 'deol'] +the +['put', 'uk', 'test'] +test +['Test', 'testn', 'testen'] +déôl +['deol', 'déôr', 'test'] + +test 3-3 +# file: Xtest.utf-8.spl +foo +mï +------- +bad +['foo', 'mï'] +bar +['barfoo', 'foobar', 'foo'] +la +['mï', 'foo'] +foomï +['foo mï', 'foo', 'foofoo'] +barmï +['barfoo', 'mï', 'barbar'] +mïfoo +['mï foo', 'foo', 'foofoo'] +mïbar +['foobar', 'barbar', 'mï'] +mïmï +['mï mï', 'mï'] +lala +[] +mïla +['mï', 'mï mï'] +lamï +['mï', 'mï mï'] +foola +['foo', 'foobar', 'foofoo'] +labar +['barbar', 'foobar'] + +test 4-4 +# file: Xtest.utf-8.spl +bork +prebork +end +pro-ok +start +tomato +util +utilize +utils +word +nouword +------- +bad +['end', 'bork', 'word'] +wordutilize +['word utilize', 'wordutils', 'wordutil'] +pro +['bork', 'word', 'end'] +borkborkborkborkborkbork +['bork borkborkborkborkbork', 'borkbork borkborkborkbork', 'borkborkbork borkborkbork'] +tomatotomatotomato +['tomato tomatotomato', 'tomatotomato tomato', 'tomato tomato tomato'] +endstart +['end start', 'start'] +endend +['end end', 'end'] +startstart +['start start'] +wordend +['word end', 'word', 'wordword'] +wordstart +['word start', 'bork start'] +preborkprebork +['prebork prebork', 'preborkbork', 'preborkborkbork'] +preborkpreborkbork +['prebork preborkbork', 'preborkborkbork', 'preborkborkborkbork'] +startwordwordwordwordend +['startwordwordwordword end', 'startwordwordwordword', 'start wordwordwordword end'] +borkpreborkpreborkbork +['bork preborkpreborkbork', 'bork prebork preborkbork', 'bork preborkprebork bork'] +utilsbork +['utilbork', 'utils bork', 'util bork'] +startnouword +['start nouword', 'startword', 'startborkword'] + +test 5-5 +# file: Xtest.utf-8.spl +bar +barbork +end +fooa1 +fooaé +nouend +prebar +prebarbork +start +------- +bad +['bar', 'end', 'fooa1'] +foo +['fooa1', 'fooaé', 'bar'] +fooa2 +['fooa1', 'fooaé', 'bar'] +prabar +['prebar', 'bar', 'bar bar'] +probarbirk +['prebarbork'] +middle +[] +startmiddle +['startmiddleend', 'startmiddlebar'] +middleend +[] +endstart +['end start', 'start'] +startprobar +['startprebar', 'start prebar', 'startbar'] +startnouend +['start nouend', 'startend'] + +test 6-6 +# file: Xtest.utf-8.spl +bar +barbork +end +lead +meea1 +meeaé +prebar +prebarbork +------- +bad +['bar', 'end', 'lead'] +mee +['meea1', 'meeaé', 'bar'] +meea2 +['meea1', 'meeaé', 'lead'] +prabar +['prebar', 'bar', 'leadbar'] +probarbirk +['prebarbork'] +middle +[] +leadmiddle +['leadmiddleend', 'leadmiddlebar'] +middleend +[] +endlead +['end lead', 'lead', 'end end'] +leadprobar +['leadprebar', 'lead prebar', 'leadbar'] + +test 7-7 +# file: Xtest.utf-8.spl +bar +barmeat +lead +meea1 +meeaé +prebar +prebarmeat +tail +------- +bad +['bar', 'lead', 'tail'] +mee +['meea1', 'meeaé', 'bar'] +meea2 +['meea1', 'meeaé', 'lead'] +prabar +['prebar', 'bar', 'leadbar'] +probarmaat +['prebarmeat'] +middle +[] +leadmiddle +['leadmiddlebar'] +middletail +[] +taillead +['tail lead', 'tail'] +leadprobar +['leadprebar', 'lead prebar', 'leadbar'] diff --git a/src/nvim/testdir/test6.in b/src/nvim/testdir/test6.in new file mode 100644 index 0000000000..1ebbe2fa51 --- /dev/null +++ b/src/nvim/testdir/test6.in @@ -0,0 +1,24 @@ +Test for autocommand that redefines the argument list, when doing ":all". + +STARTTEST +:so small.vim +:au BufReadPost Xxx2 next Xxx2 Xxx1 +/^start of +A1:.,/end of/w! Xxx1 " write test file Xxx1 +$r2:.,/end of/w! Xxx2 " write test file Xxx2 +$r3:.,/end of/w! Xxx3 " write test file Xxx3 +:next! Xxx1 Xxx2 Xxx3 " redefine arglist; go to Xxx1 +:all " open window for all args +:w! test.out " Write contents of Xxx1 +:w >>test.out " Append contents of last window (Xxx1) +:rew " should now be in Xxx2 +:w >>test.out " Append contents of Xxx2 +:qa! +ENDTEST + +start of test file Xxx + this is a test + this is a test + this is a test + this is a test +end of test file Xxx diff --git a/src/nvim/testdir/test6.ok b/src/nvim/testdir/test6.ok new file mode 100644 index 0000000000..b6b0c93e4e --- /dev/null +++ b/src/nvim/testdir/test6.ok @@ -0,0 +1,18 @@ +start of test file Xxx1 + this is a test + this is a test + this is a test + this is a test +end of test file Xxx +start of test file Xxx1 + this is a test + this is a test + this is a test + this is a test +end of test file Xxx +start of test file Xxx2 + this is a test + this is a test + this is a test + this is a test +end of test file Xxx diff --git a/src/nvim/testdir/test60.in b/src/nvim/testdir/test60.in new file mode 100644 index 0000000000..8835df9e0c --- /dev/null +++ b/src/nvim/testdir/test60.in @@ -0,0 +1,610 @@ +Tests for the exists() and has() functions. vim: set ft=vim ts=8 sw=2 : + +STARTTEST +:so small.vim +:function! RunTest(str, result) + if exists(a:str) == a:result + echo "OK" + else + echo "FAILED: Checking for " . a:str + endif +endfunction +:function! TestExists() + augroup myagroup + autocmd! BufEnter *.my echo "myfile edited" + autocmd! FuncUndefined UndefFun exec "fu UndefFun()\nendfu" + augroup END + set rtp+=./sautest + + let test_cases = [] + + " valid autocmd group + let test_cases += [['#myagroup', 1]] + " valid autocmd group with garbage + let test_cases += [['#myagroup+b', 0]] + " Valid autocmd group and event + let test_cases += [['#myagroup#BufEnter', 1]] + " Valid autocmd group, event and pattern + let test_cases += [['#myagroup#BufEnter#*.my', 1]] + " Valid autocmd event + let test_cases += [['#BufEnter', 1]] + " Valid autocmd event and pattern + let test_cases += [['#BufEnter#*.my', 1]] + " Non-existing autocmd group or event + let test_cases += [['#xyzagroup', 0]] + " Non-existing autocmd group and valid autocmd event + let test_cases += [['#xyzagroup#BufEnter', 0]] + " Valid autocmd group and event with no matching pattern + let test_cases += [['#myagroup#CmdwinEnter', 0]] + " Valid autocmd group and non-existing autocmd event + let test_cases += [['#myagroup#xyzacmd', 0]] + " Valid autocmd group and event and non-matching pattern + let test_cases += [['#myagroup#BufEnter#xyzpat', 0]] + " Valid autocmd event and non-matching pattern + let test_cases += [['#BufEnter#xyzpat', 0]] + " Empty autocmd group, event and pattern + let test_cases += [['###', 0]] + " Empty autocmd group and event or empty event and pattern + let test_cases += [['##', 0]] + " Valid autocmd event + let test_cases += [['##FileReadCmd', 1]] + " Non-existing autocmd event + let test_cases += [['##MySpecialCmd', 0]] + + " Existing and working option (long form) + let test_cases += [['&textwidth', 1]] + " Existing and working option (short form) + let test_cases += [['&tw', 1]] + " Existing and working option with garbage + let test_cases += [['&tw-', 0]] + " Global option + let test_cases += [['&g:errorformat', 1]] + " Local option + let test_cases += [['&l:errorformat', 1]] + " Negative form of existing and working option (long form) + let test_cases += [['&nojoinspaces', 0]] + " Negative form of existing and working option (short form) + let test_cases += [['&nojs', 0]] + " Non-existing option + let test_cases += [['&myxyzoption', 0]] + + " Existing and working option (long form) + let test_cases += [['+incsearch', 1]] + " Existing and working option with garbage + let test_cases += [['+incsearch!1', 0]] + " Existing and working option (short form) + let test_cases += [['+is', 1]] + " Existing option that is hidden. + let test_cases += [['+autoprint', 0]] + + " Existing environment variable + let $EDITOR_NAME = 'Vim Editor' + let test_cases += [['$EDITOR_NAME', 1]] + " Non-existing environment variable + let test_cases += [['$NON_ENV_VAR', 0]] + + " Valid internal function + let test_cases += [['*bufnr', 1]] + " Valid internal function with () + let test_cases += [['*bufnr()', 1]] + " Non-existing internal function + let test_cases += [['*myxyzfunc', 0]] + " Valid internal function with garbage + let test_cases += [['*bufnr&6', 0]] + + " Valid user defined function + let test_cases += [['*TestExists', 1]] + " Non-existing user defined function + let test_cases += [['*MyxyzFunc', 0]] + + " Function that may be created by FuncUndefined event + let test_cases += [['*UndefFun', 0]] + " Function that may be created by script autoloading + let test_cases += [['*footest#F', 0]] + + redir! > test.out + + for [test_case, result] in test_cases + echo test_case . ": " . result + call RunTest(test_case, result) + endfor + + " Valid internal command (full match) + echo ':edit: 2' + if exists(':edit') == 2 + echo "OK" + else + echo "FAILED" + endif + + " Valid internal command (full match) with garbage + echo ':edit/a: 0' + if exists(':edit/a') == 0 + echo "OK" + else + echo "FAILED" + endif + + " Valid internal command (partial match) + echo ':q: 1' + if exists(':q') == 1 + echo "OK" + else + echo "FAILED" + endif + + " Non-existing internal command + echo ':invalidcmd: 0' + if !exists(':invalidcmd') + echo "OK" + else + echo "FAILED" + endif + + " User defined command (full match) + command! MyCmd :echo 'My command' + echo ':MyCmd: 2' + if exists(':MyCmd') == 2 + echo "OK" + else + echo "FAILED" + endif + + " User defined command (partial match) + command! MyOtherCmd :echo 'Another command' + echo ':My: 3' + if exists(':My') == 3 + echo "OK" + else + echo "FAILED" + endif + + " Command modifier + echo ':rightbelow: 2' + if exists(':rightbelow') == 2 + echo "OK" + else + echo "FAILED" + endif + + " Non-existing user defined command (full match) + delcommand MyCmd + + echo ':MyCmd: 0' + if !exists(':MyCmd') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing user defined command (partial match) + delcommand MyOtherCmd + + echo ':My: 0' + if !exists(':My') + echo "OK" + else + echo "FAILED" + endif + + " Valid local variable + let local_var = 1 + echo 'local_var: 1' + if exists('local_var') + echo "OK" + else + echo "FAILED" + endif + + " Valid local variable with garbage + let local_var = 1 + echo 'local_var%n: 0' + if !exists('local_var%n') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing local variable + unlet local_var + echo 'local_var: 0' + if !exists('local_var') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing autoload variable that may be autoloaded + echo 'footest#x: 0' + if !exists('footest#x') + echo "OK" + else + echo "FAILED" + endif + + " Valid local list + let local_list = ["blue", "orange"] + echo 'local_list: 1' + if exists('local_list') + echo "OK" + else + echo "FAILED" + endif + + " Valid local list item + echo 'local_list[1]: 1' + if exists('local_list[1]') + echo "OK" + else + echo "FAILED" + endif + + " Valid local list item with garbage + echo 'local_list[1]+5: 0' + if !exists('local_list[1]+5') + echo "OK" + else + echo "FAILED" + endif + + " Invalid local list item + echo 'local_list[2]: 0' + if !exists('local_list[2]') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing local list + unlet local_list + echo 'local_list: 0' + if !exists('local_list') + echo "OK" + else + echo "FAILED" + endif + + " Valid local dictionary + let local_dict = {"xcord":100, "ycord":2} + echo 'local_dict: 1' + if exists('local_dict') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing local dictionary + unlet local_dict + echo 'local_dict: 0' + if !exists('local_dict') + echo "OK" + else + echo "FAILED" + endif + + " Existing local curly-brace variable + let str = "local" + let curly_{str}_var = 1 + echo 'curly_' . str . '_var: 1' + if exists('curly_{str}_var') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing local curly-brace variable + unlet curly_{str}_var + echo 'curly_' . str . '_var: 0' + if !exists('curly_{str}_var') + echo "OK" + else + echo "FAILED" + endif + + + " Existing global variable + let g:global_var = 1 + echo 'g:global_var: 1' + if exists('g:global_var') + echo "OK" + else + echo "FAILED" + endif + + " Existing global variable with garbage + echo 'g:global_var-n: 1' + if !exists('g:global_var-n') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing global variable + unlet g:global_var + echo 'g:global_var: 0' + if !exists('g:global_var') + echo "OK" + else + echo "FAILED" + endif + + " Existing global list + let g:global_list = ["blue", "orange"] + echo 'g:global_list: 1' + if exists('g:global_list') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing global list + unlet g:global_list + echo 'g:global_list: 0' + if !exists('g:global_list') + echo "OK" + else + echo "FAILED" + endif + + " Existing global dictionary + let g:global_dict = {"xcord":100, "ycord":2} + echo 'g:global_dict: 1' + if exists('g:global_dict') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing global dictionary + unlet g:global_dict + echo 'g:global_dict: 0' + if !exists('g:global_dict') + echo "OK" + else + echo "FAILED" + endif + + " Existing global curly-brace variable + let str = "global" + let g:curly_{str}_var = 1 + echo 'g:curly_' . str . '_var: 1' + if exists('g:curly_{str}_var') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing global curly-brace variable + unlet g:curly_{str}_var + echo 'g:curly_' . str . '_var: 0' + if !exists('g:curly_{str}_var') + echo "OK" + else + echo "FAILED" + endif + + " Existing window variable + echo 'w:window_var: 1' + let w:window_var = 1 + if exists('w:window_var') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing window variable + unlet w:window_var + echo 'w:window_var: 0' + if !exists('w:window_var') + echo "OK" + else + echo "FAILED" + endif + + " Existing window list + let w:window_list = ["blue", "orange"] + echo 'w:window_list: 1' + if exists('w:window_list') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing window list + unlet w:window_list + echo 'w:window_list: 0' + if !exists('w:window_list') + echo "OK" + else + echo "FAILED" + endif + + " Existing window dictionary + let w:window_dict = {"xcord":100, "ycord":2} + echo 'w:window_dict: 1' + if exists('w:window_dict') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing window dictionary + unlet w:window_dict + echo 'w:window_dict: 0' + if !exists('w:window_dict') + echo "OK" + else + echo "FAILED" + endif + + " Existing window curly-brace variable + let str = "window" + let w:curly_{str}_var = 1 + echo 'w:curly_' . str . '_var: 1' + if exists('w:curly_{str}_var') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing window curly-brace variable + unlet w:curly_{str}_var + echo 'w:curly_' . str . '_var: 0' + if !exists('w:curly_{str}_var') + echo "OK" + else + echo "FAILED" + endif + + " Existing buffer variable + echo 'b:buffer_var: 1' + let b:buffer_var = 1 + if exists('b:buffer_var') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing buffer variable + unlet b:buffer_var + echo 'b:buffer_var: 0' + if !exists('b:buffer_var') + echo "OK" + else + echo "FAILED" + endif + + " Existing buffer list + let b:buffer_list = ["blue", "orange"] + echo 'b:buffer_list: 1' + if exists('b:buffer_list') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing buffer list + unlet b:buffer_list + echo 'b:buffer_list: 0' + if !exists('b:buffer_list') + echo "OK" + else + echo "FAILED" + endif + + " Existing buffer dictionary + let b:buffer_dict = {"xcord":100, "ycord":2} + echo 'b:buffer_dict: 1' + if exists('b:buffer_dict') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing buffer dictionary + unlet b:buffer_dict + echo 'b:buffer_dict: 0' + if !exists('b:buffer_dict') + echo "OK" + else + echo "FAILED" + endif + + " Existing buffer curly-brace variable + let str = "buffer" + let b:curly_{str}_var = 1 + echo 'b:curly_' . str . '_var: 1' + if exists('b:curly_{str}_var') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing buffer curly-brace variable + unlet b:curly_{str}_var + echo 'b:curly_' . str . '_var: 0' + if !exists('b:curly_{str}_var') + echo "OK" + else + echo "FAILED" + endif + + " Script-local tests + source test60.vim + + " Existing Vim internal variable + echo 'v:version: 1' + if exists('v:version') + echo "OK" + else + echo "FAILED" + endif + + " Non-existing Vim internal variable + echo 'v:non_exists_var: 0' + if !exists('v:non_exists_var') + echo "OK" + else + echo "FAILED" + endif + + " Function arguments + function TestFuncArg(func_arg, ...) + echo 'a:func_arg: 1' + if exists('a:func_arg') + echo "OK" + else + echo "FAILED" + endif + + echo 'a:non_exists_arg: 0' + if !exists('a:non_exists_arg') + echo "OK" + else + echo "FAILED" + endif + + echo 'a:1: 1' + if exists('a:1') + echo "OK" + else + echo "FAILED" + endif + + echo 'a:2: 0' + if !exists('a:2') + echo "OK" + else + echo "FAILED" + endif + endfunction + + call TestFuncArg("arg1", "arg2") + + echo ' g:footest#x =' g:footest#x + echo ' footest#F()' footest#F() + echo 'UndefFun()' UndefFun() + + redir END +endfunction +:call TestExists() +:" +:function TestHas() + redir >> test.out + for pl in ['6.9.999', '7.1.999', '7.4.123', '9.1.0', '9.9.1'] + echo 'has patch ' . pl . ': ' . has('patch-' . pl) + endfor + redir END +endfunc +:call TestHas() +:" +:delfunc TestExists +:delfunc RunTest +:delfunc TestFuncArg +:edit! test.out +:set ff=unix +:w +:qa! +:while getchar(1) | call getchar() | endwhile +ENDTEST + diff --git a/src/nvim/testdir/test60.ok b/src/nvim/testdir/test60.ok new file mode 100644 index 0000000000..dabcd0c05d --- /dev/null +++ b/src/nvim/testdir/test60.ok @@ -0,0 +1,211 @@ + +#myagroup: 1 +OK +#myagroup+b: 0 +OK +#myagroup#BufEnter: 1 +OK +#myagroup#BufEnter#*.my: 1 +OK +#BufEnter: 1 +OK +#BufEnter#*.my: 1 +OK +#xyzagroup: 0 +OK +#xyzagroup#BufEnter: 0 +OK +#myagroup#CmdwinEnter: 0 +OK +#myagroup#xyzacmd: 0 +OK +#myagroup#BufEnter#xyzpat: 0 +OK +#BufEnter#xyzpat: 0 +OK +###: 0 +OK +##: 0 +OK +##FileReadCmd: 1 +OK +##MySpecialCmd: 0 +OK +&textwidth: 1 +OK +&tw: 1 +OK +&tw-: 0 +OK +&g:errorformat: 1 +OK +&l:errorformat: 1 +OK +&nojoinspaces: 0 +OK +&nojs: 0 +OK +&myxyzoption: 0 +OK ++incsearch: 1 +OK ++incsearch!1: 0 +OK ++is: 1 +OK ++autoprint: 0 +OK +$EDITOR_NAME: 1 +OK +$NON_ENV_VAR: 0 +OK +*bufnr: 1 +OK +*bufnr(): 1 +OK +*myxyzfunc: 0 +OK +*bufnr&6: 0 +OK +*TestExists: 1 +OK +*MyxyzFunc: 0 +OK +*UndefFun: 0 +OK +*footest#F: 0 +OK +:edit: 2 +OK +:edit/a: 0 +OK +:q: 1 +OK +:invalidcmd: 0 +OK +:MyCmd: 2 +OK +:My: 3 +OK +:rightbelow: 2 +OK +:MyCmd: 0 +OK +:My: 0 +OK +local_var: 1 +OK +local_var%n: 0 +OK +local_var: 0 +OK +footest#x: 0 +OK +local_list: 1 +OK +local_list[1]: 1 +OK +local_list[1]+5: 0 +OK +local_list[2]: 0 +OK +local_list: 0 +OK +local_dict: 1 +OK +local_dict: 0 +OK +curly_local_var: 1 +OK +curly_local_var: 0 +OK +g:global_var: 1 +OK +g:global_var-n: 1 +OK +g:global_var: 0 +OK +g:global_list: 1 +OK +g:global_list: 0 +OK +g:global_dict: 1 +OK +g:global_dict: 0 +OK +g:curly_global_var: 1 +OK +g:curly_global_var: 0 +OK +w:window_var: 1 +OK +w:window_var: 0 +OK +w:window_list: 1 +OK +w:window_list: 0 +OK +w:window_dict: 1 +OK +w:window_dict: 0 +OK +w:curly_window_var: 1 +OK +w:curly_window_var: 0 +OK +b:buffer_var: 1 +OK +b:buffer_var: 0 +OK +b:buffer_list: 1 +OK +b:buffer_list: 0 +OK +b:buffer_dict: 1 +OK +b:buffer_dict: 0 +OK +b:curly_buffer_var: 1 +OK +b:curly_buffer_var: 0 +OK +s:script_var: 1 +OK +s:script_var: 0 +OK +s:script_list: 1 +OK +s:script_list: 0 +OK +s:script_dict: 1 +OK +s:script_dict: 0 +OK +s:curly_script_var: 1 +OK +s:curly_script_var: 0 +OK +*s:my_script_func: 1 +OK +*s:my_script_func: 0 +OK +v:version: 1 +OK +v:non_exists_var: 0 +OK +a:func_arg: 1 +OK +a:non_exists_arg: 0 +OK +a:1: 1 +OK +a:2: 0 +OK + g:footest#x = 1 + footest#F() 0 +UndefFun() 0 +has patch 6.9.999: 1 +has patch 7.1.999: 1 +has patch 7.4.123: 1 +has patch 9.1.0: 0 +has patch 9.9.1: 0 diff --git a/src/nvim/testdir/test60.vim b/src/nvim/testdir/test60.vim new file mode 100644 index 0000000000..f1157f73f9 --- /dev/null +++ b/src/nvim/testdir/test60.vim @@ -0,0 +1,98 @@ +" Vim script for exists() function test +" Script-local variables are checked here + +" Existing script-local variable +let s:script_var = 1 +echo 's:script_var: 1' +if exists('s:script_var') + echo "OK" +else + echo "FAILED" +endif + +" Non-existing script-local variable +unlet s:script_var +echo 's:script_var: 0' +if !exists('s:script_var') + echo "OK" +else + echo "FAILED" +endif + +" Existing script-local list +let s:script_list = ["blue", "orange"] +echo 's:script_list: 1' +if exists('s:script_list') + echo "OK" +else + echo "FAILED" +endif + +" Non-existing script-local list +unlet s:script_list +echo 's:script_list: 0' +if !exists('s:script_list') + echo "OK" +else + echo "FAILED" +endif + +" Existing script-local dictionary +let s:script_dict = {"xcord":100, "ycord":2} +echo 's:script_dict: 1' +if exists('s:script_dict') + echo "OK" +else + echo "FAILED" +endif + +" Non-existing script-local dictionary +unlet s:script_dict +echo 's:script_dict: 0' +if !exists('s:script_dict') + echo "OK" +else + echo "FAILED" +endif + +" Existing script curly-brace variable +let str = "script" +let s:curly_{str}_var = 1 +echo 's:curly_' . str . '_var: 1' +if exists('s:curly_{str}_var') + echo "OK" +else + echo "FAILED" +endif + +" Non-existing script-local curly-brace variable +unlet s:curly_{str}_var +echo 's:curly_' . str . '_var: 0' +if !exists('s:curly_{str}_var') + echo "OK" +else + echo "FAILED" +endif + +" Existing script-local function +function! s:my_script_func() +endfunction + +echo '*s:my_script_func: 1' +if exists('*s:my_script_func') + echo "OK" +else + echo "FAILED" +endif + +" Non-existing script-local function +delfunction s:my_script_func + +echo '*s:my_script_func: 0' +if !exists('*s:my_script_func') + echo "OK" +else + echo "FAILED" +endif +unlet str + diff --git a/src/nvim/testdir/test61.in b/src/nvim/testdir/test61.in new file mode 100644 index 0000000000..dc24ab9804 --- /dev/null +++ b/src/nvim/testdir/test61.in @@ -0,0 +1,113 @@ +Tests for undo tree. +Since this script is sourced we need to explicitly break changes up in +undo-able pieces. Do that by setting 'undolevels'. +Also tests :earlier and :later. + +STARTTEST +:echo undotree().entries +ENDTEST + +STARTTEST +:" Delete three characters and undo +Gx:set ul=100 +x:set ul=100 +x:.w! test.out +g-:.w >>test.out +g-:.w >>test.out +g-:.w >>test.out +g-:.w >>test.out +:" +:/^111/w >>test.out +:" Delete three other characters and go back in time step by step +$x:set ul=100 +x:set ul=100 +x:.w >>test.out +:sleep 1 +g-:.w >>test.out +g-:.w >>test.out +g-:.w >>test.out +g-:.w >>test.out +g-:.w >>test.out +g-:.w >>test.out +g-:.w >>test.out +g-:.w >>test.out +10g+:.w >>test.out +:" +:/^222/w >>test.out +:" Delay for three seconds and go some seconds forward and backward +:sleep 2 +Aa:set ul=100 +Ab:set ul=100 +Ac:set ul=100 +:.w >>test.out +:ear 1s +:.w >>test.out +:ear 3s +:.w >>test.out +:later 1s +:.w >>test.out +:later 1h +:.w >>test.out +:" +:" test undojoin +Goaaaa:set ul=100 +obbbbu:.w >>test.out +obbbb:set ul=100 +:undojoin +occccu:.w >>test.out +:e! Xtest +ione one one:set ul=100 +:w! +otwo:set ul=100 +otwo:set ul=100 +:w +othree:earlier 1f +:" expect "one one one\ntwo\ntwo" +:%yank a +:earlier 1f +:" expect "one one one" +:%yank b +:earlier 1f +:" expect empty line +:%yank c +:later 1f +:" expect "one one one" +:%yank d +:later 1f +:" expect "one one one\ntwo\ntwo" +:%yank e +:later 1f +:" expect "one one one\ntwo\ntwo\nthree" +ggO---:0put e +ggO---:0put d +ggO---:0put c +ggO---:0put b +ggO---:0put a +ggO---:w >>test.out +:so small.vim +:set nocp viminfo+=nviminfo +:enew! +oa +:set ul=100 +ob +:set ul=100 +o1a2=setline('.','1234') + +uu:" +oc +:set ul=100 +o1a2=setline('.','1234') + +u:" +od +:set ul=100 +o1a2=string(123) +u:" +:%w >>test.out +:qa! +ENDTEST + +1111 ----- +2222 ----- + +123456789 diff --git a/src/nvim/testdir/test61.ok b/src/nvim/testdir/test61.ok new file mode 100644 index 0000000000..ea4b473ad7 --- /dev/null +++ b/src/nvim/testdir/test61.ok @@ -0,0 +1,49 @@ +456789 +3456789 +23456789 +123456789 +123456789 +1111 ----- +123456 +1234567 +12345678 +456789 +3456789 +23456789 +123456789 +123456789 +123456789 +123456 +2222 ----- +123456abc +123456 +123456789 +123456 +123456abc +aaaa +aaaa +--- +one one one +two +two +--- +one one one +--- + +--- +one one one +--- +one one one +two +two +--- +one one one +two +two +three + +a +b +c +12 +d diff --git a/src/nvim/testdir/test62.in b/src/nvim/testdir/test62.in new file mode 100644 index 0000000000..93d968b33e --- /dev/null +++ b/src/nvim/testdir/test62.in @@ -0,0 +1,191 @@ +Tests for tab pages + +STARTTEST +:so small.vim +:lang C +:" Simple test for opening and closing a tab page +:tabnew +:let nr = tabpagenr() +:q +:call append(line('$'), 'tab page ' . nr) +:unlet nr +:" +:" Open three tab pages and use ":tabdo" +:0tabnew +:1tabnew +:888tabnew +:tabdo call append(line('$'), 'this is tab page ' . tabpagenr()) +:tabclose! 2 +:tabrewind +:let line1 = getline('$') +:undo +:q +:tablast +:let line2 = getline('$') +:q! +:call append(line('$'), line1) +:call append(line('$'), line2) +:unlet line1 line2 +:" +:" Test for settabvar() and gettabvar() functions. Open a new tab page and +:" set 3 variables to a number, string and a list. Verify that the variables +:" are correctly set. +:tabnew +:tabfirst +:call settabvar(2, 'val_num', 100) +:call settabvar(2, 'val_str', 'SetTabVar test') +:call settabvar(2, 'val_list', ['red', 'blue', 'green']) +:" +:let test_status = 'gettabvar: fail' +:if gettabvar(2, 'val_num') == 100 && gettabvar(2, 'val_str') == 'SetTabVar test' && gettabvar(2, 'val_list') == ['red', 'blue', 'green'] +: let test_status = 'gettabvar: pass' +:endif +:call append(line('$'), test_status) +:" +:tabnext 2 +:let test_status = 'settabvar: fail' +:if t:val_num == 100 && t:val_str == 'SetTabVar test' && t:val_list == ['red', 'blue', 'green'] +: let test_status = 'settabvar: pass' +:endif +:tabclose +:call append(line('$'), test_status) +:" +:if has('gui') || has('clientserver') +:" Test for ":tab drop exist-file" to keep current window. +:sp test1 +:tab drop test1 +:let test_status = 'tab drop 1: fail' +:if tabpagenr('$') == 1 && winnr('$') == 2 && winnr() == 1 +: let test_status = 'tab drop 1: pass' +:endif +:close +:call append(line('$'), test_status) +:" +:" +:" Test for ":tab drop new-file" to keep current window of tabpage 1. +:split +:tab drop newfile +:let test_status = 'tab drop 2: fail' +:if tabpagenr('$') == 2 && tabpagewinnr(1, '$') == 2 && tabpagewinnr(1) == 1 +: let test_status = 'tab drop 2: pass' +:endif +:tabclose +:q +:call append(line('$'), test_status) +:" +:" +:" Test for ":tab drop multi-opend-file" to keep current tabpage and window. +:new test1 +:tabnew +:new test1 +:tab drop test1 +:let test_status = 'tab drop 3: fail' +:if tabpagenr() == 2 && tabpagewinnr(2, '$') == 2 && tabpagewinnr(2) == 1 +: let test_status = 'tab drop 3: pass' +:endif +:tabclose +:q +:call append(line('$'), test_status) +:else +:" :drop not supported +:call append(line('$'), 'tab drop 1: pass') +:call append(line('$'), 'tab drop 2: pass') +:call append(line('$'), 'tab drop 3: pass') +:endif +:" +:" +:for i in range(9) | tabnew | endfor +1gt +Go=tabpagenr()
+:tabmove 5 +i=tabpagenr()
+:tabmove -2 +i=tabpagenr()
+:tabmove +4 +i=tabpagenr()
+:tabmove +i=tabpagenr()
+:tabmove -20 +i=tabpagenr()
+:tabmove +20 +i=tabpagenr()
+:3tabmove +i=tabpagenr()
+:7tabmove 5 +i=tabpagenr()
+:let a='No error caught.' +:try +:tabmove foo +:catch E474 +:let a='E474 caught.' +:endtry +i=a
+:" +:" Test autocommands +:tabonly! +:let g:r=[] +:command -nargs=1 -bar C :call add(g:r, '=== ' . <q-args> . ' ===')|<args> +:function Test() + let hasau=has('autocmd') + if hasau + autocmd TabEnter * :call add(g:r, 'TabEnter') + autocmd WinEnter * :call add(g:r, 'WinEnter') + autocmd BufEnter * :call add(g:r, 'BufEnter') + autocmd TabLeave * :call add(g:r, 'TabLeave') + autocmd WinLeave * :call add(g:r, 'WinLeave') + autocmd BufLeave * :call add(g:r, 'BufLeave') + endif + let t:a='a' + C tab split + if !hasau + let g:r+=['WinLeave', 'TabLeave', 'WinEnter', 'TabEnter'] + endif + let t:a='b' + C tabnew + if !hasau + let g:r+=['WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufLeave', 'BufEnter'] + endif + let t:a='c' + call add(g:r, join(map(range(1, tabpagenr('$')), 'gettabvar(v:val, "a")'))) + C call map(range(1, tabpagenr('$')), 'settabvar(v:val, ''a'', v:val*2)') + call add(g:r, join(map(range(1, tabpagenr('$')), 'gettabvar(v:val, "a")'))) + let w:a='a' + C vsplit + if !hasau + let g:r+=['WinLeave', 'WinEnter'] + endif + let w:a='a' + let tabn=tabpagenr() + let winr=range(1, winnr('$')) + C tabnext 1 + if !hasau + let g:r+=['BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufEnter'] + endif + call add(g:r, join(map(copy(winr), 'gettabwinvar('.tabn.', v:val, "a")'))) + C call map(copy(winr), 'settabwinvar('.tabn.', v:val, ''a'', v:val*2)') + call add(g:r, join(map(copy(winr), 'gettabwinvar('.tabn.', v:val, "a")'))) + if hasau + augroup TabDestructive + autocmd TabEnter * :C tabnext 2 | C tabclose 3 + augroup END + C tabnext 3 + let g:r+=[tabpagenr().'/'.tabpagenr('$')] + autocmd! TabDestructive TabEnter + C tabnew + C tabnext 1 + autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3 + C tabnext 3 + let g:r+=[tabpagenr().'/'.tabpagenr('$')] + else + let g:r+=["=== tabnext 3 ===","BufLeave","WinLeave","TabLeave","WinEnter","TabEnter","=== tabnext 2 ===","=== tabclose 3 ===","2/2","=== tabnew ===","WinLeave","TabLeave","WinEnter","TabEnter","BufLeave","BufEnter","=== tabnext 1 ===","BufLeave","WinLeave","TabLeave","WinEnter","TabEnter","BufEnter","=== tabnext 3 ===","BufLeave","WinLeave","TabLeave","WinEnter","TabEnter","=== tabnext 2 ===","BufLeave","WinLeave","TabLeave","WinEnter","TabEnter","=== tabnext 2 ===","=== tabclose 3 ===","BufEnter","=== tabclose 3 ===","2/2",] + endif +endfunction +:call Test() +:$ put =g:r +:" +:" +:/^Results/,$w! test.out +:qa! +ENDTEST + +Results: diff --git a/src/nvim/testdir/test62.ok b/src/nvim/testdir/test62.ok new file mode 100644 index 0000000000..e35b2b1c67 --- /dev/null +++ b/src/nvim/testdir/test62.ok @@ -0,0 +1,88 @@ +Results: +tab page 2 +this is tab page 3 +this is tab page 1 +this is tab page 4 +gettabvar: pass +settabvar: pass +tab drop 1: pass +tab drop 2: pass +tab drop 3: pass +1 +6 +4 +8 +10 +1 +10 +4 +6 +E474 caught. +=== tab split === +WinLeave +TabLeave +WinEnter +TabEnter +=== tabnew === +WinLeave +TabLeave +WinEnter +TabEnter +BufLeave +BufEnter +a b c +=== call map(range(1, tabpagenr('$')), 'settabvar(v:val, ''a'', v:val*2)') === +2 4 6 +=== vsplit === +WinLeave +WinEnter +=== tabnext 1 === +BufLeave +WinLeave +TabLeave +WinEnter +TabEnter +BufEnter +a a +=== call map(copy(winr), 'settabwinvar('.tabn.', v:val, ''a'', v:val*2)') === +2 4 +=== tabnext 3 === +BufLeave +WinLeave +TabLeave +WinEnter +TabEnter +=== tabnext 2 === +=== tabclose 3 === +2/2 +=== tabnew === +WinLeave +TabLeave +WinEnter +TabEnter +BufLeave +BufEnter +=== tabnext 1 === +BufLeave +WinLeave +TabLeave +WinEnter +TabEnter +BufEnter +=== tabnext 3 === +BufLeave +WinLeave +TabLeave +WinEnter +TabEnter +=== tabnext 2 === +BufLeave +WinLeave +TabLeave +WinEnter +TabEnter +=== tabnext 2 === +=== tabclose 3 === +BufEnter +=== tabclose 3 === +2/2 diff --git a/src/nvim/testdir/test63.in b/src/nvim/testdir/test63.in new file mode 100644 index 0000000000..74339c3e35 --- /dev/null +++ b/src/nvim/testdir/test63.in @@ -0,0 +1,157 @@ +Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()", +"matchadd()", "matcharg()", "matchdelete()", and "setmatches()". + +STARTTEST +:so small.vim +:" --- Check that "matcharg()" returns the correct group and pattern if a match +:" --- is defined. +:let @r = "*** Test 1: " +:highlight MyGroup1 ctermbg=red +:highlight MyGroup2 ctermbg=green +:highlight MyGroup3 ctermbg=blue +:match MyGroup1 /TODO/ +:2match MyGroup2 /FIXME/ +:3match MyGroup3 /XXX/ +:if matcharg(1) == ['MyGroup1', 'TODO'] && matcharg(2) == ['MyGroup2', 'FIXME'] && matcharg(3) == ['MyGroup3', 'XXX'] +: let @r .= "OK\n" +:else +: let @r .= "FAILED\n" +:endif +:" --- Check that "matcharg()" returns an empty list if the argument is not 1, +:" --- 2 or 3 (only 0 and 4 are tested). +:let @r .= "*** Test 2: " +:if matcharg(0) == [] && matcharg(4) == [] +: let @r .= "OK\n" +:else +: let @r .= "FAILED\n" +:endif +:" --- Check that "matcharg()" returns ['', ''] if a match is not defined. +:let @r .= "*** Test 3: " +:match +:2match +:3match +:if matcharg(1) == ['', ''] && matcharg(2) == ['', ''] && matcharg(3) == ['', ''] +: let @r .= "OK\n" +:else +: let @r .= "FAILED\n" +:endif +:" --- Check that "matchadd()" and "getmatches()" agree on added matches and +:" --- that default values apply. +:let @r .= "*** Test 4: " +:let m1 = matchadd("MyGroup1", "TODO") +:let m2 = matchadd("MyGroup2", "FIXME", 42) +:let m3 = matchadd("MyGroup3", "XXX", 60, 17) +:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5}, {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}] +: let @r .= "OK\n" +:else +: let @r .= "FAILED\n" +:endif +:" --- Check that "matchdelete()" deletes the matches defined in the previous +:" --- test correctly. +:let @r .= "*** Test 5: " +:call matchdelete(m1) +:call matchdelete(m2) +:call matchdelete(m3) +:unlet m1 +:unlet m2 +:unlet m3 +:if getmatches() == [] +: let @r .= "OK\n" +:else +: let @r .= "FAILED\n" +:endif +:" --- Check that "matchdelete()" returns 0 if successful and otherwise -1. +:let @r .= "*** Test 6: " +:let m = matchadd("MyGroup1", "TODO") +:let r1 = matchdelete(m) +:let r2 = matchdelete(42) +:if r1 == 0 && r2 == -1 +: let @r .= "OK\n" +:else +: let @r .= "FAILED\n" +:endif +:unlet m +:unlet r1 +:unlet r2 +:" --- Check that "clearmatches()" clears all matches defined by ":match" and +:" --- "matchadd()". +:let @r .= "*** Test 7: " +:let m1 = matchadd("MyGroup1", "TODO") +:let m2 = matchadd("MyGroup2", "FIXME", 42) +:let m3 = matchadd("MyGroup3", "XXX", 60, 17) +:match MyGroup1 /COFFEE/ +:2match MyGroup2 /HUMPPA/ +:3match MyGroup3 /VIM/ +:call clearmatches() +:if getmatches() == [] +: let @r .= "OK\n" +:else +: let @r .= "FAILED\n" +:endif +:unlet m1 +:unlet m2 +:unlet m3 +:" --- Check that "setmatches()" restores a list of matches saved by +:" --- "getmatches()" without changes. (Matches with equal priority must also +:" --- remain in the same order.) +:let @r .= "*** Test 8: " +:let m1 = matchadd("MyGroup1", "TODO") +:let m2 = matchadd("MyGroup2", "FIXME", 42) +:let m3 = matchadd("MyGroup3", "XXX", 60, 17) +:match MyGroup1 /COFFEE/ +:2match MyGroup2 /HUMPPA/ +:3match MyGroup3 /VIM/ +:let ml = getmatches() +:call clearmatches() +:call setmatches(ml) +:if getmatches() == ml +: let @r .= "OK\n" +:else +: let @r .= "FAILED\n" +:endif +:call clearmatches() +:unlet m1 +:unlet m2 +:unlet m3 +:unlet ml +:" --- Check that "setmatches()" will not add two matches with the same ID. The +:" --- expected behaviour (for now) is to add the first match but not the +:" --- second and to return 0 (even though it is a matter of debate whether +:" --- this can be considered successful behaviour). +:let @r .= "*** Test 9: " +:let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}]) +:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0 +: let @r .= "OK\n" +:else +: let @r .= "FAILED\n" +:endif +:call clearmatches() +:unlet r1 +:" --- Check that "setmatches()" returns 0 if successful and otherwise -1. +:" --- (A range of valid and invalid input values are tried out to generate the +:" --- return values.) +:let @r .= "*** Test 10: " +:let rs1 = setmatches([]) +:let rs2 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}]) +:call clearmatches() +:let rf1 = setmatches(0) +:let rf2 = setmatches([0]) +:let rf3 = setmatches([{'wrong key': 'wrong value'}]) +:if rs1 == 0 && rs2 == 0 && rf1 == -1 && rf2 == -1 && rf3 == -1 +: let @r .= "OK\n" +:else +: let @r .= "FAILED\n" +:endif +:unlet rs1 +:unlet rs2 +:unlet rf1 +:unlet rf2 +:unlet rf3 +:highlight clear MyGroup1 +:highlight clear MyGroup2 +:highlight clear MyGroup3 +G"rp +:/^Results/,$wq! test.out +ENDTEST + +Results of test63: diff --git a/src/nvim/testdir/test63.ok b/src/nvim/testdir/test63.ok new file mode 100644 index 0000000000..14973985eb --- /dev/null +++ b/src/nvim/testdir/test63.ok @@ -0,0 +1,11 @@ +Results of test63: +*** Test 1: OK +*** Test 2: OK +*** Test 3: OK +*** Test 4: OK +*** Test 5: OK +*** Test 6: OK +*** Test 7: OK +*** Test 8: OK +*** Test 9: OK +*** Test 10: OK diff --git a/src/nvim/testdir/test64.in b/src/nvim/testdir/test64.in new file mode 100644 index 0000000000..29bf0b902b --- /dev/null +++ b/src/nvim/testdir/test64.in @@ -0,0 +1,633 @@ +Test for regexp patterns without multi-byte support. +See test95 for multi-byte tests. + +A pattern that gives the expected result produces OK, so that we know it was +actually tried. + +STARTTEST +:so small.vim +:" tl is a List of Lists with: +:" regexp pattern +:" text to test the pattern on +:" expected match (optional) +:" expected submatch 1 (optional) +:" expected submatch 2 (optional) +:" etc. +:" When there is no match use only the first two items. +:let tl = [] +:" +:"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +:"""" Previously written tests """""""""""""""""""""""""""""""" +:"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +:" +:call add(tl, [2, 'ab', 'aab', 'ab']) +:call add(tl, [2, 'b', 'abcdef', 'b']) +:call add(tl, [2, 'bc*', 'abccccdef', 'bcccc']) +:call add(tl, [2, 'bc\{-}', 'abccccdef', 'b']) +:call add(tl, [2, 'bc\{-}\(d\)', 'abccccdef', 'bccccd', 'd']) +:call add(tl, [2, 'bc*', 'abbdef', 'b']) +:call add(tl, [2, 'c*', 'ccc', 'ccc']) +:call add(tl, [2, 'bc*', 'abdef', 'b']) +:call add(tl, [2, 'c*', 'abdef', '']) +:call add(tl, [2, 'bc\+', 'abccccdef', 'bcccc']) +:call add(tl, [2, 'bc\+', 'abdef']) "no match +:" +:"operator \| +:call add(tl, [2, 'a\|ab', 'cabd', 'a']) "alternation is ordered +:" +:call add(tl, [2, 'c\?', 'ccb', 'c']) +:call add(tl, [2, 'bc\?', 'abd', 'b']) +:call add(tl, [2, 'bc\?', 'abccd', 'bc']) +:" +:call add(tl, [2, '\va{1}', 'ab', 'a']) +:" +:call add(tl, [2, '\va{2}', 'aa', 'aa']) +:call add(tl, [2, '\va{2}', 'caad', 'aa']) +:call add(tl, [2, '\va{2}', 'aba']) +:call add(tl, [2, '\va{2}', 'ab']) +:call add(tl, [2, '\va{2}', 'abaa', 'aa']) +:call add(tl, [2, '\va{2}', 'aaa', 'aa']) +:" +:call add(tl, [2, '\vb{1}', 'abca', 'b']) +:call add(tl, [2, '\vba{2}', 'abaa', 'baa']) +:call add(tl, [2, '\vba{3}', 'aabaac']) +:" +:call add(tl, [2, '\v(ab){1}', 'ab', 'ab', 'ab']) +:call add(tl, [2, '\v(ab){1}', 'dabc', 'ab', 'ab']) +:call add(tl, [2, '\v(ab){1}', 'acb']) +:" +:call add(tl, [2, '\v(ab){0,2}', 'acb', "", ""]) +:call add(tl, [2, '\v(ab){0,2}', 'ab', 'ab', 'ab']) +:call add(tl, [2, '\v(ab){1,2}', 'ab', 'ab', 'ab']) +:call add(tl, [2, '\v(ab){1,2}', 'ababc', 'abab', 'ab']) +:call add(tl, [2, '\v(ab){2,4}', 'ababcab', 'abab', 'ab']) +:call add(tl, [2, '\v(ab){2,4}', 'abcababa', 'abab', 'ab']) +:" +:call add(tl, [2, '\v(ab){2}', 'abab', 'abab', 'ab']) +:call add(tl, [2, '\v(ab){2}', 'cdababe', 'abab', 'ab']) +:call add(tl, [2, '\v(ab){2}', 'abac']) +:call add(tl, [2, '\v(ab){2}', 'abacabab', 'abab', 'ab']) +:call add(tl, [2, '\v((ab){2}){2}', 'abababab', 'abababab', 'abab', 'ab']) +:call add(tl, [2, '\v((ab){2}){2}', 'abacabababab', 'abababab', 'abab', 'ab']) +:" +:call add(tl, [2, '\v(a{1}){1}', 'a', 'a', 'a']) +:call add(tl, [2, '\v(a{2}){1}', 'aa', 'aa', 'aa']) +:call add(tl, [2, '\v(a{2}){1}', 'aaac', 'aa', 'aa']) +:call add(tl, [2, '\v(a{2}){1}', 'daaac', 'aa', 'aa']) +:call add(tl, [2, '\v(a{1}){2}', 'daaac', 'aa', 'a']) +:call add(tl, [2, '\v(a{1}){2}', 'aaa', 'aa', 'a']) +:call add(tl, [2, '\v(a{2})+', 'adaac', 'aa', 'aa']) +:call add(tl, [2, '\v(a{2})+', 'aa', 'aa', 'aa']) +:call add(tl, [2, '\v(a{2}){1}', 'aa', 'aa', 'aa']) +:call add(tl, [2, '\v(a{1}){2}', 'aa', 'aa', 'a']) +:call add(tl, [2, '\v(a{1}){1}', 'a', 'a', 'a']) +:call add(tl, [2, '\v(a{2}){2}', 'aaaa', 'aaaa', 'aa']) +:call add(tl, [2, '\v(a{2}){2}', 'aaabaaaa', 'aaaa', 'aa']) +:" +:call add(tl, [2, '\v(a+){2}', 'dadaac', 'aa', 'a']) +:call add(tl, [2, '\v(a{3}){2}', 'aaaaaaa', 'aaaaaa', 'aaa']) +:" +:call add(tl, [2, '\v(a{1,2}){2}', 'daaac', 'aaa', 'a']) +:call add(tl, [2, '\v(a{1,3}){2}', 'daaaac', 'aaaa', 'a']) +:call add(tl, [2, '\v(a{1,3}){2}', 'daaaaac', 'aaaaa', 'aa']) +:call add(tl, [2, '\v(a{1,3}){3}', 'daac']) +:call add(tl, [2, '\v(a{1,2}){2}', 'dac']) +:call add(tl, [2, '\v(a+)+', 'daac', 'aa', 'aa']) +:call add(tl, [2, '\v(a+)+', 'aaa', 'aaa', 'aaa']) +:call add(tl, [2, '\v(a+){1,2}', 'aaa', 'aaa', 'aaa']) +:call add(tl, [2, '\v(a+)(a+)', 'aaa', 'aaa', 'aa', 'a']) +:call add(tl, [2, '\v(a{3})+', 'daaaac', 'aaa', 'aaa']) +:call add(tl, [2, '\v(a|b|c)+', 'aacb', 'aacb', 'b']) +:call add(tl, [2, '\v(a|b|c){2}', 'abcb', 'ab', 'b']) +:call add(tl, [2, '\v(abc){2}', 'abcabd', ]) +:call add(tl, [2, '\v(abc){2}', 'abdabcabc','abcabc', 'abc']) +:" +:call add(tl, [2, 'a*', 'cc', '']) +:call add(tl, [2, '\v(a*)+', 'cc', '']) +:call add(tl, [2, '\v((ab)+)+', 'ab', 'ab', 'ab', 'ab']) +:call add(tl, [2, '\v(((ab)+)+)+', 'ab', 'ab', 'ab', 'ab', 'ab']) +:call add(tl, [2, '\v(((ab)+)+)+', 'dababc', 'abab', 'abab', 'abab', 'ab']) +:call add(tl, [2, '\v(a{0,2})+', 'cc', '']) +:call add(tl, [2, '\v(a*)+', '', '']) +:call add(tl, [2, '\v((a*)+)+', '', '']) +:call add(tl, [2, '\v((ab)*)+', '', '']) +:call add(tl, [2, '\va{1,3}', 'aab', 'aa']) +:call add(tl, [2, '\va{2,3}', 'abaa', 'aa']) +:" +:call add(tl, [2, '\v((ab)+|c*)+', 'abcccaba', 'abcccab', '', 'ab']) +:call add(tl, [2, '\v(a{2})|(b{3})', 'bbabbbb', 'bbb', '', 'bbb']) +:call add(tl, [2, '\va{2}|b{2}', 'abab']) +:call add(tl, [2, '\v(a)+|(c)+', 'bbacbaacbbb', 'a', 'a']) +:call add(tl, [2, '\vab{2,3}c', 'aabbccccccccccccc', 'abbc']) +:call add(tl, [2, '\vab{2,3}c', 'aabbbccccccccccccc', 'abbbc']) +:call add(tl, [2, '\vab{2,3}cd{2,3}e', 'aabbbcddee', 'abbbcdde']) +:call add(tl, [2, '\va(bc){2}d', 'aabcbfbc' ]) +:call add(tl, [2, '\va*a{2}', 'a', ]) +:call add(tl, [2, '\va*a{2}', 'aa', 'aa' ]) +:call add(tl, [2, '\va*a{2}', 'aaa', 'aaa' ]) +:call add(tl, [2, '\va*a{2}', 'bbbabcc', ]) +:call add(tl, [2, '\va*b*|a*c*', 'a', 'a']) +:call add(tl, [2, '\va{1}b{1}|a{1}b{1}', '']) +:" +:"submatches +:call add(tl, [2, '\v(a)', 'ab', 'a', 'a']) +:call add(tl, [2, '\v(a)(b)', 'ab', 'ab', 'a', 'b']) +:call add(tl, [2, '\v(ab)(b)(c)', 'abbc', 'abbc', 'ab', 'b', 'c']) +:call add(tl, [2, '\v((a)(b))', 'ab', 'ab', 'ab', 'a', 'b']) +:call add(tl, [2, '\v(a)|(b)', 'ab', 'a', 'a']) +:" +:call add(tl, [2, '\v(a*)+', 'aaaa', 'aaaa', '']) +:call add(tl, [2, 'x', 'abcdef']) +:" +:"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +:""""" Simple tests """"""""""""""""""""""""""""""""""""""""""" +:"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +:" +:" Search single groups +:call add(tl, [2, 'ab', 'aab', 'ab']) +:call add(tl, [2, 'ab', 'baced']) +:call add(tl, [2, 'ab', ' ab ', 'ab']) +:" +:" Search multi-modifiers +:call add(tl, [2, 'x*', 'xcd', 'x']) +:call add(tl, [2, 'x*', 'xxxxxxxxxxxxxxxxsofijiojgf', 'xxxxxxxxxxxxxxxx']) +:" empty match is good +:call add(tl, [2, 'x*', 'abcdoij', '']) +:" no match here +:call add(tl, [2, 'x\+', 'abcdoin']) +:call add(tl, [2, 'x\+', 'abcdeoijdfxxiuhfij', 'xx']) +:call add(tl, [2, 'x\+', 'xxxxx', 'xxxxx']) +:call add(tl, [2, 'x\+', 'abc x siufhiush xxxxxxxxx', 'x']) +:call add(tl, [2, 'x\=', 'x sdfoij', 'x']) +:call add(tl, [2, 'x\=', 'abc sfoij', '']) " empty match is good +:call add(tl, [2, 'x\=', 'xxxxxxxxx c', 'x']) +:call add(tl, [2, 'x\?', 'x sdfoij', 'x']) +:" empty match is good +:call add(tl, [2, 'x\?', 'abc sfoij', '']) +:call add(tl, [2, 'x\?', 'xxxxxxxxxx c', 'x']) +:" +:call add(tl, [2, 'a\{0,0}', 'abcdfdoij', '']) +:" same thing as 'a?' +:call add(tl, [2, 'a\{0,1}', 'asiubid axxxaaa', 'a']) +:" same thing as 'a\{0,1}' +:call add(tl, [2, 'a\{1,0}', 'asiubid axxxaaa', 'a']) +:call add(tl, [2, 'a\{3,6}', 'aa siofuh']) +:call add(tl, [2, 'a\{3,6}', 'aaaaa asfoij afaa', 'aaaaa']) +:call add(tl, [2, 'a\{3,6}', 'aaaaaaaa', 'aaaaaa']) +:call add(tl, [2, 'a\{0}', 'asoiuj', '']) +:call add(tl, [2, 'a\{2}', 'aaaa', 'aa']) +:call add(tl, [2, 'a\{2}', 'iuash fiusahfliusah fiushfilushfi uhsaifuh askfj nasfvius afg aaaa sfiuhuhiushf', 'aa']) +:call add(tl, [2, 'a\{2}', 'abcdefghijklmnopqrestuvwxyz1234567890']) +:" same thing as 'a*' +:call add(tl, [2, 'a\{0,}', 'oij sdigfusnf', '']) +:call add(tl, [2, 'a\{0,}', 'aaaaa aa', 'aaaaa']) +:call add(tl, [2, 'a\{2,}', 'sdfiougjdsafg']) +:call add(tl, [2, 'a\{2,}', 'aaaaasfoij ', 'aaaaa']) +:call add(tl, [2, 'a\{5,}', 'xxaaaaxxx ']) +:call add(tl, [2, 'a\{5,}', 'xxaaaaaxxx ', 'aaaaa']) +:call add(tl, [2, 'a\{,0}', 'oidfguih iuhi hiu aaaa', '']) +:call add(tl, [2, 'a\{,5}', 'abcd', 'a']) +:call add(tl, [2, 'a\{,5}', 'aaaaaaaaaa', 'aaaaa']) +:" leading star as normal char when \{} follows +:call add(tl, [2, '^*\{4,}$', '***']) +:call add(tl, [2, '^*\{4,}$', '****', '****']) +:call add(tl, [2, '^*\{4,}$', '*****', '*****']) +:" same thing as 'a*' +:call add(tl, [2, 'a\{}', 'bbbcddiuhfcd', '']) +:call add(tl, [2, 'a\{}', 'aaaaioudfh coisf jda', 'aaaa']) +:" +:call add(tl, [2, 'a\{-0,0}', 'abcdfdoij', '']) +:" anti-greedy version of 'a?' +:call add(tl, [2, 'a\{-0,1}', 'asiubid axxxaaa', '']) +:call add(tl, [2, 'a\{-3,6}', 'aa siofuh']) +:call add(tl, [2, 'a\{-3,6}', 'aaaaa asfoij afaa', 'aaa']) +:call add(tl, [2, 'a\{-3,6}', 'aaaaaaaa', 'aaa']) +:call add(tl, [2, 'a\{-0}', 'asoiuj', '']) +:call add(tl, [2, 'a\{-2}', 'aaaa', 'aa']) +:call add(tl, [2, 'a\{-2}', 'abcdefghijklmnopqrestuvwxyz1234567890']) +:call add(tl, [2, 'a\{-0,}', 'oij sdigfusnf', '']) +:call add(tl, [2, 'a\{-0,}', 'aaaaa aa', '']) +:call add(tl, [2, 'a\{-2,}', 'sdfiougjdsafg']) +:call add(tl, [2, 'a\{-2,}', 'aaaaasfoij ', 'aa']) +:call add(tl, [2, 'a\{-,0}', 'oidfguih iuhi hiu aaaa', '']) +:call add(tl, [2, 'a\{-,5}', 'abcd', '']) +:call add(tl, [2, 'a\{-,5}', 'aaaaaaaaaa', '']) +:" anti-greedy version of 'a*' +:call add(tl, [2, 'a\{-}', 'bbbcddiuhfcd', '']) +:call add(tl, [2, 'a\{-}', 'aaaaioudfh coisf jda', '']) +:" +:" Test groups of characters and submatches +:call add(tl, [2, '\(abc\)*', 'abcabcabc', 'abcabcabc', 'abc']) +:call add(tl, [2, '\(ab\)\+', 'abababaaaaa', 'ababab', 'ab']) +:call add(tl, [2, '\(abaaaaa\)*cd', 'cd', 'cd', '']) +:call add(tl, [2, '\(test1\)\? \(test2\)\?', 'test1 test3', 'test1 ', 'test1', '']) +:call add(tl, [2, '\(test1\)\= \(test2\) \(test4443\)\=', ' test2 test4443 yupiiiiiiiiiii', ' test2 test4443', '', 'test2', 'test4443']) +:call add(tl, [2, '\(\(sub1\) hello \(sub 2\)\)', 'asterix sub1 hello sub 2 obelix', 'sub1 hello sub 2', 'sub1 hello sub 2', 'sub1', 'sub 2']) +:call add(tl, [2, '\(\(\(yyxxzz\)\)\)', 'abcdddsfiusfyyzzxxyyxxzz', 'yyxxzz', 'yyxxzz', 'yyxxzz', 'yyxxzz']) +:call add(tl, [2, '\v((ab)+|c+)+', 'abcccaba', 'abcccab', 'ab', 'ab']) +:call add(tl, [2, '\v((ab)|c*)+', 'abcccaba', 'abcccab', '', 'ab']) +:call add(tl, [2, '\v(a(c*)+b)+', 'acbababaaa', 'acbabab', 'ab', '']) +:call add(tl, [2, '\v(a|b*)+', 'aaaa', 'aaaa', '']) +:call add(tl, [2, '\p*', 'aá ', 'aá ']) +:" +:" Test greedy-ness and lazy-ness +:call add(tl, [2, 'a\{-2,7}','aaaaaaaaaaaaa', 'aa']) +:call add(tl, [2, 'a\{-2,7}x','aaaaaaaaax', 'aaaaaaax']) +:call add(tl, [2, 'a\{2,7}','aaaaaaaaaaaaaaaaaaaa', 'aaaaaaa']) +:call add(tl, [2, 'a\{2,7}x','aaaaaaaaax', 'aaaaaaax']) +:call add(tl, [2, '\vx(.{-,8})yz(.*)','xayxayzxayzxayz','xayxayzxayzxayz','ayxa','xayzxayz']) +:call add(tl, [2, '\vx(.*)yz(.*)','xayxayzxayzxayz','xayxayzxayzxayz', 'ayxayzxayzxa','']) +:call add(tl, [2, '\v(a{1,2}){-2,3}','aaaaaaa','aaaa','aa']) +:call add(tl, [2, '\v(a{-1,3})+','aa','aa','a']) +:" +:" Test Character classes +:call add(tl, [2, '\d\+e\d\d','test 10e23 fd','10e23']) +:" +:" Test collections and character range [] +:call add(tl, [2, '\v[a]', 'abcd', 'a']) +:call add(tl, [2, 'a[bcd]', 'abcd', 'ab']) +:call add(tl, [2, 'a[b-d]', 'acbd', 'ac']) +:call add(tl, [2, '[a-d][e-f][x-x]d', 'cexdxx', 'cexd']) +:call add(tl, [2, '\v[[:alpha:]]+', 'abcdefghijklmnopqrstuvwxyz6','abcdefghijklmnopqrstuvwxyz']) +:call add(tl, [2, '[[:alpha:]\+]', '6x8','x']) +:call add(tl, [2, '[^abc]\+','abcabcabc']) +:call add(tl, [2, '[^abc]','defghiasijvoinasoiunbvb','d']) +:call add(tl, [2, '[^abc]\+','ddddddda','ddddddd']) +:call add(tl, [2, '[^a-d]\+','aaaAAAZIHFNCddd','AAAZIHFNC']) +:call add(tl, [2, '[a-f]*','iiiiiiii','']) +:call add(tl, [2, '[a-f]*','abcdefgh','abcdef']) +:call add(tl, [2, '[^a-f]\+','abcdefgh','gh']) +:call add(tl, [2, '[a-c]\{-3,6}','abcabc','abc']) +:call add(tl, [2, '[^[:alpha:]]\+','abcccadfoij7787ysf287yrnccdu','7787']) +:call add(tl, [2, '[-a]', '-', '-']) +:call add(tl, [2, '[a-]', '-', '-']) +:call add(tl, [2, '[a-f]*\c','ABCDEFGH','ABCDEF']) +:call add(tl, [2, '[abc][xyz]\c','-af-AF-BY--','BY']) +:" filename regexp +:call add(tl, [2, '[-./[:alnum:]_~]\+', 'log13.file', 'log13.file']) +:" special chars +:call add(tl, [2, '[\]\^\-\\]\+', '\^\\\-\---^', '\^\\\-\---^']) +:" collation elem +:call add(tl, [2, '[[.a.]]\+', 'aa', 'aa']) +:" middle of regexp +:call add(tl, [2, 'abc[0-9]*ddd', 'siuhabc ii']) +:call add(tl, [2, 'abc[0-9]*ddd', 'adf abc44482ddd oijs', 'abc44482ddd']) +:call add(tl, [2, '\_[0-9]\+', 'asfi9888u', '9888']) +:call add(tl, [2, '[0-9\n]\+', 'asfi9888u', '9888']) +:call add(tl, [2, '\_[0-9]\+', "asfi\n9888u", "\n9888"]) +:call add(tl, [2, '\_f', " \na ", "\n"]) +:call add(tl, [2, '\_f\+', " \na ", "\na"]) +:call add(tl, [2, '[0-9A-Za-z-_.]\+', " @0_a.A-{ ", "0_a.A-"]) +:" +:"""" Test start/end of line, start/end of file +:call add(tl, [2, '^a.', "a_\nb ", "a_"]) +:call add(tl, [2, '^a.', "b a \na_"]) +:call add(tl, [2, '.a$', " a\n "]) +:call add(tl, [2, '.a$', " a b\n_a", "_a"]) +:call add(tl, [2, '\%^a.', "a a\na", "a "]) +:call add(tl, [2, '\%^a', " a \na "]) +:call add(tl, [2, '.a\%$', " a\n "]) +:call add(tl, [2, '.a\%$', " a\n_a", "_a"]) +:" +:"""" Test recognition of character classes +:call add(tl, [2, '[0-7]\+', 'x0123456789x', '01234567']) +:call add(tl, [2, '[^0-7]\+', '0a;X+% 897', 'a;X+% 89']) +:call add(tl, [2, '[0-9]\+', 'x0123456789x', '0123456789']) +:call add(tl, [2, '[^0-9]\+', '0a;X+% 9', 'a;X+% ']) +:call add(tl, [2, '[0-9a-fA-F]\+', 'x0189abcdefg', '0189abcdef']) +:call add(tl, [2, '[^0-9A-Fa-f]\+', '0189g;X+% ab', 'g;X+% ']) +:call add(tl, [2, '[a-z_A-Z0-9]\+', ';+aso_SfOij ', 'aso_SfOij']) +:call add(tl, [2, '[^a-z_A-Z0-9]\+', 'aSo_;+% sfOij', ';+% ']) +:call add(tl, [2, '[a-z_A-Z]\+', '0abyz_ABYZ;', 'abyz_ABYZ']) +:call add(tl, [2, '[^a-z_A-Z]\+', 'abAB_09;+% yzYZ', '09;+% ']) +:call add(tl, [2, '[a-z]\+', '0abcxyz1', 'abcxyz']) +:call add(tl, [2, '[a-z]\+', 'AabxyzZ', 'abxyz']) +:call add(tl, [2, '[^a-z]\+', 'a;X09+% x', ';X09+% ']) +:call add(tl, [2, '[^a-z]\+', 'abX0;%yz', 'X0;%']) +:call add(tl, [2, '[a-zA-Z]\+', '0abABxzXZ9', 'abABxzXZ']) +:call add(tl, [2, '[^a-zA-Z]\+', 'ab09_;+ XZ', '09_;+ ']) +:call add(tl, [2, '[A-Z]\+', 'aABXYZz', 'ABXYZ']) +:call add(tl, [2, '[^A-Z]\+', 'ABx0;%YZ', 'x0;%']) +:call add(tl, [2, '[a-z]\+\c', '0abxyzABXYZ;', 'abxyzABXYZ']) +:call add(tl, [2, '[A-Z]\+\c', '0abABxzXZ9', 'abABxzXZ']) +:call add(tl, [2, '\c[^a-z]\+', 'ab09_;+ XZ', '09_;+ ']) +:call add(tl, [2, '\c[^A-Z]\+', 'ab09_;+ XZ', '09_;+ ']) +:call add(tl, [2, '\C[^A-Z]\+', 'ABCOIJDEOIFNSD jsfoij sa', ' jsfoij sa']) +:" +:"""" Tests for \z features +:" match ends at \ze +:call add(tl, [2, 'xx \ze test', 'xx ']) +:call add(tl, [2, 'abc\zeend', 'oij abcend', 'abc']) +:call add(tl, [2, 'aa\zebb\|aaxx', ' aabb ', 'aa']) +:call add(tl, [2, 'aa\zebb\|aaxx', ' aaxx ', 'aaxx']) +:call add(tl, [2, 'aabb\|aa\zebb', ' aabb ', 'aabb']) +:call add(tl, [2, 'aa\zebb\|aaebb', ' aabb ', 'aa']) +:" match starts at \zs +:call add(tl, [2, 'abc\zsdd', 'ddabcddxyzt', 'dd']) +:call add(tl, [2, 'aa \zsax', ' ax']) +:call add(tl, [2, 'abc \zsmatch\ze abc', 'abc abc abc match abc abc', 'match']) +:call add(tl, [2, '\v(a \zsif .*){2}', 'a if then a if last', 'if last', 'a if last']) +:call add(tl, [2, '\>\zs.', 'aword. ', '.']) +:call add(tl, [2, '\s\+\ze\[/\|\s\zs\s\+', 'is [a t', ' ']) +:" +:"""" Tests for \@= and \& features +:call add(tl, [2, 'abc\@=', 'abc', 'ab']) +:call add(tl, [2, 'abc\@=cd', 'abcd', 'abcd']) +:call add(tl, [2, 'abc\@=', 'ababc', 'ab']) +:" will never match, no matter the input text +:call add(tl, [2, 'abcd\@=e', 'abcd']) +:" will never match +:call add(tl, [2, 'abcd\@=e', 'any text in here ... ']) +:call add(tl, [2, '\v(abc)@=..', 'xabcd', 'ab', 'abc']) +:call add(tl, [2, '\(.*John\)\@=.*Bob', 'here is John, and here is B']) +:call add(tl, [2, '\(John.*\)\@=.*Bob', 'John is Bobs friend', 'John is Bob', 'John is Bobs friend']) +:call add(tl, [2, '\<\S\+\())\)\@=', '$((i=i+1))', 'i=i+1', '))']) +:call add(tl, [2, '.*John\&.*Bob', 'here is John, and here is B']) +:call add(tl, [2, '.*John\&.*Bob', 'John is Bobs friend', 'John is Bob']) +:call add(tl, [2, '\v(test1)@=.*yep', 'this is a test1, yep it is', 'test1, yep', 'test1']) +:call add(tl, [2, 'foo\(bar\)\@!', 'foobar']) +:call add(tl, [2, 'foo\(bar\)\@!', 'foo bar', 'foo']) +:call add(tl, [2, 'if \(\(then\)\@!.\)*$', ' if then else']) +:call add(tl, [2, 'if \(\(then\)\@!.\)*$', ' if else ', 'if else ', ' ']) +:call add(tl, [2, '\(foo\)\@!bar', 'foobar', 'bar']) +:call add(tl, [2, '\(foo\)\@!...bar', 'foobar']) +:call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' bar foo ']) +:call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' foo bar ']) +:call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' foo xxx ', 'foo']) +:call add(tl, [2, '[ ]\@!\p\%([ ]\@!\p\)*:', 'implicit mappings:', 'mappings:']) +:call add(tl, [2, '[ ]\@!\p\([ ]\@!\p\)*:', 'implicit mappings:', 'mappings:', 's']) +:call add(tl, [2, 'm\k\+_\@=\%(_\@!\k\)\@<=\k\+e', 'mx__xe', 'mx__xe']) +:call add(tl, [2, '\%(\U\@<=S\k*\|S\l\)R', 'SuR', 'SuR']) +:" +:"""" Combining different tests and features +:call add(tl, [2, '[[:alpha:]]\{-2,6}', '787abcdiuhsasiuhb4', 'ab']) +:call add(tl, [2, '', 'abcd', '']) +:call add(tl, [2, '\v(())', 'any possible text', '']) +:call add(tl, [2, '\v%(ab(xyz)c)', ' abxyzc ', 'abxyzc', 'xyz']) +:call add(tl, [2, '\v(test|)empty', 'tesempty', 'empty', '']) +:call add(tl, [2, '\v(a|aa)(a|aa)', 'aaa', 'aa', 'a', 'a']) +:" +:"""" \%u and friends +:call add(tl, [2, '\%d32', 'yes no', ' ']) +:call add(tl, [2, '\%o40', 'yes no', ' ']) +:call add(tl, [2, '\%x20', 'yes no', ' ']) +:call add(tl, [2, '\%u0020', 'yes no', ' ']) +:call add(tl, [2, '\%U00000020', 'yes no', ' ']) +:call add(tl, [2, '\%d0', "yes\x0ano", "\x0a"]) +:" +:""""" \%[abc] +:call add(tl, [2, 'foo\%[bar]', 'fobar']) +:call add(tl, [2, 'foo\%[bar]', 'foobar', 'foobar']) +:call add(tl, [2, 'foo\%[bar]', 'fooxx', 'foo']) +:call add(tl, [2, 'foo\%[bar]', 'foobxx', 'foob']) +:call add(tl, [2, 'foo\%[bar]', 'foobaxx', 'fooba']) +:call add(tl, [2, 'foo\%[bar]', 'foobarxx', 'foobar']) +:call add(tl, [2, 'foo\%[bar]x', 'foobxx', 'foobx']) +:call add(tl, [2, 'foo\%[bar]x', 'foobarxx', 'foobarx']) +:call add(tl, [2, '\%[bar]x', 'barxx', 'barx']) +:call add(tl, [2, '\%[bar]x', 'bxx', 'bx']) +:call add(tl, [2, '\%[bar]x', 'xxx', 'x']) +:call add(tl, [2, 'b\%[[ao]r]', 'bar bor', 'bar']) +:call add(tl, [2, 'b\%[[]]r]', 'b]r bor', 'b]r']) +:call add(tl, [2, '@\%[\w\-]*', '<http://john.net/pandoc/>[@pandoc]', '@pandoc']) +:" +:"""" Alternatives, must use first longest match +:call add(tl, [2, 'goo\|go', 'google', 'goo']) +:call add(tl, [2, '\<goo\|\<go', 'google', 'goo']) +:call add(tl, [2, '\<goo\|go', 'google', 'goo']) +:" +:"""" Back references +:call add(tl, [2, '\(\i\+\) \1', ' abc abc', 'abc abc', 'abc']) +:call add(tl, [2, '\(\i\+\) \1', 'xgoo goox', 'goo goo', 'goo']) +:call add(tl, [2, '\(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9', 'xabcddefghiabcddefghix', 'abcddefghiabcddefghi', 'a', 'b', 'c', 'dd', 'e', 'f', 'g', 'h', 'i']) +:call add(tl, [2, '\(\d*\)a \1b', ' a b ', 'a b', '']) +:call add(tl, [2, '^.\(.\).\_..\1.', "aaa\naaa\nb", "aaa\naaa", 'a']) +:call add(tl, [2, '^.*\.\(.*\)/.\+\(\1\)\@<!$', 'foo.bat/foo.com', 'foo.bat/foo.com', 'bat']) +:call add(tl, [2, '^.*\.\(.*\)/.\+\(\1\)\@<!$', 'foo.bat/foo.bat']) +:call add(tl, [2, '^.*\.\(.*\)/.\+\(\1\)\@<=$', 'foo.bat/foo.bat', 'foo.bat/foo.bat', 'bat', 'bat']) +:call add(tl, [2, '\\\@<!\${\(\d\+\%(:.\{-}\)\?\\\@<!\)}', '2013-06-27${0}', '${0}', '0']) +:call add(tl, [2, '^\(a*\)\1$', 'aaaaaaaa', 'aaaaaaaa', 'aaaa']) +:" +:"""" Look-behind with limit +:call add(tl, [2, '<\@<=span.', 'xxspanxx<spanyyy', 'spany']) +:call add(tl, [2, '<\@1<=span.', 'xxspanxx<spanyyy', 'spany']) +:call add(tl, [2, '<\@2<=span.', 'xxspanxx<spanyyy', 'spany']) +:call add(tl, [2, '\(<<\)\@<=span.', 'xxspanxxxx<spanxx<<spanyyy', 'spany', '<<']) +:call add(tl, [2, '\(<<\)\@1<=span.', 'xxspanxxxx<spanxx<<spanyyy']) +:call add(tl, [2, '\(<<\)\@2<=span.', 'xxspanxxxx<spanxx<<spanyyy', 'spany', '<<']) +:call add(tl, [2, '\(foo\)\@<!bar.', 'xx foobar1 xbar2 xx', 'bar2']) +:" +:" look-behind match in front of a zero-width item +:call add(tl, [2, '\v\C%(<Last Changed:\s+)@<=.*$', '" test header']) +:call add(tl, [2, '\v\C%(<Last Changed:\s+)@<=.*$', '" Last Changed: 1970', '1970']) +:call add(tl, [2, '\(foo\)\@<=\>', 'foobar']) +:call add(tl, [2, '\(foo\)\@<=\>', 'barfoo', '', 'foo']) +:call add(tl, [2, '\(foo\)\@<=.*', 'foobar', 'bar', 'foo']) +:" +:" complicated look-behind match +:call add(tl, [2, '\(r\@<=\|\w\@<!\)\/', 'x = /word/;', '/']) +:call add(tl, [2, '^[a-z]\+\ze \&\(asdf\)\@<!', 'foo bar', 'foo']) +:" +:""""" \@> +:call add(tl, [2, '\(a*\)\@>a', 'aaaa']) +:call add(tl, [2, '\(a*\)\@>b', 'aaab', 'aaab', 'aaa']) +:call add(tl, [2, '^\(.\{-}b\)\@>.', ' abcbd', ' abc', ' ab']) +:call add(tl, [2, '\(.\{-}\)\(\)\@>$', 'abc', 'abc', 'abc', '']) +:" TODO: BT engine does not restore submatch after failure +:call add(tl, [1, '\(a*\)\@>a\|a\+', 'aaaa', 'aaaa']) +:" +:"""" "\_" prepended negated collection matches EOL +:call add(tl, [2, '\_[^8-9]\+', "asfi\n9888", "asfi\n"]) +:call add(tl, [2, '\_[^a]\+', "asfi\n9888", "sfi\n9888"]) +:" +:"""" Requiring lots of states. +:call add(tl, [2, '[0-9a-zA-Z]\{8}-\([0-9a-zA-Z]\{4}-\)\{3}[0-9a-zA-Z]\{12}', " 12345678-1234-1234-1234-123456789012 ", "12345678-1234-1234-1234-123456789012", "1234-"]) +:" +:"""" Skip adding state twice +:call add(tl, [2, '^\%(\%(^\s*#\s*if\>\|#\s*if\)\)\(\%>1c.*$\)\@=', "#if FOO", "#if", ' FOO']) +:" +:"""" Run the tests +:" +:for t in tl +: let re = t[0] +: let pat = t[1] +: let text = t[2] +: let matchidx = 3 +: for engine in [0, 1, 2] +: if engine == 2 && re == 0 || engine == 1 && re ==1 +: continue +: endif +: let ®expengine = engine +: try +: let l = matchlist(text, pat) +: catch +: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", caused an exception: \"' . v:exception . '\"' +: endtry +:" check the match itself +: if len(l) == 0 && len(t) > matchidx +: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", did not match, expected: \"' . t[matchidx] . '\"' +: elseif len(l) > 0 && len(t) == matchidx +: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected no match' +: elseif len(t) > matchidx && l[0] != t[matchidx] +: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected: \"' . t[matchidx] . '\"' +: else +: $put ='OK ' . engine . ' - ' . pat +: endif +: if len(l) > 0 +:" check all the nine submatches +: for i in range(1, 9) +: if len(t) <= matchidx + i +: let e = '' +: else +: let e = t[matchidx + i] +: endif +: if l[i] != e +: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"' +: endif +: endfor +: unlet i +: endif +: endfor +:endfor +:unlet t tl e l +:" +:"""""" multi-line tests """""""""""""""""""" +:let tl = [] +:" +:"""" back references +:call add(tl, [2, '^.\(.\).\_..\1.', ['aaa', 'aaa', 'b'], ['XX', 'b']]) +:call add(tl, [2, '\v.*\/(.*)\n.*\/\1$', ['./Dir1/Dir2/zyxwvuts.txt', './Dir1/Dir2/abcdefgh.bat', '', './Dir1/Dir2/file1.txt', './OtherDir1/OtherDir2/file1.txt'], ['./Dir1/Dir2/zyxwvuts.txt', './Dir1/Dir2/abcdefgh.bat', '', 'XX']]) +:" +:"""" line breaks +:call add(tl, [2, '\S.*\nx', ['abc', 'def', 'ghi', 'xjk', 'lmn'], ['abc', 'def', 'XXjk', 'lmn']]) +:" +:" Check that \_[0-9] matching EOL does not break a following \> +:call add(tl, [2, '\<\(\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\.\)\{3\}\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\>', ['', 'localnet/192.168.0.1', ''], ['', 'localnet/XX', '']]) +:" +:" Check a pattern with a line break and ^ and $ +:call add(tl, [2, 'a\n^b$\n^c', ['a', 'b', 'c'], ['XX']]) +:" +:call add(tl, [2, '\(^.\+\n\)\1', [' dog', ' dog', 'asdf'], ['XXasdf']]) +:" +:"""" Run the multi-line tests +:" +:$put ='multi-line tests' +:for t in tl +: let re = t[0] +: let pat = t[1] +: let before = t[2] +: let after = t[3] +: for engine in [0, 1, 2] +: if engine == 2 && re == 0 || engine == 1 && re ==1 +: continue +: endif +: let ®expengine = engine +: new +: call setline(1, before) +: exe '%s/' . pat . '/XX/' +: let result = getline(1, '$') +: q! +: if result != after +: $put ='ERROR: pat: \"' . pat . '\", text: \"' . string(before) . '\", expected: \"' . string(after) . '\", got: \"' . string(result) . '\"' +: else +: $put ='OK ' . engine . ' - ' . pat +: endif +: endfor +:endfor +:unlet t tl +:" +:" Check that using a pattern on two lines doesn't get messed up by using +:" matchstr() with \ze in between. +:set re=0 +/^Substitute here +:.+1,.+2s/""/\='"'.matchstr(getline("."), '\d\+\ze<').'"' +/^Substitute here +:.+1,.+2yank +Gop:" +:" +:" Check a pattern with a look beind crossing a line boundary +/^Behind: +/\(<\_[xy]\+\)\@3<=start +:.yank +Gop:" +:" +:" Check matching Visual area +/^Visual: +jfxvfx:s/\%Ve/E/g +jV:s/\%Va/A/g +jfxfxj:s/\%Vo/O/g +:/^Visual/+1,/^Visual/+4yank +Gop:" +:" +:" Check matching marks +/^Marks: +jfSmsfEme:.-4,.+6s/.\%>'s.*\%<'e../here/ +jfSmsj0fEme:.-4,.+6s/.\%>'s\_.*\%<'e../again/ +:/^Marks:/+1,/^Marks:/+3yank +Gop:" +:" +:" Check patterns matching cursor position. +:func! Postest() + new + call setline(1, ['ffooooo', 'boboooo', 'zoooooo', 'koooooo', 'moooooo', "\t\t\tfoo", 'abababababababfoo', 'bababababababafoo', '********_']) + call setpos('.', [0, 1, 0, 0]) + s/\%>3c.//g + call setpos('.', [0, 2, 4, 0]) + s/\%#.*$//g + call setpos('.', [0, 3, 0, 0]) + s/\%<3c./_/g + %s/\%4l\%>5c./_/g + %s/\%6l\%>25v./_/g + %s/\%>6l\%3c./!/g + %s/\%>7l\%12c./?/g + %s/\%>7l\%<9l\%>5v\%<8v./#/g + 1,$yank + quit! +endfunc +Go-0-:set re=0 +:call Postest() +:put +o-1-:set re=1 +:call Postest() +:put +o-2-:set re=2 +:call Postest() +:put +:" +:" start and end of buffer +/\%^ +yeGop:" +50%/\%^.. +yeGopA END:" +50%/\%$ +"ayb20gg/..\%$ +"bybGo"apo"bp:" +:" +:""""" Write the results """"""""""""" +:/\%#=1^Results/,$wq! test.out +ENDTEST + +Substitute here: +<T="">Ta 5</Title> +<T="">Ac 7</Title> + +Behind: +asdfasd<yyy +xxstart1 +asdfasd<yy +xxxstart2 +asdfasd<yy +xxstart3 + +Visual: +thexe the thexethe +andaxand andaxand +oooxofor foroxooo +oooxofor foroxooo + +Marks: +asdfSasdfsadfEasdf +asdfSas +dfsadfEasdf + +Results of test64: diff --git a/src/nvim/testdir/test64.ok b/src/nvim/testdir/test64.ok new file mode 100644 index 0000000000..a1498ea5d6 --- /dev/null +++ b/src/nvim/testdir/test64.ok @@ -0,0 +1,1084 @@ +Results of test64: +OK 0 - ab +OK 1 - ab +OK 2 - ab +OK 0 - b +OK 1 - b +OK 2 - b +OK 0 - bc* +OK 1 - bc* +OK 2 - bc* +OK 0 - bc\{-} +OK 1 - bc\{-} +OK 2 - bc\{-} +OK 0 - bc\{-}\(d\) +OK 1 - bc\{-}\(d\) +OK 2 - bc\{-}\(d\) +OK 0 - bc* +OK 1 - bc* +OK 2 - bc* +OK 0 - c* +OK 1 - c* +OK 2 - c* +OK 0 - bc* +OK 1 - bc* +OK 2 - bc* +OK 0 - c* +OK 1 - c* +OK 2 - c* +OK 0 - bc\+ +OK 1 - bc\+ +OK 2 - bc\+ +OK 0 - bc\+ +OK 1 - bc\+ +OK 2 - bc\+ +OK 0 - a\|ab +OK 1 - a\|ab +OK 2 - a\|ab +OK 0 - c\? +OK 1 - c\? +OK 2 - c\? +OK 0 - bc\? +OK 1 - bc\? +OK 2 - bc\? +OK 0 - bc\? +OK 1 - bc\? +OK 2 - bc\? +OK 0 - \va{1} +OK 1 - \va{1} +OK 2 - \va{1} +OK 0 - \va{2} +OK 1 - \va{2} +OK 2 - \va{2} +OK 0 - \va{2} +OK 1 - \va{2} +OK 2 - \va{2} +OK 0 - \va{2} +OK 1 - \va{2} +OK 2 - \va{2} +OK 0 - \va{2} +OK 1 - \va{2} +OK 2 - \va{2} +OK 0 - \va{2} +OK 1 - \va{2} +OK 2 - \va{2} +OK 0 - \va{2} +OK 1 - \va{2} +OK 2 - \va{2} +OK 0 - \vb{1} +OK 1 - \vb{1} +OK 2 - \vb{1} +OK 0 - \vba{2} +OK 1 - \vba{2} +OK 2 - \vba{2} +OK 0 - \vba{3} +OK 1 - \vba{3} +OK 2 - \vba{3} +OK 0 - \v(ab){1} +OK 1 - \v(ab){1} +OK 2 - \v(ab){1} +OK 0 - \v(ab){1} +OK 1 - \v(ab){1} +OK 2 - \v(ab){1} +OK 0 - \v(ab){1} +OK 1 - \v(ab){1} +OK 2 - \v(ab){1} +OK 0 - \v(ab){0,2} +OK 1 - \v(ab){0,2} +OK 2 - \v(ab){0,2} +OK 0 - \v(ab){0,2} +OK 1 - \v(ab){0,2} +OK 2 - \v(ab){0,2} +OK 0 - \v(ab){1,2} +OK 1 - \v(ab){1,2} +OK 2 - \v(ab){1,2} +OK 0 - \v(ab){1,2} +OK 1 - \v(ab){1,2} +OK 2 - \v(ab){1,2} +OK 0 - \v(ab){2,4} +OK 1 - \v(ab){2,4} +OK 2 - \v(ab){2,4} +OK 0 - \v(ab){2,4} +OK 1 - \v(ab){2,4} +OK 2 - \v(ab){2,4} +OK 0 - \v(ab){2} +OK 1 - \v(ab){2} +OK 2 - \v(ab){2} +OK 0 - \v(ab){2} +OK 1 - \v(ab){2} +OK 2 - \v(ab){2} +OK 0 - \v(ab){2} +OK 1 - \v(ab){2} +OK 2 - \v(ab){2} +OK 0 - \v(ab){2} +OK 1 - \v(ab){2} +OK 2 - \v(ab){2} +OK 0 - \v((ab){2}){2} +OK 1 - \v((ab){2}){2} +OK 2 - \v((ab){2}){2} +OK 0 - \v((ab){2}){2} +OK 1 - \v((ab){2}){2} +OK 2 - \v((ab){2}){2} +OK 0 - \v(a{1}){1} +OK 1 - \v(a{1}){1} +OK 2 - \v(a{1}){1} +OK 0 - \v(a{2}){1} +OK 1 - \v(a{2}){1} +OK 2 - \v(a{2}){1} +OK 0 - \v(a{2}){1} +OK 1 - \v(a{2}){1} +OK 2 - \v(a{2}){1} +OK 0 - \v(a{2}){1} +OK 1 - \v(a{2}){1} +OK 2 - \v(a{2}){1} +OK 0 - \v(a{1}){2} +OK 1 - \v(a{1}){2} +OK 2 - \v(a{1}){2} +OK 0 - \v(a{1}){2} +OK 1 - \v(a{1}){2} +OK 2 - \v(a{1}){2} +OK 0 - \v(a{2})+ +OK 1 - \v(a{2})+ +OK 2 - \v(a{2})+ +OK 0 - \v(a{2})+ +OK 1 - \v(a{2})+ +OK 2 - \v(a{2})+ +OK 0 - \v(a{2}){1} +OK 1 - \v(a{2}){1} +OK 2 - \v(a{2}){1} +OK 0 - \v(a{1}){2} +OK 1 - \v(a{1}){2} +OK 2 - \v(a{1}){2} +OK 0 - \v(a{1}){1} +OK 1 - \v(a{1}){1} +OK 2 - \v(a{1}){1} +OK 0 - \v(a{2}){2} +OK 1 - \v(a{2}){2} +OK 2 - \v(a{2}){2} +OK 0 - \v(a{2}){2} +OK 1 - \v(a{2}){2} +OK 2 - \v(a{2}){2} +OK 0 - \v(a+){2} +OK 1 - \v(a+){2} +OK 2 - \v(a+){2} +OK 0 - \v(a{3}){2} +OK 1 - \v(a{3}){2} +OK 2 - \v(a{3}){2} +OK 0 - \v(a{1,2}){2} +OK 1 - \v(a{1,2}){2} +OK 2 - \v(a{1,2}){2} +OK 0 - \v(a{1,3}){2} +OK 1 - \v(a{1,3}){2} +OK 2 - \v(a{1,3}){2} +OK 0 - \v(a{1,3}){2} +OK 1 - \v(a{1,3}){2} +OK 2 - \v(a{1,3}){2} +OK 0 - \v(a{1,3}){3} +OK 1 - \v(a{1,3}){3} +OK 2 - \v(a{1,3}){3} +OK 0 - \v(a{1,2}){2} +OK 1 - \v(a{1,2}){2} +OK 2 - \v(a{1,2}){2} +OK 0 - \v(a+)+ +OK 1 - \v(a+)+ +OK 2 - \v(a+)+ +OK 0 - \v(a+)+ +OK 1 - \v(a+)+ +OK 2 - \v(a+)+ +OK 0 - \v(a+){1,2} +OK 1 - \v(a+){1,2} +OK 2 - \v(a+){1,2} +OK 0 - \v(a+)(a+) +OK 1 - \v(a+)(a+) +OK 2 - \v(a+)(a+) +OK 0 - \v(a{3})+ +OK 1 - \v(a{3})+ +OK 2 - \v(a{3})+ +OK 0 - \v(a|b|c)+ +OK 1 - \v(a|b|c)+ +OK 2 - \v(a|b|c)+ +OK 0 - \v(a|b|c){2} +OK 1 - \v(a|b|c){2} +OK 2 - \v(a|b|c){2} +OK 0 - \v(abc){2} +OK 1 - \v(abc){2} +OK 2 - \v(abc){2} +OK 0 - \v(abc){2} +OK 1 - \v(abc){2} +OK 2 - \v(abc){2} +OK 0 - a* +OK 1 - a* +OK 2 - a* +OK 0 - \v(a*)+ +OK 1 - \v(a*)+ +OK 2 - \v(a*)+ +OK 0 - \v((ab)+)+ +OK 1 - \v((ab)+)+ +OK 2 - \v((ab)+)+ +OK 0 - \v(((ab)+)+)+ +OK 1 - \v(((ab)+)+)+ +OK 2 - \v(((ab)+)+)+ +OK 0 - \v(((ab)+)+)+ +OK 1 - \v(((ab)+)+)+ +OK 2 - \v(((ab)+)+)+ +OK 0 - \v(a{0,2})+ +OK 1 - \v(a{0,2})+ +OK 2 - \v(a{0,2})+ +OK 0 - \v(a*)+ +OK 1 - \v(a*)+ +OK 2 - \v(a*)+ +OK 0 - \v((a*)+)+ +OK 1 - \v((a*)+)+ +OK 2 - \v((a*)+)+ +OK 0 - \v((ab)*)+ +OK 1 - \v((ab)*)+ +OK 2 - \v((ab)*)+ +OK 0 - \va{1,3} +OK 1 - \va{1,3} +OK 2 - \va{1,3} +OK 0 - \va{2,3} +OK 1 - \va{2,3} +OK 2 - \va{2,3} +OK 0 - \v((ab)+|c*)+ +OK 1 - \v((ab)+|c*)+ +OK 2 - \v((ab)+|c*)+ +OK 0 - \v(a{2})|(b{3}) +OK 1 - \v(a{2})|(b{3}) +OK 2 - \v(a{2})|(b{3}) +OK 0 - \va{2}|b{2} +OK 1 - \va{2}|b{2} +OK 2 - \va{2}|b{2} +OK 0 - \v(a)+|(c)+ +OK 1 - \v(a)+|(c)+ +OK 2 - \v(a)+|(c)+ +OK 0 - \vab{2,3}c +OK 1 - \vab{2,3}c +OK 2 - \vab{2,3}c +OK 0 - \vab{2,3}c +OK 1 - \vab{2,3}c +OK 2 - \vab{2,3}c +OK 0 - \vab{2,3}cd{2,3}e +OK 1 - \vab{2,3}cd{2,3}e +OK 2 - \vab{2,3}cd{2,3}e +OK 0 - \va(bc){2}d +OK 1 - \va(bc){2}d +OK 2 - \va(bc){2}d +OK 0 - \va*a{2} +OK 1 - \va*a{2} +OK 2 - \va*a{2} +OK 0 - \va*a{2} +OK 1 - \va*a{2} +OK 2 - \va*a{2} +OK 0 - \va*a{2} +OK 1 - \va*a{2} +OK 2 - \va*a{2} +OK 0 - \va*a{2} +OK 1 - \va*a{2} +OK 2 - \va*a{2} +OK 0 - \va*b*|a*c* +OK 1 - \va*b*|a*c* +OK 2 - \va*b*|a*c* +OK 0 - \va{1}b{1}|a{1}b{1} +OK 1 - \va{1}b{1}|a{1}b{1} +OK 2 - \va{1}b{1}|a{1}b{1} +OK 0 - \v(a) +OK 1 - \v(a) +OK 2 - \v(a) +OK 0 - \v(a)(b) +OK 1 - \v(a)(b) +OK 2 - \v(a)(b) +OK 0 - \v(ab)(b)(c) +OK 1 - \v(ab)(b)(c) +OK 2 - \v(ab)(b)(c) +OK 0 - \v((a)(b)) +OK 1 - \v((a)(b)) +OK 2 - \v((a)(b)) +OK 0 - \v(a)|(b) +OK 1 - \v(a)|(b) +OK 2 - \v(a)|(b) +OK 0 - \v(a*)+ +OK 1 - \v(a*)+ +OK 2 - \v(a*)+ +OK 0 - x +OK 1 - x +OK 2 - x +OK 0 - ab +OK 1 - ab +OK 2 - ab +OK 0 - ab +OK 1 - ab +OK 2 - ab +OK 0 - ab +OK 1 - ab +OK 2 - ab +OK 0 - x* +OK 1 - x* +OK 2 - x* +OK 0 - x* +OK 1 - x* +OK 2 - x* +OK 0 - x* +OK 1 - x* +OK 2 - x* +OK 0 - x\+ +OK 1 - x\+ +OK 2 - x\+ +OK 0 - x\+ +OK 1 - x\+ +OK 2 - x\+ +OK 0 - x\+ +OK 1 - x\+ +OK 2 - x\+ +OK 0 - x\+ +OK 1 - x\+ +OK 2 - x\+ +OK 0 - x\= +OK 1 - x\= +OK 2 - x\= +OK 0 - x\= +OK 1 - x\= +OK 2 - x\= +OK 0 - x\= +OK 1 - x\= +OK 2 - x\= +OK 0 - x\? +OK 1 - x\? +OK 2 - x\? +OK 0 - x\? +OK 1 - x\? +OK 2 - x\? +OK 0 - x\? +OK 1 - x\? +OK 2 - x\? +OK 0 - a\{0,0} +OK 1 - a\{0,0} +OK 2 - a\{0,0} +OK 0 - a\{0,1} +OK 1 - a\{0,1} +OK 2 - a\{0,1} +OK 0 - a\{1,0} +OK 1 - a\{1,0} +OK 2 - a\{1,0} +OK 0 - a\{3,6} +OK 1 - a\{3,6} +OK 2 - a\{3,6} +OK 0 - a\{3,6} +OK 1 - a\{3,6} +OK 2 - a\{3,6} +OK 0 - a\{3,6} +OK 1 - a\{3,6} +OK 2 - a\{3,6} +OK 0 - a\{0} +OK 1 - a\{0} +OK 2 - a\{0} +OK 0 - a\{2} +OK 1 - a\{2} +OK 2 - a\{2} +OK 0 - a\{2} +OK 1 - a\{2} +OK 2 - a\{2} +OK 0 - a\{2} +OK 1 - a\{2} +OK 2 - a\{2} +OK 0 - a\{0,} +OK 1 - a\{0,} +OK 2 - a\{0,} +OK 0 - a\{0,} +OK 1 - a\{0,} +OK 2 - a\{0,} +OK 0 - a\{2,} +OK 1 - a\{2,} +OK 2 - a\{2,} +OK 0 - a\{2,} +OK 1 - a\{2,} +OK 2 - a\{2,} +OK 0 - a\{5,} +OK 1 - a\{5,} +OK 2 - a\{5,} +OK 0 - a\{5,} +OK 1 - a\{5,} +OK 2 - a\{5,} +OK 0 - a\{,0} +OK 1 - a\{,0} +OK 2 - a\{,0} +OK 0 - a\{,5} +OK 1 - a\{,5} +OK 2 - a\{,5} +OK 0 - a\{,5} +OK 1 - a\{,5} +OK 2 - a\{,5} +OK 0 - ^*\{4,}$ +OK 1 - ^*\{4,}$ +OK 2 - ^*\{4,}$ +OK 0 - ^*\{4,}$ +OK 1 - ^*\{4,}$ +OK 2 - ^*\{4,}$ +OK 0 - ^*\{4,}$ +OK 1 - ^*\{4,}$ +OK 2 - ^*\{4,}$ +OK 0 - a\{} +OK 1 - a\{} +OK 2 - a\{} +OK 0 - a\{} +OK 1 - a\{} +OK 2 - a\{} +OK 0 - a\{-0,0} +OK 1 - a\{-0,0} +OK 2 - a\{-0,0} +OK 0 - a\{-0,1} +OK 1 - a\{-0,1} +OK 2 - a\{-0,1} +OK 0 - a\{-3,6} +OK 1 - a\{-3,6} +OK 2 - a\{-3,6} +OK 0 - a\{-3,6} +OK 1 - a\{-3,6} +OK 2 - a\{-3,6} +OK 0 - a\{-3,6} +OK 1 - a\{-3,6} +OK 2 - a\{-3,6} +OK 0 - a\{-0} +OK 1 - a\{-0} +OK 2 - a\{-0} +OK 0 - a\{-2} +OK 1 - a\{-2} +OK 2 - a\{-2} +OK 0 - a\{-2} +OK 1 - a\{-2} +OK 2 - a\{-2} +OK 0 - a\{-0,} +OK 1 - a\{-0,} +OK 2 - a\{-0,} +OK 0 - a\{-0,} +OK 1 - a\{-0,} +OK 2 - a\{-0,} +OK 0 - a\{-2,} +OK 1 - a\{-2,} +OK 2 - a\{-2,} +OK 0 - a\{-2,} +OK 1 - a\{-2,} +OK 2 - a\{-2,} +OK 0 - a\{-,0} +OK 1 - a\{-,0} +OK 2 - a\{-,0} +OK 0 - a\{-,5} +OK 1 - a\{-,5} +OK 2 - a\{-,5} +OK 0 - a\{-,5} +OK 1 - a\{-,5} +OK 2 - a\{-,5} +OK 0 - a\{-} +OK 1 - a\{-} +OK 2 - a\{-} +OK 0 - a\{-} +OK 1 - a\{-} +OK 2 - a\{-} +OK 0 - \(abc\)* +OK 1 - \(abc\)* +OK 2 - \(abc\)* +OK 0 - \(ab\)\+ +OK 1 - \(ab\)\+ +OK 2 - \(ab\)\+ +OK 0 - \(abaaaaa\)*cd +OK 1 - \(abaaaaa\)*cd +OK 2 - \(abaaaaa\)*cd +OK 0 - \(test1\)\? \(test2\)\? +OK 1 - \(test1\)\? \(test2\)\? +OK 2 - \(test1\)\? \(test2\)\? +OK 0 - \(test1\)\= \(test2\) \(test4443\)\= +OK 1 - \(test1\)\= \(test2\) \(test4443\)\= +OK 2 - \(test1\)\= \(test2\) \(test4443\)\= +OK 0 - \(\(sub1\) hello \(sub 2\)\) +OK 1 - \(\(sub1\) hello \(sub 2\)\) +OK 2 - \(\(sub1\) hello \(sub 2\)\) +OK 0 - \(\(\(yyxxzz\)\)\) +OK 1 - \(\(\(yyxxzz\)\)\) +OK 2 - \(\(\(yyxxzz\)\)\) +OK 0 - \v((ab)+|c+)+ +OK 1 - \v((ab)+|c+)+ +OK 2 - \v((ab)+|c+)+ +OK 0 - \v((ab)|c*)+ +OK 1 - \v((ab)|c*)+ +OK 2 - \v((ab)|c*)+ +OK 0 - \v(a(c*)+b)+ +OK 1 - \v(a(c*)+b)+ +OK 2 - \v(a(c*)+b)+ +OK 0 - \v(a|b*)+ +OK 1 - \v(a|b*)+ +OK 2 - \v(a|b*)+ +OK 0 - \p* +OK 1 - \p* +OK 2 - \p* +OK 0 - a\{-2,7} +OK 1 - a\{-2,7} +OK 2 - a\{-2,7} +OK 0 - a\{-2,7}x +OK 1 - a\{-2,7}x +OK 2 - a\{-2,7}x +OK 0 - a\{2,7} +OK 1 - a\{2,7} +OK 2 - a\{2,7} +OK 0 - a\{2,7}x +OK 1 - a\{2,7}x +OK 2 - a\{2,7}x +OK 0 - \vx(.{-,8})yz(.*) +OK 1 - \vx(.{-,8})yz(.*) +OK 2 - \vx(.{-,8})yz(.*) +OK 0 - \vx(.*)yz(.*) +OK 1 - \vx(.*)yz(.*) +OK 2 - \vx(.*)yz(.*) +OK 0 - \v(a{1,2}){-2,3} +OK 1 - \v(a{1,2}){-2,3} +OK 2 - \v(a{1,2}){-2,3} +OK 0 - \v(a{-1,3})+ +OK 1 - \v(a{-1,3})+ +OK 2 - \v(a{-1,3})+ +OK 0 - \d\+e\d\d +OK 1 - \d\+e\d\d +OK 2 - \d\+e\d\d +OK 0 - \v[a] +OK 1 - \v[a] +OK 2 - \v[a] +OK 0 - a[bcd] +OK 1 - a[bcd] +OK 2 - a[bcd] +OK 0 - a[b-d] +OK 1 - a[b-d] +OK 2 - a[b-d] +OK 0 - [a-d][e-f][x-x]d +OK 1 - [a-d][e-f][x-x]d +OK 2 - [a-d][e-f][x-x]d +OK 0 - \v[[:alpha:]]+ +OK 1 - \v[[:alpha:]]+ +OK 2 - \v[[:alpha:]]+ +OK 0 - [[:alpha:]\+] +OK 1 - [[:alpha:]\+] +OK 2 - [[:alpha:]\+] +OK 0 - [^abc]\+ +OK 1 - [^abc]\+ +OK 2 - [^abc]\+ +OK 0 - [^abc] +OK 1 - [^abc] +OK 2 - [^abc] +OK 0 - [^abc]\+ +OK 1 - [^abc]\+ +OK 2 - [^abc]\+ +OK 0 - [^a-d]\+ +OK 1 - [^a-d]\+ +OK 2 - [^a-d]\+ +OK 0 - [a-f]* +OK 1 - [a-f]* +OK 2 - [a-f]* +OK 0 - [a-f]* +OK 1 - [a-f]* +OK 2 - [a-f]* +OK 0 - [^a-f]\+ +OK 1 - [^a-f]\+ +OK 2 - [^a-f]\+ +OK 0 - [a-c]\{-3,6} +OK 1 - [a-c]\{-3,6} +OK 2 - [a-c]\{-3,6} +OK 0 - [^[:alpha:]]\+ +OK 1 - [^[:alpha:]]\+ +OK 2 - [^[:alpha:]]\+ +OK 0 - [-a] +OK 1 - [-a] +OK 2 - [-a] +OK 0 - [a-] +OK 1 - [a-] +OK 2 - [a-] +OK 0 - [a-f]*\c +OK 1 - [a-f]*\c +OK 2 - [a-f]*\c +OK 0 - [abc][xyz]\c +OK 1 - [abc][xyz]\c +OK 2 - [abc][xyz]\c +OK 0 - [-./[:alnum:]_~]\+ +OK 1 - [-./[:alnum:]_~]\+ +OK 2 - [-./[:alnum:]_~]\+ +OK 0 - [\]\^\-\\]\+ +OK 1 - [\]\^\-\\]\+ +OK 2 - [\]\^\-\\]\+ +OK 0 - [[.a.]]\+ +OK 1 - [[.a.]]\+ +OK 2 - [[.a.]]\+ +OK 0 - abc[0-9]*ddd +OK 1 - abc[0-9]*ddd +OK 2 - abc[0-9]*ddd +OK 0 - abc[0-9]*ddd +OK 1 - abc[0-9]*ddd +OK 2 - abc[0-9]*ddd +OK 0 - \_[0-9]\+ +OK 1 - \_[0-9]\+ +OK 2 - \_[0-9]\+ +OK 0 - [0-9\n]\+ +OK 1 - [0-9\n]\+ +OK 2 - [0-9\n]\+ +OK 0 - \_[0-9]\+ +OK 1 - \_[0-9]\+ +OK 2 - \_[0-9]\+ +OK 0 - \_f +OK 1 - \_f +OK 2 - \_f +OK 0 - \_f\+ +OK 1 - \_f\+ +OK 2 - \_f\+ +OK 0 - [0-9A-Za-z-_.]\+ +OK 1 - [0-9A-Za-z-_.]\+ +OK 2 - [0-9A-Za-z-_.]\+ +OK 0 - ^a. +OK 1 - ^a. +OK 2 - ^a. +OK 0 - ^a. +OK 1 - ^a. +OK 2 - ^a. +OK 0 - .a$ +OK 1 - .a$ +OK 2 - .a$ +OK 0 - .a$ +OK 1 - .a$ +OK 2 - .a$ +OK 0 - \%^a. +OK 1 - \%^a. +OK 2 - \%^a. +OK 0 - \%^a +OK 1 - \%^a +OK 2 - \%^a +OK 0 - .a\%$ +OK 1 - .a\%$ +OK 2 - .a\%$ +OK 0 - .a\%$ +OK 1 - .a\%$ +OK 2 - .a\%$ +OK 0 - [0-7]\+ +OK 1 - [0-7]\+ +OK 2 - [0-7]\+ +OK 0 - [^0-7]\+ +OK 1 - [^0-7]\+ +OK 2 - [^0-7]\+ +OK 0 - [0-9]\+ +OK 1 - [0-9]\+ +OK 2 - [0-9]\+ +OK 0 - [^0-9]\+ +OK 1 - [^0-9]\+ +OK 2 - [^0-9]\+ +OK 0 - [0-9a-fA-F]\+ +OK 1 - [0-9a-fA-F]\+ +OK 2 - [0-9a-fA-F]\+ +OK 0 - [^0-9A-Fa-f]\+ +OK 1 - [^0-9A-Fa-f]\+ +OK 2 - [^0-9A-Fa-f]\+ +OK 0 - [a-z_A-Z0-9]\+ +OK 1 - [a-z_A-Z0-9]\+ +OK 2 - [a-z_A-Z0-9]\+ +OK 0 - [^a-z_A-Z0-9]\+ +OK 1 - [^a-z_A-Z0-9]\+ +OK 2 - [^a-z_A-Z0-9]\+ +OK 0 - [a-z_A-Z]\+ +OK 1 - [a-z_A-Z]\+ +OK 2 - [a-z_A-Z]\+ +OK 0 - [^a-z_A-Z]\+ +OK 1 - [^a-z_A-Z]\+ +OK 2 - [^a-z_A-Z]\+ +OK 0 - [a-z]\+ +OK 1 - [a-z]\+ +OK 2 - [a-z]\+ +OK 0 - [a-z]\+ +OK 1 - [a-z]\+ +OK 2 - [a-z]\+ +OK 0 - [^a-z]\+ +OK 1 - [^a-z]\+ +OK 2 - [^a-z]\+ +OK 0 - [^a-z]\+ +OK 1 - [^a-z]\+ +OK 2 - [^a-z]\+ +OK 0 - [a-zA-Z]\+ +OK 1 - [a-zA-Z]\+ +OK 2 - [a-zA-Z]\+ +OK 0 - [^a-zA-Z]\+ +OK 1 - [^a-zA-Z]\+ +OK 2 - [^a-zA-Z]\+ +OK 0 - [A-Z]\+ +OK 1 - [A-Z]\+ +OK 2 - [A-Z]\+ +OK 0 - [^A-Z]\+ +OK 1 - [^A-Z]\+ +OK 2 - [^A-Z]\+ +OK 0 - [a-z]\+\c +OK 1 - [a-z]\+\c +OK 2 - [a-z]\+\c +OK 0 - [A-Z]\+\c +OK 1 - [A-Z]\+\c +OK 2 - [A-Z]\+\c +OK 0 - \c[^a-z]\+ +OK 1 - \c[^a-z]\+ +OK 2 - \c[^a-z]\+ +OK 0 - \c[^A-Z]\+ +OK 1 - \c[^A-Z]\+ +OK 2 - \c[^A-Z]\+ +OK 0 - \C[^A-Z]\+ +OK 1 - \C[^A-Z]\+ +OK 2 - \C[^A-Z]\+ +OK 0 - xx \ze test +OK 1 - xx \ze test +OK 2 - xx \ze test +OK 0 - abc\zeend +OK 1 - abc\zeend +OK 2 - abc\zeend +OK 0 - aa\zebb\|aaxx +OK 1 - aa\zebb\|aaxx +OK 2 - aa\zebb\|aaxx +OK 0 - aa\zebb\|aaxx +OK 1 - aa\zebb\|aaxx +OK 2 - aa\zebb\|aaxx +OK 0 - aabb\|aa\zebb +OK 1 - aabb\|aa\zebb +OK 2 - aabb\|aa\zebb +OK 0 - aa\zebb\|aaebb +OK 1 - aa\zebb\|aaebb +OK 2 - aa\zebb\|aaebb +OK 0 - abc\zsdd +OK 1 - abc\zsdd +OK 2 - abc\zsdd +OK 0 - aa \zsax +OK 1 - aa \zsax +OK 2 - aa \zsax +OK 0 - abc \zsmatch\ze abc +OK 1 - abc \zsmatch\ze abc +OK 2 - abc \zsmatch\ze abc +OK 0 - \v(a \zsif .*){2} +OK 1 - \v(a \zsif .*){2} +OK 2 - \v(a \zsif .*){2} +OK 0 - \>\zs. +OK 1 - \>\zs. +OK 2 - \>\zs. +OK 0 - \s\+\ze\[/\|\s\zs\s\+ +OK 1 - \s\+\ze\[/\|\s\zs\s\+ +OK 2 - \s\+\ze\[/\|\s\zs\s\+ +OK 0 - abc\@= +OK 1 - abc\@= +OK 2 - abc\@= +OK 0 - abc\@=cd +OK 1 - abc\@=cd +OK 2 - abc\@=cd +OK 0 - abc\@= +OK 1 - abc\@= +OK 2 - abc\@= +OK 0 - abcd\@=e +OK 1 - abcd\@=e +OK 2 - abcd\@=e +OK 0 - abcd\@=e +OK 1 - abcd\@=e +OK 2 - abcd\@=e +OK 0 - \v(abc)@=.. +OK 1 - \v(abc)@=.. +OK 2 - \v(abc)@=.. +OK 0 - \(.*John\)\@=.*Bob +OK 1 - \(.*John\)\@=.*Bob +OK 2 - \(.*John\)\@=.*Bob +OK 0 - \(John.*\)\@=.*Bob +OK 1 - \(John.*\)\@=.*Bob +OK 2 - \(John.*\)\@=.*Bob +OK 0 - \<\S\+\())\)\@= +OK 1 - \<\S\+\())\)\@= +OK 2 - \<\S\+\())\)\@= +OK 0 - .*John\&.*Bob +OK 1 - .*John\&.*Bob +OK 2 - .*John\&.*Bob +OK 0 - .*John\&.*Bob +OK 1 - .*John\&.*Bob +OK 2 - .*John\&.*Bob +OK 0 - \v(test1)@=.*yep +OK 1 - \v(test1)@=.*yep +OK 2 - \v(test1)@=.*yep +OK 0 - foo\(bar\)\@! +OK 1 - foo\(bar\)\@! +OK 2 - foo\(bar\)\@! +OK 0 - foo\(bar\)\@! +OK 1 - foo\(bar\)\@! +OK 2 - foo\(bar\)\@! +OK 0 - if \(\(then\)\@!.\)*$ +OK 1 - if \(\(then\)\@!.\)*$ +OK 2 - if \(\(then\)\@!.\)*$ +OK 0 - if \(\(then\)\@!.\)*$ +OK 1 - if \(\(then\)\@!.\)*$ +OK 2 - if \(\(then\)\@!.\)*$ +OK 0 - \(foo\)\@!bar +OK 1 - \(foo\)\@!bar +OK 2 - \(foo\)\@!bar +OK 0 - \(foo\)\@!...bar +OK 1 - \(foo\)\@!...bar +OK 2 - \(foo\)\@!...bar +OK 0 - ^\%(.*bar\)\@!.*\zsfoo +OK 1 - ^\%(.*bar\)\@!.*\zsfoo +OK 2 - ^\%(.*bar\)\@!.*\zsfoo +OK 0 - ^\%(.*bar\)\@!.*\zsfoo +OK 1 - ^\%(.*bar\)\@!.*\zsfoo +OK 2 - ^\%(.*bar\)\@!.*\zsfoo +OK 0 - ^\%(.*bar\)\@!.*\zsfoo +OK 1 - ^\%(.*bar\)\@!.*\zsfoo +OK 2 - ^\%(.*bar\)\@!.*\zsfoo +OK 0 - [ ]\@!\p\%([ ]\@!\p\)*: +OK 1 - [ ]\@!\p\%([ ]\@!\p\)*: +OK 2 - [ ]\@!\p\%([ ]\@!\p\)*: +OK 0 - [ ]\@!\p\([ ]\@!\p\)*: +OK 1 - [ ]\@!\p\([ ]\@!\p\)*: +OK 2 - [ ]\@!\p\([ ]\@!\p\)*: +OK 0 - m\k\+_\@=\%(_\@!\k\)\@<=\k\+e +OK 1 - m\k\+_\@=\%(_\@!\k\)\@<=\k\+e +OK 2 - m\k\+_\@=\%(_\@!\k\)\@<=\k\+e +OK 0 - \%(\U\@<=S\k*\|S\l\)R +OK 1 - \%(\U\@<=S\k*\|S\l\)R +OK 2 - \%(\U\@<=S\k*\|S\l\)R +OK 0 - [[:alpha:]]\{-2,6} +OK 1 - [[:alpha:]]\{-2,6} +OK 2 - [[:alpha:]]\{-2,6} +OK 0 - +OK 1 - +OK 2 - +OK 0 - \v(()) +OK 1 - \v(()) +OK 2 - \v(()) +OK 0 - \v%(ab(xyz)c) +OK 1 - \v%(ab(xyz)c) +OK 2 - \v%(ab(xyz)c) +OK 0 - \v(test|)empty +OK 1 - \v(test|)empty +OK 2 - \v(test|)empty +OK 0 - \v(a|aa)(a|aa) +OK 1 - \v(a|aa)(a|aa) +OK 2 - \v(a|aa)(a|aa) +OK 0 - \%d32 +OK 1 - \%d32 +OK 2 - \%d32 +OK 0 - \%o40 +OK 1 - \%o40 +OK 2 - \%o40 +OK 0 - \%x20 +OK 1 - \%x20 +OK 2 - \%x20 +OK 0 - \%u0020 +OK 1 - \%u0020 +OK 2 - \%u0020 +OK 0 - \%U00000020 +OK 1 - \%U00000020 +OK 2 - \%U00000020 +OK 0 - \%d0 +OK 1 - \%d0 +OK 2 - \%d0 +OK 0 - foo\%[bar] +OK 1 - foo\%[bar] +OK 2 - foo\%[bar] +OK 0 - foo\%[bar] +OK 1 - foo\%[bar] +OK 2 - foo\%[bar] +OK 0 - foo\%[bar] +OK 1 - foo\%[bar] +OK 2 - foo\%[bar] +OK 0 - foo\%[bar] +OK 1 - foo\%[bar] +OK 2 - foo\%[bar] +OK 0 - foo\%[bar] +OK 1 - foo\%[bar] +OK 2 - foo\%[bar] +OK 0 - foo\%[bar] +OK 1 - foo\%[bar] +OK 2 - foo\%[bar] +OK 0 - foo\%[bar]x +OK 1 - foo\%[bar]x +OK 2 - foo\%[bar]x +OK 0 - foo\%[bar]x +OK 1 - foo\%[bar]x +OK 2 - foo\%[bar]x +OK 0 - \%[bar]x +OK 1 - \%[bar]x +OK 2 - \%[bar]x +OK 0 - \%[bar]x +OK 1 - \%[bar]x +OK 2 - \%[bar]x +OK 0 - \%[bar]x +OK 1 - \%[bar]x +OK 2 - \%[bar]x +OK 0 - b\%[[ao]r] +OK 1 - b\%[[ao]r] +OK 2 - b\%[[ao]r] +OK 0 - b\%[[]]r] +OK 1 - b\%[[]]r] +OK 2 - b\%[[]]r] +OK 0 - @\%[\w\-]* +OK 1 - @\%[\w\-]* +OK 2 - @\%[\w\-]* +OK 0 - goo\|go +OK 1 - goo\|go +OK 2 - goo\|go +OK 0 - \<goo\|\<go +OK 1 - \<goo\|\<go +OK 2 - \<goo\|\<go +OK 0 - \<goo\|go +OK 1 - \<goo\|go +OK 2 - \<goo\|go +OK 0 - \(\i\+\) \1 +OK 1 - \(\i\+\) \1 +OK 2 - \(\i\+\) \1 +OK 0 - \(\i\+\) \1 +OK 1 - \(\i\+\) \1 +OK 2 - \(\i\+\) \1 +OK 0 - \(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9 +OK 1 - \(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9 +OK 2 - \(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9 +OK 0 - \(\d*\)a \1b +OK 1 - \(\d*\)a \1b +OK 2 - \(\d*\)a \1b +OK 0 - ^.\(.\).\_..\1. +OK 1 - ^.\(.\).\_..\1. +OK 2 - ^.\(.\).\_..\1. +OK 0 - ^.*\.\(.*\)/.\+\(\1\)\@<!$ +OK 1 - ^.*\.\(.*\)/.\+\(\1\)\@<!$ +OK 2 - ^.*\.\(.*\)/.\+\(\1\)\@<!$ +OK 0 - ^.*\.\(.*\)/.\+\(\1\)\@<!$ +OK 1 - ^.*\.\(.*\)/.\+\(\1\)\@<!$ +OK 2 - ^.*\.\(.*\)/.\+\(\1\)\@<!$ +OK 0 - ^.*\.\(.*\)/.\+\(\1\)\@<=$ +OK 1 - ^.*\.\(.*\)/.\+\(\1\)\@<=$ +OK 2 - ^.*\.\(.*\)/.\+\(\1\)\@<=$ +OK 0 - \\\@<!\${\(\d\+\%(:.\{-}\)\?\\\@<!\)} +OK 1 - \\\@<!\${\(\d\+\%(:.\{-}\)\?\\\@<!\)} +OK 2 - \\\@<!\${\(\d\+\%(:.\{-}\)\?\\\@<!\)} +OK 0 - ^\(a*\)\1$ +OK 1 - ^\(a*\)\1$ +OK 2 - ^\(a*\)\1$ +OK 0 - <\@<=span. +OK 1 - <\@<=span. +OK 2 - <\@<=span. +OK 0 - <\@1<=span. +OK 1 - <\@1<=span. +OK 2 - <\@1<=span. +OK 0 - <\@2<=span. +OK 1 - <\@2<=span. +OK 2 - <\@2<=span. +OK 0 - \(<<\)\@<=span. +OK 1 - \(<<\)\@<=span. +OK 2 - \(<<\)\@<=span. +OK 0 - \(<<\)\@1<=span. +OK 1 - \(<<\)\@1<=span. +OK 2 - \(<<\)\@1<=span. +OK 0 - \(<<\)\@2<=span. +OK 1 - \(<<\)\@2<=span. +OK 2 - \(<<\)\@2<=span. +OK 0 - \(foo\)\@<!bar. +OK 1 - \(foo\)\@<!bar. +OK 2 - \(foo\)\@<!bar. +OK 0 - \v\C%(<Last Changed:\s+)@<=.*$ +OK 1 - \v\C%(<Last Changed:\s+)@<=.*$ +OK 2 - \v\C%(<Last Changed:\s+)@<=.*$ +OK 0 - \v\C%(<Last Changed:\s+)@<=.*$ +OK 1 - \v\C%(<Last Changed:\s+)@<=.*$ +OK 2 - \v\C%(<Last Changed:\s+)@<=.*$ +OK 0 - \(foo\)\@<=\> +OK 1 - \(foo\)\@<=\> +OK 2 - \(foo\)\@<=\> +OK 0 - \(foo\)\@<=\> +OK 1 - \(foo\)\@<=\> +OK 2 - \(foo\)\@<=\> +OK 0 - \(foo\)\@<=.* +OK 1 - \(foo\)\@<=.* +OK 2 - \(foo\)\@<=.* +OK 0 - \(r\@<=\|\w\@<!\)\/ +OK 1 - \(r\@<=\|\w\@<!\)\/ +OK 2 - \(r\@<=\|\w\@<!\)\/ +OK 0 - ^[a-z]\+\ze \&\(asdf\)\@<! +OK 1 - ^[a-z]\+\ze \&\(asdf\)\@<! +OK 2 - ^[a-z]\+\ze \&\(asdf\)\@<! +OK 0 - \(a*\)\@>a +OK 1 - \(a*\)\@>a +OK 2 - \(a*\)\@>a +OK 0 - \(a*\)\@>b +OK 1 - \(a*\)\@>b +OK 2 - \(a*\)\@>b +OK 0 - ^\(.\{-}b\)\@>. +OK 1 - ^\(.\{-}b\)\@>. +OK 2 - ^\(.\{-}b\)\@>. +OK 0 - \(.\{-}\)\(\)\@>$ +OK 1 - \(.\{-}\)\(\)\@>$ +OK 2 - \(.\{-}\)\(\)\@>$ +OK 0 - \(a*\)\@>a\|a\+ +OK 2 - \(a*\)\@>a\|a\+ +OK 0 - \_[^8-9]\+ +OK 1 - \_[^8-9]\+ +OK 2 - \_[^8-9]\+ +OK 0 - \_[^a]\+ +OK 1 - \_[^a]\+ +OK 2 - \_[^a]\+ +OK 0 - [0-9a-zA-Z]\{8}-\([0-9a-zA-Z]\{4}-\)\{3}[0-9a-zA-Z]\{12} +OK 1 - [0-9a-zA-Z]\{8}-\([0-9a-zA-Z]\{4}-\)\{3}[0-9a-zA-Z]\{12} +OK 2 - [0-9a-zA-Z]\{8}-\([0-9a-zA-Z]\{4}-\)\{3}[0-9a-zA-Z]\{12} +OK 0 - ^\%(\%(^\s*#\s*if\>\|#\s*if\)\)\(\%>1c.*$\)\@= +OK 1 - ^\%(\%(^\s*#\s*if\>\|#\s*if\)\)\(\%>1c.*$\)\@= +OK 2 - ^\%(\%(^\s*#\s*if\>\|#\s*if\)\)\(\%>1c.*$\)\@= +multi-line tests +OK 0 - ^.\(.\).\_..\1. +OK 1 - ^.\(.\).\_..\1. +OK 2 - ^.\(.\).\_..\1. +OK 0 - \v.*\/(.*)\n.*\/\1$ +OK 1 - \v.*\/(.*)\n.*\/\1$ +OK 2 - \v.*\/(.*)\n.*\/\1$ +OK 0 - \S.*\nx +OK 1 - \S.*\nx +OK 2 - \S.*\nx +OK 0 - \<\(\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\.\)\{3\}\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\> +OK 1 - \<\(\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\.\)\{3\}\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\> +OK 2 - \<\(\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\.\)\{3\}\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\> +OK 0 - a\n^b$\n^c +OK 1 - a\n^b$\n^c +OK 2 - a\n^b$\n^c +OK 0 - \(^.\+\n\)\1 +OK 1 - \(^.\+\n\)\1 +OK 2 - \(^.\+\n\)\1 + +<T="5">Ta 5</Title> +<T="7">Ac 7</Title> + +xxstart3 + +thexE thE thExethe +AndAxAnd AndAxAnd +oooxOfOr fOrOxooo +oooxOfOr fOrOxooo + +asdfhereasdf +asdfagainasdf + +-0- +ffo +bob +__ooooo +koooo__ +moooooo + f__ +ab!babababababfoo +ba!ab##abab?bafoo +**!*****_ +-1- +ffo +bob +__ooooo +koooo__ +moooooo + f__ +ab!babababababfoo +ba!ab##abab?bafoo +**!*****_ +-2- +ffo +bob +__ooooo +koooo__ +moooooo + f__ +ab!babababababfoo +ba!ab##abab?bafoo +**!*****_ +Test +Test END +EN +E diff --git a/src/nvim/testdir/test65.in b/src/nvim/testdir/test65.in new file mode 100644 index 0000000000..ca53f27555 --- /dev/null +++ b/src/nvim/testdir/test65.in @@ -0,0 +1,95 @@ +Test for floating point and logical operators. + +STARTTEST +:so small.vim +:if !has("float") +: e! test.ok +: wq! test.out +:endif +:" +:$put =printf('%f', 123.456) +:$put =printf('%e', 123.456) +:$put =printf('%g', 123.456) +:" check we don't crash on division by zero +:echo 1.0 / 0.0 +:$put ='+=' +:let v = 1.234 +:let v += 6.543 +:$put =printf('%g', v) +:let v = 1.234 +:let v += 5 +:$put =printf('%g', v) +:let a = 5 +:let a += 3.333 +:$put =string(a) +:$put ='==' +:let v = 1.234 +:$put =v == 1.234 +:$put =v == 1.2341 +:$put ='add-subtract' +:$put =printf('%g', 4 + 1.234) +:$put =printf('%g', 1.234 - 8) +:$put ='mult-div' +:$put =printf('%g', 4 * 1.234) +:$put =printf('%g', 4.0 / 1234) +:$put ='dict' +:$put =string({'x': 1.234, 'y': -2.0e20}) +:$put ='list' +:$put =string([-123.4, 2.0e-20]) +:$put ='abs' +:$put =printf('%d', abs(1456)) +:$put =printf('%d', abs(-4)) +:$put =printf('%d', abs([1, 2, 3])) +:$put =printf('%g', abs(14.56)) +:$put =printf('%g', abs(-54.32)) +:$put ='ceil' +:$put =printf('%g', ceil(1.456)) +:$put =printf('%g', ceil(-5.456)) +:$put =printf('%g', ceil(-4.000)) +:$put ='floor' +:$put =printf('%g', floor(1.856)) +:$put =printf('%g', floor(-5.456)) +:$put =printf('%g', floor(4.0)) +:$put ='log10' +:$put =printf('%g', log10(1000)) +:$put =printf('%g', log10(0.01000)) +:$put ='pow' +:$put =printf('%g', pow(3, 3.0)) +:$put =printf('%g', pow(2, 16)) +:$put ='round' +:$put =printf('%g', round(0.456)) +:$put =printf('%g', round(4.5)) +:$put =printf('%g', round(-4.50)) +:$put ='sqrt' +:$put =printf('%g', sqrt(100)) +:echo sqrt(-4.01) +:$put ='str2float' +:$put =printf('%g', str2float('1e40')) +:$put ='trunc' +:$put =printf('%g', trunc(1.456)) +:$put =printf('%g', trunc(-5.456)) +:$put =printf('%g', trunc(4.000)) +:$put ='float2nr' +:$put =float2nr(123.456) +:$put =float2nr(-123.456) +:$put ='AND' +:$put =and(127, 127) +:$put =and(127, 16) +:$put =and(127, 128) +:$put ='OR' +:$put =or(16, 7) +:$put =or(8, 7) +:$put =or(0, 123) +:$put ='XOR' +:$put =xor(127, 127) +:$put =xor(127, 16) +:$put =xor(127, 128) +:$put ='invert' +:$put =and(invert(127), 65535) +:$put =and(invert(16), 65535) +:$put =and(invert(128), 65535) +:$put =invert(1.0) +:/^Results/,$wq! test.out +ENDTEST + +Results of test65: diff --git a/src/nvim/testdir/test65.ok b/src/nvim/testdir/test65.ok new file mode 100644 index 0000000000..7aac326058 --- /dev/null +++ b/src/nvim/testdir/test65.ok @@ -0,0 +1,73 @@ +Results of test65: +123.456000 +1.234560e+02 +123.456 ++= +7.777 +6.234 +8.333 +== +1 +0 +add-subtract +5.234 +-6.766 +mult-div +4.936 +0.003241 +dict +{'x': 1.234, 'y': -2.0e20} +list +[-123.4, 2.0e-20] +abs +1456 +4 +-1 +14.56 +54.32 +ceil +2.0 +-5.0 +-4.0 +floor +1.0 +-6.0 +4.0 +log10 +3.0 +-2.0 +pow +27.0 +65536.0 +round +0.0 +5.0 +-5.0 +sqrt +10.0 +str2float +1.0e40 +trunc +1.0 +-5.0 +4.0 +float2nr +123 +-123 +AND +127 +16 +0 +OR +23 +15 +123 +XOR +0 +111 +255 +invert +65408 +65519 +65407 +0 diff --git a/src/nvim/testdir/test66.in b/src/nvim/testdir/test66.in new file mode 100644 index 0000000000..f1fdce3792 --- /dev/null +++ b/src/nvim/testdir/test66.in @@ -0,0 +1,33 @@ + +Test for visual block shift and tab characters. + +STARTTEST +:so small.vim +/^one +fe4jRugvr1:'<,'>w! test.out +/^abcdefgh +4jI j<<11|D +7|a +7|a +7|a 4k13|4j< +:$-5,$w >> test.out +:$-4,$s/\s\+//g +4kI j<< +7|a +7|a +7|a 4k13|4j3< +:$-4,$w >> test.out +:qa! +ENDTEST + +one two three +one two three +one two three +one two three +one two three + +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz diff --git a/src/nvim/testdir/test66.ok b/src/nvim/testdir/test66.ok new file mode 100644 index 0000000000..4c3ab0fb56 --- /dev/null +++ b/src/nvim/testdir/test66.ok @@ -0,0 +1,16 @@ +on1 two three +on1 two three +on1 two three +on1 two three +on1 two three + + abcdefghijklmnopqrstuvwxyz +abcdefghij + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz + abcdefghijklmnopqrstuvwxyz +abcdefghij + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz diff --git a/src/nvim/testdir/test67.in b/src/nvim/testdir/test67.in new file mode 100644 index 0000000000..08b4e3701f --- /dev/null +++ b/src/nvim/testdir/test67.in @@ -0,0 +1,33 @@ +Test that groups and patterns are tested correctly when calling exists() for +autocommands. + +STARTTEST +:so small.vim +:let results=[] +:augroup auexists +:augroup END +:call add(results, "##BufEnter: " . exists("##BufEnter")) +:call add(results, "#BufEnter: " . exists("#BufEnter")) +:au BufEnter * let g:entered=1 +:call add(results, "#BufEnter: " . exists("#BufEnter")) +:call add(results, "#auexists#BufEnter: " . exists("#auexists#BufEnter")) +:augroup auexists +:au BufEnter * let g:entered=1 +:augroup END +:call add(results, "#auexists#BufEnter: " . exists("#auexists#BufEnter")) +:call add(results, "#BufEnter#*.test: " . exists("#BufEnter#*.test")) +:au BufEnter *.test let g:entered=1 +:call add(results, "#BufEnter#*.test: " . exists("#BufEnter#*.test")) +:edit testfile.test +:call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>")) +:au BufEnter <buffer> let g:entered=1 +:call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>")) +:edit testfile2.test +:call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>")) +:e test.out +:call append(0, results) +:$d +:w +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test67.ok b/src/nvim/testdir/test67.ok new file mode 100644 index 0000000000..51188e5afd --- /dev/null +++ b/src/nvim/testdir/test67.ok @@ -0,0 +1,10 @@ +##BufEnter: 1 +#BufEnter: 0 +#BufEnter: 1 +#auexists#BufEnter: 0 +#auexists#BufEnter: 1 +#BufEnter#*.test: 0 +#BufEnter#*.test: 1 +#BufEnter#<buffer>: 0 +#BufEnter#<buffer>: 1 +#BufEnter#<buffer>: 0 diff --git a/src/nvim/testdir/test68.in b/src/nvim/testdir/test68.in new file mode 100644 index 0000000000..ceaf9af1ab --- /dev/null +++ b/src/nvim/testdir/test68.in @@ -0,0 +1,131 @@ +Test for text formatting. + +Results of test68: + +STARTTEST +:so small.vim +/^{/+1 +:set noai tw=2 fo=t +gRa b +ENDTEST + +{ + + +} + +STARTTEST +/^{/+1 +:set ai tw=2 fo=tw +gqgqjjllab +ENDTEST + +{ +a b + +a +} + +STARTTEST +/^{/+1 +:set tw=3 fo=t +gqgqo +a +ENDTEST + +{ +a +} + +STARTTEST +/^{/+1 +:set tw=2 fo=tcq1 comments=:# +gqgqjgqgqo +a b +#a b +ENDTEST + +{ +a b +#a b +} + +STARTTEST +/^{/+1 +:set tw=5 fo=tcn comments=:# +A bjA b +ENDTEST + +{ + 1 a +# 1 a +} + +STARTTEST +/^{/+3 +:set tw=5 fo=t2a si +i A_ +ENDTEST + +{ + + x a + b + c + +} + +STARTTEST +/^{/+1 +:set tw=5 fo=qn comments=:# +gwap +ENDTEST + +{ +# 1 a b +} + +STARTTEST +/^{/+1 +:set tw=5 fo=q2 comments=:# +gwap +ENDTEST + +{ +# x +# a b +} + +STARTTEST +/^{/+2 +:set tw& fo=a +I^^ +ENDTEST + +{ + 1aa + 2bb +} + +STARTTEST +/mno pqr/ +:setl tw=20 fo=an12wcq comments=s1:/*,mb:*,ex:*/ +A vwx yz +ENDTEST + +/* abc def ghi jkl + * mno pqr stu + */ + +STARTTEST +/^#/ +:setl tw=12 fo=tqnc comments=:# +A foobar +ENDTEST + +# 1 xxxxx + +STARTTEST +:g/^STARTTEST/.,/^ENDTEST/d +:1;/^Results/,$wq! test.out +ENDTEST diff --git a/src/nvim/testdir/test68.ok b/src/nvim/testdir/test68.ok new file mode 100644 index 0000000000..b3726a0a27 --- /dev/null +++ b/src/nvim/testdir/test68.ok @@ -0,0 +1,77 @@ +Results of test68: + + +{ +a +b +} + + +{ +a +b + +a +b +} + + +{ +a + + +a + +} + + +{ +a b +#a b + +a b +#a b +} + + +{ + 1 a + b +# 1 a +# b +} + + +{ + + x a + b_ + c + +} + + +{ +# 1 a +# b +} + + +{ +# x a +# b +} + + +{ 1aa ^^2bb } + + +/* abc def ghi jkl + * mno pqr stu + * vwx yz + */ + + +# 1 xxxxx +# foobar + diff --git a/src/nvim/testdir/test69.in b/src/nvim/testdir/test69.in new file mode 100644 index 0000000000..75317b4954 --- /dev/null +++ b/src/nvim/testdir/test69.in @@ -0,0 +1,185 @@ +Test for multi-byte text formatting. +Also test, that 'mps' with multibyte chars works. +And test "ra" on multi-byte characters. +Also test byteidx() and byteidxcomp() + +STARTTEST +:so mbyte.vim +:set encoding=utf-8 +ENDTEST + +Results of test69: + +STARTTEST +/^{/+1 +:set tw=2 fo=t +gqgqjgqgqo +XYZ +abc XYZ +ENDTEST + +{ +XYZ +abc XYZ +} + +STARTTEST +/^{/+1 +:set tw=1 fo=tm +gqgqjgqgqjgqgqjgqgqjgqgqo +X +Xa +X a +XY +X Y +ENDTEST + +{ +X +Xa +X a +XY +X Y +} + +STARTTEST +/^{/+1 +:set tw=2 fo=tm +gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqo +X +Xa +X a +XY +X Y +aX +abX +abcX +abX c +abXY +ENDTEST + +{ +X +Xa +X a +XY +X Y +aX +abX +abcX +abX c +abXY +} + +STARTTEST +/^{/+1 +:set ai tw=2 fo=tm +gqgqjgqgqo +X +Xa +ENDTEST + +{ + X + Xa +} + +STARTTEST +/^{/+1 +:set noai tw=2 fo=tm +gqgqjgqgqo + X + Xa +ENDTEST + +{ + X + Xa +} + +STARTTEST +/^{/+1 +:set tw=2 fo=cqm comments=n:X +gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqo +X +Xa +XaY +XY +XYZ +X Y +X YZ +XX +XXa +XXY +ENDTEST + +{ +X +Xa +XaY +XY +XYZ +X Y +X YZ +XX +XXa +XXY +} + +STARTTEST +/^{/+1 +:set tw=2 fo=tm +RXa +ENDTEST + +{ + +} + +STARTTEST +/^{/+1 +:set mps+=u2018:u2019 +d% +ENDTEST + +{ +‘ two three ’ four +} +STARTTEST +/^ra test +jVjra +ENDTEST + +ra test +abba +aab + +STARTTEST +:set whichwrap+=h +/^x +dh +:set whichwrap-=h +ENDTEST + +á +x + +STARTTEST +:let a = '.é.' " one char of two bytes +:let b = '.é.' " normal e with composing char +/^byteidx +:put =string([byteidx(a, 0), byteidx(a, 1), byteidx(a, 2), byteidx(a, 3), byteidx(a, 4)]) +:put =string([byteidx(b, 0), byteidx(b, 1), byteidx(b, 2), byteidx(b, 3), byteidx(b, 4)]) +/^byteidxcomp +:put =string([byteidxcomp(a, 0), byteidxcomp(a, 1), byteidxcomp(a, 2), byteidxcomp(a, 3), byteidxcomp(a, 4)]) +:let b = '.é.' +:put =string([byteidxcomp(b, 0), byteidxcomp(b, 1), byteidxcomp(b, 2), byteidxcomp(b, 3), byteidxcomp(b, 4), byteidxcomp(b, 5)]) +ENDTEST + +byteidx +byteidxcomp + +STARTTEST +:g/^STARTTEST/.,/^ENDTEST/d +:1;/^Results/,$wq! test.out +ENDTEST diff --git a/src/nvim/testdir/test69.ok b/src/nvim/testdir/test69.ok new file mode 100644 index 0000000000..41cd9d02c3 --- /dev/null +++ b/src/nvim/testdir/test69.ok @@ -0,0 +1,162 @@ +Results of test69: + + +{ +XYZ +abc +XYZ + +XYZ +abc +XYZ +} + + +{ +X +X +a +X +a +X +Y +X +Y + +X +X +a +X +a +X +Y +X +Y +} + + +{ +X +X +a +X +a +X +Y +X +Y +a +X +ab +X +abc +X +ab +X +c +ab +X +Y + +X +X +a +X +a +X +Y +X +Y +a +X +ab +X +abc +X +ab +X +c +ab +X +Y +} + + +{ + X + X + a + + X + X + a +} + + +{ + X + X +a + + X + X +a +} + + +{ +X +Xa +Xa +XY +XY +XY +XZ +X Y +X Y +X Z +XX +XXa +XXY + +X +Xa +Xa +XY +XY +XY +XZ +X Y +X Y +X Z +XX +XXa +XXY +} + + +{ +X +a +} + + +{ + four +} + +ra test +aaaa +aaa + + +áx + + +byteidx +[0, 1, 3, 4, -1] +[0, 1, 4, 5, -1] +byteidxcomp +[0, 1, 3, 4, -1] +[0, 1, 2, 4, 5, -1] + diff --git a/src/nvim/testdir/test7.in b/src/nvim/testdir/test7.in new file mode 100644 index 0000000000..b9cc0585f6 --- /dev/null +++ b/src/nvim/testdir/test7.in @@ -0,0 +1,26 @@ +Test for autocommand that changes the buffer list, when doing ":ball". + +STARTTEST +:so small.vim +/^start of +A1:.,/end of/w! Xxx1 " write test file Xxx1 +:sp Xxx1 +:close +$r2:.,/end of/w! Xxx2 " write test file Xxx2 +:sp Xxx2 +:close +$r3:.,/end of/w! Xxx3 " write test file Xxx3 +:sp Xxx3 +:close +:au BufReadPost Xxx2 bwipe +$r4:ball " open window for all args, close Xxx2 +:.,$w! test.out " Write contents of this file +:w >>test.out " Append contents of second window (Xxx1) +:/^start of/,$w >>test.out " Append contents of last window (this file) +:qa! +ENDTEST + +start of test file Xxx + this is a test + this is a test +end of test file Xxx diff --git a/src/nvim/testdir/test7.ok b/src/nvim/testdir/test7.ok new file mode 100644 index 0000000000..a0d1ff94a3 --- /dev/null +++ b/src/nvim/testdir/test7.ok @@ -0,0 +1,12 @@ +start of test file Xxx4 + this is a test + this is a test +end of test file Xxx +start of test file Xxx1 + this is a test + this is a test +end of test file Xxx +start of test file Xxx4 + this is a test + this is a test +end of test file Xxx diff --git a/src/nvim/testdir/test70.in b/src/nvim/testdir/test70.in new file mode 100644 index 0000000000..9fbe818b3d --- /dev/null +++ b/src/nvim/testdir/test70.in @@ -0,0 +1,63 @@ +Smoke test for MzScheme interface and mzeval() function + +STARTTEST +:so mzscheme.vim +:set nocompatible viminfo+=nviminfo +:function! MzRequire() +:redir => l:mzversion +:mz (version) +:redir END +:if strpart(l:mzversion, 1, 1) < "4" +:" MzScheme versions < 4.x: +:mz (require (prefix vim- vimext)) +:else +:" newer versions: +:mz (require (prefix-in vim- 'vimext)) +:mz (require r5rs) +:endif +:endfunction +:silent call MzRequire() +:mz (define l '("item0" "dictionary with list OK" "item2")) +:mz (define h (make-hash)) +:mz (hash-set! h "list" l) +/^1 +:" change buffer contents +:mz (vim-set-buff-line (vim-eval "line('.')") "1 changed line 1") +:" scalar test +:let tmp_string = mzeval('"string"') +:let tmp_1000 = mzeval('1000') +:if tmp_string . tmp_1000 == "string1000" +:let scalar_res = "OK" +:else +:let scalar_res = "FAILED" +:endif +:call append(search("^1"), "scalar test " . scalar_res) +:" dictionary containing a list +:let tmp = mzeval("h")["list"][1] +:/^2/put =tmp +:" circular list (at the same time test lists containing lists) +:mz (set-car! (cddr l) l) +:let l2 = mzeval("h")["list"] +:if l2[2] == l2 +:let res = "OK" +:else +:let res = "FAILED: " . l2[2] +:endif +:call setline(search("^3"), "circular test " . res) +:" funcrefs +:mz (define vim:max (vim-eval "function('max')")) +:mz (define m (vim:max '(1 100 8))) +:let m = mzeval('m') +:if m == 100 +:let fref_res = "OK" +:else +:let fref_res = "FAILED: " . m +:end +:call append(line('$'), 'funcrefs '. fref_res) +:?^1?,$w! test.out +:qa! +ENDTEST + +1 line 1 +2 line 2 +3 line 3 diff --git a/src/nvim/testdir/test70.ok b/src/nvim/testdir/test70.ok new file mode 100644 index 0000000000..9c82a86f2d --- /dev/null +++ b/src/nvim/testdir/test70.ok @@ -0,0 +1,6 @@ +1 changed line 1 +scalar test OK +2 line 2 +dictionary with list OK +circular test OK +funcrefs OK diff --git a/src/nvim/testdir/test71.in b/src/nvim/testdir/test71.in new file mode 100644 index 0000000000..155fd413bc --- /dev/null +++ b/src/nvim/testdir/test71.in @@ -0,0 +1,67 @@ +Test for encryption. +The test data is in another file to avoid problems with 'encoding', especially +cp932. + +STARTTEST +:so small.vim +:set enc=latin1 +:bwipe! +:r test71a.in +:/^start of text/+1 +:let text_lines = getline('.', line('.') + 2) +:/^start of cm=zip bytes/+1 +:let cm0_bytes = getline('.', '.') +:/^start of cm=blowfish bytes/+1 +:let cm1_bytes = getline('.', '.') +:bwipe! +:call append(0, text_lines) +:$d +:X +foobar +foobar +:w! Xtestfile +:bwipe! +:e Xtestfile +foobar +:let cm0_read_back = getline('.', '$') +:set key= +:set cryptmethod=blowfish +:" If the blowfish test fails 'cryptmethod' will be 'zip' now. +:%s/^/\=&cryptmethod == 'blowfish' ? "OK " : "blowfish test failed "/ +:X +barfoo +barfoo +:w! Xtestfile +:bwipe! +:e Xtestfile +barfoo +:let cm1_read_back = getline('.', '$') +:bwipe! +:set bin noeol key= +:call append(0, cm0_bytes) +:$d +:set fenc=latin1 +:w! Xtestfile +:bwipe! +:set nobin +:e Xtestfile +foofoo +:let cm0_read_bin = getline('.', '$') +:bwipe! +:set bin noeol key= +:call append(0, cm1_bytes) +:$d +:set fenc=latin1 +:w! Xtestfile +:bwipe! +:set nobin +:e Xtestfile +barbar +:call append(0, cm0_read_bin) +:call append(0, cm1_read_back) +:call append(0, cm0_read_back) +:set key= fenc=latin1 +:w! test.out +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test71.ok b/src/nvim/testdir/test71.ok new file mode 100644 index 0000000000..24652c4380 --- /dev/null +++ b/src/nvim/testdir/test71.ok @@ -0,0 +1,10 @@ +01234567890123456789012345678901234567 +line 2 foo bar blah +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +OK 01234567890123456789012345678901234567 +OK line 2 foo bar blah +OK line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +1234567890 +abbccddeff +asdfasdfasdf +0001112223333 diff --git a/src/nvim/testdir/test71a.in b/src/nvim/testdir/test71a.in new file mode 100644 index 0000000000..85bd22cd01 --- /dev/null +++ b/src/nvim/testdir/test71a.in @@ -0,0 +1,14 @@ + +start of text +01234567890123456789012345678901234567 +line 2 foo bar blah +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +end of text + +start of cm=zip bytes +VimCrypt~01!lV'}MgVE#32U +end of cm=zip bytes + +start of cm=blowfish bytes +VimCrypt~02!k)#S=#MJAͥM!
+end of cm=blowfish bytes diff --git a/src/nvim/testdir/test72.in b/src/nvim/testdir/test72.in new file mode 100644 index 0000000000..220adad67a --- /dev/null +++ b/src/nvim/testdir/test72.in @@ -0,0 +1,115 @@ +Tests for undo file. +Since this script is sourced we need to explicitly break changes up in +undo-able pieces. Do that by setting 'undolevels'. + +STARTTEST +:so small.vim +:" +:" Test 'undofile': first a simple one-line change. +:set nocompatible viminfo+=nviminfo visualbell +:set ul=100 undofile nomore +:e! Xtestfile +ggdGithis is one line:set ul=100 +:s/one/ONE/ +:set ul=100 +:w +:bwipe! +:e Xtestfile +u:.w! test.out +:" +:" Test 'undofile', change in original file fails check +:set noundofile +:e! Xtestfile +:s/line/Line/ +:w +:set undofile +:bwipe! +:e Xtestfile +:" TODO: this beeps +u:.w >>test.out +:" +:" Test 'undofile', add 10 lines, delete 6 lines, undo 3 +:set undofile +ggdGione +two +three +four +five +six +seven +eight +nine +ten:set ul=100 +3Gdd:set ul=100 +dd:set ul=100 +dd:set ul=100 +dd:set ul=100 +dd:set ul=100 +dd:set ul=100 +:w +:bwipe! +:e Xtestfile +uuu:w >>test.out +:" +:" Test that reading the undofiles when setting undofile works +:set noundofile ul=0 +i +u:e! Xtestfile +:set undofile ul=100 +uuuuuu:w >>test.out +:" And now with encryption, cryptmethod=zip +:e! Xtestfile +:set undofile cm=zip +ggdGimonday +tuesday +wednesday +thursday +friday:set ul=100 +kkkdd:set ul=100 +dd:set ul=100 +dd:set ul=100 +:X +foobar +foobar +:w! +:bwipe! +:e Xtestfile +foobar +:set key= +uu:w >>test.out +:" +:" +:" With encryption, cryptmethod=blowfish +:e! Xtestfile +:set undofile cm=blowfish +ggdGijan +feb +mar +apr +jun:set ul=100 +kk0ifoo :set ul=100 +dd:set ul=100 +ibar :set ul=100 +:X +foobar +foobar +:w! +:bwipe! +:e Xtestfile +foobar +:set key= +/bar +:.w >>test.out +u:.w >>test.out +u:.w >>test.out +u:.w >>test.out +:" +:" Rename the undo file so that it gets cleaned up. +:call rename(".Xtestfile.un~", "Xtestundo") +:qa! +ENDTEST + +1111 ----- +2222 ----- + +123456789 diff --git a/src/nvim/testdir/test72.ok b/src/nvim/testdir/test72.ok new file mode 100644 index 0000000000..bb267d0d8b --- /dev/null +++ b/src/nvim/testdir/test72.ok @@ -0,0 +1,27 @@ +this is one line +this is ONE Line +one +two +six +seven +eight +nine +ten +one +two +three +four +five +six +seven +eight +nine +ten +monday +wednesday +thursday +friday +bar apr +apr +foo mar +mar diff --git a/src/nvim/testdir/test73.in b/src/nvim/testdir/test73.in new file mode 100644 index 0000000000..666e4d2e50 --- /dev/null +++ b/src/nvim/testdir/test73.in @@ -0,0 +1,176 @@ +Tests for find completion. + +STARTTEST +:so small.vim +:" Do all test in a separate window to avoid E211 when we recursively +:" delete the Xfind directory during cleanup +:" +:" This will cause a few errors, do it silently. +:set visualbell +:set nocp viminfo+=nviminfo +:" +:function! DeleteDirectory(dir) +: if has("win16") || has("win32") || has("win64") || has("dos16") || has("dos32") +: exec "silent !rmdir /Q /S " . a:dir +: else +: exec "silent !rm -rf " . a:dir +: endif +:endfun +:" On windows a stale "Xfind" directory may exist, remove it so that +:" we start from a clean state. +:call DeleteDirectory("Xfind") +:new +:let cwd=getcwd() +:let test_out = cwd . '/test.out' +:call mkdir('Xfind') +:cd Xfind +:set path= +:find +:exec "w! " . test_out +:close +:new +:set path=. +:find +:exec "w >>" . test_out +:close +:new +:set path=.,, +:find +:exec "w >>" . test_out +:close +:new +:set path=./** +:find +:exec "w >>" . test_out +:close +:new +:" We shouldn't find any file at this point, test.out must be empty. +:call mkdir('in') +:cd in +:call mkdir('path') +:exec "cd " . cwd +:e Xfind/file.txt +SHoly Grail:w +:e Xfind/in/file.txt +SJimmy Hoffa:w +:e Xfind/in/stuff.txt +SAnother Holy Grail:w +:e Xfind/in/path/file.txt +SE.T.:w +:set path=Xfind/** +:find file +:exec "w >>" . test_out +:find file +:exec "w >>" . test_out +:find file +:exec "w >>" . test_out +:" Rerun the previous three find completions, using fullpath in 'path' +:exec "set path=" . cwd . "/Xfind/**" +:find file +:exec "w >>" . test_out +:find file +:exec "w >>" . test_out +:find file +:exec "w >>" . test_out +:" Same steps again, using relative and fullpath items that point to the same +:" recursive location. +:" This is to test that there are no duplicates in the completion list. +:exec "set path+=Xfind/**" +:find file +:exec "w >>" . test_out +:find file +:exec "w >>" . test_out +:find file +:exec "w >>" . test_out +:find file +:" Test find completion for directory of current buffer, which at this point +:" is Xfind/in/file.txt. +:set path=. +:find st +:exec "w >>" . test_out +:" Test find completion for empty path item ",," which is the current directory +:cd Xfind +:set path=,, +:find f +:exec "w >>" . test_out +:" Test shortening of +:" +:" foo/x/bar/voyager.txt +:" foo/y/bar/voyager.txt +:" +:" When current directory is above foo/ they should be shortened to (in order +:" of appearance): +:" +:" x/bar/voyager.txt +:" y/bar/voyager.txt +:call mkdir('foo') +:cd foo +:call mkdir('x') +:call mkdir('y') +:cd x +:call mkdir('bar') +:cd .. +:cd y +:call mkdir('bar') +:cd .. +:cd .. +:" We should now be in the Xfind directory +:e foo/x/bar/voyager.txt +SVoyager 1:w +:e foo/y/bar/voyager.txt +SVoyager 2:w +:exec "set path=" . cwd . "/Xfind/**" +:find voyager +:exec "w >>" . test_out +:find voyager +:exec "w >>" . test_out +:" +:" When current directory is .../foo/y/bar they should be shortened to (in +:" order of appearance): +:" +:" ./voyager.txt +:" x/bar/voyager.txt +:cd foo +:cd y +:cd bar +:find voyager +:exec "w >> " . test_out +:find voyager +:exec "w >> " . test_out +:" Check the opposite too: +:cd .. +:cd .. +:cd x +:cd bar +:find voyager +:exec "w >> " . test_out +:find voyager +:exec "w >> " . test_out +:" Check for correct handling of shorten_fname()'s behavior on windows +:exec "cd " . cwd . "/Xfind/in" +:find file +:exec "w >>" . test_out +:" Test for relative to current buffer 'path' item +:exec "cd " . cwd . "/Xfind/" +:set path=./path +:" Open the file where Jimmy Hoffa is found +:e in/file.txt +:" Find the file containing 'E.T.' in the Xfind/in/path directory +:find file +:exec "w >>" . test_out +:" +:" Test that completion works when path=.,, +:" +:set path=.,, +:" Open Jimmy Hoffa file +:e in/file.txt +:exec "w >>" . test_out +:" Search for the file containing Holy Grail in same directory as in/path.txt +:find stu +:exec "w >>" . test_out +:q +:exec "cd " . cwd +:call DeleteDirectory("Xfind") +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test73.ok b/src/nvim/testdir/test73.ok new file mode 100644 index 0000000000..90efab756f --- /dev/null +++ b/src/nvim/testdir/test73.ok @@ -0,0 +1,21 @@ +Holy Grail +Jimmy Hoffa +E.T. +Holy Grail +Jimmy Hoffa +E.T. +Holy Grail +Jimmy Hoffa +E.T. +Another Holy Grail +Holy Grail +Voyager 1 +Voyager 2 +Voyager 2 +Voyager 1 +Voyager 1 +Voyager 2 +Jimmy Hoffa +E.T. +Jimmy Hoffa +Another Holy Grail diff --git a/src/nvim/testdir/test74.in b/src/nvim/testdir/test74.in new file mode 100644 index 0000000000..4fbe5e4d01 --- /dev/null +++ b/src/nvim/testdir/test74.in @@ -0,0 +1,36 @@ +" Tests for storing global variables in the .viminfo file vim: set ft=vim: + +STARTTEST +:so small.vim +:" Do all test in a separate window to avoid E211 when we recursively +:" delete the Xfind directory during cleanup +:" +:" This will cause a few errors, do it silently. +:set visualbell +:set nocp viminfo+=!,nviminfo +:let MY_GLOBAL_DICT={'foo': 1, 'bar': 0, 'longvarible': 1000} +:" store a really long list, so line wrapping will occur in viminfo file +:let MY_GLOBAL_LIST=range(1,100) +:wv! Xviminfo +:unlet MY_GLOBAL_DICT +:unlet MY_GLOBAL_LIST +:rv! Xviminfo +:call delete('Xviminfo') +:if exists("MY_GLOBAL_DICT") +:redir >> test.out +:echo MY_GLOBAL_DICT +:redir end +:endif +:if exists("MY_GLOBAL_LIST") +:redir >> test.out +:echo MY_GLOBAL_LIST +:redir end +:endif +:redir >> test.out +:echo "foobar" +:redir end +:endif +:qa! +ENDTEST + +eof diff --git a/src/nvim/testdir/test74.ok b/src/nvim/testdir/test74.ok new file mode 100644 index 0000000000..b026c33c35 --- /dev/null +++ b/src/nvim/testdir/test74.ok @@ -0,0 +1,5 @@ + +{'foo': 1, 'longvarible': 1000, 'bar': 0} +[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100] + +foobar diff --git a/src/nvim/testdir/test75.in b/src/nvim/testdir/test75.in new file mode 100644 index 0000000000..b7f2783f54 --- /dev/null +++ b/src/nvim/testdir/test75.in @@ -0,0 +1,41 @@ +Tests for maparg(). +Also test utf8 map with a 0x80 byte. + +STARTTEST +:so small.vim +:so mbyte.vim +:set cpo-=< +:set encoding=utf8 +:" Test maparg() with a string result +:map foo<C-V> is<F4>foo +:vnoremap <script> <buffer> <expr> <silent> bar isbar +:call append('$', maparg('foo<C-V>')) +:call append('$', string(maparg('foo<C-V>', '', 0, 1))) +:call append('$', string(maparg('bar', '', 0, 1))) +:map <buffer> <nowait> foo bar +:call append('$', string(maparg('foo', '', 0, 1))) +:" +:map abc x<char-114>x +:call append('$', maparg('abc')) +:map abc y<S-char-114>y +:call append('$', maparg('abc')) +:" +Go:" +:" Outside of the range, minimum +:inoremap <Char-0x1040> a +:call feedkeys("a\u1040\<Esc>") +:" Inside of the range, minimum +:inoremap <Char-0x103f> b +:call feedkeys("a\u103f\<Esc>") +:" Inside of the range, maximum +:inoremap <Char-0xf03f> c +:call feedkeys("a\uf03f\<Esc>") +:" Outside of the range, maximum +:inoremap <Char-0xf040> d +:call feedkeys("a\uf040\<Esc>") +:" +:/^eof/+1,$w! test.out +:qa! +ENDTEST + +eof diff --git a/src/nvim/testdir/test75.ok b/src/nvim/testdir/test75.ok new file mode 100644 index 0000000000..a2c5c5ac3d --- /dev/null +++ b/src/nvim/testdir/test75.ok @@ -0,0 +1,7 @@ +is<F4>foo +{'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0} +{'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'nowait': 0, 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1} +{'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ', 'nowait': 1, 'expr': 0, 'sid': 0, 'rhs': 'bar', 'buffer': 1} +xrx +yRy +abcd diff --git a/src/nvim/testdir/test76.in b/src/nvim/testdir/test76.in new file mode 100644 index 0000000000..db7ebe2169 --- /dev/null +++ b/src/nvim/testdir/test76.in @@ -0,0 +1,46 @@ +Tests for completefunc/omnifunc. vim: set ft=vim : + +STARTTEST +:"Test that nothing happens if the 'completefunc' opens +:"a new window (no completion, no crash) +:so small.vim +:function! DummyCompleteOne(findstart, base) +: if a:findstart +: return 0 +: else +: wincmd n +: return ['onedef', 'oneDEF'] +: endif +:endfunction +:setlocal completefunc=DummyCompleteOne +/^one +A:q! +:function! DummyCompleteTwo(findstart, base) +: if a:findstart +: wincmd n +: return 0 +: else +: return ['twodef', 'twoDEF'] +: endif +:endfunction +:setlocal completefunc=DummyCompleteTwo +/^two +A:q! +:"Test that 'completefunc' works when it's OK. +:function! DummyCompleteThree(findstart, base) +: if a:findstart +: return 0 +: else +: return ['threedef', 'threeDEF'] +: endif +:endfunction +:setlocal completefunc=DummyCompleteThree +/^three +A:/^+++/,/^three/w! test.out +:qa! +ENDTEST + ++++ +one +two +three diff --git a/src/nvim/testdir/test76.ok b/src/nvim/testdir/test76.ok new file mode 100644 index 0000000000..2a70acbade --- /dev/null +++ b/src/nvim/testdir/test76.ok @@ -0,0 +1,4 @@ ++++ + +two +threeDEF diff --git a/src/nvim/testdir/test77.in b/src/nvim/testdir/test77.in new file mode 100644 index 0000000000..0dbc4fcbaf --- /dev/null +++ b/src/nvim/testdir/test77.in @@ -0,0 +1,30 @@ +Inserts 2 million lines with consecutive integers starting from 1 +(essentially, the output of GNU's seq 1 2000000), writes them to Xtest +and writes its cksum to test.out. + +We need 2 million lines to trigger a call to mf_hash_grow(). If it would mess +up the lines the checksum would differ. + +cksum is part of POSIX and so should be available on most Unixes. +If it isn't available then the test will be skipped. + +STARTTEST +:so small.vim +:if !executable("cksum") +: e! test.ok +: w! test.out +: qa! +:endif +:set fileformat=unix undolevels=-1 +ggdG +:let i = 1 +:while i <= 2000000 | call append(i, range(i, i + 99)) | let i += 100 | endwhile +ggdd +:w! Xtest +:r !cksum Xtest +:s/\s/ /g +:set fileformat& +:.w! test.out +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test77.ok b/src/nvim/testdir/test77.ok new file mode 100644 index 0000000000..11f148c73f --- /dev/null +++ b/src/nvim/testdir/test77.ok @@ -0,0 +1 @@ +3678979763 14888896 Xtest diff --git a/src/nvim/testdir/test78.in b/src/nvim/testdir/test78.in new file mode 100644 index 0000000000..1850bd9236 --- /dev/null +++ b/src/nvim/testdir/test78.in @@ -0,0 +1,46 @@ +Inserts 10000 lines with text to fill the swap file with two levels of pointer +blocks. Then recovers from the swap file and checks all text is restored. + +We need about 10000 lines of 100 characters to get two levels of pointer +blocks. + +STARTTEST +:so small.vim +:set nocp fileformat=unix undolevels=-1 viminfo+=nviminfo +:e! Xtest +ggdG +:let text = "\tabcdefghijklmnoparstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnoparstuvwxyz0123456789" +:let i = 1 +:let linecount = 10000 +:while i <= linecount | call append(i - 1, i . text) | let i += 1 | endwhile +:preserve +:" get the name of the swap file +:redir => swapname +:swapname +:redir END +:let swapname = substitute(swapname, '[[:blank:][:cntrl:]]*\(.\{-}\)[[:blank:][:cntrl:]]*$', '\1', '') +:" make a copy of the swap file in Xswap +:set bin +:exe 'sp ' . swapname +:w! Xswap +:echo swapname +:set nobin +:new +:only! +:bwipe! Xtest +:call rename('Xswap', swapname) +:recover Xtest +:call delete(swapname) +:new +:call append(0, 'recovery start') +:wincmd w +:let linedollar = line('$') +:if linedollar < linecount | exe 'wincmd w' | call append(line('$'), "expected " . linecount . " lines but found only " . linedollar) | exe 'wincmd w' | let linecount = linedollar | endif +:let i = 1 +:while i <= linecount | if getline(i) != i . text | exe 'wincmd w' | call append(line('$'), i . ' differs') | exe 'wincmd w' | endif | let i += 1 | endwhile +:q! +:call append(line('$'), 'recovery end') +:w! test.out +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test78.ok b/src/nvim/testdir/test78.ok new file mode 100644 index 0000000000..6c3ecefe3c --- /dev/null +++ b/src/nvim/testdir/test78.ok @@ -0,0 +1,3 @@ +recovery start + +recovery end diff --git a/src/nvim/testdir/test79.in b/src/nvim/testdir/test79.in Binary files differnew file mode 100644 index 0000000000..8278bd8000 --- /dev/null +++ b/src/nvim/testdir/test79.in diff --git a/src/nvim/testdir/test79.ok b/src/nvim/testdir/test79.ok Binary files differnew file mode 100644 index 0000000000..e22eee0b71 --- /dev/null +++ b/src/nvim/testdir/test79.ok diff --git a/src/nvim/testdir/test8.in b/src/nvim/testdir/test8.in new file mode 100644 index 0000000000..d9d00d97ae --- /dev/null +++ b/src/nvim/testdir/test8.in @@ -0,0 +1,46 @@ +Test for BufWritePre autocommand that deletes or unloads the buffer. +Test for BufUnload autocommand that unloads all other buffers. + +STARTTEST +:so small.vim +:au BufWritePre Xxx1 bunload +:au BufWritePre Xxx2 bwipe +/^start of +A1:.,/end of/w! Xxx1 " write test file Xxx1 +$r2:.,/end of/w! Xxx2 " write test file Xxx2 +:e! Xxx2 " edit Xxx2 +:bdel test8.in " delete this file from the buffer list +:e Xxx1 " edit Xxx1 +:w " write it, will unload it and give an error msg +:w! test.out " Write contents of this file +:e! Xxx2 " start editing Xxx2 +:bwipe test.out " remove test.out from the buffer list +:w " write it, will delete the buffer and give an error msg +:w >>test.out " Append contents of this file +:au! BufWritePre +:func CloseAll() + let i = 0 + while i <= bufnr('$') + if i != bufnr('%') && bufloaded(i) + exe i . "bunload" + endif + let i += 1 + endwhile +endfunc +:func WriteToOut() + edit! test.out + $put ='VimLeave done' + write +endfunc +:set viminfo='100,nviminfo +:au BufUnload * call CloseAll() +:au VimLeave * call WriteToOut() +:e small.vim +:sp mbyte.vim +:q +:qa! +ENDTEST + +start of Xxx + test +end of Xxx diff --git a/src/nvim/testdir/test8.ok b/src/nvim/testdir/test8.ok new file mode 100644 index 0000000000..adecb2f4be --- /dev/null +++ b/src/nvim/testdir/test8.ok @@ -0,0 +1,7 @@ +start of Xxx2 + test +end of Xxx +start of Xxx1 + test +end of Xxx +VimLeave done diff --git a/src/nvim/testdir/test80.in b/src/nvim/testdir/test80.in new file mode 100644 index 0000000000..406fb6dac7 --- /dev/null +++ b/src/nvim/testdir/test80.in @@ -0,0 +1,201 @@ +Test for *sub-replace-special* and *sub-replace-expression* on substitue(). +Test for submatch() on substitue(). +Test for *:s%* on :substitute. + +STARTTEST +:so small.vim +ENDTEST + +TEST_1: + +STARTTEST +:set magic +:set cpo& +:$put =\"\n\nTEST_1:\" +:$put =substitute('A', 'A', '&&', '') +:$put =substitute('B', 'B', '\&', '') +:$put =substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', '') +:$put =substitute('D', 'D', 'd', '') +:$put =substitute('E', 'E', '~', '') +:$put =substitute('F', 'F', '\~', '') +:$put =substitute('G', 'G', '\ugg', '') +:$put =substitute('H', 'H', '\Uh\Eh', '') +:$put =substitute('I', 'I', '\lII', '') +:$put =substitute('J', 'J', '\LJ\EJ', '') +:$put =substitute('K', 'K', '\Uk\ek', '') +:$put =substitute('lLl', 'L', '
', '') +:$put =substitute('mMm', 'M', '\r', '') +:$put =substitute('nNn', 'N', '\
', '') +:$put =substitute('oOo', 'O', '\n', '') +:$put =substitute('pPp', 'P', '\b', '') +:$put =substitute('qQq', 'Q', '\t', '') +:$put =substitute('rRr', 'R', '\\', '') +:$put =substitute('sSs', 'S', '\c', '') +:$put =substitute('uUu', 'U', \"\n\", '') +:$put =substitute('vVv', 'V', \"\b\", '') +:$put =substitute('wWw', 'W', \"\\\", '') +:$put =substitute('xXx', 'X', \"\r\", '') +:$put =substitute('Y', 'Y', '\L\uyYy\l\EY', '') +:$put =substitute('Z', 'Z', '\U\lZzZ\u\Ez', '') +/^TEST_2 +ENDTEST + +TEST_2: + +STARTTEST +:set nomagic +:set cpo& +:$put =\"\n\nTEST_2:\" +:$put =substitute('A', 'A', '&&', '') +:$put =substitute('B', 'B', '\&', '') +:$put =substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', '') +:$put =substitute('D', 'D', 'd', '') +:$put =substitute('E', 'E', '~', '') +:$put =substitute('F', 'F', '\~', '') +:$put =substitute('G', 'G', '\ugg', '') +:$put =substitute('H', 'H', '\Uh\Eh', '') +:$put =substitute('I', 'I', '\lII', '') +:$put =substitute('J', 'J', '\LJ\EJ', '') +:$put =substitute('K', 'K', '\Uk\ek', '') +:$put =substitute('lLl', 'L', '
', '') +:$put =substitute('mMm', 'M', '\r', '') +:$put =substitute('nNn', 'N', '\
', '') +:$put =substitute('oOo', 'O', '\n', '') +:$put =substitute('pPp', 'P', '\b', '') +:$put =substitute('qQq', 'Q', '\t', '') +:$put =substitute('rRr', 'R', '\\', '') +:$put =substitute('sSs', 'S', '\c', '') +:$put =substitute('tTt', 'T', \"\r\", '') +:$put =substitute('uUu', 'U', \"\n\", '') +:$put =substitute('vVv', 'V', \"\b\", '') +:$put =substitute('wWw', 'W', \"\\\", '') +:$put =substitute('X', 'X', '\L\uxXx\l\EX', '') +:$put =substitute('Y', 'Y', '\U\lYyY\u\Ey', '') +/^TEST_3 +ENDTEST + +TEST_3: + +STARTTEST +:set magic& +:set cpo& +:$put =\"\n\nTEST_3:\" +:let y = substitute('aAa', 'A', '\="\\"', '') | $put =y +:let y = substitute('bBb', 'B', '\="\\\\"', '') | $put =y +:let y = substitute('cCc', 'C', '\="
"', '') | $put =y +:let y = substitute('dDd', 'D', '\="\\
"', '') | $put =y +:let y = substitute('eEe', 'E', '\="\\\\
"', '') | $put =y +:let y = substitute('fFf', 'F', '\="\\r"', '') | $put =y +:let y = substitute('jJj', 'J', '\="\\n"', '') | $put =y +:let y = substitute('kKk', 'K', '\="\r"', '') | $put =y +:let y = substitute('lLl', 'L', '\="\n"', '') | $put =y +/^TEST_4 +ENDTEST + +TEST_4: + +STARTTEST +:set magic& +:set cpo& +:$put =\"\n\nTEST_4:\" +:let y = substitute('aAa', 'A', '\=substitute(submatch(0), ".", "\\", "")', '') | $put =y +:let y = substitute('bBb', 'B', '\=substitute(submatch(0), ".", "\\\\", "")', '') | $put =y +:let y = substitute('cCc', 'C', '\=substitute(submatch(0), ".", "
", "")', '') | $put =y +:let y = substitute('dDd', 'D', '\=substitute(submatch(0), ".", "\\
", "")', '') | $put =y +:let y = substitute('eEe', 'E', '\=substitute(submatch(0), ".", "\\\\
", "")', '') | $put =y +:let y = substitute('fFf', 'F', '\=substitute(submatch(0), ".", "\\r", "")', '') | $put =y +:let y = substitute('jJj', 'J', '\=substitute(submatch(0), ".", "\\n", "")', '') | $put =y +:let y = substitute('kKk', 'K', '\=substitute(submatch(0), ".", "\r", "")', '') | $put =y +:let y = substitute('lLl', 'L', '\=substitute(submatch(0), ".", "\n", "")', '') | $put =y +/^TEST_5 +ENDTEST + +TEST_5: + +STARTTEST +:set magic& +:set cpo& +:$put =\"\n\nTEST_5:\" +:$put =substitute('A123456789', 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . submatch(6) . submatch(5) . submatch(4) . submatch(3) . submatch(2) . submatch(1)', '') +:$put =substitute('A123456789', 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\=string([submatch(0, 1), submatch(9, 1), submatch(8, 1), submatch(7, 1), submatch(6, 1), submatch(5, 1), submatch(4, 1), submatch(3, 1), submatch(2, 1), submatch(1, 1)])', '') +/^TEST_6 +ENDTEST + +TEST_6: + +STARTTEST +:set magic& +:$put =\"\n\nTEST_6:\" +:set cpo+=/ +:$put =substitute('A', 'A', 'a', '') +:$put =substitute('B', 'B', '%', '') +:set cpo-=/ +:$put =substitute('C', 'C', 'c', '') +:$put =substitute('D', 'D', '%', '') +/^TEST_7 +ENDTEST + +TEST_7: + +STARTTEST +:set magic& +:set cpo& +:$put =\"\n\nTEST_7:\" +:$put =substitute('A
A', 'A.', '\=submatch(0)', '') +:$put =substitute(\"B\nB\", 'B.', '\=submatch(0)', '') +:$put =substitute(\"B\nB\", 'B.', '\=string(submatch(0, 1))', '') +:$put =substitute('-bb', '\zeb', 'a', 'g') +:$put =substitute('-bb', '\ze', 'c', 'g') +/^TEST_8 +ENDTEST + +TEST_8: + +STARTTEST +:set magic& +:set cpo& +:$put =\"\n\nTEST_8:\" +:$put =',,X' +:s/\(^\|,\)\ze\(,\|X\)/\1N/g +:$put =',,Y' +:s/\(^\|,\)\ze\(,\|Y\)/\1N/gc +a:$put =',,Z' +:s/\(^\|,\)\ze\(,\|Z\)/\1N/gc +yy/^TEST_9: +ENDTEST + +TEST_9: + +STARTTEST +:set magic& +:set cpo& +:$put =\"\n\nTEST_9:\" +:$put ='xxx' +:s/x/X/gc +yyq/^TEST_10: +ENDTEST + +TEST_10: + +STARTTEST +:set magic& +:set cpo& +:$put =\"\n\nTEST_10:\" +:let y = substitute('123', '\zs', 'a', 'g') | $put =y +:let y = substitute('123', '\zs.', 'a', 'g') | $put =y +:let y = substitute('123', '.\zs', 'a', 'g') | $put =y +:let y = substitute('123', '\ze', 'a', 'g') | $put =y +:let y = substitute('123', '\ze.', 'a', 'g') | $put =y +:let y = substitute('123', '.\ze', 'a', 'g') | $put =y +:let y = substitute('123', '1\|\ze', 'a', 'g') | $put =y +:let y = substitute('123', '1\zs\|[23]', 'a', 'g') | $put =y +/^TEST_11 +ENDTEST + +TEST_11: + +STARTTEST +:/^Results/,$wq! test.out +ENDTEST + +Results of test72: diff --git a/src/nvim/testdir/test80.ok b/src/nvim/testdir/test80.ok new file mode 100644 index 0000000000..b42f604a07 --- /dev/null +++ b/src/nvim/testdir/test80.ok @@ -0,0 +1,131 @@ +Results of test72: + + +TEST_1: +AA +& +C123456789987654321 +d +~ +~ +Gg +Hh +iI +jJ +Kk +l
l +m
m +n
n +o +o +pp +q q +r\r +scs +u +u +vv +w\w +x
x +YyyY +zZZz + + +TEST_2: +AA +& +C123456789987654321 +d +~ +~ +Gg +Hh +iI +jJ +Kk +l
l +m
m +n
n +o +o +pp +q q +r\r +scs +t
t +u +u +vv +w\w +XxxX +yYYy + + +TEST_3: +a\a +b\\b +c
c +d\
d +e\\
e +f\rf +j\nj +k
k +l +l + + +TEST_4: +a\a +b\b +c
c +d
d +e\
e +f
f +j +j +k
k +l +l + + +TEST_5: +A123456789987654321 +[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']] + + +TEST_6: +a +% +c +% + + +TEST_7: +A
A +B +B +['B +']B +-abab +c-cbcbc + + +TEST_8: +N,,NX +N,,NY +N,,NZ + + +TEST_9: +XXx + + +TEST_10: +a1a2a3a +aaa +1a2a3a +a1a2a3a +a1a2a3 +aaa +aa2a3a +1aaa diff --git a/src/nvim/testdir/test81.in b/src/nvim/testdir/test81.in new file mode 100644 index 0000000000..82a6892a1d --- /dev/null +++ b/src/nvim/testdir/test81.in @@ -0,0 +1,22 @@ +Test for t movement command and 'cpo-;' setting + +STARTTEST +:set nocompatible viminfo+=nviminfo +:set cpo-=; +/firstline/ +j0tt;D +0fz;D +$Fy;D +$Ty;D:set cpo+=; +j0tt;;D +$Ty;;D:?firstline?+1,$w! test.out +:qa! +ENDTEST + +firstline +aaa two three four + zzz +yyy +bbb yee yoo four +ccc two three four +ddd yee yoo four diff --git a/src/nvim/testdir/test81.ok b/src/nvim/testdir/test81.ok new file mode 100644 index 0000000000..e9f17dc4f8 --- /dev/null +++ b/src/nvim/testdir/test81.ok @@ -0,0 +1,6 @@ +aaa two + z +y +bbb y +ccc +ddd yee y diff --git a/src/nvim/testdir/test82.in b/src/nvim/testdir/test82.in new file mode 100644 index 0000000000..8503f5488f --- /dev/null +++ b/src/nvim/testdir/test82.in @@ -0,0 +1,103 @@ +Tests for case-insensitive UTF-8 comparisons (utf_strnicmp() in mbyte.c) +Also test "g~ap". + +STARTTEST +:so small.vim +:if !has("multi_byte") +: e! test.ok +: w! test.out +: qa! +:endif +:set enc=utf8 +ggdG +: +:function! Ch(a, op, b, expected) +: if eval(printf('"%s" %s "%s"', a:a, a:op, a:b)) != a:expected +: call append(line('$'), printf('"%s" %s "%s" should return %d', a:a, a:op, a:b, a:expected)) +: else +: let b:passed += 1 +: endif +:endfunction +: +:function! Chk(a, b, result) +: if a:result == 0 +: call Ch(a:a, '==?', a:b, 1) +: call Ch(a:a, '!=?', a:b, 0) +: call Ch(a:a, '<=?', a:b, 1) +: call Ch(a:a, '>=?', a:b, 1) +: call Ch(a:a, '<?', a:b, 0) +: call Ch(a:a, '>?', a:b, 0) +: elseif a:result > 0 +: call Ch(a:a, '==?', a:b, 0) +: call Ch(a:a, '!=?', a:b, 1) +: call Ch(a:a, '<=?', a:b, 0) +: call Ch(a:a, '>=?', a:b, 1) +: call Ch(a:a, '<?', a:b, 0) +: call Ch(a:a, '>?', a:b, 1) +: else +: call Ch(a:a, '==?', a:b, 0) +: call Ch(a:a, '!=?', a:b, 1) +: call Ch(a:a, '<=?', a:b, 1) +: call Ch(a:a, '>=?', a:b, 0) +: call Ch(a:a, '<?', a:b, 1) +: call Ch(a:a, '>?', a:b, 0) +: endif +:endfunction +: +:function! Check(a, b, result) +: call Chk(a:a, a:b, a:result) +: call Chk(a:b, a:a, -a:result) +:endfunction +: +:function! LT(a, b) +: call Check(a:a, a:b, -1) +:endfunction +: +:function! GT(a, b) +: call Check(a:a, a:b, 1) +:endfunction +: +:function! EQ(a, b) +: call Check(a:a, a:b, 0) +:endfunction +: +:let b:passed=0 +:call EQ('', '') +:call LT('', 'a') +:call EQ('abc', 'abc') +:call EQ('Abc', 'abC') +:call LT('ab', 'abc') +:call LT('AB', 'abc') +:call LT('ab', 'aBc') +:call EQ('\xd0\xb9\xd1\x86\xd1\x83\xd0\xba\xd0\xb5\xd0\xbd', '\xd0\xb9\xd0\xa6\xd0\xa3\xd0\xba\xd0\x95\xd0\xbd') +:call LT('\xd0\xb9\xd1\x86\xd1\x83\xd0\xba\xd0\xb5\xd0\xbd', '\xd0\xaf\xd1\x86\xd1\x83\xd0\xba\xd0\xb5\xd0\xbd') +:call EQ('\xe2\x84\xaa', 'k') +:call LT('\xe2\x84\xaa', 'kkkkkk') +:call EQ('\xe2\x84\xaa\xe2\x84\xaa\xe2\x84\xaa', 'kkk') +:call LT('kk', '\xe2\x84\xaa\xe2\x84\xaa\xe2\x84\xaa') +:call EQ('\xe2\x84\xaa\xe2\x84\xa6k\xe2\x84\xaak\xcf\x89', 'k\xcf\x89\xe2\x84\xaakk\xe2\x84\xa6') +:call EQ('Abc\x80', 'AbC\x80') +:call LT('Abc\x80', 'AbC\x81') +:call LT('Abc', 'AbC\x80') +:call LT('abc\x80DEF', 'abc\x80def') " case folding stops at the first bad character +:call LT('\xc3XYZ', '\xc3xyz') +:call EQ('\xef\xbc\xba', '\xef\xbd\x9a') " FF3A (upper), FF5A (lower) +:call GT('\xef\xbc\xba', '\xef\xbc\xff') " first string is ok and equals \xef\xbd\x9a after folding, second string is illegal and was left unchanged, then the strings were bytewise compared +:call LT('\xc3', '\xc3\x83') +:call EQ('\xc3\xa3xYz', '\xc3\x83XyZ') +:for n in range(0x60, 0xFF) | call LT(printf('xYz\x%.2X', n-1), printf('XyZ\x%.2X', n)) | endfor +:for n in range(0x80, 0xBF) | call EQ(printf('xYz\xc2\x%.2XUvW', n), printf('XyZ\xc2\x%.2XuVw', n)) | endfor +:for n in range(0xC0, 0xFF) | call LT(printf('xYz\xc2\x%.2XUvW', n), printf('XyZ\xc2\x%.2XuVw', n)) | endfor +:call append(0, printf('%d checks passed', b:passed)) +:" +:" test that g~ap changes one paragraph only. +:new +iabcd + +defggg0g~ap:let lns = getline(1,3) +:q! +:call append(line('$'), lns) +:" +:wq! test.out +ENDTEST + diff --git a/src/nvim/testdir/test82.ok b/src/nvim/testdir/test82.ok new file mode 100644 index 0000000000..3f1866a0fb --- /dev/null +++ b/src/nvim/testdir/test82.ok @@ -0,0 +1,5 @@ +3732 checks passed + +ABCD + +defg diff --git a/src/nvim/testdir/test83-tags2 b/src/nvim/testdir/test83-tags2 new file mode 100644 index 0000000000..7f9f21b0eb --- /dev/null +++ b/src/nvim/testdir/test83-tags2 @@ -0,0 +1,2 @@ +!_TAG_FILE_ENCODING cp932 // +`ab Xtags2.txt /`ab diff --git a/src/nvim/testdir/test83-tags3 b/src/nvim/testdir/test83-tags3 new file mode 100644 index 0000000000..0cb6591562 --- /dev/null +++ b/src/nvim/testdir/test83-tags3 @@ -0,0 +1,102 @@ +!_TAG_FILE_SORTED 1 // +!_TAG_FILE_ENCODING cp932 // +abc1 Xtags3.txt /`ab +abc2 Xtags3.txt /`ab +abc3 Xtags3.txt /`ab +abc4 Xtags3.txt /`ab +abc5 Xtags3.txt /`ab +abc6 Xtags3.txt /`ab +abc7 Xtags3.txt /`ab +abc8 Xtags3.txt /`ab +abc9 Xtags3.txt /`ab +abc10 Xtags3.txt /`ab +abc11 Xtags3.txt /`ab +abc12 Xtags3.txt /`ab +abc13 Xtags3.txt /`ab +abc14 Xtags3.txt /`ab +abc15 Xtags3.txt /`ab +abc16 Xtags3.txt /`ab +abc17 Xtags3.txt /`ab +abc18 Xtags3.txt /`ab +abc19 Xtags3.txt /`ab +abc20 Xtags3.txt /`ab +abc21 Xtags3.txt /`ab +abc22 Xtags3.txt /`ab +abc23 Xtags3.txt /`ab +abc24 Xtags3.txt /`ab +abc25 Xtags3.txt /`ab +abc26 Xtags3.txt /`ab +abc27 Xtags3.txt /`ab +abc28 Xtags3.txt /`ab +abc29 Xtags3.txt /`ab +abc30 Xtags3.txt /`ab +abc31 Xtags3.txt /`ab +abc32 Xtags3.txt /`ab +abc33 Xtags3.txt /`ab +abc34 Xtags3.txt /`ab +abc35 Xtags3.txt /`ab +abc36 Xtags3.txt /`ab +abc37 Xtags3.txt /`ab +abc38 Xtags3.txt /`ab +abc39 Xtags3.txt /`ab +abc40 Xtags3.txt /`ab +abc41 Xtags3.txt /`ab +abc42 Xtags3.txt /`ab +abc43 Xtags3.txt /`ab +abc44 Xtags3.txt /`ab +abc45 Xtags3.txt /`ab +abc46 Xtags3.txt /`ab +abc47 Xtags3.txt /`ab +abc48 Xtags3.txt /`ab +abc49 Xtags3.txt /`ab +abc50 Xtags3.txt /`ab +abc51 Xtags3.txt /`ab +abc52 Xtags3.txt /`ab +abc53 Xtags3.txt /`ab +abc54 Xtags3.txt /`ab +abc55 Xtags3.txt /`ab +abc56 Xtags3.txt /`ab +abc57 Xtags3.txt /`ab +abc58 Xtags3.txt /`ab +abc59 Xtags3.txt /`ab +abc60 Xtags3.txt /`ab +abc61 Xtags3.txt /`ab +abc62 Xtags3.txt /`ab +abc63 Xtags3.txt /`ab +abc64 Xtags3.txt /`ab +abc65 Xtags3.txt /`ab +abc66 Xtags3.txt /`ab +abc67 Xtags3.txt /`ab +abc68 Xtags3.txt /`ab +abc69 Xtags3.txt /`ab +abc70 Xtags3.txt /`ab +abc71 Xtags3.txt /`ab +abc72 Xtags3.txt /`ab +abc73 Xtags3.txt /`ab +abc74 Xtags3.txt /`ab +abc75 Xtags3.txt /`ab +abc76 Xtags3.txt /`ab +abc77 Xtags3.txt /`ab +abc78 Xtags3.txt /`ab +abc79 Xtags3.txt /`ab +abc80 Xtags3.txt /`ab +abc81 Xtags3.txt /`ab +abc82 Xtags3.txt /`ab +abc83 Xtags3.txt /`ab +abc84 Xtags3.txt /`ab +abc85 Xtags3.txt /`ab +abc86 Xtags3.txt /`ab +abc87 Xtags3.txt /`ab +abc88 Xtags3.txt /`ab +abc89 Xtags3.txt /`ab +abc90 Xtags3.txt /`ab +abc91 Xtags3.txt /`ab +abc92 Xtags3.txt /`ab +abc93 Xtags3.txt /`ab +abc94 Xtags3.txt /`ab +abc95 Xtags3.txt /`ab +abc96 Xtags3.txt /`ab +abc97 Xtags3.txt /`ab +abc98 Xtags3.txt /`ab +abc99 Xtags3.txt /`ab +abc100 Xtags3.txt /`ab diff --git a/src/nvim/testdir/test83.in b/src/nvim/testdir/test83.in new file mode 100644 index 0000000000..297d560d2f --- /dev/null +++ b/src/nvim/testdir/test83.in @@ -0,0 +1,76 @@ +Tests for tag search with !_TAG_FILE_ENCODING. + +STARTTEST +:so mbyte.vim +:set enc=utf8 +:if !has('iconv') || iconv("\x82\x60", "cp932", "utf-8") != "\uff21" +: e! test.ok +: w! test.out +: qa! +:endif + +:/^text for tags1$/,/^text for tags1$/+1w! Xtags1.txt +:/^text for tags2$/,/^text for tags2$/+1w! Xtags2.txt +:/^text for tags3$/,/^text for tags3$/+1w! Xtags3.txt +:/^tags1$/+1,/^tags1-end$/-1w! Xtags1 + +ggdG + +:call setline('.', 'Results of test83') + +:" case1: +:new +:set tags=Xtags1 +:let v:errmsg = '' +:tag abcdefghijklmnopqrs +:if v:errmsg =~ 'E426:' || getline('.') != 'abcdefghijklmnopqrs' +: close +: put ='case1: failed' +:else +: close +: put ='case1: ok' +:endif + +:" case2: +:new +:set tags=test83-tags2 +:let v:errmsg = '' +:tag /.BC +:if v:errmsg =~ 'E426:' || getline('.') != 'ABC' +: close +: put ='case2: failed' +:else +: close +: put ='case2: ok' +:endif + +:" case3: +:new +:set tags=test83-tags3 +:let v:errmsg = '' +:tag abc50 +:if v:errmsg =~ 'E426:' || getline('.') != 'ABC' +: close +: put ='case3: failed' +:else +: close +: put ='case3: ok' +:endif +:close + +:wq! test.out +ENDTEST + +text for tags1 +abcdefghijklmnopqrs + +text for tags2 +ABC + +text for tags3 +ABC + +tags1 +!_TAG_FILE_ENCODING utf-8 // +abcdefghijklmnopqrs Xtags1.txt /abcdefghijklmnopqrs +tags1-end diff --git a/src/nvim/testdir/test83.ok b/src/nvim/testdir/test83.ok new file mode 100644 index 0000000000..61a1a04a18 --- /dev/null +++ b/src/nvim/testdir/test83.ok @@ -0,0 +1,4 @@ +Results of test83 +case1: ok +case2: ok +case3: ok diff --git a/src/nvim/testdir/test84.in b/src/nvim/testdir/test84.in new file mode 100644 index 0000000000..25482db54c --- /dev/null +++ b/src/nvim/testdir/test84.in @@ -0,0 +1,35 @@ +Tests for curswant not changing when setting an option + +STARTTEST +:so small.vim +:/^start target options$/+1,/^end target options$/-1 yank +:let target_option_names = split(@0) +:function TestCurswant(option_name) +: normal! ggf8j +: let curswant_before = winsaveview().curswant +: execute 'let' '&'.a:option_name '=' '&'.a:option_name +: let curswant_after = winsaveview().curswant +: return [a:option_name, curswant_before, curswant_after] +:endfunction +: +:new +:put =['1234567890', '12345'] +:1 delete _ +:let result = [] +:for option_name in target_option_names +: call add(result, TestCurswant(option_name)) +:endfor +: +:new +:put =map(copy(result), 'join(v:val, '' '')') +:1 delete _ +:write test.out +: +:qall! +ENDTEST + +start target options + tabstop + timeoutlen + ttimeoutlen +end target options diff --git a/src/nvim/testdir/test84.ok b/src/nvim/testdir/test84.ok new file mode 100644 index 0000000000..8b8e4ee824 --- /dev/null +++ b/src/nvim/testdir/test84.ok @@ -0,0 +1,3 @@ +tabstop 7 4 +timeoutlen 7 7 +ttimeoutlen 7 7 diff --git a/src/nvim/testdir/test85.in b/src/nvim/testdir/test85.in new file mode 100644 index 0000000000..c5ca873a49 --- /dev/null +++ b/src/nvim/testdir/test85.in @@ -0,0 +1,85 @@ +Test for Lua interface and luaeval() function + +STARTTEST +:so small.vim +:so lua.vim +:set nocompatible viminfo+=nviminfo +:lua l = vim.list():add"item0":add"dictionary with list OK":add"item2" +:lua h = vim.dict(); h.list = l +:call garbagecollect() +/^1 +:" change buffer contents +:lua curbuf = vim.buffer() +:lua curline = vim.eval"line('.')" +:lua curbuf[curline] = "1 changed line 1" +:" scalar test +:let tmp_string = luaeval('"string"') +:let tmp_1000 = luaeval('1000') +:if printf("%s%.0f", tmp_string, tmp_1000) == "string1000" +:let scalar_res = "OK" +:else +:let scalar_res = "FAILED" +:endif +:call append(search("^1"), "scalar test " . scalar_res) +:" dictionary containing a list +:let tmp = luaeval("h").list[1] +:/^2/put =tmp +:" circular list (at the same time test lists containing lists) +:lua l[2] = l +:let l2 = luaeval("h").list +:if l2[2] == l2 +:let res = "OK" +:else +:let res = "FAILED" +:endif +:call setline(search("^3"), "circular test " . res) + +:let l = [] +:lua l = vim.eval("l") +:lua l:add(123) +:lua l:add("abc") +:lua l:add(vim.eval("[1, 2, 3]")) +:lua l:add(vim.eval("{'a':1, 'b':2, 'c':3}")) +:lua l:insert(123) +:lua l:insert("abc") +:lua l:insert(vim.eval("[1, 2, 3]")) +:lua l:insert(vim.eval("{'a':1, 'b':2, 'c':3}")) +:lua l[0] = l[0] +:lua l[1] = l[1] +:lua l[2] = l[2] +:lua l[3] = l[3] +:lua l[0] = 123 +:lua l[1] = "abc" +:lua l[2] = vim.eval("[1, 2, 3]") +:lua l[3] = vim.eval("{'a':1, 'b':2, 'c':3}") +:lua l[3] = nil +:lua l[2] = nil +:lua l[1] = nil +:lua l[0] = nil +:lua l = nil +:$put =string(l) + +:let d = {} +:lua d = vim.eval("d") +:lua d[0] = 123 +:lua d[1] = "abc" +:lua d[2] = vim.eval("[1, 2, 3]") +:lua d[3] = vim.eval("{'a':1, 'b':2, 'c':3}") +:lua d[4] = d[0] +:lua d[5] = d[1] +:lua d[6] = d[2] +:lua d[7] = d[3] +:lua d[3] = nil +:lua d[2] = nil +:lua d[1] = nil +:lua d[0] = nil +:lua d = nil +:$put =string(d) + +:?^1?,$w! test.out +:qa! +ENDTEST + +1 line 1 +2 line 2 +3 line 3 diff --git a/src/nvim/testdir/test85.ok b/src/nvim/testdir/test85.ok new file mode 100644 index 0000000000..4753483240 --- /dev/null +++ b/src/nvim/testdir/test85.ok @@ -0,0 +1,7 @@ +1 changed line 1 +scalar test OK +2 line 2 +dictionary with list OK +circular test OK +[123.0, 'abc', [1, 2, 3], {'a': 1, 'b': 2, 'c': 3}] +{'4': 123.0, '5': 'abc', '6': [1, 2, 3], '7': {'a': 1, 'b': 2, 'c': 3}} diff --git a/src/nvim/testdir/test86.in b/src/nvim/testdir/test86.in new file mode 100644 index 0000000000..240e07e477 --- /dev/null +++ b/src/nvim/testdir/test86.in @@ -0,0 +1,1429 @@ +Tests for various python features. vim: set ft=vim : + +NOTE: This will cause errors when run under valgrind. +This would require recompiling Python with: + ./configure --without-pymalloc +See http://svn.python.org/view/python/trunk/Misc/README.valgrind?view=markup + +STARTTEST +:so small.vim +:set encoding=latin1 +:set noswapfile +:if !has('python') | e! test.ok | wq! test.out | endif +:lang C +:fun Test() +:py import vim +:let l = [] +:py l=vim.bindeval('l') +:py f=vim.bindeval('function("strlen")') +:" Extending List directly with different types +:py l.extend([1, "as'd", [1, 2, f, {'a': 1}]]) +:$put =string(l) +:$put =string(l[-1]) +:try +: $put =string(l[-4]) +:catch +: $put =v:exception[:13] +:endtry +:" List assignment +:py l[0]=0 +:$put =string(l) +:py l[-2]=f +:$put =string(l) +:" +:" Extending Dictionary directly with different types +:let d = {} +:fun d.f() +: return 1 +:endfun +py << EOF +d=vim.bindeval('d') +d['1']='asd' +d.update(b=[1, 2, f]) +d.update((('-1', {'a': 1}),)) +d.update({'0': -1}) +dk = d.keys() +dv = d.values() +di = d.items() +cmpfun = lambda a, b: cmp(repr(a), repr(b)) +dk.sort(cmpfun) +dv.sort(cmpfun) +di.sort(cmpfun) +EOF +:$put =pyeval('d[''f''](self={})') +:$put =pyeval('repr(dk)') +:$put =substitute(pyeval('repr(dv)'),'0x\x\+','','g') +:$put =substitute(pyeval('repr(di)'),'0x\x\+','','g') +:for [key, Val] in sort(items(d)) +: $put =string(key) . ' : ' . string(Val) +: unlet key Val +:endfor +:py del dk +:py del di +:py del dv +:" +:" removing items with del +:py del l[2] +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:try +: py del l[:3] +: py del l[1:] +:catch +: $put =v:exception +:endtry +:$put =string(l) +:" +:py del d['-1'] +:py del d['f'] +:$put =string(pyeval('d.get(''b'', 1)')) +:$put =string(pyeval('d.pop(''b'')')) +:$put =string(pyeval('d.get(''b'', 1)')) +:$put =string(pyeval('d.pop(''1'', 2)')) +:$put =string(pyeval('d.pop(''1'', 2)')) +:$put =pyeval('repr(d.has_key(''0''))') +:$put =pyeval('repr(d.has_key(''1''))') +:$put =pyeval('repr(''0'' in d)') +:$put =pyeval('repr(''1'' in d)') +:$put =pyeval('repr(list(iter(d)))') +:$put =string(d) +:$put =pyeval('repr(d.popitem())') +:$put =pyeval('repr(d.get(''0''))') +:$put =pyeval('repr(list(iter(d)))') +:" +:" removing items out of range: silently skip items that don't exist +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:" The following two ranges delete nothing as they match empty list: +:py del l[2:1] +:$put =string(l) +:py del l[2:2] +:$put =string(l) +:py del l[2:3] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[2:4] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[2:5] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[2:6] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:" The following two ranges delete nothing as they match empty list: +:py del l[-1:2] +:$put =string(l) +:py del l[-2:2] +:$put =string(l) +:py del l[-3:2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[-4:2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[-5:2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[-6:2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[::2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[3:0:-2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[2:4:-2] +:$put =string(l) +:" +:" Slice assignment to a list +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py l[0:0]=['a'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py l[1:2]=['b'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py l[2:4]=['c'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py l[4:4]=['d'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py l[-1:2]=['e'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py l[-10:2]=['f'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py l[2:-10]=['g'] +:$put =string(l) +:let l = [] +:py l=vim.bindeval('l') +:py l[0:0]=['h'] +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[2:6:2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[6:2:-2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[6:2] = () +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[6:2:1] = () +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[2:2:1] = () +:$put =string(l) +:" +:" Locked variables +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:lockvar! l +:py l[2]='i' +:$put =string(l) +:unlockvar! l +:" +:" Function calls +py << EOF +import sys +def ee(expr, g=globals(), l=locals()): + try: + exec(expr, g, l) + except: + ei = sys.exc_info() + msg = sys.exc_info()[0].__name__ + ':' + repr(sys.exc_info()[1].args) + msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'') + if expr.find('None') > -1: + msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', + 'TypeError:("\'NoneType\' object is not iterable",)') + if expr.find('FailingNumber') > -1: + msg = msg.replace(', not \'FailingNumber\'', '').replace('"', '\'') + msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', + 'TypeError:("\'FailingNumber\' object is not iterable",)') + if msg.find('(\'\'') > -1 or msg.find('(\'can\'t') > -1: + msg = msg.replace('(\'', '("').replace('\',)', '",)') + if expr == 'fd(self=[])': + # HACK: PyMapping_Check changed meaning + msg = msg.replace('AttributeError:(\'keys\',)', + 'TypeError:(\'unable to convert list to vim dictionary\',)') + vim.current.buffer.append(expr + ':' + msg) + else: + vim.current.buffer.append(expr + ':NOT FAILED') +EOF +:fun New(...) +: return ['NewStart']+a:000+['NewEnd'] +:endfun +:fun DictNew(...) dict +: return ['DictNewStart']+a:000+['DictNewEnd', self] +:endfun +:let l=[function('New'), function('DictNew')] +:py l=vim.bindeval('l') +:py l.extend(list(l[0](1, 2, 3))) +:$put =string(l) +:py l.extend(list(l[1](1, 2, 3, self={'a': 'b'}))) +:$put =string(l) +:py l.extend([l[0].name]) +:$put =string(l) +:py ee('l[1](1, 2, 3)') +:py f=l[0] +:delfunction New +:py ee('f(1, 2, 3)') +:if has('float') +: let l=[0.0] +: py l=vim.bindeval('l') +: py l.extend([0.0]) +: $put =string(l) +:else +: $put ='[0.0, 0.0]' +:endif +:let messages=[] +:delfunction DictNew +py <<EOF +d=vim.bindeval('{}') +m=vim.bindeval('messages') +def em(expr, g=globals(), l=locals()): + try: + exec(expr, g, l) + except: + m.extend([sys.exc_type.__name__]) + +em('d["abc1"]') +em('d["abc1"]="\\0"') +em('d["abc1"]=vim') +em('d[""]=1') +em('d["a\\0b"]=1') +em('d[u"a\\0b"]=1') + +em('d.pop("abc1")') +em('d.popitem()') +del em +del m +EOF +:$put =messages +:unlet messages +:" locked and scope attributes +:let d={} | let dl={} | lockvar dl +:for s in split("d dl v: g:") +: let name=tr(s, ':', 's') +: execute 'py '.name.'=vim.bindeval("'.s.'")' +: let toput=s.' : '.join(map(['locked', 'scope'], 'v:val.":".pyeval(name.".".v:val)'), ';') +: $put =toput +:endfor +:silent! let d.abc2=1 +:silent! let dl.abc3=1 +:py d.locked=True +:py dl.locked=False +:silent! let d.def=1 +:silent! let dl.def=1 +:put ='d:'.string(d) +:put ='dl:'.string(dl) +:unlet d dl +: +:let l=[] | let ll=[] | lockvar ll +:for s in split("l ll") +: let name=tr(s, ':', 's') +: execute 'py '.name.'=vim.bindeval("'.s.'")' +: let toput=s.' : locked:'.pyeval(name.'.locked') +: $put =toput +:endfor +:silent! call extend(l, [0]) +:silent! call extend(ll, [0]) +:py l.locked=True +:py ll.locked=False +:silent! call extend(l, [1]) +:silent! call extend(ll, [1]) +:put ='l:'.string(l) +:put ='ll:'.string(ll) +:unlet l ll +:" +:" pyeval() +:let l=pyeval('range(3)') +:$put =string(l) +:let d=pyeval('{"a": "b", "c": 1, "d": ["e"]}') +:$put =sort(items(d)) +:if has('float') +: let f=pyeval('0.0') +: $put =string(f) +:else +: $put ='0.0' +:endif +:" Invalid values: +:for e in ['"\0"', '{"\0": 1}', 'undefined_name', 'vim'] +: try +: let v=pyeval(e) +: catch +: let toput=e.":\t".v:exception[:13] +: $put =toput +: endtry +:endfor +:" +:" threading +:let l = [0] +:py l=vim.bindeval('l') +py <<EOF +import threading +import time + +class T(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + self.t = 0 + self.running = True + + def run(self): + while self.running: + self.t += 1 + time.sleep(0.1) + +t = T() +del T +t.start() +EOF +:sleep 1 +:py t.running = False +:py t.join() +:py l[0] = t.t > 8 # check if the background thread is working +:py del time +:py del threading +:py del t +:$put =string(l) +:" +:" settrace +:let l = [] +:py l=vim.bindeval('l') +py <<EOF +import sys + +def traceit(frame, event, arg): + global l + if event == "line": + l.extend([frame.f_lineno]) + return traceit + +def trace_main(): + for i in range(5): + pass +EOF +:py sys.settrace(traceit) +:py trace_main() +:py sys.settrace(None) +:py del traceit +:py del trace_main +:$put =string(l) +:" +:" Slice +:py ll = vim.bindeval('[0, 1, 2, 3, 4, 5]') +:py l = ll[:4] +:$put =string(pyeval('l')) +:py l = ll[2:] +:$put =string(pyeval('l')) +:py l = ll[:-4] +:$put =string(pyeval('l')) +:py l = ll[-2:] +:$put =string(pyeval('l')) +:py l = ll[2:4] +:$put =string(pyeval('l')) +:py l = ll[4:2] +:$put =string(pyeval('l')) +:py l = ll[-4:-2] +:$put =string(pyeval('l')) +:py l = ll[-2:-4] +:$put =string(pyeval('l')) +:py l = ll[:] +:$put =string(pyeval('l')) +:py l = ll[0:6] +:$put =string(pyeval('l')) +:py l = ll[-10:10] +:$put =string(pyeval('l')) +:py l = ll[4:2:-1] +:$put =string(pyeval('l')) +:py l = ll[::2] +:$put =string(pyeval('l')) +:py l = ll[4:2:1] +:$put =string(pyeval('l')) +:py del l +:" +:" Vars +:let g:foo = 'bac' +:let w:abc3 = 'def' +:let b:baz = 'bar' +:let t:bar = 'jkl' +:try +: throw "Abc" +:catch +: put =pyeval('vim.vvars[''exception'']') +:endtry +:put =pyeval('vim.vars[''foo'']') +:put =pyeval('vim.current.window.vars[''abc3'']') +:put =pyeval('vim.current.buffer.vars[''baz'']') +:put =pyeval('vim.current.tabpage.vars[''bar'']') +:" +:" Options +:" paste: boolean, global +:" previewheight number, global +:" operatorfunc: string, global +:" number: boolean, window-local +:" numberwidth: number, window-local +:" colorcolumn: string, window-local +:" statusline: string, window-local/global +:" autoindent: boolean, buffer-local +:" shiftwidth: number, buffer-local +:" omnifunc: string, buffer-local +:" preserveindent: boolean, buffer-local/global +:" path: string, buffer-local/global +:let g:bufs=[bufnr('%')] +:new +:let g:bufs+=[bufnr('%')] +:vnew +:let g:bufs+=[bufnr('%')] +:wincmd j +:vnew +:let g:bufs+=[bufnr('%')] +:wincmd l +:fun RecVars(opt) +: let gval =string(eval('&g:'.a:opt)) +: let wvals=join(map(range(1, 4), 'v:val.":".string(getwinvar(v:val, "&".a:opt))')) +: let bvals=join(map(copy(g:bufs), 'v:val.":".string(getbufvar(v:val, "&".a:opt))')) +: put =' G: '.gval +: put =' W: '.wvals +: put =' B: '.wvals +:endfun +py << EOF +def e(s, g=globals(), l=locals()): + try: + exec(s, g, l) + except: + vim.command('return ' + repr(sys.exc_type.__name__)) + +def ev(s, g=globals(), l=locals()): + try: + return eval(s, g, l) + except: + vim.command('let exc=' + repr(sys.exc_type.__name__)) + return 0 +EOF +:fun E(s) +: python e(vim.eval('a:s')) +:endfun +:fun Ev(s) +: let r=pyeval('ev(vim.eval("a:s"))') +: if exists('exc') +: throw exc +: endif +: return r +:endfun +:py gopts1=vim.options +:py wopts1=vim.windows[2].options +:py wopts2=vim.windows[0].options +:py wopts3=vim.windows[1].options +:py bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options +:py bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options +:py bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options +:$put ='wopts iters equal: '.pyeval('list(wopts1) == list(wopts2)') +:$put ='bopts iters equal: '.pyeval('list(bopts1) == list(bopts2)') +:py gset=set(iter(gopts1)) +:py wset=set(iter(wopts1)) +:py bset=set(iter(bopts1)) +:set path=.,..,, +:let lst=[] +:let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]] +:let lst+=[['previewheight', 5, 1, 6, 'a', 0, 1, 0 ]] +:let lst+=[['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0 ]] +:let lst+=[['number', 0, 1, 1, 0, 1, 0, 1 ]] +:let lst+=[['numberwidth', 2, 3, 5, -100, 0, 0, 1 ]] +:let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1 ]] +:let lst+=[['statusline', '1', '2', '4', 0, 0, 1, 1 ]] +:let lst+=[['autoindent', 0, 1, 1, 2, 1, 0, 2 ]] +:let lst+=[['shiftwidth', 0, 2, 1, 3, 0, 0, 2 ]] +:let lst+=[['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2 ]] +:let lst+=[['preserveindent', 0, 1, 1, 2, 1, 1, 2 ]] +:let lst+=[['path', '.,,', ',,', '.', 0, 0, 1, 2 ]] +:for [oname, oval1, oval2, oval3, invval, bool, global, local] in lst +: py oname=vim.eval('oname') +: py oval1=vim.bindeval('oval1') +: py oval2=vim.bindeval('oval2') +: py oval3=vim.bindeval('oval3') +: if invval is 0 || invval is 1 +: py invval=bool(vim.bindeval('invval')) +: else +: py invval=vim.bindeval('invval') +: endif +: if bool +: py oval1=bool(oval1) +: py oval2=bool(oval2) +: py oval3=bool(oval3) +: endif +: put ='>>> '.oname +: $put =' g/w/b:'.pyeval('oname in gset').'/'.pyeval('oname in wset').'/'.pyeval('oname in bset') +: $put =' g/w/b (in):'.pyeval('oname in gopts1').'/'.pyeval('oname in wopts1').'/'.pyeval('oname in bopts1') +: for v in ['gopts1', 'wopts1', 'bopts1'] +: try +: put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])') +: catch +: put =' p/'.v.'! '.v:exception +: endtry +: let r=E(v.'['''.oname.''']=invval') +: if r isnot 0 +: put =' inv: '.string(invval).'! '.r +: endif +: for vv in (v is# 'gopts1' ? [v] : [v, v[:-2].'2', v[:-2].'3']) +: let val=substitute(vv, '^.opts', 'oval', '') +: let r=E(vv.'['''.oname.''']='.val) +: if r isnot 0 +: put =' '.vv.'! '.r +: endif +: endfor +: endfor +: call RecVars(oname) +: for v in ['wopts3', 'bopts3'] +: let r=E('del '.v.'["'.oname.'"]') +: if r isnot 0 +: put =' del '.v.'! '.r +: endif +: endfor +: call RecVars(oname) +:endfor +:delfunction RecVars +:delfunction E +:delfunction Ev +:py del ev +:py del e +:only +:for buf in g:bufs[1:] +: execute 'bwipeout!' buf +:endfor +:py del gopts1 +:py del wopts1 +:py del wopts2 +:py del wopts3 +:py del bopts1 +:py del bopts2 +:py del bopts3 +:py del oval1 +:py del oval2 +:py del oval3 +:py del oname +:py del invval +:" +:" Test buffer object +:vnew +:put ='First line' +:put ='Second line' +:put ='Third line' +:1 delete _ +:py b=vim.current.buffer +:wincmd w +:mark a +:augroup BUFS +: autocmd BufFilePost * python cb.append(vim.eval('expand("<abuf>")') + ':BufFilePost:' + vim.eval('bufnr("%")')) +: autocmd BufFilePre * python cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")')) +:augroup END +py << EOF +cb = vim.current.buffer +# Tests BufferAppend and BufferItem +cb.append(b[0]) +# Tests BufferSlice and BufferAssSlice +cb.append('abc5') # Will be overwritten +cb[-1:] = b[:-2] +# Test BufferLength and BufferAssSlice +cb.append('def') # Will not be overwritten +cb[len(cb):] = b[:] +# Test BufferAssItem and BufferMark +cb.append('ghi') # Will be overwritten +cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1])) +# Test BufferRepr +cb.append(repr(cb) + repr(b)) +# Modify foreign buffer +b.append('foo') +b[0]='bar' +b[0:0]=['baz'] +vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number) +# Test assigning to name property +import os +old_name = cb.name +cb.name = 'foo' +cb.append(cb.name[-11:].replace(os.path.sep, '/')) +b.name = 'bar' +cb.append(b.name[-11:].replace(os.path.sep, '/')) +cb.name = old_name +cb.append(cb.name[-17:].replace(os.path.sep, '/')) +del old_name +# Test CheckBuffer +for _b in vim.buffers: + if _b is not cb: + vim.command('bwipeout! ' + str(_b.number)) +del _b +cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid))) +for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")', 'b.name = "!"'): + try: + exec(expr) + except vim.error: + pass + else: + # Usually a SEGV here + # Should not happen in any case + cb.append('No exception for ' + expr) +vim.command('cd .') +del b +EOF +:augroup BUFS +: autocmd! +:augroup END +:augroup! BUFS +:" +:" Test vim.buffers object +:set hidden +:edit a +:buffer # +:edit b +:buffer # +:edit c +:buffer # +py << EOF +try: + from __builtin__ import next +except ImportError: + next = lambda o: o.next() +# Check GCing iterator that was not fully exhausted +i = iter(vim.buffers) +cb.append('i:' + str(next(i))) +# and also check creating more then one iterator at a time +i2 = iter(vim.buffers) +cb.append('i2:' + str(next(i2))) +cb.append('i:' + str(next(i))) +# The following should trigger GC and not cause any problems +del i +del i2 +i3 = iter(vim.buffers) +cb.append('i3:' + str(next(i3))) +del i3 + +prevnum = 0 +for b in vim.buffers: + # Check buffer order + if prevnum >= b.number: + cb.append('!!! Buffer numbers not in strictly ascending order') + # Check indexing: vim.buffers[number].number == number + cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b)) + prevnum = b.number +del prevnum + +cb.append(str(len(vim.buffers))) + +bnums = list(map(lambda b: b.number, vim.buffers))[1:] + +# Test wiping out buffer with existing iterator +i4 = iter(vim.buffers) +cb.append('i4:' + str(next(i4))) +vim.command('bwipeout! ' + str(bnums.pop(0))) +try: + next(i4) +except vim.error: + pass +else: + cb.append('!!!! No vim.error') +i4 = iter(vim.buffers) +vim.command('bwipeout! ' + str(bnums.pop(-1))) +vim.command('bwipeout! ' + str(bnums.pop(-1))) +cb.append('i4:' + str(next(i4))) +try: + next(i4) +except StopIteration: + cb.append('StopIteration') +del i4 +del bnums +EOF +:" +:" Test vim.{tabpage,window}list and vim.{tabpage,window} objects +:tabnew 0 +:tabnew 1 +:vnew a.1 +:tabnew 2 +:vnew a.2 +:vnew b.2 +:vnew c.2 +py << EOF +cb.append('Number of tabs: ' + str(len(vim.tabpages))) +cb.append('Current tab pages:') +def W(w): + if repr(w).find('(unknown)') != -1: + return '<window object (unknown)>' + else: + return repr(w) + +start = len(cb) + +def Cursor(w): + if w.buffer is cb: + return repr((start - w.cursor[0], w.cursor[1])) + else: + return repr(w.cursor) + +for t in vim.tabpages: + cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window)) + cb.append(' Windows:') + for w in t.windows: + cb.append(' ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w)) + # Other values depend on the size of the terminal, so they are checked partly: + for attr in ('height', 'row', 'width', 'col'): + try: + aval = getattr(w, attr) + if type(aval) is not long: + raise TypeError + if aval < 0: + raise ValueError + except Exception: + cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + sys.exc_type.__name__) + del aval + del attr + w.cursor = (len(w.buffer), 0) +del W +del Cursor +cb.append('Number of windows in current tab page: ' + str(len(vim.windows))) +if list(vim.windows) != list(vim.current.tabpage.windows): + cb.append('!!!!!! Windows differ') +EOF +:" +:" Test vim.current +py << EOF +def H(o): + return repr(o) +cb.append('Current tab page: ' + repr(vim.current.tabpage)) +cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window)) +cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ ' is ' + H(vim.current.tabpage.window.buffer)) +del H +# Assigning: fails +try: + vim.current.window = vim.tabpages[0].window +except ValueError: + cb.append('ValueError at assigning foreign tab window') + +for attr in ('window', 'tabpage', 'buffer'): + try: + setattr(vim.current, attr, None) + except TypeError: + cb.append('Type error at assigning None to vim.current.' + attr) +del attr + +# Assigning: success +vim.current.tabpage = vim.tabpages[-2] +vim.current.buffer = cb +vim.current.window = vim.windows[0] +vim.current.window.cursor = (len(vim.current.buffer), 0) +cb.append('Current tab page: ' + repr(vim.current.tabpage)) +cb.append('Current window: ' + repr(vim.current.window)) +cb.append('Current buffer: ' + repr(vim.current.buffer)) +cb.append('Current line: ' + repr(vim.current.line)) +ws = list(vim.windows) +ts = list(vim.tabpages) +for b in vim.buffers: + if b is not cb: + vim.command('bwipeout! ' + str(b.number)) +del b +cb.append('w.valid: ' + repr([w.valid for w in ws])) +cb.append('t.valid: ' + repr([t.valid for t in ts])) +del w +del t +del ts +del ws +EOF +:tabonly! +:only! +:" +:" Test types +py << EOF +for expr, attr in ( + ('vim.vars', 'Dictionary'), + ('vim.options', 'Options'), + ('vim.bindeval("{}")', 'Dictionary'), + ('vim.bindeval("[]")', 'List'), + ('vim.bindeval("function(\'tr\')")', 'Function'), + ('vim.current.buffer', 'Buffer'), + ('vim.current.range', 'Range'), + ('vim.current.window', 'Window'), + ('vim.current.tabpage', 'TabPage'), +): + cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr))) +del expr +del attr +EOF +:" +:" Test __dir__() method +py << EOF +for name, o in ( + ('current', vim.current), + ('buffer', vim.current.buffer), + ('window', vim.current.window), + ('tabpage', vim.current.tabpage), + ('range', vim.current.range), + ('dictionary', vim.bindeval('{}')), + ('list', vim.bindeval('[]')), + ('function', vim.bindeval('function("tr")')), + ('output', sys.stdout), + ): + cb.append(name + ':' + ','.join(dir(o))) +del name +del o +EOF +:" +:" Test vim.*.__new__ +:$put =string(pyeval('vim.Dictionary({})')) +:$put =string(pyeval('vim.Dictionary(a=1)')) +:$put =string(pyeval('vim.Dictionary(((''a'', 1),))')) +:$put =string(pyeval('vim.List()')) +:$put =string(pyeval('vim.List(iter(''abc7''))')) +:$put =string(pyeval('vim.Function(''tr'')')) +:" +:" Test stdout/stderr +:redir => messages +:py sys.stdout.write('abc8') ; sys.stdout.write('def') +:py sys.stderr.write('abc9') ; sys.stderr.write('def') +:py sys.stdout.writelines(iter('abcA')) +:py sys.stderr.writelines(iter('abcB')) +:redir END +:$put =string(substitute(messages, '\d\+', '', 'g')) +:" Test subclassing +:fun Put(...) +: $put =string(a:000) +: return a:000 +:endfun +py << EOF +class DupDict(vim.Dictionary): + def __setitem__(self, key, value): + super(DupDict, self).__setitem__(key, value) + super(DupDict, self).__setitem__('dup_' + key, value) +dd = DupDict() +dd['a'] = 'b' + +class DupList(vim.List): + def __getitem__(self, idx): + return [super(DupList, self).__getitem__(idx)] * 2 + +dl = DupList() +dl2 = DupList(iter('abcC')) +dl.extend(dl2[0]) + +class DupFun(vim.Function): + def __call__(self, arg): + return super(DupFun, self).__call__(arg, arg) + +df = DupFun('Put') +EOF +:$put =string(sort(keys(pyeval('dd')))) +:$put =string(pyeval('dl')) +:$put =string(pyeval('dl2')) +:$put =string(pyeval('df(2)')) +:$put =string(pyeval('dl') is# pyeval('dl')) +:$put =string(pyeval('dd') is# pyeval('dd')) +:$put =string(pyeval('df')) +:delfunction Put +py << EOF +del DupDict +del DupList +del DupFun +del dd +del dl +del dl2 +del df +EOF +:" +:" Test chdir +py << EOF +import os +fnamemodify = vim.Function('fnamemodify') +cb.append(fnamemodify('.', ':p:h:t')) +cb.append(vim.eval('@%')) +os.chdir('..') +path = fnamemodify('.', ':p:h:t') +if path != 'src': + # Running tests from a shadow directory, so move up another level + # This will result in @% looking like shadow/testdir/test86.in, hence the + # extra fnamemodify + os.chdir('..') + cb.append(fnamemodify('.', ':p:h:t')) + cb.append(fnamemodify(vim.eval('@%'), ':s?^%s.??' % path).replace(os.path.sep, '/')) + os.chdir(path) + del path +else: + cb.append(fnamemodify('.', ':p:h:t')) + cb.append(vim.eval('@%').replace(os.path.sep, '/')) +os.chdir('testdir') +cb.append(fnamemodify('.', ':p:h:t')) +cb.append(vim.eval('@%')) +del fnamemodify +EOF +:" +:" Test errors +:fun F() dict +:endfun +:fun D() +:endfun +py << EOF +d = vim.Dictionary() +ned = vim.Dictionary(foo='bar', baz='abcD') +dl = vim.Dictionary(a=1) +dl.locked = True +l = vim.List() +ll = vim.List('abcE') +ll.locked = True +nel = vim.List('abcO') +f = vim.Function('string') +fd = vim.Function('F') +fdel = vim.Function('D') +vim.command('delfunction D') + +def subexpr_test(expr, name, subexprs): + cb.append('>>> Testing %s using %s' % (name, expr)) + for subexpr in subexprs: + ee(expr % subexpr) + cb.append('<<< Finished') + +def stringtochars_test(expr): + return subexpr_test(expr, 'StringToChars', ( + '1', # Fail type checks + 'u"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check + '"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check + )) + +class Mapping(object): + def __init__(self, d): + self.d = d + + def __getitem__(self, key): + return self.d[key] + + def keys(self): + return self.d.keys() + + def items(self): + return self.d.items() + +def convertfrompyobject_test(expr, recurse=True): + # pydict_to_tv + stringtochars_test(expr % '{%s : 1}') + if recurse: + convertfrompyobject_test(expr % '{"abcF" : %s}', False) + # pymap_to_tv + stringtochars_test(expr % 'Mapping({%s : 1})') + if recurse: + convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False) + # pyseq_to_tv + iter_test(expr) + return subexpr_test(expr, 'ConvertFromPyObject', ( + 'None', # Not conversible + '{"": 1}', # Empty key not allowed + '{u"": 1}', # Same, but with unicode object + 'FailingMapping()', # + 'FailingMappingKey()', # + 'FailingNumber()', # + )) + +def convertfrompymapping_test(expr): + convertfrompyobject_test(expr) + return subexpr_test(expr, 'ConvertFromPyMapping', ( + '[]', + )) + +def iter_test(expr): + return subexpr_test(expr, '*Iter*', ( + 'FailingIter()', + 'FailingIterNext()', + )) + +def number_test(expr, natural=False, unsigned=False): + if natural: + unsigned = True + return subexpr_test(expr, 'NumberToLong', ( + '[]', + 'None', + ) + (unsigned and ('-1',) or ()) + + (natural and ('0',) or ())) + +class FailingTrue(object): + def __nonzero__(self): + raise NotImplementedError('bool') + +class FailingIter(object): + def __iter__(self): + raise NotImplementedError('iter') + +class FailingIterNext(object): + def __iter__(self): + return self + + def next(self): + raise NotImplementedError('next') + +class FailingIterNextN(object): + def __init__(self, n): + self.n = n + + def __iter__(self): + return self + + def next(self): + if self.n: + self.n -= 1 + return 1 + else: + raise NotImplementedError('next N') + +class FailingMappingKey(object): + def __getitem__(self, item): + raise NotImplementedError('getitem:mappingkey') + + def keys(self): + return list("abcH") + +class FailingMapping(object): + def __getitem__(self): + raise NotImplementedError('getitem:mapping') + + def keys(self): + raise NotImplementedError('keys') + +class FailingList(list): + def __getitem__(self, idx): + if i == 2: + raise NotImplementedError('getitem:list') + else: + return super(FailingList, self).__getitem__(idx) + +class NoArgsCall(object): + def __call__(self): + pass + +class FailingCall(object): + def __call__(self, path): + raise NotImplementedError('call') + +class FailingNumber(object): + def __int__(self): + raise NotImplementedError('int') + +cb.append("> Output") +cb.append(">> OutputSetattr") +ee('del sys.stdout.softspace') +number_test('sys.stdout.softspace = %s', unsigned=True) +number_test('sys.stderr.softspace = %s', unsigned=True) +ee('sys.stdout.attr = None') +cb.append(">> OutputWrite") +ee('sys.stdout.write(None)') +cb.append(">> OutputWriteLines") +ee('sys.stdout.writelines(None)') +ee('sys.stdout.writelines([1])') +iter_test('sys.stdout.writelines(%s)') +cb.append("> VimCommand") +stringtochars_test('vim.command(%s)') +ee('vim.command("", 2)') +#! Not checked: vim->python exceptions translating: checked later +cb.append("> VimToPython") +#! Not checked: everything: needs errors in internal python functions +cb.append("> VimEval") +stringtochars_test('vim.eval(%s)') +ee('vim.eval("", FailingTrue())') +#! Not checked: everything: needs errors in internal python functions +cb.append("> VimEvalPy") +stringtochars_test('vim.bindeval(%s)') +ee('vim.eval("", 2)') +#! Not checked: vim->python exceptions translating: checked later +cb.append("> VimStrwidth") +stringtochars_test('vim.strwidth(%s)') +cb.append("> VimForeachRTP") +ee('vim.foreach_rtp(None)') +ee('vim.foreach_rtp(NoArgsCall())') +ee('vim.foreach_rtp(FailingCall())') +ee('vim.foreach_rtp(int, 2)') +cb.append('> import') +old_rtp = vim.options['rtp'] +vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\') +ee('import xxx_no_such_module_xxx') +ee('import failing_import') +ee('import failing') +vim.options['rtp'] = old_rtp +del old_rtp +cb.append("> Options") +cb.append(">> OptionsItem") +ee('vim.options["abcQ"]') +ee('vim.options[""]') +stringtochars_test('vim.options[%s]') +cb.append(">> OptionsContains") +stringtochars_test('%s in vim.options') +cb.append("> Dictionary") +cb.append(">> DictionaryConstructor") +ee('vim.Dictionary("abcI")') +##! Not checked: py_dict_alloc failure +cb.append(">> DictionarySetattr") +ee('del d.locked') +ee('d.locked = FailingTrue()') +ee('vim.vvars.locked = False') +ee('d.scope = True') +ee('d.xxx = True') +cb.append(">> _DictionaryItem") +ee('d.get("a", 2, 3)') +stringtochars_test('d.get(%s)') +ee('d.pop("a")') +ee('dl.pop("a")') +cb.append(">> DictionaryContains") +ee('"" in d') +ee('0 in d') +cb.append(">> DictionaryIterNext") +ee('for i in ned: ned["a"] = 1') +del i +cb.append(">> DictionaryAssItem") +ee('dl["b"] = 1') +stringtochars_test('d[%s] = 1') +convertfrompyobject_test('d["a"] = %s') +cb.append(">> DictionaryUpdate") +cb.append(">>> kwargs") +cb.append(">>> iter") +ee('d.update(FailingMapping())') +ee('d.update([FailingIterNext()])') +ee('d.update([FailingIterNextN(1)])') +iter_test('d.update(%s)') +convertfrompyobject_test('d.update(%s)') +stringtochars_test('d.update(((%s, 0),))') +convertfrompyobject_test('d.update((("a", %s),))') +cb.append(">> DictionaryPopItem") +ee('d.popitem(1, 2)') +cb.append(">> DictionaryHasKey") +ee('d.has_key()') +cb.append("> List") +cb.append(">> ListConstructor") +ee('vim.List(1, 2)') +ee('vim.List(a=1)') +iter_test('vim.List(%s)') +convertfrompyobject_test('vim.List([%s])') +cb.append(">> ListItem") +ee('l[1000]') +cb.append(">> ListAssItem") +ee('ll[1] = 2') +ee('l[1000] = 3') +cb.append(">> ListAssSlice") +ee('ll[1:100] = "abcJ"') +iter_test('l[:] = %s') +ee('nel[1:10:2] = "abcK"') +cb.append(repr(tuple(nel))) +ee('nel[1:10:2] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[1:1:-1] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[:] = FailingIterNextN(2)') +cb.append(repr(tuple(nel))) +convertfrompyobject_test('l[:] = [%s]') +cb.append(">> ListConcatInPlace") +iter_test('l.extend(%s)') +convertfrompyobject_test('l.extend([%s])') +cb.append(">> ListSetattr") +ee('del l.locked') +ee('l.locked = FailingTrue()') +ee('l.xxx = True') +cb.append("> Function") +cb.append(">> FunctionConstructor") +ee('vim.Function("123")') +ee('vim.Function("xxx_non_existent_function_xxx")') +ee('vim.Function("xxx#non#existent#function#xxx")') +cb.append(">> FunctionCall") +convertfrompyobject_test('f(%s)') +convertfrompymapping_test('fd(self=%s)') +cb.append("> TabPage") +cb.append(">> TabPageAttr") +ee('vim.current.tabpage.xxx') +cb.append("> TabList") +cb.append(">> TabListItem") +ee('vim.tabpages[1000]') +cb.append("> Window") +cb.append(">> WindowAttr") +ee('vim.current.window.xxx') +cb.append(">> WindowSetattr") +ee('vim.current.window.buffer = 0') +ee('vim.current.window.cursor = (100000000, 100000000)') +ee('vim.current.window.cursor = True') +number_test('vim.current.window.height = %s', unsigned=True) +number_test('vim.current.window.width = %s', unsigned=True) +ee('vim.current.window.xxxxxx = True') +cb.append("> WinList") +cb.append(">> WinListItem") +ee('vim.windows[1000]') +cb.append("> Buffer") +cb.append(">> StringToLine (indirect)") +ee('vim.current.buffer[0] = u"\\na"') +ee('vim.current.buffer[0] = "\\na"') +cb.append(">> SetBufferLine (indirect)") +ee('vim.current.buffer[0] = True') +cb.append(">> SetBufferLineList (indirect)") +ee('vim.current.buffer[:] = True') +ee('vim.current.buffer[:] = ["\\na", "bc"]') +cb.append(">> InsertBufferLines (indirect)") +ee('vim.current.buffer.append(None)') +ee('vim.current.buffer.append(["\\na", "bc"])') +ee('vim.current.buffer.append("\\nbc")') +cb.append(">> RBItem") +ee('vim.current.buffer[100000000]') +cb.append(">> RBAsItem") +ee('vim.current.buffer[100000000] = ""') +cb.append(">> BufferAttr") +ee('vim.current.buffer.xxx') +cb.append(">> BufferSetattr") +ee('vim.current.buffer.name = True') +ee('vim.current.buffer.xxx = True') +cb.append(">> BufferMark") +ee('vim.current.buffer.mark(0)') +ee('vim.current.buffer.mark("abcM")') +ee('vim.current.buffer.mark("!")') +cb.append(">> BufferRange") +ee('vim.current.buffer.range(1, 2, 3)') +cb.append("> BufMap") +cb.append(">> BufMapItem") +ee('vim.buffers[100000000]') +number_test('vim.buffers[%s]', natural=True) +cb.append("> Current") +cb.append(">> CurrentGetattr") +ee('vim.current.xxx') +cb.append(">> CurrentSetattr") +ee('vim.current.line = True') +ee('vim.current.buffer = True') +ee('vim.current.window = True') +ee('vim.current.tabpage = True') +ee('vim.current.xxx = True') +del d +del ned +del dl +del l +del ll +del nel +del f +del fd +del fdel +del subexpr_test +del stringtochars_test +del Mapping +del convertfrompyobject_test +del convertfrompymapping_test +del iter_test +del number_test +del FailingTrue +del FailingIter +del FailingIterNext +del FailingIterNextN +del FailingMapping +del FailingMappingKey +del FailingList +del NoArgsCall +del FailingCall +del FailingNumber +EOF +:delfunction F +:" +:" Test import +py << EOF +sys.path.insert(0, os.path.join(os.getcwd(), 'python_before')) +sys.path.append(os.path.join(os.getcwd(), 'python_after')) +vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\') +l = [] +def callback(path): + l.append(path[-len('/testdir'):].replace(os.path.sep, '/')) +vim.foreach_rtp(callback) +cb.append(repr(l)) +del l +def callback(path): + return path[-len('/testdir'):].replace(os.path.sep, '/') +cb.append(repr(vim.foreach_rtp(callback))) +del callback +from module import dir as d +from modulex import ddir +cb.append(d + ',' + ddir) +import before +cb.append(before.dir) +import after +cb.append(after.dir) +import topmodule as tm +import topmodule.submodule as tms +import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss +cb.append(tm.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):]) +cb.append(tms.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):]) +cb.append(tmsss.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):]) +del before +del after +del d +del ddir +del tm +del tms +del tmsss +EOF +:" +:" Test exceptions +:fun Exe(e) +: execute a:e +:endfun +py << EOF +Exe = vim.bindeval('function("Exe")') +ee('vim.command("throw \'abcN\'")') +ee('Exe("throw \'def\'")') +ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")') +ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")') +ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")') +ee('vim.eval("xxx_unknown_function_xxx()")') +ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")') +del Exe +EOF +:delfunction Exe +:" +:" Regression: interrupting vim.command propagates to next vim.command +py << EOF +def test_keyboard_interrupt(): + try: + vim.command('while 1 | endwhile') + except KeyboardInterrupt: + cb.append('Caught KeyboardInterrupt') + except Exception: + cb.append('!!!!!!!! Caught exception: ' + repr(sys.exc_info)) + else: + cb.append('!!!!!!!! No exception') + try: + vim.command('$ put =\'Running :put\'') + except KeyboardInterrupt: + cb.append('!!!!!!!! Caught KeyboardInterrupt') + except Exception: + cb.append('!!!!!!!! Caught exception: ' + repr(sys.exc_info)) + else: + cb.append('No exception') +EOF +:debuggreedy +:call inputsave() +:call feedkeys("s\ns\ns\ns\nq\n") +:redir => output +:debug silent! py test_keyboard_interrupt() +:redir END +:0 debuggreedy +:silent $put =output +:unlet output +:py del test_keyboard_interrupt +:" +:" Cleanup +py << EOF +del cb +del ee +del sys +del os +del vim +EOF +:endfun +:" +:fun RunTest() +:let checkrefs = !empty($PYTHONDUMPREFS) +:let start = getline(1, '$') +:for i in range(checkrefs ? 10 : 1) +: if i != 0 +: %d _ +: call setline(1, start) +: endif +: call Test() +: if i == 0 +: let result = getline(1, '$') +: endif +:endfor +:if checkrefs +: %d _ +: call setline(1, result) +:endif +:endfun +:" +:call RunTest() +:delfunction RunTest +:delfunction Test +:call garbagecollect(1) +:" +:/^start:/,$wq! test.out +:" vim: et ts=4 isk-=\: +:call getchar() +ENDTEST + +start: diff --git a/src/nvim/testdir/test86.ok b/src/nvim/testdir/test86.ok new file mode 100644 index 0000000000..257a5ee4cd --- /dev/null +++ b/src/nvim/testdir/test86.ok @@ -0,0 +1,1266 @@ +start: +[1, 'as''d', [1, 2, function('strlen'), {'a': 1}]] +[1, 2, function('strlen'), {'a': 1}] +Vim(put):E684: +[0, 'as''d', [1, 2, function('strlen'), {'a': 1}]] +[0, function('strlen'), [1, 2, function('strlen'), {'a': 1}]] +1 +['-1', '0', '1', 'b', 'f'] +['asd', -1L, <vim.Function '1'>, <vim.dictionary object at >, <vim.list object at >] +[('-1', <vim.dictionary object at >), ('0', -1L), ('1', 'asd'), ('b', <vim.list object at >), ('f', <vim.Function '1'>)] +'-1' : {'a': 1} +'0' : -1 +'1' : 'asd' +'b' : [1, 2, function('strlen')] +'f' : function('1') +[0, function('strlen')] +[3] +[1, 2, function('strlen')] +[1, 2, function('strlen')] +1 +'asd' +2 +True +False +True +False +['0'] +{'0': -1} +('0', -1L) +None +[] +[0, 1, 2, 3] +[0, 1, 2, 3] +[0, 1, 3] +[0, 1] +[0, 1] +[0, 1] +[0, 1, 2, 3] +[0, 1, 2, 3] +[0, 2, 3] +[2, 3] +[2, 3] +[2, 3] +[1, 3] +[0, 2] +[0, 1, 2, 3] +['a', 0, 1, 2, 3] +[0, 'b', 2, 3] +[0, 1, 'c'] +[0, 1, 2, 3, 'd'] +[0, 1, 2, 'e', 3] +['f', 2, 3] +[0, 1, 'g', 2, 3] +['h'] +[0, 1, 10, 3, 20, 5, 6, 7] +[0, 1, 2, 3, 20, 5, 10, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3] +[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'] +[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}] +[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New'] +l[1](1, 2, 3):error:('Vim:E725: Calling dict function without Dictionary: DictNew',) +f(1, 2, 3):error:('Vim:E117: Unknown function: New',) +[0.0, 0.0] +KeyError +TypeError +TypeError +ValueError +TypeError +TypeError +KeyError +KeyError +d : locked:0;scope:0 +dl : locked:1;scope:0 +v: : locked:2;scope:1 +g: : locked:0;scope:2 +d:{'abc2': 1} +dl:{'def': 1} +l : locked:0 +ll : locked:1 +l:[0] +ll:[1] +[0, 1, 2] +['a', 'b'] +['c', 1] +['d', ['e']] +0.0 +"\0": Vim(let):E859: +{"\0": 1}: Vim(let):E859: +undefined_name: Vim(let):Trace +vim: Vim(let):E859: +[1] +[1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1] +[0, 1, 2, 3] +[2, 3, 4, 5] +[0, 1] +[4, 5] +[2, 3] +[] +[2, 3] +[] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5] +[4, 3] +[0, 2, 4] +[] +Abc +bac +def +bar +jkl +wopts iters equal: 1 +bopts iters equal: 1 +>>> paste + g/w/b:1/0/0 + g/w/b (in):1/0/0 + p/gopts1: False + p/wopts1! KeyError + inv: 2! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1! KeyError + inv: 2! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: 1 + W: 1:1 2:1 3:1 4:1 + B: 1:1 2:1 3:1 4:1 + del wopts3! KeyError + del bopts3! KeyError + G: 1 + W: 1:1 2:1 3:1 4:1 + B: 1:1 2:1 3:1 4:1 +>>> previewheight + g/w/b:1/0/0 + g/w/b (in):1/0/0 + p/gopts1: 12 + inv: 'a'! TypeError + p/wopts1! KeyError + inv: 'a'! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1! KeyError + inv: 'a'! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: 5 + W: 1:5 2:5 3:5 4:5 + B: 1:5 2:5 3:5 4:5 + del wopts3! KeyError + del bopts3! KeyError + G: 5 + W: 1:5 2:5 3:5 4:5 + B: 1:5 2:5 3:5 4:5 +>>> operatorfunc + g/w/b:1/0/0 + g/w/b (in):1/0/0 + p/gopts1: '' + inv: 2! TypeError + p/wopts1! KeyError + inv: 2! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1! KeyError + inv: 2! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: 'A' + W: 1:'A' 2:'A' 3:'A' 4:'A' + B: 1:'A' 2:'A' 3:'A' 4:'A' + del wopts3! KeyError + del bopts3! KeyError + G: 'A' + W: 1:'A' 2:'A' 3:'A' 4:'A' + B: 1:'A' 2:'A' 3:'A' 4:'A' +>>> number + g/w/b:0/1/0 + g/w/b (in):0/1/0 + p/gopts1! KeyError + inv: 0! KeyError + gopts1! KeyError + p/wopts1: False + p/bopts1! KeyError + inv: 0! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: 0 + W: 1:1 2:1 3:0 4:0 + B: 1:1 2:1 3:0 4:0 + del wopts3! ValueError + del bopts3! KeyError + G: 0 + W: 1:1 2:1 3:0 4:0 + B: 1:1 2:1 3:0 4:0 +>>> numberwidth + g/w/b:0/1/0 + g/w/b (in):0/1/0 + p/gopts1! KeyError + inv: -100! KeyError + gopts1! KeyError + p/wopts1: 8 + inv: -100! error + p/bopts1! KeyError + inv: -100! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: 8 + W: 1:3 2:5 3:2 4:8 + B: 1:3 2:5 3:2 4:8 + del wopts3! ValueError + del bopts3! KeyError + G: 8 + W: 1:3 2:5 3:2 4:8 + B: 1:3 2:5 3:2 4:8 +>>> colorcolumn + g/w/b:0/1/0 + g/w/b (in):0/1/0 + p/gopts1! KeyError + inv: 'abc4'! KeyError + gopts1! KeyError + p/wopts1: '' + inv: 'abc4'! error + p/bopts1! KeyError + inv: 'abc4'! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: '' + W: 1:'+2' 2:'+3' 3:'+1' 4:'' + B: 1:'+2' 2:'+3' 3:'+1' 4:'' + del wopts3! ValueError + del bopts3! KeyError + G: '' + W: 1:'+2' 2:'+3' 3:'+1' 4:'' + B: 1:'+2' 2:'+3' 3:'+1' 4:'' +>>> statusline + g/w/b:1/1/0 + g/w/b (in):1/1/0 + p/gopts1: '' + inv: 0! TypeError + p/wopts1: None + inv: 0! TypeError + p/bopts1! KeyError + inv: 0! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: '1' + W: 1:'2' 2:'4' 3:'1' 4:'1' + B: 1:'2' 2:'4' 3:'1' 4:'1' + del bopts3! KeyError + G: '1' + W: 1:'2' 2:'1' 3:'1' 4:'1' + B: 1:'2' 2:'1' 3:'1' 4:'1' +>>> autoindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 + p/gopts1! KeyError + inv: 2! KeyError + gopts1! KeyError + p/wopts1! KeyError + inv: 2! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1: False + G: 0 + W: 1:0 2:1 3:0 4:1 + B: 1:0 2:1 3:0 4:1 + del wopts3! KeyError + del bopts3! ValueError + G: 0 + W: 1:0 2:1 3:0 4:1 + B: 1:0 2:1 3:0 4:1 +>>> shiftwidth + g/w/b:0/0/1 + g/w/b (in):0/0/1 + p/gopts1! KeyError + inv: 3! KeyError + gopts1! KeyError + p/wopts1! KeyError + inv: 3! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1: 8 + G: 8 + W: 1:0 2:2 3:8 4:1 + B: 1:0 2:2 3:8 4:1 + del wopts3! KeyError + del bopts3! ValueError + G: 8 + W: 1:0 2:2 3:8 4:1 + B: 1:0 2:2 3:8 4:1 +>>> omnifunc + g/w/b:0/0/1 + g/w/b (in):0/0/1 + p/gopts1! KeyError + inv: 1! KeyError + gopts1! KeyError + p/wopts1! KeyError + inv: 1! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1: '' + inv: 1! TypeError + G: '' + W: 1:'A' 2:'B' 3:'' 4:'C' + B: 1:'A' 2:'B' 3:'' 4:'C' + del wopts3! KeyError + del bopts3! ValueError + G: '' + W: 1:'A' 2:'B' 3:'' 4:'C' + B: 1:'A' 2:'B' 3:'' 4:'C' +>>> preserveindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 + p/gopts1! KeyError + inv: 2! KeyError + gopts1! KeyError + p/wopts1! KeyError + inv: 2! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1: False + G: 0 + W: 1:0 2:1 3:0 4:1 + B: 1:0 2:1 3:0 4:1 + del wopts3! KeyError + del bopts3! ValueError + G: 0 + W: 1:0 2:1 3:0 4:1 + B: 1:0 2:1 3:0 4:1 +>>> path + g/w/b:1/0/1 + g/w/b (in):1/0/1 + p/gopts1: '.,..,,' + inv: 0! TypeError + p/wopts1! KeyError + inv: 0! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1: None + inv: 0! TypeError + G: '.,,' + W: 1:'.,,' 2:',,' 3:'.,,' 4:'.' + B: 1:'.,,' 2:',,' 3:'.,,' 4:'.' + del wopts3! KeyError + G: '.,,' + W: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,' + B: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,' +First line +First line +def +First line +Second line +Third line +(7, 2) +<buffer test86.in><buffer > +baz +bar +Second line +Third line +foo +1:BufFilePre:1 +1:BufFilePost:1 +testdir/foo +5:BufFilePre:5 +5:BufFilePost:5 +testdir/bar +1:BufFilePre:1 +1:BufFilePost:1 +testdir/test86.in +valid: b:False, cb:True +i:<buffer test86.in> +i2:<buffer test86.in> +i:<buffer a> +i3:<buffer test86.in> +1:<buffer test86.in>=<buffer test86.in> +8:<buffer a>=<buffer a> +9:<buffer b>=<buffer b> +10:<buffer c>=<buffer c> +4 +i4:<buffer test86.in> +i4:<buffer test86.in> +StopIteration +Number of tabs: 4 +Current tab pages: + <tabpage 0>(1): 1 windows, current is <window object (unknown)> + Windows: + <window object (unknown)>(1): displays buffer <buffer test86.in>; cursor is at (37, 0) + <tabpage 1>(2): 1 windows, current is <window object (unknown)> + Windows: + <window object (unknown)>(1): displays buffer <buffer 0>; cursor is at (1, 0) + <tabpage 2>(3): 2 windows, current is <window object (unknown)> + Windows: + <window object (unknown)>(1): displays buffer <buffer a.1>; cursor is at (1, 0) + <window object (unknown)>(2): displays buffer <buffer 1>; cursor is at (1, 0) + <tabpage 3>(4): 4 windows, current is <window 0> + Windows: + <window 0>(1): displays buffer <buffer c.2>; cursor is at (1, 0) + <window 1>(2): displays buffer <buffer b.2>; cursor is at (1, 0) + <window 2>(3): displays buffer <buffer a.2>; cursor is at (1, 0) + <window 3>(4): displays buffer <buffer 2>; cursor is at (1, 0) +Number of windows in current tab page: 4 +Current tab page: <tabpage 3> +Current window: <window 0>: <window 0> is <window 0> +Current buffer: <buffer c.2>: <buffer c.2> is <buffer c.2> is <buffer c.2> +ValueError at assigning foreign tab window +Type error at assigning None to vim.current.window +Type error at assigning None to vim.current.tabpage +Type error at assigning None to vim.current.buffer +Current tab page: <tabpage 2> +Current window: <window 0> +Current buffer: <buffer test86.in> +Current line: 'Type error at assigning None to vim.current.buffer' +w.valid: [True, False] +t.valid: [True, False, True, False] +vim.vars:Dictionary:True +vim.options:Options:True +vim.bindeval("{}"):Dictionary:True +vim.bindeval("[]"):List:True +vim.bindeval("function('tr')"):Function:True +vim.current.buffer:Buffer:True +vim.current.range:Range:True +vim.current.window:Window:True +vim.current.tabpage:TabPage:True +current:__dir__,__members__,buffer,line,range,tabpage,window +buffer:__dir__,__members__,append,mark,name,number,options,range,valid,vars +window:__dir__,__members__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars +tabpage:__dir__,__members__,number,valid,vars,window,windows +range:__dir__,__members__,append,end,start +dictionary:__dir__,__members__,get,has_key,items,keys,locked,pop,popitem,scope,update,values +list:__dir__,__members__,extend,locked +function:__dir__,__members__,softspace +output:__dir__,__members__,flush,softspace,write,writelines +{} +{'a': 1} +{'a': 1} +[] +['a', 'b', 'c', '7'] +function('tr') +' +abcdef +line : +abcdef +abcA +line : +abcB' +['a', 'dup_a'] +['a', 'a'] +['a', 'b', 'c', 'C'] +[2, 2] +[2, 2] +1 +1 +function('Put') +testdir +test86.in +src +testdir/test86.in +testdir +test86.in +> Output +>> OutputSetattr +del sys.stdout.softspace:AttributeError:("can't delete OutputObject attributes",) +>>> Testing NumberToLong using sys.stdout.softspace = %s +sys.stdout.softspace = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',) +sys.stdout.softspace = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',) +sys.stdout.softspace = -1:ValueError:('number must be greater or equal to zero',) +<<< Finished +>>> Testing NumberToLong using sys.stderr.softspace = %s +sys.stderr.softspace = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',) +sys.stderr.softspace = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',) +sys.stderr.softspace = -1:ValueError:('number must be greater or equal to zero',) +<<< Finished +sys.stdout.attr = None:AttributeError:('invalid attribute: attr',) +>> OutputWrite +sys.stdout.write(None):TypeError:('coercing to Unicode: need string or buffer, NoneType found',) +>> OutputWriteLines +sys.stdout.writelines(None):TypeError:("'NoneType' object is not iterable",) +sys.stdout.writelines([1]):TypeError:('coercing to Unicode: need string or buffer, int found',) +>>> Testing *Iter* using sys.stdout.writelines(%s) +sys.stdout.writelines(FailingIter()):NotImplementedError:('iter',) +sys.stdout.writelines(FailingIterNext()):NotImplementedError:('next',) +<<< Finished +> VimCommand +>>> Testing StringToChars using vim.command(%s) +vim.command(1):TypeError:('expected str() or unicode() instance, but got int',) +vim.command(u"\0"):TypeError:('expected string without null bytes',) +vim.command("\0"):TypeError:('expected string without null bytes',) +<<< Finished +vim.command("", 2):TypeError:('command() takes exactly one argument (2 given)',) +> VimToPython +> VimEval +>>> Testing StringToChars using vim.eval(%s) +vim.eval(1):TypeError:('expected str() or unicode() instance, but got int',) +vim.eval(u"\0"):TypeError:('expected string without null bytes',) +vim.eval("\0"):TypeError:('expected string without null bytes',) +<<< Finished +vim.eval("", FailingTrue()):TypeError:('function takes exactly 1 argument (2 given)',) +> VimEvalPy +>>> Testing StringToChars using vim.bindeval(%s) +vim.bindeval(1):TypeError:('expected str() or unicode() instance, but got int',) +vim.bindeval(u"\0"):TypeError:('expected string without null bytes',) +vim.bindeval("\0"):TypeError:('expected string without null bytes',) +<<< Finished +vim.eval("", 2):TypeError:('function takes exactly 1 argument (2 given)',) +> VimStrwidth +>>> Testing StringToChars using vim.strwidth(%s) +vim.strwidth(1):TypeError:('expected str() or unicode() instance, but got int',) +vim.strwidth(u"\0"):TypeError:('expected string without null bytes',) +vim.strwidth("\0"):TypeError:('expected string without null bytes',) +<<< Finished +> VimForeachRTP +vim.foreach_rtp(None):TypeError:("'NoneType' object is not callable",) +vim.foreach_rtp(NoArgsCall()):TypeError:('__call__() takes exactly 1 argument (2 given)',) +vim.foreach_rtp(FailingCall()):NotImplementedError:('call',) +vim.foreach_rtp(int, 2):TypeError:('foreach_rtp() takes exactly one argument (2 given)',) +> import +import xxx_no_such_module_xxx:ImportError:('No module named xxx_no_such_module_xxx',) +import failing_import:ImportError:('No module named failing_import',) +import failing:NotImplementedError:() +> Options +>> OptionsItem +vim.options["abcQ"]:KeyError:('abcQ',) +vim.options[""]:ValueError:('empty keys are not allowed',) +>>> Testing StringToChars using vim.options[%s] +vim.options[1]:TypeError:('expected str() or unicode() instance, but got int',) +vim.options[u"\0"]:TypeError:('expected string without null bytes',) +vim.options["\0"]:TypeError:('expected string without null bytes',) +<<< Finished +>> OptionsContains +>>> Testing StringToChars using %s in vim.options +1 in vim.options:TypeError:('expected str() or unicode() instance, but got int',) +u"\0" in vim.options:TypeError:('expected string without null bytes',) +"\0" in vim.options:TypeError:('expected string without null bytes',) +<<< Finished +> Dictionary +>> DictionaryConstructor +vim.Dictionary("abcI"):ValueError:('expected sequence element of size 2, but got sequence of size 1',) +>> DictionarySetattr +del d.locked:AttributeError:('cannot delete vim.Dictionary attributes',) +d.locked = FailingTrue():NotImplementedError:('bool',) +vim.vvars.locked = False:TypeError:('cannot modify fixed dictionary',) +d.scope = True:AttributeError:('cannot set attribute scope',) +d.xxx = True:AttributeError:('cannot set attribute xxx',) +>> _DictionaryItem +d.get("a", 2, 3):TypeError:('function takes at most 2 arguments (3 given)',) +>>> Testing StringToChars using d.get(%s) +d.get(1):TypeError:('expected str() or unicode() instance, but got int',) +d.get(u"\0"):TypeError:('expected string without null bytes',) +d.get("\0"):TypeError:('expected string without null bytes',) +<<< Finished +d.pop("a"):KeyError:('a',) +dl.pop("a"):error:('dictionary is locked',) +>> DictionaryContains +"" in d:ValueError:('empty keys are not allowed',) +0 in d:TypeError:('expected str() or unicode() instance, but got int',) +>> DictionaryIterNext +for i in ned: ned["a"] = 1:RuntimeError:('hashtab changed during iteration',) +>> DictionaryAssItem +dl["b"] = 1:error:('dictionary is locked',) +>>> Testing StringToChars using d[%s] = 1 +d[1] = 1:TypeError:('expected str() or unicode() instance, but got int',) +d[u"\0"] = 1:TypeError:('expected string without null bytes',) +d["\0"] = 1:TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d["a"] = {%s : 1} +d["a"] = {1 : 1}:TypeError:('expected str() or unicode() instance, but got int',) +d["a"] = {u"\0" : 1}:TypeError:('expected string without null bytes',) +d["a"] = {"\0" : 1}:TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d["a"] = {"abcF" : {%s : 1}} +d["a"] = {"abcF" : {1 : 1}}:TypeError:('expected str() or unicode() instance, but got int',) +d["a"] = {"abcF" : {u"\0" : 1}}:TypeError:('expected string without null bytes',) +d["a"] = {"abcF" : {"\0" : 1}}:TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d["a"] = {"abcF" : Mapping({%s : 1})} +d["a"] = {"abcF" : Mapping({1 : 1})}:TypeError:('expected str() or unicode() instance, but got int',) +d["a"] = {"abcF" : Mapping({u"\0" : 1})}:TypeError:('expected string without null bytes',) +d["a"] = {"abcF" : Mapping({"\0" : 1})}:TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using d["a"] = {"abcF" : %s} +d["a"] = {"abcF" : FailingIter()}:TypeError:('unable to convert FailingIter to vim structure',) +d["a"] = {"abcF" : FailingIterNext()}:NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s} +d["a"] = {"abcF" : None}:TypeError:('unable to convert NoneType to vim structure',) +d["a"] = {"abcF" : {"": 1}}:ValueError:('empty keys are not allowed',) +d["a"] = {"abcF" : {u"": 1}}:ValueError:('empty keys are not allowed',) +d["a"] = {"abcF" : FailingMapping()}:NotImplementedError:('keys',) +d["a"] = {"abcF" : FailingMappingKey()}:NotImplementedError:('getitem:mappingkey',) +d["a"] = {"abcF" : FailingNumber()}:TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing StringToChars using d["a"] = Mapping({%s : 1}) +d["a"] = Mapping({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',) +d["a"] = Mapping({u"\0" : 1}):TypeError:('expected string without null bytes',) +d["a"] = Mapping({"\0" : 1}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d["a"] = Mapping({"abcG" : {%s : 1}}) +d["a"] = Mapping({"abcG" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',) +d["a"] = Mapping({"abcG" : {u"\0" : 1}}):TypeError:('expected string without null bytes',) +d["a"] = Mapping({"abcG" : {"\0" : 1}}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d["a"] = Mapping({"abcG" : Mapping({%s : 1})}) +d["a"] = Mapping({"abcG" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',) +d["a"] = Mapping({"abcG" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',) +d["a"] = Mapping({"abcG" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s}) +d["a"] = Mapping({"abcG" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',) +d["a"] = Mapping({"abcG" : FailingIterNext()}):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s}) +d["a"] = Mapping({"abcG" : None}):TypeError:('unable to convert NoneType to vim structure',) +d["a"] = Mapping({"abcG" : {"": 1}}):ValueError:('empty keys are not allowed',) +d["a"] = Mapping({"abcG" : {u"": 1}}):ValueError:('empty keys are not allowed',) +d["a"] = Mapping({"abcG" : FailingMapping()}):NotImplementedError:('keys',) +d["a"] = Mapping({"abcG" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',) +d["a"] = Mapping({"abcG" : FailingNumber()}):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing *Iter* using d["a"] = %s +d["a"] = FailingIter():TypeError:('unable to convert FailingIter to vim structure',) +d["a"] = FailingIterNext():NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using d["a"] = %s +d["a"] = None:TypeError:('unable to convert NoneType to vim structure',) +d["a"] = {"": 1}:ValueError:('empty keys are not allowed',) +d["a"] = {u"": 1}:ValueError:('empty keys are not allowed',) +d["a"] = FailingMapping():NotImplementedError:('keys',) +d["a"] = FailingMappingKey():NotImplementedError:('getitem:mappingkey',) +d["a"] = FailingNumber():TypeError:('long() argument must be a string or a number',) +<<< Finished +>> DictionaryUpdate +>>> kwargs +>>> iter +d.update(FailingMapping()):NotImplementedError:('keys',) +d.update([FailingIterNext()]):NotImplementedError:('next',) +d.update([FailingIterNextN(1)]):NotImplementedError:('next N',) +>>> Testing *Iter* using d.update(%s) +d.update(FailingIter()):NotImplementedError:('iter',) +d.update(FailingIterNext()):NotImplementedError:('next',) +<<< Finished +>>> Testing StringToChars using d.update({%s : 1}) +d.update({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',) +d.update({u"\0" : 1}):TypeError:('expected string without null bytes',) +d.update({"\0" : 1}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d.update({"abcF" : {%s : 1}}) +d.update({"abcF" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',) +d.update({"abcF" : {u"\0" : 1}}):TypeError:('expected string without null bytes',) +d.update({"abcF" : {"\0" : 1}}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d.update({"abcF" : Mapping({%s : 1})}) +d.update({"abcF" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',) +d.update({"abcF" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',) +d.update({"abcF" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using d.update({"abcF" : %s}) +d.update({"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',) +d.update({"abcF" : FailingIterNext()}):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using d.update({"abcF" : %s}) +d.update({"abcF" : None}):TypeError:('unable to convert NoneType to vim structure',) +d.update({"abcF" : {"": 1}}):ValueError:('empty keys are not allowed',) +d.update({"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',) +d.update({"abcF" : FailingMapping()}):NotImplementedError:('keys',) +d.update({"abcF" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',) +d.update({"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing StringToChars using d.update(Mapping({%s : 1})) +d.update(Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',) +d.update(Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',) +d.update(Mapping({"\0" : 1})):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d.update(Mapping({"abcG" : {%s : 1}})) +d.update(Mapping({"abcG" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',) +d.update(Mapping({"abcG" : {u"\0" : 1}})):TypeError:('expected string without null bytes',) +d.update(Mapping({"abcG" : {"\0" : 1}})):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d.update(Mapping({"abcG" : Mapping({%s : 1})})) +d.update(Mapping({"abcG" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',) +d.update(Mapping({"abcG" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',) +d.update(Mapping({"abcG" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using d.update(Mapping({"abcG" : %s})) +d.update(Mapping({"abcG" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',) +d.update(Mapping({"abcG" : FailingIterNext()})):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s})) +d.update(Mapping({"abcG" : None})):TypeError:('unable to convert NoneType to vim structure',) +d.update(Mapping({"abcG" : {"": 1}})):ValueError:('empty keys are not allowed',) +d.update(Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',) +d.update(Mapping({"abcG" : FailingMapping()})):NotImplementedError:('keys',) +d.update(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:('getitem:mappingkey',) +d.update(Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing *Iter* using d.update(%s) +d.update(FailingIter()):NotImplementedError:('iter',) +d.update(FailingIterNext()):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using d.update(%s) +d.update(None):TypeError:("'NoneType' object is not iterable",) +d.update({"": 1}):ValueError:('empty keys are not allowed',) +d.update({u"": 1}):ValueError:('empty keys are not allowed',) +d.update(FailingMapping()):NotImplementedError:('keys',) +d.update(FailingMappingKey()):NotImplementedError:('getitem:mappingkey',) +d.update(FailingNumber()):TypeError:("'FailingNumber' object is not iterable",) +<<< Finished +>>> Testing StringToChars using d.update(((%s, 0),)) +d.update(((1, 0),)):TypeError:('expected str() or unicode() instance, but got int',) +d.update(((u"\0", 0),)):TypeError:('expected string without null bytes',) +d.update((("\0", 0),)):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d.update((("a", {%s : 1}),)) +d.update((("a", {1 : 1}),)):TypeError:('expected str() or unicode() instance, but got int',) +d.update((("a", {u"\0" : 1}),)):TypeError:('expected string without null bytes',) +d.update((("a", {"\0" : 1}),)):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d.update((("a", {"abcF" : {%s : 1}}),)) +d.update((("a", {"abcF" : {1 : 1}}),)):TypeError:('expected str() or unicode() instance, but got int',) +d.update((("a", {"abcF" : {u"\0" : 1}}),)):TypeError:('expected string without null bytes',) +d.update((("a", {"abcF" : {"\0" : 1}}),)):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d.update((("a", {"abcF" : Mapping({%s : 1})}),)) +d.update((("a", {"abcF" : Mapping({1 : 1})}),)):TypeError:('expected str() or unicode() instance, but got int',) +d.update((("a", {"abcF" : Mapping({u"\0" : 1})}),)):TypeError:('expected string without null bytes',) +d.update((("a", {"abcF" : Mapping({"\0" : 1})}),)):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using d.update((("a", {"abcF" : %s}),)) +d.update((("a", {"abcF" : FailingIter()}),)):TypeError:('unable to convert FailingIter to vim structure',) +d.update((("a", {"abcF" : FailingIterNext()}),)):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),)) +d.update((("a", {"abcF" : None}),)):TypeError:('unable to convert NoneType to vim structure',) +d.update((("a", {"abcF" : {"": 1}}),)):ValueError:('empty keys are not allowed',) +d.update((("a", {"abcF" : {u"": 1}}),)):ValueError:('empty keys are not allowed',) +d.update((("a", {"abcF" : FailingMapping()}),)):NotImplementedError:('keys',) +d.update((("a", {"abcF" : FailingMappingKey()}),)):NotImplementedError:('getitem:mappingkey',) +d.update((("a", {"abcF" : FailingNumber()}),)):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),)) +d.update((("a", Mapping({1 : 1})),)):TypeError:('expected str() or unicode() instance, but got int',) +d.update((("a", Mapping({u"\0" : 1})),)):TypeError:('expected string without null bytes',) +d.update((("a", Mapping({"\0" : 1})),)):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d.update((("a", Mapping({"abcG" : {%s : 1}})),)) +d.update((("a", Mapping({"abcG" : {1 : 1}})),)):TypeError:('expected str() or unicode() instance, but got int',) +d.update((("a", Mapping({"abcG" : {u"\0" : 1}})),)):TypeError:('expected string without null bytes',) +d.update((("a", Mapping({"abcG" : {"\0" : 1}})),)):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using d.update((("a", Mapping({"abcG" : Mapping({%s : 1})})),)) +d.update((("a", Mapping({"abcG" : Mapping({1 : 1})})),)):TypeError:('expected str() or unicode() instance, but got int',) +d.update((("a", Mapping({"abcG" : Mapping({u"\0" : 1})})),)):TypeError:('expected string without null bytes',) +d.update((("a", Mapping({"abcG" : Mapping({"\0" : 1})})),)):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using d.update((("a", Mapping({"abcG" : %s})),)) +d.update((("a", Mapping({"abcG" : FailingIter()})),)):TypeError:('unable to convert FailingIter to vim structure',) +d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abcG" : %s})),)) +d.update((("a", Mapping({"abcG" : None})),)):TypeError:('unable to convert NoneType to vim structure',) +d.update((("a", Mapping({"abcG" : {"": 1}})),)):ValueError:('empty keys are not allowed',) +d.update((("a", Mapping({"abcG" : {u"": 1}})),)):ValueError:('empty keys are not allowed',) +d.update((("a", Mapping({"abcG" : FailingMapping()})),)):NotImplementedError:('keys',) +d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):NotImplementedError:('getitem:mappingkey',) +d.update((("a", Mapping({"abcG" : FailingNumber()})),)):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing *Iter* using d.update((("a", %s),)) +d.update((("a", FailingIter()),)):TypeError:('unable to convert FailingIter to vim structure',) +d.update((("a", FailingIterNext()),)):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using d.update((("a", %s),)) +d.update((("a", None),)):TypeError:('unable to convert NoneType to vim structure',) +d.update((("a", {"": 1}),)):ValueError:('empty keys are not allowed',) +d.update((("a", {u"": 1}),)):ValueError:('empty keys are not allowed',) +d.update((("a", FailingMapping()),)):NotImplementedError:('keys',) +d.update((("a", FailingMappingKey()),)):NotImplementedError:('getitem:mappingkey',) +d.update((("a", FailingNumber()),)):TypeError:('long() argument must be a string or a number',) +<<< Finished +>> DictionaryPopItem +d.popitem(1, 2):TypeError:('popitem() takes no arguments (2 given)',) +>> DictionaryHasKey +d.has_key():TypeError:('has_key() takes exactly one argument (0 given)',) +> List +>> ListConstructor +vim.List(1, 2):TypeError:('function takes at most 1 argument (2 given)',) +vim.List(a=1):TypeError:('list constructor does not accept keyword arguments',) +>>> Testing *Iter* using vim.List(%s) +vim.List(FailingIter()):NotImplementedError:('iter',) +vim.List(FailingIterNext()):NotImplementedError:('next',) +<<< Finished +>>> Testing StringToChars using vim.List([{%s : 1}]) +vim.List([{1 : 1}]):TypeError:('expected str() or unicode() instance, but got int',) +vim.List([{u"\0" : 1}]):TypeError:('expected string without null bytes',) +vim.List([{"\0" : 1}]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using vim.List([{"abcF" : {%s : 1}}]) +vim.List([{"abcF" : {1 : 1}}]):TypeError:('expected str() or unicode() instance, but got int',) +vim.List([{"abcF" : {u"\0" : 1}}]):TypeError:('expected string without null bytes',) +vim.List([{"abcF" : {"\0" : 1}}]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using vim.List([{"abcF" : Mapping({%s : 1})}]) +vim.List([{"abcF" : Mapping({1 : 1})}]):TypeError:('expected str() or unicode() instance, but got int',) +vim.List([{"abcF" : Mapping({u"\0" : 1})}]):TypeError:('expected string without null bytes',) +vim.List([{"abcF" : Mapping({"\0" : 1})}]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using vim.List([{"abcF" : %s}]) +vim.List([{"abcF" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',) +vim.List([{"abcF" : FailingIterNext()}]):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using vim.List([{"abcF" : %s}]) +vim.List([{"abcF" : None}]):TypeError:('unable to convert NoneType to vim structure',) +vim.List([{"abcF" : {"": 1}}]):ValueError:('empty keys are not allowed',) +vim.List([{"abcF" : {u"": 1}}]):ValueError:('empty keys are not allowed',) +vim.List([{"abcF" : FailingMapping()}]):NotImplementedError:('keys',) +vim.List([{"abcF" : FailingMappingKey()}]):NotImplementedError:('getitem:mappingkey',) +vim.List([{"abcF" : FailingNumber()}]):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing StringToChars using vim.List([Mapping({%s : 1})]) +vim.List([Mapping({1 : 1})]):TypeError:('expected str() or unicode() instance, but got int',) +vim.List([Mapping({u"\0" : 1})]):TypeError:('expected string without null bytes',) +vim.List([Mapping({"\0" : 1})]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using vim.List([Mapping({"abcG" : {%s : 1}})]) +vim.List([Mapping({"abcG" : {1 : 1}})]):TypeError:('expected str() or unicode() instance, but got int',) +vim.List([Mapping({"abcG" : {u"\0" : 1}})]):TypeError:('expected string without null bytes',) +vim.List([Mapping({"abcG" : {"\0" : 1}})]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using vim.List([Mapping({"abcG" : Mapping({%s : 1})})]) +vim.List([Mapping({"abcG" : Mapping({1 : 1})})]):TypeError:('expected str() or unicode() instance, but got int',) +vim.List([Mapping({"abcG" : Mapping({u"\0" : 1})})]):TypeError:('expected string without null bytes',) +vim.List([Mapping({"abcG" : Mapping({"\0" : 1})})]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using vim.List([Mapping({"abcG" : %s})]) +vim.List([Mapping({"abcG" : FailingIter()})]):TypeError:('unable to convert FailingIter to vim structure',) +vim.List([Mapping({"abcG" : FailingIterNext()})]):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using vim.List([Mapping({"abcG" : %s})]) +vim.List([Mapping({"abcG" : None})]):TypeError:('unable to convert NoneType to vim structure',) +vim.List([Mapping({"abcG" : {"": 1}})]):ValueError:('empty keys are not allowed',) +vim.List([Mapping({"abcG" : {u"": 1}})]):ValueError:('empty keys are not allowed',) +vim.List([Mapping({"abcG" : FailingMapping()})]):NotImplementedError:('keys',) +vim.List([Mapping({"abcG" : FailingMappingKey()})]):NotImplementedError:('getitem:mappingkey',) +vim.List([Mapping({"abcG" : FailingNumber()})]):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing *Iter* using vim.List([%s]) +vim.List([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',) +vim.List([FailingIterNext()]):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using vim.List([%s]) +vim.List([None]):TypeError:('unable to convert NoneType to vim structure',) +vim.List([{"": 1}]):ValueError:('empty keys are not allowed',) +vim.List([{u"": 1}]):ValueError:('empty keys are not allowed',) +vim.List([FailingMapping()]):NotImplementedError:('keys',) +vim.List([FailingMappingKey()]):NotImplementedError:('getitem:mappingkey',) +vim.List([FailingNumber()]):TypeError:('long() argument must be a string or a number',) +<<< Finished +>> ListItem +l[1000]:IndexError:('list index out of range',) +>> ListAssItem +ll[1] = 2:error:('list is locked',) +l[1000] = 3:IndexError:('list index out of range',) +>> ListAssSlice +ll[1:100] = "abcJ":error:('list is locked',) +>>> Testing *Iter* using l[:] = %s +l[:] = FailingIter():NotImplementedError:('iter',) +l[:] = FailingIterNext():NotImplementedError:('next',) +<<< Finished +nel[1:10:2] = "abcK":ValueError:('attempt to assign sequence of size greater then 2 to extended slice',) +('a', 'b', 'c', 'O') +nel[1:10:2] = "a":ValueError:('attempt to assign sequence of size 1 to extended slice of size 2',) +('a', 'b', 'c', 'O') +nel[1:1:-1] = "a":ValueError:('attempt to assign sequence of size greater then 0 to extended slice',) +('a', 'b', 'c', 'O') +nel[:] = FailingIterNextN(2):NotImplementedError:('next N',) +('a', 'b', 'c', 'O') +>>> Testing StringToChars using l[:] = [{%s : 1}] +l[:] = [{1 : 1}]:TypeError:('expected str() or unicode() instance, but got int',) +l[:] = [{u"\0" : 1}]:TypeError:('expected string without null bytes',) +l[:] = [{"\0" : 1}]:TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using l[:] = [{"abcF" : {%s : 1}}] +l[:] = [{"abcF" : {1 : 1}}]:TypeError:('expected str() or unicode() instance, but got int',) +l[:] = [{"abcF" : {u"\0" : 1}}]:TypeError:('expected string without null bytes',) +l[:] = [{"abcF" : {"\0" : 1}}]:TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using l[:] = [{"abcF" : Mapping({%s : 1})}] +l[:] = [{"abcF" : Mapping({1 : 1})}]:TypeError:('expected str() or unicode() instance, but got int',) +l[:] = [{"abcF" : Mapping({u"\0" : 1})}]:TypeError:('expected string without null bytes',) +l[:] = [{"abcF" : Mapping({"\0" : 1})}]:TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using l[:] = [{"abcF" : %s}] +l[:] = [{"abcF" : FailingIter()}]:TypeError:('unable to convert FailingIter to vim structure',) +l[:] = [{"abcF" : FailingIterNext()}]:NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using l[:] = [{"abcF" : %s}] +l[:] = [{"abcF" : None}]:TypeError:('unable to convert NoneType to vim structure',) +l[:] = [{"abcF" : {"": 1}}]:ValueError:('empty keys are not allowed',) +l[:] = [{"abcF" : {u"": 1}}]:ValueError:('empty keys are not allowed',) +l[:] = [{"abcF" : FailingMapping()}]:NotImplementedError:('keys',) +l[:] = [{"abcF" : FailingMappingKey()}]:NotImplementedError:('getitem:mappingkey',) +l[:] = [{"abcF" : FailingNumber()}]:TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing StringToChars using l[:] = [Mapping({%s : 1})] +l[:] = [Mapping({1 : 1})]:TypeError:('expected str() or unicode() instance, but got int',) +l[:] = [Mapping({u"\0" : 1})]:TypeError:('expected string without null bytes',) +l[:] = [Mapping({"\0" : 1})]:TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using l[:] = [Mapping({"abcG" : {%s : 1}})] +l[:] = [Mapping({"abcG" : {1 : 1}})]:TypeError:('expected str() or unicode() instance, but got int',) +l[:] = [Mapping({"abcG" : {u"\0" : 1}})]:TypeError:('expected string without null bytes',) +l[:] = [Mapping({"abcG" : {"\0" : 1}})]:TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using l[:] = [Mapping({"abcG" : Mapping({%s : 1})})] +l[:] = [Mapping({"abcG" : Mapping({1 : 1})})]:TypeError:('expected str() or unicode() instance, but got int',) +l[:] = [Mapping({"abcG" : Mapping({u"\0" : 1})})]:TypeError:('expected string without null bytes',) +l[:] = [Mapping({"abcG" : Mapping({"\0" : 1})})]:TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})] +l[:] = [Mapping({"abcG" : FailingIter()})]:TypeError:('unable to convert FailingIter to vim structure',) +l[:] = [Mapping({"abcG" : FailingIterNext()})]:NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using l[:] = [Mapping({"abcG" : %s})] +l[:] = [Mapping({"abcG" : None})]:TypeError:('unable to convert NoneType to vim structure',) +l[:] = [Mapping({"abcG" : {"": 1}})]:ValueError:('empty keys are not allowed',) +l[:] = [Mapping({"abcG" : {u"": 1}})]:ValueError:('empty keys are not allowed',) +l[:] = [Mapping({"abcG" : FailingMapping()})]:NotImplementedError:('keys',) +l[:] = [Mapping({"abcG" : FailingMappingKey()})]:NotImplementedError:('getitem:mappingkey',) +l[:] = [Mapping({"abcG" : FailingNumber()})]:TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing *Iter* using l[:] = [%s] +l[:] = [FailingIter()]:TypeError:('unable to convert FailingIter to vim structure',) +l[:] = [FailingIterNext()]:NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using l[:] = [%s] +l[:] = [None]:TypeError:('unable to convert NoneType to vim structure',) +l[:] = [{"": 1}]:ValueError:('empty keys are not allowed',) +l[:] = [{u"": 1}]:ValueError:('empty keys are not allowed',) +l[:] = [FailingMapping()]:NotImplementedError:('keys',) +l[:] = [FailingMappingKey()]:NotImplementedError:('getitem:mappingkey',) +l[:] = [FailingNumber()]:TypeError:('long() argument must be a string or a number',) +<<< Finished +>> ListConcatInPlace +>>> Testing *Iter* using l.extend(%s) +l.extend(FailingIter()):NotImplementedError:('iter',) +l.extend(FailingIterNext()):NotImplementedError:('next',) +<<< Finished +>>> Testing StringToChars using l.extend([{%s : 1}]) +l.extend([{1 : 1}]):TypeError:('expected str() or unicode() instance, but got int',) +l.extend([{u"\0" : 1}]):TypeError:('expected string without null bytes',) +l.extend([{"\0" : 1}]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using l.extend([{"abcF" : {%s : 1}}]) +l.extend([{"abcF" : {1 : 1}}]):TypeError:('expected str() or unicode() instance, but got int',) +l.extend([{"abcF" : {u"\0" : 1}}]):TypeError:('expected string without null bytes',) +l.extend([{"abcF" : {"\0" : 1}}]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using l.extend([{"abcF" : Mapping({%s : 1})}]) +l.extend([{"abcF" : Mapping({1 : 1})}]):TypeError:('expected str() or unicode() instance, but got int',) +l.extend([{"abcF" : Mapping({u"\0" : 1})}]):TypeError:('expected string without null bytes',) +l.extend([{"abcF" : Mapping({"\0" : 1})}]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using l.extend([{"abcF" : %s}]) +l.extend([{"abcF" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',) +l.extend([{"abcF" : FailingIterNext()}]):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using l.extend([{"abcF" : %s}]) +l.extend([{"abcF" : None}]):TypeError:('unable to convert NoneType to vim structure',) +l.extend([{"abcF" : {"": 1}}]):ValueError:('empty keys are not allowed',) +l.extend([{"abcF" : {u"": 1}}]):ValueError:('empty keys are not allowed',) +l.extend([{"abcF" : FailingMapping()}]):NotImplementedError:('keys',) +l.extend([{"abcF" : FailingMappingKey()}]):NotImplementedError:('getitem:mappingkey',) +l.extend([{"abcF" : FailingNumber()}]):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing StringToChars using l.extend([Mapping({%s : 1})]) +l.extend([Mapping({1 : 1})]):TypeError:('expected str() or unicode() instance, but got int',) +l.extend([Mapping({u"\0" : 1})]):TypeError:('expected string without null bytes',) +l.extend([Mapping({"\0" : 1})]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using l.extend([Mapping({"abcG" : {%s : 1}})]) +l.extend([Mapping({"abcG" : {1 : 1}})]):TypeError:('expected str() or unicode() instance, but got int',) +l.extend([Mapping({"abcG" : {u"\0" : 1}})]):TypeError:('expected string without null bytes',) +l.extend([Mapping({"abcG" : {"\0" : 1}})]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using l.extend([Mapping({"abcG" : Mapping({%s : 1})})]) +l.extend([Mapping({"abcG" : Mapping({1 : 1})})]):TypeError:('expected str() or unicode() instance, but got int',) +l.extend([Mapping({"abcG" : Mapping({u"\0" : 1})})]):TypeError:('expected string without null bytes',) +l.extend([Mapping({"abcG" : Mapping({"\0" : 1})})]):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using l.extend([Mapping({"abcG" : %s})]) +l.extend([Mapping({"abcG" : FailingIter()})]):TypeError:('unable to convert FailingIter to vim structure',) +l.extend([Mapping({"abcG" : FailingIterNext()})]):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using l.extend([Mapping({"abcG" : %s})]) +l.extend([Mapping({"abcG" : None})]):TypeError:('unable to convert NoneType to vim structure',) +l.extend([Mapping({"abcG" : {"": 1}})]):ValueError:('empty keys are not allowed',) +l.extend([Mapping({"abcG" : {u"": 1}})]):ValueError:('empty keys are not allowed',) +l.extend([Mapping({"abcG" : FailingMapping()})]):NotImplementedError:('keys',) +l.extend([Mapping({"abcG" : FailingMappingKey()})]):NotImplementedError:('getitem:mappingkey',) +l.extend([Mapping({"abcG" : FailingNumber()})]):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing *Iter* using l.extend([%s]) +l.extend([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',) +l.extend([FailingIterNext()]):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using l.extend([%s]) +l.extend([None]):TypeError:('unable to convert NoneType to vim structure',) +l.extend([{"": 1}]):ValueError:('empty keys are not allowed',) +l.extend([{u"": 1}]):ValueError:('empty keys are not allowed',) +l.extend([FailingMapping()]):NotImplementedError:('keys',) +l.extend([FailingMappingKey()]):NotImplementedError:('getitem:mappingkey',) +l.extend([FailingNumber()]):TypeError:('long() argument must be a string or a number',) +<<< Finished +>> ListSetattr +del l.locked:AttributeError:('cannot delete vim.List attributes',) +l.locked = FailingTrue():NotImplementedError:('bool',) +l.xxx = True:AttributeError:('cannot set attribute xxx',) +> Function +>> FunctionConstructor +vim.Function("123"):ValueError:('unnamed function 123 does not exist',) +vim.Function("xxx_non_existent_function_xxx"):ValueError:('function xxx_non_existent_function_xxx does not exist',) +vim.Function("xxx#non#existent#function#xxx"):NOT FAILED +>> FunctionCall +>>> Testing StringToChars using f({%s : 1}) +f({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',) +f({u"\0" : 1}):TypeError:('expected string without null bytes',) +f({"\0" : 1}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using f({"abcF" : {%s : 1}}) +f({"abcF" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',) +f({"abcF" : {u"\0" : 1}}):TypeError:('expected string without null bytes',) +f({"abcF" : {"\0" : 1}}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using f({"abcF" : Mapping({%s : 1})}) +f({"abcF" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',) +f({"abcF" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',) +f({"abcF" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using f({"abcF" : %s}) +f({"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',) +f({"abcF" : FailingIterNext()}):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using f({"abcF" : %s}) +f({"abcF" : None}):TypeError:('unable to convert NoneType to vim structure',) +f({"abcF" : {"": 1}}):ValueError:('empty keys are not allowed',) +f({"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',) +f({"abcF" : FailingMapping()}):NotImplementedError:('keys',) +f({"abcF" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',) +f({"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing StringToChars using f(Mapping({%s : 1})) +f(Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',) +f(Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',) +f(Mapping({"\0" : 1})):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using f(Mapping({"abcG" : {%s : 1}})) +f(Mapping({"abcG" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',) +f(Mapping({"abcG" : {u"\0" : 1}})):TypeError:('expected string without null bytes',) +f(Mapping({"abcG" : {"\0" : 1}})):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using f(Mapping({"abcG" : Mapping({%s : 1})})) +f(Mapping({"abcG" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',) +f(Mapping({"abcG" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',) +f(Mapping({"abcG" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using f(Mapping({"abcG" : %s})) +f(Mapping({"abcG" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',) +f(Mapping({"abcG" : FailingIterNext()})):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using f(Mapping({"abcG" : %s})) +f(Mapping({"abcG" : None})):TypeError:('unable to convert NoneType to vim structure',) +f(Mapping({"abcG" : {"": 1}})):ValueError:('empty keys are not allowed',) +f(Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',) +f(Mapping({"abcG" : FailingMapping()})):NotImplementedError:('keys',) +f(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:('getitem:mappingkey',) +f(Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing *Iter* using f(%s) +f(FailingIter()):TypeError:('unable to convert FailingIter to vim structure',) +f(FailingIterNext()):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using f(%s) +f(None):TypeError:('unable to convert NoneType to vim structure',) +f({"": 1}):ValueError:('empty keys are not allowed',) +f({u"": 1}):ValueError:('empty keys are not allowed',) +f(FailingMapping()):NotImplementedError:('keys',) +f(FailingMappingKey()):NotImplementedError:('getitem:mappingkey',) +f(FailingNumber()):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing StringToChars using fd(self={%s : 1}) +fd(self={1 : 1}):TypeError:('expected str() or unicode() instance, but got int',) +fd(self={u"\0" : 1}):TypeError:('expected string without null bytes',) +fd(self={"\0" : 1}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using fd(self={"abcF" : {%s : 1}}) +fd(self={"abcF" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',) +fd(self={"abcF" : {u"\0" : 1}}):TypeError:('expected string without null bytes',) +fd(self={"abcF" : {"\0" : 1}}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using fd(self={"abcF" : Mapping({%s : 1})}) +fd(self={"abcF" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',) +fd(self={"abcF" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',) +fd(self={"abcF" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using fd(self={"abcF" : %s}) +fd(self={"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',) +fd(self={"abcF" : FailingIterNext()}):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using fd(self={"abcF" : %s}) +fd(self={"abcF" : None}):TypeError:('unable to convert NoneType to vim structure',) +fd(self={"abcF" : {"": 1}}):ValueError:('empty keys are not allowed',) +fd(self={"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',) +fd(self={"abcF" : FailingMapping()}):NotImplementedError:('keys',) +fd(self={"abcF" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',) +fd(self={"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing StringToChars using fd(self=Mapping({%s : 1})) +fd(self=Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',) +fd(self=Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',) +fd(self=Mapping({"\0" : 1})):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using fd(self=Mapping({"abcG" : {%s : 1}})) +fd(self=Mapping({"abcG" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',) +fd(self=Mapping({"abcG" : {u"\0" : 1}})):TypeError:('expected string without null bytes',) +fd(self=Mapping({"abcG" : {"\0" : 1}})):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing StringToChars using fd(self=Mapping({"abcG" : Mapping({%s : 1})})) +fd(self=Mapping({"abcG" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',) +fd(self=Mapping({"abcG" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',) +fd(self=Mapping({"abcG" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',) +<<< Finished +>>> Testing *Iter* using fd(self=Mapping({"abcG" : %s})) +fd(self=Mapping({"abcG" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',) +fd(self=Mapping({"abcG" : FailingIterNext()})):NotImplementedError:('next',) +<<< Finished +>>> Testing ConvertFromPyObject using fd(self=Mapping({"abcG" : %s})) +fd(self=Mapping({"abcG" : None})):TypeError:('unable to convert NoneType to vim structure',) +fd(self=Mapping({"abcG" : {"": 1}})):ValueError:('empty keys are not allowed',) +fd(self=Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',) +fd(self=Mapping({"abcG" : FailingMapping()})):NotImplementedError:('keys',) +fd(self=Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:('getitem:mappingkey',) +fd(self=Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',) +<<< Finished +>>> Testing *Iter* using fd(self=%s) +fd(self=FailingIter()):TypeError:('unable to convert FailingIter to vim dictionary',) +fd(self=FailingIterNext()):TypeError:('unable to convert FailingIterNext to vim dictionary',) +<<< Finished +>>> Testing ConvertFromPyObject using fd(self=%s) +fd(self=None):TypeError:('unable to convert NoneType to vim dictionary',) +fd(self={"": 1}):ValueError:('empty keys are not allowed',) +fd(self={u"": 1}):ValueError:('empty keys are not allowed',) +fd(self=FailingMapping()):NotImplementedError:('keys',) +fd(self=FailingMappingKey()):NotImplementedError:('getitem:mappingkey',) +fd(self=FailingNumber()):TypeError:('unable to convert FailingNumber to vim dictionary',) +<<< Finished +>>> Testing ConvertFromPyMapping using fd(self=%s) +fd(self=[]):TypeError:('unable to convert list to vim dictionary',) +<<< Finished +> TabPage +>> TabPageAttr +vim.current.tabpage.xxx:AttributeError:('xxx',) +> TabList +>> TabListItem +vim.tabpages[1000]:IndexError:('no such tab page',) +> Window +>> WindowAttr +vim.current.window.xxx:AttributeError:('xxx',) +>> WindowSetattr +vim.current.window.buffer = 0:TypeError:('readonly attribute: buffer',) +vim.current.window.cursor = (100000000, 100000000):error:('cursor position outside buffer',) +vim.current.window.cursor = True:TypeError:('argument must be 2-item sequence, not bool',) +>>> Testing NumberToLong using vim.current.window.height = %s +vim.current.window.height = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',) +vim.current.window.height = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',) +vim.current.window.height = -1:ValueError:('number must be greater or equal to zero',) +<<< Finished +>>> Testing NumberToLong using vim.current.window.width = %s +vim.current.window.width = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',) +vim.current.window.width = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',) +vim.current.window.width = -1:ValueError:('number must be greater or equal to zero',) +<<< Finished +vim.current.window.xxxxxx = True:AttributeError:('xxxxxx',) +> WinList +>> WinListItem +vim.windows[1000]:IndexError:('no such window',) +> Buffer +>> StringToLine (indirect) +vim.current.buffer[0] = u"\na":error:('string cannot contain newlines',) +vim.current.buffer[0] = "\na":error:('string cannot contain newlines',) +>> SetBufferLine (indirect) +vim.current.buffer[0] = True:TypeError:('bad argument type for built-in operation',) +>> SetBufferLineList (indirect) +vim.current.buffer[:] = True:TypeError:('bad argument type for built-in operation',) +vim.current.buffer[:] = ["\na", "bc"]:error:('string cannot contain newlines',) +>> InsertBufferLines (indirect) +vim.current.buffer.append(None):TypeError:('bad argument type for built-in operation',) +vim.current.buffer.append(["\na", "bc"]):error:('string cannot contain newlines',) +vim.current.buffer.append("\nbc"):error:('string cannot contain newlines',) +>> RBItem +vim.current.buffer[100000000]:IndexError:('line number out of range',) +>> RBAsItem +vim.current.buffer[100000000] = "":IndexError:('line number out of range',) +>> BufferAttr +vim.current.buffer.xxx:AttributeError:('xxx',) +>> BufferSetattr +vim.current.buffer.name = True:TypeError:('expected str() or unicode() instance, but got bool',) +vim.current.buffer.xxx = True:AttributeError:('xxx',) +>> BufferMark +vim.current.buffer.mark(0):TypeError:('expected str() or unicode() instance, but got int',) +vim.current.buffer.mark("abcM"):ValueError:('mark name must be a single character',) +vim.current.buffer.mark("!"):error:('invalid mark name',) +>> BufferRange +vim.current.buffer.range(1, 2, 3):TypeError:('function takes exactly 2 arguments (3 given)',) +> BufMap +>> BufMapItem +vim.buffers[100000000]:KeyError:(100000000,) +>>> Testing NumberToLong using vim.buffers[%s] +vim.buffers[[]]:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',) +vim.buffers[None]:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',) +vim.buffers[-1]:ValueError:('number must be greater then zero',) +vim.buffers[0]:ValueError:('number must be greater then zero',) +<<< Finished +> Current +>> CurrentGetattr +vim.current.xxx:AttributeError:('xxx',) +>> CurrentSetattr +vim.current.line = True:TypeError:('bad argument type for built-in operation',) +vim.current.buffer = True:TypeError:('expected vim.Buffer object, but got bool',) +vim.current.window = True:TypeError:('expected vim.Window object, but got bool',) +vim.current.tabpage = True:TypeError:('expected vim.TabPage object, but got bool',) +vim.current.xxx = True:AttributeError:('xxx',) +['/testdir'] +'/testdir' +2,xx +before +after +pythonx/topmodule/__init__.py +pythonx/topmodule/submodule/__init__.py +pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py +vim.command("throw 'abcN'"):error:('abcN',) +Exe("throw 'def'"):error:('def',) +vim.eval("Exe('throw ''ghi''')"):error:('ghi',) +vim.eval("Exe('echoerr ''jkl''')"):error:('Vim(echoerr):jkl',) +vim.eval("Exe('xxx_non_existent_command_xxx')"):error:('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',) +vim.eval("xxx_unknown_function_xxx()"):error:('Vim:E117: Unknown function: xxx_unknown_function_xxx',) +vim.bindeval("Exe('xxx_non_existent_command_xxx')"):error:('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',) +Caught KeyboardInterrupt +Running :put +No exception + diff --git a/src/nvim/testdir/test87.in b/src/nvim/testdir/test87.in new file mode 100644 index 0000000000..e45883b59d --- /dev/null +++ b/src/nvim/testdir/test87.in @@ -0,0 +1,1406 @@ +Tests for various python features. vim: set ft=vim : + +STARTTEST +:so small.vim +:set noswapfile +:if !has('python3') | e! test.ok | wq! test.out | endif +:lang C +:fun Test() +:py3 import vim +:let l = [] +:py3 l=vim.bindeval('l') +:py3 f=vim.bindeval('function("strlen")') +:" Extending List directly with different types +:py3 l+=[1, "as'd", [1, 2, f, {'a': 1}]] +:$put =string(l) +:$put =string(l[-1]) +:try +: $put =string(l[-4]) +:catch +: $put =v:exception[:13] +:endtry +:" List assignment +:py3 l[0]=0 +:$put =string(l) +:py3 l[-2]=f +:$put =string(l) +:" +:" Extending Dictionary directly with different types +:let d = {} +:fun d.f() +: return 1 +:endfun +py3 << EOF +d=vim.bindeval('d') +d['1']='asd' +d.update(b=[1, 2, f]) +d.update((('-1', {'a': 1}),)) +d.update({'0': -1}) +dk = d.keys() +dv = d.values() +di = d.items() +dk.sort(key=repr) +dv.sort(key=repr) +di.sort(key=repr) +EOF +:$put =py3eval('d[''f''](self={})') +:$put =py3eval('repr(dk)') +:$put =substitute(py3eval('repr(dv)'),'0x\x\+','','g') +:$put =substitute(py3eval('repr(di)'),'0x\x\+','','g') +:for [key, Val] in sort(items(d)) +: $put =string(key) . ' : ' . string(Val) +: unlet key Val +:endfor +:py3 del dk +:py3 del di +:py3 del dv +:" +:" removing items with del +:py3 del l[2] +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:try +: py3 del l[:3] +: py3 del l[1:] +:catch +: $put =v:exception +:endtry +:$put =string(l) +:" +:py3 del d['-1'] +:py3 del d['f'] +:$put =string(py3eval('d.get(''b'', 1)')) +:$put =string(py3eval('d.pop(''b'')')) +:$put =string(py3eval('d.get(''b'', 1)')) +:$put =string(py3eval('d.pop(''1'', 2)')) +:$put =string(py3eval('d.pop(''1'', 2)')) +:$put =py3eval('repr(d.has_key(''0''))') +:$put =py3eval('repr(d.has_key(''1''))') +:$put =py3eval('repr(''0'' in d)') +:$put =py3eval('repr(''1'' in d)') +:$put =py3eval('repr(list(iter(d)))') +:$put =string(d) +:$put =py3eval('repr(d.popitem())') +:$put =py3eval('repr(d.get(''0''))') +:$put =py3eval('repr(list(iter(d)))') +:" +:" removing items out of range: silently skip items that don't exist +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:" The following two ranges delete nothing as they match empty list: +:py3 del l[2:1] +:$put =string(l) +:py3 del l[2:2] +:$put =string(l) +:py3 del l[2:3] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[2:4] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[2:5] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[2:6] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:" The following two ranges delete nothing as they match empty list: +:py3 del l[-1:2] +:$put =string(l) +:py3 del l[-2:2] +:$put =string(l) +:py3 del l[-3:2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[-4:2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[-5:2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[-6:2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[::2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[3:0:-2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[2:4:-2] +:$put =string(l) +:" +:" Slice assignment to a list +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 l[0:0]=['a'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 l[1:2]=['b'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 l[2:4]=['c'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 l[4:4]=['d'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 l[-1:2]=['e'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 l[-10:2]=['f'] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 l[2:-10]=['g'] +:$put =string(l) +:let l = [] +:py3 l=vim.bindeval('l') +:py3 l[0:0]=['h'] +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[2:6:2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[6:2:-2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[6:2] = () +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[6:2:1] = () +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[2:2:1] = () +:$put =string(l) +:" +:" Locked variables +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:lockvar! l +:py3 l[2]='i' +:$put =string(l) +:unlockvar! l +:" +:" Function calls +py3 << EOF +import sys +import re + +py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$') + +def ee(expr, g=globals(), l=locals()): + cb = vim.current.buffer + try: + try: + exec(expr, g, l) + except Exception as e: + if sys.version_info >= (3, 3) and e.__class__ is AttributeError and str(e).find('has no attribute')>=0 and not str(e).startswith("'vim."): + cb.append(expr + ':' + repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1])))) + elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0: + cb.append(expr + ':' + repr((e.__class__, ImportError(str(e).replace("'", ''))))) + elif sys.version_info >= (3, 3) and e.__class__ is TypeError: + m = py33_type_error_pattern.search(str(e)) + if m: + msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2)) + cb.append(expr + ':' + repr((e.__class__, TypeError(msg)))) + else: + cb.append(expr + ':' + repr((e.__class__, e))) + else: + cb.append(expr + ':' + repr((e.__class__, e))) + else: + cb.append(expr + ':NOT FAILED') + except Exception as e: + cb.append(expr + '::' + repr((e.__class__, e))) +EOF +:fun New(...) +: return ['NewStart']+a:000+['NewEnd'] +:endfun +:fun DictNew(...) dict +: return ['DictNewStart']+a:000+['DictNewEnd', self] +:endfun +:let l=[function('New'), function('DictNew')] +:py3 l=vim.bindeval('l') +:py3 l.extend(list(l[0](1, 2, 3))) +:$put =string(l) +:py3 l.extend(list(l[1](1, 2, 3, self={'a': 'b'}))) +:$put =string(l) +:py3 l+=[l[0].name] +:$put =string(l) +:py3 ee('l[1](1, 2, 3)') +:py3 f=l[0] +:delfunction New +:py3 ee('f(1, 2, 3)') +:if has('float') +: let l=[0.0] +: py3 l=vim.bindeval('l') +: py3 l.extend([0.0]) +: $put =string(l) +:else +: $put ='[0.0, 0.0]' +:endif +:let messages=[] +:delfunction DictNew +py3 <<EOF +d=vim.bindeval('{}') +m=vim.bindeval('messages') +def em(expr, g=globals(), l=locals()): + try: + exec(expr, g, l) + except Exception as e: + m.extend([e.__class__.__name__]) + +em('d["abc1"]') +em('d["abc1"]="\\0"') +em('d["abc1"]=vim') +em('d[""]=1') +em('d["a\\0b"]=1') +em('d[b"a\\0b"]=1') + +em('d.pop("abc1")') +em('d.popitem()') +del em +del m +EOF +:$put =messages +:unlet messages +:" locked and scope attributes +:let d={} | let dl={} | lockvar dl +:for s in split("d dl v: g:") +: let name=tr(s, ':', 's') +: execute 'py3 '.name.'=vim.bindeval("'.s.'")' +: let toput=s.' : '.join(map(['locked', 'scope'], 'v:val.":".py3eval(name.".".v:val)'), ';') +: $put =toput +:endfor +:silent! let d.abc2=1 +:silent! let dl.abc3=1 +:py3 d.locked=True +:py3 dl.locked=False +:silent! let d.def=1 +:silent! let dl.def=1 +:put ='d:'.string(d) +:put ='dl:'.string(dl) +:unlet d dl +: +:let l=[] | let ll=[] | lockvar ll +:for s in split("l ll") +: let name=tr(s, ':', 's') +: execute 'py3 '.name.'=vim.bindeval("'.s.'")' +: let toput=s.' : locked:'.py3eval(name.'.locked') +: $put =toput +:endfor +:silent! call extend(l, [0]) +:silent! call extend(ll, [0]) +:py3 l.locked=True +:py3 ll.locked=False +:silent! call extend(l, [1]) +:silent! call extend(ll, [1]) +:put ='l:'.string(l) +:put ='ll:'.string(ll) +:unlet l ll +:" +:" py3eval() +:let l=py3eval('[0, 1, 2]') +:$put =string(l) +:let d=py3eval('{"a": "b", "c": 1, "d": ["e"]}') +:$put =sort(items(d)) +:if has('float') +: let f=py3eval('0.0') +: $put =string(f) +:else +: $put ='0.0' +:endif +:" Invalid values: +:for e in ['"\0"', '{"\0": 1}', 'undefined_name', 'vim'] +: try +: let v=py3eval(e) +: catch +: let toput=e.":\t".v:exception[:13] +: $put =toput +: endtry +:endfor +:" +:" threading +:let l = [0] +:py3 l=vim.bindeval('l') +py3 <<EOF +import threading +import time + +class T(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + self.t = 0 + self.running = True + + def run(self): + while self.running: + self.t += 1 + time.sleep(0.1) + +t = T() +del T +t.start() +EOF +:sleep 1 +:py3 t.running = False +:py3 t.join() +:py3 l[0] = t.t > 8 # check if the background thread is working +:py3 del time +:py3 del threading +:py3 del t +:$put =string(l) +:" +:" settrace +:let l = [] +:py3 l=vim.bindeval('l') +py3 <<EOF +import sys + +def traceit(frame, event, arg): + global l + if event == "line": + l += [frame.f_lineno] + return traceit + +def trace_main(): + for i in range(5): + pass +EOF +:py3 sys.settrace(traceit) +:py3 trace_main() +:py3 sys.settrace(None) +:py3 del traceit +:py3 del trace_main +:$put =string(l) +:" +:" Slice +:py3 ll = vim.bindeval('[0, 1, 2, 3, 4, 5]') +:py3 l = ll[:4] +:$put =string(py3eval('l')) +:py3 l = ll[2:] +:$put =string(py3eval('l')) +:py3 l = ll[:-4] +:$put =string(py3eval('l')) +:py3 l = ll[-2:] +:$put =string(py3eval('l')) +:py3 l = ll[2:4] +:$put =string(py3eval('l')) +:py3 l = ll[4:2] +:$put =string(py3eval('l')) +:py3 l = ll[-4:-2] +:$put =string(py3eval('l')) +:py3 l = ll[-2:-4] +:$put =string(py3eval('l')) +:py3 l = ll[:] +:$put =string(py3eval('l')) +:py3 l = ll[0:6] +:$put =string(py3eval('l')) +:py3 l = ll[-10:10] +:$put =string(py3eval('l')) +:py3 l = ll[4:2:-1] +:$put =string(py3eval('l')) +:py3 l = ll[::2] +:$put =string(py3eval('l')) +:py3 l = ll[4:2:1] +:$put =string(py3eval('l')) +:py3 del l +:" +:" Vars +:let g:foo = 'bac' +:let w:abc3 = 'def' +:let b:baz = 'bar' +:let t:bar = 'jkl' +:try +: throw "Abc" +:catch +: put =py3eval('vim.vvars[''exception'']') +:endtry +:put =py3eval('vim.vars[''foo'']') +:put =py3eval('vim.current.window.vars[''abc3'']') +:put =py3eval('vim.current.buffer.vars[''baz'']') +:put =py3eval('vim.current.tabpage.vars[''bar'']') +:" +:" Options +:" paste: boolean, global +:" previewheight number, global +:" operatorfunc: string, global +:" number: boolean, window-local +:" numberwidth: number, window-local +:" colorcolumn: string, window-local +:" statusline: string, window-local/global +:" autoindent: boolean, buffer-local +:" shiftwidth: number, buffer-local +:" omnifunc: string, buffer-local +:" preserveindent: boolean, buffer-local/global +:" path: string, buffer-local/global +:let g:bufs=[bufnr('%')] +:new +:let g:bufs+=[bufnr('%')] +:vnew +:let g:bufs+=[bufnr('%')] +:wincmd j +:vnew +:let g:bufs+=[bufnr('%')] +:wincmd l +:fun RecVars(opt) +: let gval =string(eval('&g:'.a:opt)) +: let wvals=join(map(range(1, 4), 'v:val.":".string(getwinvar(v:val, "&".a:opt))')) +: let bvals=join(map(copy(g:bufs), 'v:val.":".string(getbufvar(v:val, "&".a:opt))')) +: put =' G: '.gval +: put =' W: '.wvals +: put =' B: '.wvals +:endfun +py3 << EOF +def e(s, g=globals(), l=locals()): + try: + exec(s, g, l) + except Exception as e: + vim.command('return ' + repr(e.__class__.__name__)) + +def ev(s, g=globals(), l=locals()): + try: + return eval(s, g, l) + except Exception as e: + vim.command('let exc=' + repr(e.__class__.__name__)) + return 0 +EOF +:fun E(s) +: python3 e(vim.eval('a:s')) +:endfun +:fun Ev(s) +: let r=py3eval('ev(vim.eval("a:s"))') +: if exists('exc') +: throw exc +: endif +: return r +:endfun +:py3 gopts1=vim.options +:py3 wopts1=vim.windows[2].options +:py3 wopts2=vim.windows[0].options +:py3 wopts3=vim.windows[1].options +:py3 bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options +:py3 bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options +:py3 bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options +:$put ='wopts iters equal: '.py3eval('list(wopts1) == list(wopts2)') +:$put ='bopts iters equal: '.py3eval('list(bopts1) == list(bopts2)') +:py3 gset=set(iter(gopts1)) +:py3 wset=set(iter(wopts1)) +:py3 bset=set(iter(bopts1)) +:set path=.,..,, +:let lst=[] +:let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]] +:let lst+=[['previewheight', 5, 1, 6, 'a', 0, 1, 0 ]] +:let lst+=[['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0 ]] +:let lst+=[['number', 0, 1, 1, 0, 1, 0, 1 ]] +:let lst+=[['numberwidth', 2, 3, 5, -100, 0, 0, 1 ]] +:let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1 ]] +:let lst+=[['statusline', '1', '2', '4', 0, 0, 1, 1 ]] +:let lst+=[['autoindent', 0, 1, 1, 2, 1, 0, 2 ]] +:let lst+=[['shiftwidth', 0, 2, 1, 3, 0, 0, 2 ]] +:let lst+=[['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2 ]] +:let lst+=[['preserveindent', 0, 1, 1, 2, 1, 1, 2 ]] +:let lst+=[['path', '.,,', ',,', '.', 0, 0, 1, 2 ]] +:for [oname, oval1, oval2, oval3, invval, bool, global, local] in lst +: py3 oname=vim.eval('oname') +: py3 oval1=vim.bindeval('oval1') +: py3 oval2=vim.bindeval('oval2') +: py3 oval3=vim.bindeval('oval3') +: if invval is 0 || invval is 1 +: py3 invval=bool(vim.bindeval('invval')) +: else +: py3 invval=vim.bindeval('invval') +: endif +: if bool +: py3 oval1=bool(oval1) +: py3 oval2=bool(oval2) +: py3 oval3=bool(oval3) +: endif +: put ='>>> '.oname +: $put =' g/w/b:'.py3eval('oname in gset').'/'.py3eval('oname in wset').'/'.py3eval('oname in bset') +: $put =' g/w/b (in):'.py3eval('oname in gopts1').'/'.py3eval('oname in wopts1').'/'.py3eval('oname in bopts1') +: for v in ['gopts1', 'wopts1', 'bopts1'] +: try +: put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])') +: catch +: put =' p/'.v.'! '.v:exception +: endtry +: let r=E(v.'['''.oname.''']=invval') +: if r isnot 0 +: put =' inv: '.string(invval).'! '.r +: endif +: for vv in (v is# 'gopts1' ? [v] : [v, v[:-2].'2', v[:-2].'3']) +: let val=substitute(vv, '^.opts', 'oval', '') +: let r=E(vv.'['''.oname.''']='.val) +: if r isnot 0 +: put =' '.vv.'! '.r +: endif +: endfor +: endfor +: call RecVars(oname) +: for v in ['wopts3', 'bopts3'] +: let r=E('del '.v.'["'.oname.'"]') +: if r isnot 0 +: put =' del '.v.'! '.r +: endif +: endfor +: call RecVars(oname) +:endfor +:delfunction RecVars +:delfunction E +:delfunction Ev +:py3 del ev +:py3 del e +:only +:for buf in g:bufs[1:] +: execute 'bwipeout!' buf +:endfor +:py3 del gopts1 +:py3 del wopts1 +:py3 del wopts2 +:py3 del wopts3 +:py3 del bopts1 +:py3 del bopts2 +:py3 del bopts3 +:py3 del oval1 +:py3 del oval2 +:py3 del oval3 +:py3 del oname +:py3 del invval +:" +:" Test buffer object +:vnew +:put ='First line' +:put ='Second line' +:put ='Third line' +:1 delete _ +:py3 b=vim.current.buffer +:wincmd w +:mark a +:augroup BUFS +: autocmd BufFilePost * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePost:' + vim.eval('bufnr("%")')) +: autocmd BufFilePre * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")')) +:augroup END +py3 << EOF +cb = vim.current.buffer +# Tests BufferAppend and BufferItem +cb.append(b[0]) +# Tests BufferSlice and BufferAssSlice +cb.append('abc5') # Will be overwritten +cb[-1:] = b[:-2] +# Test BufferLength and BufferAssSlice +cb.append('def') # Will not be overwritten +cb[len(cb):] = b[:] +# Test BufferAssItem and BufferMark +cb.append('ghi') # Will be overwritten +cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1])) +# Test BufferRepr +cb.append(repr(cb) + repr(b)) +# Modify foreign buffer +b.append('foo') +b[0]='bar' +b[0:0]=['baz'] +vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number) +# Test assigning to name property +import os +old_name = cb.name +cb.name = 'foo' +cb.append(cb.name[-11:].replace(os.path.sep, '/')) +b.name = 'bar' +cb.append(b.name[-11:].replace(os.path.sep, '/')) +cb.name = old_name +cb.append(cb.name[-17:].replace(os.path.sep, '/')) +del old_name +# Test CheckBuffer +for _b in vim.buffers: + if _b is not cb: + vim.command('bwipeout! ' + str(_b.number)) +del _b +cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid))) +for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")'): + try: + exec(expr) + except vim.error: + pass + else: + # Usually a SEGV here + # Should not happen in any case + cb.append('No exception for ' + expr) +vim.command('cd .') +del b +EOF +:" +:" Test vim.buffers object +:set hidden +:edit a +:buffer # +:edit b +:buffer # +:edit c +:buffer # +py3 << EOF +# Check GCing iterator that was not fully exhausted +i = iter(vim.buffers) +cb.append('i:' + str(next(i))) +# and also check creating more then one iterator at a time +i2 = iter(vim.buffers) +cb.append('i2:' + str(next(i2))) +cb.append('i:' + str(next(i))) +# The following should trigger GC and not cause any problems +del i +del i2 +i3 = iter(vim.buffers) +cb.append('i3:' + str(next(i3))) +del i3 + +prevnum = 0 +for b in vim.buffers: + # Check buffer order + if prevnum >= b.number: + cb.append('!!! Buffer numbers not in strictly ascending order') + # Check indexing: vim.buffers[number].number == number + cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b)) + prevnum = b.number +del prevnum + +cb.append(str(len(vim.buffers))) + +bnums = list(map(lambda b: b.number, vim.buffers))[1:] + +# Test wiping out buffer with existing iterator +i4 = iter(vim.buffers) +cb.append('i4:' + str(next(i4))) +vim.command('bwipeout! ' + str(bnums.pop(0))) +try: + next(i4) +except vim.error: + pass +else: + cb.append('!!!! No vim.error') +i4 = iter(vim.buffers) +vim.command('bwipeout! ' + str(bnums.pop(-1))) +vim.command('bwipeout! ' + str(bnums.pop(-1))) +cb.append('i4:' + str(next(i4))) +try: + next(i4) +except StopIteration: + cb.append('StopIteration') +del i4 +del bnums +EOF +:" +:" Test vim.{tabpage,window}list and vim.{tabpage,window} objects +:tabnew 0 +:tabnew 1 +:vnew a.1 +:tabnew 2 +:vnew a.2 +:vnew b.2 +:vnew c.2 +py3 << EOF +cb.append('Number of tabs: ' + str(len(vim.tabpages))) +cb.append('Current tab pages:') + +def W(w): + if '(unknown)' in repr(w): + return '<window object (unknown)>' + else: + return repr(w) + +def Cursor(w, start=len(cb)): + if w.buffer is cb: + return repr((start - w.cursor[0], w.cursor[1])) + else: + return repr(w.cursor) + +for t in vim.tabpages: + cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window)) + cb.append(' Windows:') + for w in t.windows: + cb.append(' ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w)) + # Other values depend on the size of the terminal, so they are checked partly: + for attr in ('height', 'row', 'width', 'col'): + try: + aval = getattr(w, attr) + if type(aval) is not int: + raise TypeError + if aval < 0: + raise ValueError + except Exception as e: + cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + e.__class__.__name__) + del aval + del attr + w.cursor = (len(w.buffer), 0) +del W +del Cursor +cb.append('Number of windows in current tab page: ' + str(len(vim.windows))) +if list(vim.windows) != list(vim.current.tabpage.windows): + cb.append('!!!!!! Windows differ') +EOF +:" +:" Test vim.current +py3 << EOF +def H(o): + return repr(o) +cb.append('Current tab page: ' + repr(vim.current.tabpage)) +cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window)) +cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ ' is ' + H(vim.current.tabpage.window.buffer)) +del H +# Assigning: fails +try: + vim.current.window = vim.tabpages[0].window +except ValueError: + cb.append('ValueError at assigning foreign tab window') + +for attr in ('window', 'tabpage', 'buffer'): + try: + setattr(vim.current, attr, None) + except TypeError: + cb.append('Type error at assigning None to vim.current.' + attr) +del attr + +# Assigning: success +vim.current.tabpage = vim.tabpages[-2] +vim.current.buffer = cb +vim.current.window = vim.windows[0] +vim.current.window.cursor = (len(vim.current.buffer), 0) +cb.append('Current tab page: ' + repr(vim.current.tabpage)) +cb.append('Current window: ' + repr(vim.current.window)) +cb.append('Current buffer: ' + repr(vim.current.buffer)) +cb.append('Current line: ' + repr(vim.current.line)) +ws = list(vim.windows) +ts = list(vim.tabpages) +for b in vim.buffers: + if b is not cb: + vim.command('bwipeout! ' + str(b.number)) +del b +cb.append('w.valid: ' + repr([w.valid for w in ws])) +cb.append('t.valid: ' + repr([t.valid for t in ts])) +del w +del t +del ts +del ws +EOF +:tabonly! +:only! +:" +:" Test types +py3 << EOF +for expr, attr in ( + ('vim.vars', 'Dictionary'), + ('vim.options', 'Options'), + ('vim.bindeval("{}")', 'Dictionary'), + ('vim.bindeval("[]")', 'List'), + ('vim.bindeval("function(\'tr\')")', 'Function'), + ('vim.current.buffer', 'Buffer'), + ('vim.current.range', 'Range'), + ('vim.current.window', 'Window'), + ('vim.current.tabpage', 'TabPage'), +): + cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr))) +del expr +del attr +EOF +:" +:" Test __dir__() method +py3 << EOF +for name, o in ( + ('current', vim.current), + ('buffer', vim.current.buffer), + ('window', vim.current.window), + ('tabpage', vim.current.tabpage), + ('range', vim.current.range), + ('dictionary', vim.bindeval('{}')), + ('list', vim.bindeval('[]')), + ('function', vim.bindeval('function("tr")')), + ('output', sys.stdout), + ): + cb.append(name + ':' + ','.join(dir(o))) +del name +del o +EOF +:" +:" Test vim.*.__new__ +:$put =string(py3eval('vim.Dictionary({})')) +:$put =string(py3eval('vim.Dictionary(a=1)')) +:$put =string(py3eval('vim.Dictionary(((''a'', 1),))')) +:$put =string(py3eval('vim.List()')) +:$put =string(py3eval('vim.List(iter(''abc7''))')) +:$put =string(py3eval('vim.Function(''tr'')')) +:" +:" Test stdout/stderr +:redir => messages +:py3 sys.stdout.write('abc8') ; sys.stdout.write('def') +:py3 sys.stderr.write('abc9') ; sys.stderr.write('def') +:py3 sys.stdout.writelines(iter('abcA')) +:py3 sys.stderr.writelines(iter('abcB')) +:redir END +:$put =string(substitute(messages, '\d\+', '', 'g')) +:" Test subclassing +:fun Put(...) +: $put =string(a:000) +: return a:000 +:endfun +py3 << EOF +class DupDict(vim.Dictionary): + def __setitem__(self, key, value): + super(DupDict, self).__setitem__(key, value) + super(DupDict, self).__setitem__('dup_' + key, value) +dd = DupDict() +dd['a'] = 'b' + +class DupList(vim.List): + def __getitem__(self, idx): + return [super(DupList, self).__getitem__(idx)] * 2 + +dl = DupList() +dl2 = DupList(iter('abcC')) +dl.extend(dl2[0]) + +class DupFun(vim.Function): + def __call__(self, arg): + return super(DupFun, self).__call__(arg, arg) + +df = DupFun('Put') +EOF +:$put =string(sort(keys(py3eval('dd')))) +:$put =string(py3eval('dl')) +:$put =string(py3eval('dl2')) +:$put =string(py3eval('df(2)')) +:$put =string(py3eval('dl') is# py3eval('dl')) +:$put =string(py3eval('dd') is# py3eval('dd')) +:$put =string(py3eval('df')) +:delfunction Put +py3 << EOF +del DupDict +del DupList +del DupFun +del dd +del dl +del dl2 +del df +EOF +:" +:" Test chdir +py3 << EOF +import os +fnamemodify = vim.Function('fnamemodify') +cb.append(str(fnamemodify('.', ':p:h:t'))) +cb.append(vim.eval('@%')) +os.chdir('..') +cb.append(str(fnamemodify('.', ':p:h:t'))) +cb.append(vim.eval('@%').replace(os.path.sep, '/')) +os.chdir('testdir') +cb.append(str(fnamemodify('.', ':p:h:t'))) +cb.append(vim.eval('@%')) +del fnamemodify +EOF +:" +:" Test errors +:fun F() dict +:endfun +:fun D() +:endfun +py3 << EOF +d = vim.Dictionary() +ned = vim.Dictionary(foo='bar', baz='abcD') +dl = vim.Dictionary(a=1) +dl.locked = True +l = vim.List() +ll = vim.List('abcE') +ll.locked = True +nel = vim.List('abcO') +f = vim.Function('string') +fd = vim.Function('F') +fdel = vim.Function('D') +vim.command('delfunction D') + +def subexpr_test(expr, name, subexprs): + cb.append('>>> Testing %s using %s' % (name, expr)) + for subexpr in subexprs: + ee(expr % subexpr) + cb.append('<<< Finished') + +def stringtochars_test(expr): + return subexpr_test(expr, 'StringToChars', ( + '1', # Fail type checks + 'b"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check + '"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check + )) + +class Mapping(object): + def __init__(self, d): + self.d = d + + def __getitem__(self, key): + return self.d[key] + + def keys(self): + return self.d.keys() + + def items(self): + return self.d.items() + +def convertfrompyobject_test(expr, recurse=True): + # pydict_to_tv + stringtochars_test(expr % '{%s : 1}') + if recurse: + convertfrompyobject_test(expr % '{"abcF" : %s}', False) + # pymap_to_tv + stringtochars_test(expr % 'Mapping({%s : 1})') + if recurse: + convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False) + # pyseq_to_tv + iter_test(expr) + return subexpr_test(expr, 'ConvertFromPyObject', ( + 'None', # Not conversible + '{b"": 1}', # Empty key not allowed + '{"": 1}', # Same, but with unicode object + 'FailingMapping()', # + 'FailingMappingKey()', # + 'FailingNumber()', # + )) + +def convertfrompymapping_test(expr): + convertfrompyobject_test(expr) + return subexpr_test(expr, 'ConvertFromPyMapping', ( + '[]', + )) + +def iter_test(expr): + return subexpr_test(expr, '*Iter*', ( + 'FailingIter()', + 'FailingIterNext()', + )) + +def number_test(expr, natural=False, unsigned=False): + if natural: + unsigned = True + return subexpr_test(expr, 'NumberToLong', ( + '[]', + 'None', + ) + (('-1',) if unsigned else ()) + + (('0',) if natural else ())) + +class FailingTrue(object): + def __bool__(self): + raise NotImplementedError('bool') + +class FailingIter(object): + def __iter__(self): + raise NotImplementedError('iter') + +class FailingIterNext(object): + def __iter__(self): + return self + + def __next__(self): + raise NotImplementedError('next') + +class FailingIterNextN(object): + def __init__(self, n): + self.n = n + + def __iter__(self): + return self + + def __next__(self): + if self.n: + self.n -= 1 + return 1 + else: + raise NotImplementedError('next N') + +class FailingMappingKey(object): + def __getitem__(self, item): + raise NotImplementedError('getitem:mappingkey') + + def keys(self): + return list("abcH") + +class FailingMapping(object): + def __getitem__(self): + raise NotImplementedError('getitem:mapping') + + def keys(self): + raise NotImplementedError('keys') + +class FailingList(list): + def __getitem__(self, idx): + if i == 2: + raise NotImplementedError('getitem:list') + else: + return super(FailingList, self).__getitem__(idx) + +class NoArgsCall(object): + def __call__(self): + pass + +class FailingCall(object): + def __call__(self, path): + raise NotImplementedError('call') + +class FailingNumber(object): + def __int__(self): + raise NotImplementedError('int') + +cb.append("> Output") +cb.append(">> OutputSetattr") +ee('del sys.stdout.softspace') +number_test('sys.stdout.softspace = %s', unsigned=True) +number_test('sys.stderr.softspace = %s', unsigned=True) +ee('sys.stdout.attr = None') +cb.append(">> OutputWrite") +ee('sys.stdout.write(None)') +cb.append(">> OutputWriteLines") +ee('sys.stdout.writelines(None)') +ee('sys.stdout.writelines([1])') +iter_test('sys.stdout.writelines(%s)') +cb.append("> VimCommand") +stringtochars_test('vim.command(%s)') +ee('vim.command("", 2)') +#! Not checked: vim->python exceptions translating: checked later +cb.append("> VimToPython") +#! Not checked: everything: needs errors in internal python functions +cb.append("> VimEval") +stringtochars_test('vim.eval(%s)') +ee('vim.eval("", FailingTrue())') +#! Not checked: everything: needs errors in internal python functions +cb.append("> VimEvalPy") +stringtochars_test('vim.bindeval(%s)') +ee('vim.eval("", 2)') +#! Not checked: vim->python exceptions translating: checked later +cb.append("> VimStrwidth") +stringtochars_test('vim.strwidth(%s)') +cb.append("> VimForeachRTP") +ee('vim.foreach_rtp(None)') +ee('vim.foreach_rtp(NoArgsCall())') +ee('vim.foreach_rtp(FailingCall())') +ee('vim.foreach_rtp(int, 2)') +cb.append('> import') +old_rtp = vim.options['rtp'] +vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\') +ee('import xxx_no_such_module_xxx') +ee('import failing_import') +ee('import failing') +vim.options['rtp'] = old_rtp +del old_rtp +cb.append("> Options") +cb.append(">> OptionsItem") +ee('vim.options["abcQ"]') +ee('vim.options[""]') +stringtochars_test('vim.options[%s]') +cb.append(">> OptionsContains") +stringtochars_test('%s in vim.options') +cb.append("> Dictionary") +cb.append(">> DictionaryConstructor") +ee('vim.Dictionary("abcI")') +##! Not checked: py_dict_alloc failure +cb.append(">> DictionarySetattr") +ee('del d.locked') +ee('d.locked = FailingTrue()') +ee('vim.vvars.locked = False') +ee('d.scope = True') +ee('d.xxx = True') +cb.append(">> _DictionaryItem") +ee('d.get("a", 2, 3)') +stringtochars_test('d.get(%s)') +ee('d.pop("a")') +ee('dl.pop("a")') +cb.append(">> DictionaryContains") +ee('"" in d') +ee('0 in d') +cb.append(">> DictionaryIterNext") +ee('for i in ned: ned["a"] = 1') +del i +cb.append(">> DictionaryAssItem") +ee('dl["b"] = 1') +stringtochars_test('d[%s] = 1') +convertfrompyobject_test('d["a"] = %s') +cb.append(">> DictionaryUpdate") +cb.append(">>> kwargs") +cb.append(">>> iter") +ee('d.update(FailingMapping())') +ee('d.update([FailingIterNext()])') +ee('d.update([FailingIterNextN(1)])') +iter_test('d.update(%s)') +convertfrompyobject_test('d.update(%s)') +stringtochars_test('d.update(((%s, 0),))') +convertfrompyobject_test('d.update((("a", %s),))') +cb.append(">> DictionaryPopItem") +ee('d.popitem(1, 2)') +cb.append(">> DictionaryHasKey") +ee('d.has_key()') +cb.append("> List") +cb.append(">> ListConstructor") +ee('vim.List(1, 2)') +ee('vim.List(a=1)') +iter_test('vim.List(%s)') +convertfrompyobject_test('vim.List([%s])') +cb.append(">> ListItem") +ee('l[1000]') +cb.append(">> ListAssItem") +ee('ll[1] = 2') +ee('l[1000] = 3') +cb.append(">> ListAssSlice") +ee('ll[1:100] = "abcJ"') +iter_test('l[:] = %s') +ee('nel[1:10:2] = "abcK"') +cb.append(repr(tuple(nel))) +ee('nel[1:10:2] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[1:1:-1] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[:] = FailingIterNextN(2)') +cb.append(repr(tuple(nel))) +convertfrompyobject_test('l[:] = [%s]') +cb.append(">> ListConcatInPlace") +iter_test('l.extend(%s)') +convertfrompyobject_test('l.extend([%s])') +cb.append(">> ListSetattr") +ee('del l.locked') +ee('l.locked = FailingTrue()') +ee('l.xxx = True') +cb.append("> Function") +cb.append(">> FunctionConstructor") +ee('vim.Function("123")') +ee('vim.Function("xxx_non_existent_function_xxx")') +ee('vim.Function("xxx#non#existent#function#xxx")') +cb.append(">> FunctionCall") +convertfrompyobject_test('f(%s)') +convertfrompymapping_test('fd(self=%s)') +cb.append("> TabPage") +cb.append(">> TabPageAttr") +ee('vim.current.tabpage.xxx') +cb.append("> TabList") +cb.append(">> TabListItem") +ee('vim.tabpages[1000]') +cb.append("> Window") +cb.append(">> WindowAttr") +ee('vim.current.window.xxx') +cb.append(">> WindowSetattr") +ee('vim.current.window.buffer = 0') +ee('vim.current.window.cursor = (100000000, 100000000)') +ee('vim.current.window.cursor = True') +number_test('vim.current.window.height = %s', unsigned=True) +number_test('vim.current.window.width = %s', unsigned=True) +ee('vim.current.window.xxxxxx = True') +cb.append("> WinList") +cb.append(">> WinListItem") +ee('vim.windows[1000]') +cb.append("> Buffer") +cb.append(">> StringToLine (indirect)") +ee('vim.current.buffer[0] = "\\na"') +ee('vim.current.buffer[0] = b"\\na"') +cb.append(">> SetBufferLine (indirect)") +ee('vim.current.buffer[0] = True') +cb.append(">> SetBufferLineList (indirect)") +ee('vim.current.buffer[:] = True') +ee('vim.current.buffer[:] = ["\\na", "bc"]') +cb.append(">> InsertBufferLines (indirect)") +ee('vim.current.buffer.append(None)') +ee('vim.current.buffer.append(["\\na", "bc"])') +ee('vim.current.buffer.append("\\nbc")') +cb.append(">> RBItem") +ee('vim.current.buffer[100000000]') +cb.append(">> RBAsItem") +ee('vim.current.buffer[100000000] = ""') +cb.append(">> BufferAttr") +ee('vim.current.buffer.xxx') +cb.append(">> BufferSetattr") +ee('vim.current.buffer.name = True') +ee('vim.current.buffer.xxx = True') +cb.append(">> BufferMark") +ee('vim.current.buffer.mark(0)') +ee('vim.current.buffer.mark("abcM")') +ee('vim.current.buffer.mark("!")') +cb.append(">> BufferRange") +ee('vim.current.buffer.range(1, 2, 3)') +cb.append("> BufMap") +cb.append(">> BufMapItem") +ee('vim.buffers[100000000]') +number_test('vim.buffers[%s]', natural=True) +cb.append("> Current") +cb.append(">> CurrentGetattr") +ee('vim.current.xxx') +cb.append(">> CurrentSetattr") +ee('vim.current.line = True') +ee('vim.current.buffer = True') +ee('vim.current.window = True') +ee('vim.current.tabpage = True') +ee('vim.current.xxx = True') +del d +del ned +del dl +del l +del ll +del nel +del f +del fd +del fdel +del subexpr_test +del stringtochars_test +del Mapping +del convertfrompyobject_test +del convertfrompymapping_test +del iter_test +del number_test +del FailingTrue +del FailingIter +del FailingIterNext +del FailingIterNextN +del FailingMapping +del FailingMappingKey +del FailingList +del NoArgsCall +del FailingCall +del FailingNumber +EOF +:delfunction F +:" +:" Test import +py3 << EOF +sys.path.insert(0, os.path.join(os.getcwd(), 'python_before')) +sys.path.append(os.path.join(os.getcwd(), 'python_after')) +vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\') +l = [] +def callback(path): + l.append(os.path.relpath(path)) +vim.foreach_rtp(callback) +cb.append(repr(l)) +del l +def callback(path): + return os.path.relpath(path) +cb.append(repr(vim.foreach_rtp(callback))) +del callback +from module import dir as d +from modulex import ddir +cb.append(d + ',' + ddir) +import before +cb.append(before.dir) +import after +cb.append(after.dir) +import topmodule as tm +import topmodule.submodule as tms +import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss +cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):]) +cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):]) +cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):]) +del before +del after +del d +del ddir +del tm +del tms +del tmsss +EOF +:" +:" Test exceptions +:fun Exe(e) +: execute a:e +:endfun +py3 << EOF +Exe = vim.bindeval('function("Exe")') +ee('vim.command("throw \'abcN\'")') +ee('Exe("throw \'def\'")') +ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")') +ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")') +ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")') +ee('vim.eval("xxx_unknown_function_xxx()")') +ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")') +del Exe +EOF +:delfunction Exe +:" +:" Regression: interrupting vim.command propagates to next vim.command +py3 << EOF +def test_keyboard_interrupt(): + try: + vim.command('while 1 | endwhile') + except KeyboardInterrupt: + cb.append('Caught KeyboardInterrupt') + except Exception as e: + cb.append('!!!!!!!! Caught exception: ' + repr(e)) + else: + cb.append('!!!!!!!! No exception') + try: + vim.command('$ put =\'Running :put\'') + except KeyboardInterrupt: + cb.append('!!!!!!!! Caught KeyboardInterrupt') + except Exception as e: + cb.append('!!!!!!!! Caught exception: ' + repr(e)) + else: + cb.append('No exception') +EOF +:debuggreedy +:call inputsave() +:call feedkeys("s\ns\ns\ns\nq\n") +:redir => output +:debug silent! py3 test_keyboard_interrupt() +:redir END +:0 debuggreedy +:silent $put =output +:unlet output +:py3 del test_keyboard_interrupt +:" +:" Cleanup +py3 << EOF +del cb +del ee +del sys +del os +del vim +EOF +:endfun +:" +:fun RunTest() +:let checkrefs = !empty($PYTHONDUMPREFS) +:let start = getline(1, '$') +:for i in range(checkrefs ? 10 : 1) +: if i != 0 +: %d _ +: call setline(1, start) +: endif +: call Test() +: if i == 0 +: let result = getline(1, '$') +: endif +:endfor +:if checkrefs +: %d _ +: call setline(1, result) +:endif +:endfun +:" +:call RunTest() +:delfunction RunTest +:delfunction Test +:call garbagecollect(1) +:" +:/^start:/,$wq! test.out +:" vim: et ts=4 isk-=\: +:call getchar() +ENDTEST + +start: diff --git a/src/nvim/testdir/test87.ok b/src/nvim/testdir/test87.ok new file mode 100644 index 0000000000..d1ec84c6b8 --- /dev/null +++ b/src/nvim/testdir/test87.ok @@ -0,0 +1,1266 @@ +start: +[1, 'as''d', [1, 2, function('strlen'), {'a': 1}]] +[1, 2, function('strlen'), {'a': 1}] +Vim(put):E684: +[0, 'as''d', [1, 2, function('strlen'), {'a': 1}]] +[0, function('strlen'), [1, 2, function('strlen'), {'a': 1}]] +1 +[b'-1', b'0', b'1', b'b', b'f'] +[-1, <vim.Function '1'>, <vim.dictionary object at >, <vim.list object at >, b'asd'] +[(b'-1', <vim.dictionary object at >), (b'0', -1), (b'1', b'asd'), (b'b', <vim.list object at >), (b'f', <vim.Function '1'>)] +'-1' : {'a': 1} +'0' : -1 +'1' : 'asd' +'b' : [1, 2, function('strlen')] +'f' : function('1') +[0, function('strlen')] +[3] +[1, 2, function('strlen')] +[1, 2, function('strlen')] +1 +'asd' +2 +True +False +True +False +[b'0'] +{'0': -1} +(b'0', -1) +None +[] +[0, 1, 2, 3] +[0, 1, 2, 3] +[0, 1, 3] +[0, 1] +[0, 1] +[0, 1] +[0, 1, 2, 3] +[0, 1, 2, 3] +[0, 2, 3] +[2, 3] +[2, 3] +[2, 3] +[1, 3] +[0, 2] +[0, 1, 2, 3] +['a', 0, 1, 2, 3] +[0, 'b', 2, 3] +[0, 1, 'c'] +[0, 1, 2, 3, 'd'] +[0, 1, 2, 'e', 3] +['f', 2, 3] +[0, 1, 'g', 2, 3] +['h'] +[0, 1, 10, 3, 20, 5, 6, 7] +[0, 1, 2, 3, 20, 5, 10, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3] +[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'] +[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}] +[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New'] +l[1](1, 2, 3):(<class 'vim.error'>, error('Vim:E725: Calling dict function without Dictionary: DictNew',)) +f(1, 2, 3):(<class 'vim.error'>, error('Vim:E117: Unknown function: New',)) +[0.0, 0.0] +KeyError +TypeError +TypeError +ValueError +TypeError +TypeError +KeyError +KeyError +d : locked:0;scope:0 +dl : locked:1;scope:0 +v: : locked:2;scope:1 +g: : locked:0;scope:2 +d:{'abc2': 1} +dl:{'def': 1} +l : locked:0 +ll : locked:1 +l:[0] +ll:[1] +[0, 1, 2] +['a', 'b'] +['c', 1] +['d', ['e']] +0.0 +"\0": Vim(let):E859: +{"\0": 1}: Vim(let):E859: +undefined_name: Vim(let):Trace +vim: Vim(let):E859: +[1] +[1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1] +[0, 1, 2, 3] +[2, 3, 4, 5] +[0, 1] +[4, 5] +[2, 3] +[] +[2, 3] +[] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5] +[4, 3] +[0, 2, 4] +[] +Abc +bac +def +bar +jkl +wopts iters equal: 1 +bopts iters equal: 1 +>>> paste + g/w/b:1/0/0 + g/w/b (in):1/0/0 + p/gopts1: False + p/wopts1! KeyError + inv: 2! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1! KeyError + inv: 2! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: 1 + W: 1:1 2:1 3:1 4:1 + B: 1:1 2:1 3:1 4:1 + del wopts3! KeyError + del bopts3! KeyError + G: 1 + W: 1:1 2:1 3:1 4:1 + B: 1:1 2:1 3:1 4:1 +>>> previewheight + g/w/b:1/0/0 + g/w/b (in):1/0/0 + p/gopts1: 12 + inv: 'a'! TypeError + p/wopts1! KeyError + inv: 'a'! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1! KeyError + inv: 'a'! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: 5 + W: 1:5 2:5 3:5 4:5 + B: 1:5 2:5 3:5 4:5 + del wopts3! KeyError + del bopts3! KeyError + G: 5 + W: 1:5 2:5 3:5 4:5 + B: 1:5 2:5 3:5 4:5 +>>> operatorfunc + g/w/b:1/0/0 + g/w/b (in):1/0/0 + p/gopts1: b'' + inv: 2! TypeError + p/wopts1! KeyError + inv: 2! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1! KeyError + inv: 2! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: 'A' + W: 1:'A' 2:'A' 3:'A' 4:'A' + B: 1:'A' 2:'A' 3:'A' 4:'A' + del wopts3! KeyError + del bopts3! KeyError + G: 'A' + W: 1:'A' 2:'A' 3:'A' 4:'A' + B: 1:'A' 2:'A' 3:'A' 4:'A' +>>> number + g/w/b:0/1/0 + g/w/b (in):0/1/0 + p/gopts1! KeyError + inv: 0! KeyError + gopts1! KeyError + p/wopts1: False + p/bopts1! KeyError + inv: 0! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: 0 + W: 1:1 2:1 3:0 4:0 + B: 1:1 2:1 3:0 4:0 + del wopts3! ValueError + del bopts3! KeyError + G: 0 + W: 1:1 2:1 3:0 4:0 + B: 1:1 2:1 3:0 4:0 +>>> numberwidth + g/w/b:0/1/0 + g/w/b (in):0/1/0 + p/gopts1! KeyError + inv: -100! KeyError + gopts1! KeyError + p/wopts1: 8 + inv: -100! error + p/bopts1! KeyError + inv: -100! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: 8 + W: 1:3 2:5 3:2 4:8 + B: 1:3 2:5 3:2 4:8 + del wopts3! ValueError + del bopts3! KeyError + G: 8 + W: 1:3 2:5 3:2 4:8 + B: 1:3 2:5 3:2 4:8 +>>> colorcolumn + g/w/b:0/1/0 + g/w/b (in):0/1/0 + p/gopts1! KeyError + inv: 'abc4'! KeyError + gopts1! KeyError + p/wopts1: b'' + inv: 'abc4'! error + p/bopts1! KeyError + inv: 'abc4'! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: '' + W: 1:'+2' 2:'+3' 3:'+1' 4:'' + B: 1:'+2' 2:'+3' 3:'+1' 4:'' + del wopts3! ValueError + del bopts3! KeyError + G: '' + W: 1:'+2' 2:'+3' 3:'+1' 4:'' + B: 1:'+2' 2:'+3' 3:'+1' 4:'' +>>> statusline + g/w/b:1/1/0 + g/w/b (in):1/1/0 + p/gopts1: b'' + inv: 0! TypeError + p/wopts1: None + inv: 0! TypeError + p/bopts1! KeyError + inv: 0! KeyError + bopts1! KeyError + bopts2! KeyError + bopts3! KeyError + G: '1' + W: 1:'2' 2:'4' 3:'1' 4:'1' + B: 1:'2' 2:'4' 3:'1' 4:'1' + del bopts3! KeyError + G: '1' + W: 1:'2' 2:'1' 3:'1' 4:'1' + B: 1:'2' 2:'1' 3:'1' 4:'1' +>>> autoindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 + p/gopts1! KeyError + inv: 2! KeyError + gopts1! KeyError + p/wopts1! KeyError + inv: 2! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1: False + G: 0 + W: 1:0 2:1 3:0 4:1 + B: 1:0 2:1 3:0 4:1 + del wopts3! KeyError + del bopts3! ValueError + G: 0 + W: 1:0 2:1 3:0 4:1 + B: 1:0 2:1 3:0 4:1 +>>> shiftwidth + g/w/b:0/0/1 + g/w/b (in):0/0/1 + p/gopts1! KeyError + inv: 3! KeyError + gopts1! KeyError + p/wopts1! KeyError + inv: 3! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1: 8 + G: 8 + W: 1:0 2:2 3:8 4:1 + B: 1:0 2:2 3:8 4:1 + del wopts3! KeyError + del bopts3! ValueError + G: 8 + W: 1:0 2:2 3:8 4:1 + B: 1:0 2:2 3:8 4:1 +>>> omnifunc + g/w/b:0/0/1 + g/w/b (in):0/0/1 + p/gopts1! KeyError + inv: 1! KeyError + gopts1! KeyError + p/wopts1! KeyError + inv: 1! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1: b'' + inv: 1! TypeError + G: '' + W: 1:'A' 2:'B' 3:'' 4:'C' + B: 1:'A' 2:'B' 3:'' 4:'C' + del wopts3! KeyError + del bopts3! ValueError + G: '' + W: 1:'A' 2:'B' 3:'' 4:'C' + B: 1:'A' 2:'B' 3:'' 4:'C' +>>> preserveindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 + p/gopts1! KeyError + inv: 2! KeyError + gopts1! KeyError + p/wopts1! KeyError + inv: 2! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1: False + G: 0 + W: 1:0 2:1 3:0 4:1 + B: 1:0 2:1 3:0 4:1 + del wopts3! KeyError + del bopts3! ValueError + G: 0 + W: 1:0 2:1 3:0 4:1 + B: 1:0 2:1 3:0 4:1 +>>> path + g/w/b:1/0/1 + g/w/b (in):1/0/1 + p/gopts1: b'.,..,,' + inv: 0! TypeError + p/wopts1! KeyError + inv: 0! KeyError + wopts1! KeyError + wopts2! KeyError + wopts3! KeyError + p/bopts1: None + inv: 0! TypeError + G: '.,,' + W: 1:'.,,' 2:',,' 3:'.,,' 4:'.' + B: 1:'.,,' 2:',,' 3:'.,,' 4:'.' + del wopts3! KeyError + G: '.,,' + W: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,' + B: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,' +First line +First line +def +First line +Second line +Third line +(7, 2) +<buffer test87.in><buffer > +baz +bar +Second line +Third line +foo +1:BufFilePre:1 +1:BufFilePost:1 +testdir/foo +5:BufFilePre:5 +5:BufFilePost:5 +testdir/bar +1:BufFilePre:1 +1:BufFilePost:1 +testdir/test87.in +valid: b:False, cb:True +i:<buffer test87.in> +i2:<buffer test87.in> +i:<buffer a> +i3:<buffer test87.in> +1:<buffer test87.in>=<buffer test87.in> +8:<buffer a>=<buffer a> +9:<buffer b>=<buffer b> +10:<buffer c>=<buffer c> +4 +i4:<buffer test87.in> +i4:<buffer test87.in> +StopIteration +Number of tabs: 4 +Current tab pages: + <tabpage 0>(1): 1 windows, current is <window object (unknown)> + Windows: + <window object (unknown)>(1): displays buffer <buffer test87.in>; cursor is at (37, 0) + <tabpage 1>(2): 1 windows, current is <window object (unknown)> + Windows: + <window object (unknown)>(1): displays buffer <buffer 0>; cursor is at (1, 0) + <tabpage 2>(3): 2 windows, current is <window object (unknown)> + Windows: + <window object (unknown)>(1): displays buffer <buffer a.1>; cursor is at (1, 0) + <window object (unknown)>(2): displays buffer <buffer 1>; cursor is at (1, 0) + <tabpage 3>(4): 4 windows, current is <window 0> + Windows: + <window 0>(1): displays buffer <buffer c.2>; cursor is at (1, 0) + <window 1>(2): displays buffer <buffer b.2>; cursor is at (1, 0) + <window 2>(3): displays buffer <buffer a.2>; cursor is at (1, 0) + <window 3>(4): displays buffer <buffer 2>; cursor is at (1, 0) +Number of windows in current tab page: 4 +Current tab page: <tabpage 3> +Current window: <window 0>: <window 0> is <window 0> +Current buffer: <buffer c.2>: <buffer c.2> is <buffer c.2> is <buffer c.2> +ValueError at assigning foreign tab window +Type error at assigning None to vim.current.window +Type error at assigning None to vim.current.tabpage +Type error at assigning None to vim.current.buffer +Current tab page: <tabpage 2> +Current window: <window 0> +Current buffer: <buffer test87.in> +Current line: 'Type error at assigning None to vim.current.buffer' +w.valid: [True, False] +t.valid: [True, False, True, False] +vim.vars:Dictionary:True +vim.options:Options:True +vim.bindeval("{}"):Dictionary:True +vim.bindeval("[]"):List:True +vim.bindeval("function('tr')"):Function:True +vim.current.buffer:Buffer:True +vim.current.range:Range:True +vim.current.window:Window:True +vim.current.tabpage:TabPage:True +current:__dir__,buffer,line,range,tabpage,window +buffer:__dir__,append,mark,name,number,options,range,valid,vars +window:__dir__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars +tabpage:__dir__,number,valid,vars,window,windows +range:__dir__,append,end,start +dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values +list:__dir__,extend,locked +function:__dir__,softspace +output:__dir__,flush,softspace,write,writelines +{} +{'a': 1} +{'a': 1} +[] +['a', 'b', 'c', '7'] +function('tr') +' +abcdef +line : +abcdef +abcA +line : +abcB' +['a', 'dup_a'] +['a', 'a'] +['a', 'b', 'c', 'C'] +[2, 2] +[2, 2] +1 +1 +function('Put') +b'testdir' +test87.in +b'src' +testdir/test87.in +b'testdir' +test87.in +> Output +>> OutputSetattr +del sys.stdout.softspace:(<class 'AttributeError'>, AttributeError("can't delete OutputObject attributes",)) +>>> Testing NumberToLong using sys.stdout.softspace = %s +sys.stdout.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',)) +sys.stdout.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',)) +sys.stdout.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',)) +<<< Finished +>>> Testing NumberToLong using sys.stderr.softspace = %s +sys.stderr.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',)) +sys.stderr.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',)) +sys.stderr.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',)) +<<< Finished +sys.stdout.attr = None:(<class 'AttributeError'>, AttributeError('invalid attribute: attr',)) +>> OutputWrite +sys.stdout.write(None):(<class 'TypeError'>, TypeError("Can't convert 'NoneType' object to str implicitly",)) +>> OutputWriteLines +sys.stdout.writelines(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",)) +sys.stdout.writelines([1]):(<class 'TypeError'>, TypeError("Can't convert 'int' object to str implicitly",)) +>>> Testing *Iter* using sys.stdout.writelines(%s) +sys.stdout.writelines(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',)) +sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +> VimCommand +>>> Testing StringToChars using vim.command(%s) +vim.command(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.command(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +vim.command("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +vim.command("", 2):(<class 'TypeError'>, TypeError('command() takes exactly one argument (2 given)',)) +> VimToPython +> VimEval +>>> Testing StringToChars using vim.eval(%s) +vim.eval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.eval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +vim.eval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +vim.eval("", FailingTrue()):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',)) +> VimEvalPy +>>> Testing StringToChars using vim.bindeval(%s) +vim.bindeval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.bindeval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +vim.bindeval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +vim.eval("", 2):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',)) +> VimStrwidth +>>> Testing StringToChars using vim.strwidth(%s) +vim.strwidth(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.strwidth(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +vim.strwidth("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +> VimForeachRTP +vim.foreach_rtp(None):(<class 'TypeError'>, TypeError("'NoneType' object is not callable",)) +vim.foreach_rtp(NoArgsCall()):(<class 'TypeError'>, TypeError('__call__() takes exactly 1 positional argument (2 given)',)) +vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedError('call',)) +vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',)) +> import +import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',)) +import failing_import:(<class 'ImportError'>, ImportError('No module named failing_import',)) +import failing:(<class 'NotImplementedError'>, NotImplementedError()) +> Options +>> OptionsItem +vim.options["abcQ"]:(<class 'KeyError'>, KeyError('abcQ',)) +vim.options[""]:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +>>> Testing StringToChars using vim.options[%s] +vim.options[1]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.options[b"\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +vim.options["\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>> OptionsContains +>>> Testing StringToChars using %s in vim.options +1 in vim.options:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +b"\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +"\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +> Dictionary +>> DictionaryConstructor +vim.Dictionary("abcI"):(<class 'ValueError'>, ValueError('expected sequence element of size 2, but got sequence of size 1',)) +>> DictionarySetattr +del d.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.Dictionary attributes',)) +d.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',)) +vim.vvars.locked = False:(<class 'TypeError'>, TypeError('cannot modify fixed dictionary',)) +d.scope = True:(<class 'AttributeError'>, AttributeError('cannot set attribute scope',)) +d.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',)) +>> _DictionaryItem +d.get("a", 2, 3):(<class 'TypeError'>, TypeError('function takes at most 2 arguments (3 given)',)) +>>> Testing StringToChars using d.get(%s) +d.get(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.get(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.get("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +d.pop("a"):(<class 'KeyError'>, KeyError('a',)) +dl.pop("a"):(<class 'vim.error'>, error('dictionary is locked',)) +>> DictionaryContains +"" in d:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +0 in d:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +>> DictionaryIterNext +for i in ned: ned["a"] = 1:(<class 'RuntimeError'>, RuntimeError('hashtab changed during iteration',)) +>> DictionaryAssItem +dl["b"] = 1:(<class 'vim.error'>, error('dictionary is locked',)) +>>> Testing StringToChars using d[%s] = 1 +d[1] = 1:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d[b"\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d["\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d["a"] = {%s : 1} +d["a"] = {1 : 1}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d["a"] = {b"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d["a"] = {"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d["a"] = {"abcF" : {%s : 1}} +d["a"] = {"abcF" : {1 : 1}}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d["a"] = {"abcF" : {b"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d["a"] = {"abcF" : {"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d["a"] = {"abcF" : Mapping({%s : 1})} +d["a"] = {"abcF" : Mapping({1 : 1})}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d["a"] = {"abcF" : Mapping({b"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d["a"] = {"abcF" : Mapping({"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using d["a"] = {"abcF" : %s} +d["a"] = {"abcF" : FailingIter()}:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +d["a"] = {"abcF" : FailingIterNext()}:(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s} +d["a"] = {"abcF" : None}:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +d["a"] = {"abcF" : {b"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d["a"] = {"abcF" : {"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d["a"] = {"abcF" : FailingMapping()}:(<class 'NotImplementedError'>, NotImplementedError('keys',)) +d["a"] = {"abcF" : FailingMappingKey()}:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +d["a"] = {"abcF" : FailingNumber()}:(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing StringToChars using d["a"] = Mapping({%s : 1}) +d["a"] = Mapping({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d["a"] = Mapping({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d["a"] = Mapping({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d["a"] = Mapping({"abcG" : {%s : 1}}) +d["a"] = Mapping({"abcG" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d["a"] = Mapping({"abcG" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d["a"] = Mapping({"abcG" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d["a"] = Mapping({"abcG" : Mapping({%s : 1})}) +d["a"] = Mapping({"abcG" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d["a"] = Mapping({"abcG" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d["a"] = Mapping({"abcG" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s}) +d["a"] = Mapping({"abcG" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +d["a"] = Mapping({"abcG" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s}) +d["a"] = Mapping({"abcG" : None}):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +d["a"] = Mapping({"abcG" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d["a"] = Mapping({"abcG" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d["a"] = Mapping({"abcG" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +d["a"] = Mapping({"abcG" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +d["a"] = Mapping({"abcG" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing *Iter* using d["a"] = %s +d["a"] = FailingIter():(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +d["a"] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using d["a"] = %s +d["a"] = None:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +d["a"] = {b"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d["a"] = {"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d["a"] = FailingMapping():(<class 'NotImplementedError'>, NotImplementedError('keys',)) +d["a"] = FailingMappingKey():(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +d["a"] = FailingNumber():(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>> DictionaryUpdate +>>> kwargs +>>> iter +d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +d.update([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',)) +d.update([FailingIterNextN(1)]):(<class 'NotImplementedError'>, NotImplementedError('next N',)) +>>> Testing *Iter* using d.update(%s) +d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',)) +d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing StringToChars using d.update({%s : 1}) +d.update({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d.update({"abcF" : {%s : 1}}) +d.update({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d.update({"abcF" : Mapping({%s : 1})}) +d.update({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using d.update({"abcF" : %s}) +d.update({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +d.update({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using d.update({"abcF" : %s}) +d.update({"abcF" : None}):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +d.update({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +d.update({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +d.update({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing StringToChars using d.update(Mapping({%s : 1})) +d.update(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d.update(Mapping({"abcG" : {%s : 1}})) +d.update(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d.update(Mapping({"abcG" : Mapping({%s : 1})})) +d.update(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using d.update(Mapping({"abcG" : %s})) +d.update(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +d.update(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s})) +d.update(Mapping({"abcG" : None})):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +d.update(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +d.update(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +d.update(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing *Iter* using d.update(%s) +d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',)) +d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using d.update(%s) +d.update(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",)) +d.update({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +d.update(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +d.update(FailingNumber()):(<class 'TypeError'>, TypeError("'FailingNumber' object is not iterable",)) +<<< Finished +>>> Testing StringToChars using d.update(((%s, 0),)) +d.update(((1, 0),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update(((b"\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update((("\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d.update((("a", {%s : 1}),)) +d.update((("a", {1 : 1}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update((("a", {b"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update((("a", {"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d.update((("a", {"abcF" : {%s : 1}}),)) +d.update((("a", {"abcF" : {1 : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update((("a", {"abcF" : {b"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update((("a", {"abcF" : {"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d.update((("a", {"abcF" : Mapping({%s : 1})}),)) +d.update((("a", {"abcF" : Mapping({1 : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update((("a", {"abcF" : Mapping({b"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update((("a", {"abcF" : Mapping({"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using d.update((("a", {"abcF" : %s}),)) +d.update((("a", {"abcF" : FailingIter()}),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +d.update((("a", {"abcF" : FailingIterNext()}),)):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),)) +d.update((("a", {"abcF" : None}),)):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +d.update((("a", {"abcF" : {b"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update((("a", {"abcF" : {"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update((("a", {"abcF" : FailingMapping()}),)):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +d.update((("a", {"abcF" : FailingMappingKey()}),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +d.update((("a", {"abcF" : FailingNumber()}),)):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),)) +d.update((("a", Mapping({1 : 1})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update((("a", Mapping({b"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update((("a", Mapping({"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d.update((("a", Mapping({"abcG" : {%s : 1}})),)) +d.update((("a", Mapping({"abcG" : {1 : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update((("a", Mapping({"abcG" : {b"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update((("a", Mapping({"abcG" : {"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using d.update((("a", Mapping({"abcG" : Mapping({%s : 1})})),)) +d.update((("a", Mapping({"abcG" : Mapping({1 : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +d.update((("a", Mapping({"abcG" : Mapping({b"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +d.update((("a", Mapping({"abcG" : Mapping({"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using d.update((("a", Mapping({"abcG" : %s})),)) +d.update((("a", Mapping({"abcG" : FailingIter()})),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abcG" : %s})),)) +d.update((("a", Mapping({"abcG" : None})),)):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +d.update((("a", Mapping({"abcG" : {b"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update((("a", Mapping({"abcG" : {"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update((("a", Mapping({"abcG" : FailingMapping()})),)):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +d.update((("a", Mapping({"abcG" : FailingNumber()})),)):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing *Iter* using d.update((("a", %s),)) +d.update((("a", FailingIter()),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +d.update((("a", FailingIterNext()),)):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using d.update((("a", %s),)) +d.update((("a", None),)):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +d.update((("a", {b"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update((("a", {"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +d.update((("a", FailingMapping()),)):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +d.update((("a", FailingMappingKey()),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +d.update((("a", FailingNumber()),)):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>> DictionaryPopItem +d.popitem(1, 2):(<class 'TypeError'>, TypeError('popitem() takes no arguments (2 given)',)) +>> DictionaryHasKey +d.has_key():(<class 'TypeError'>, TypeError('has_key() takes exactly one argument (0 given)',)) +> List +>> ListConstructor +vim.List(1, 2):(<class 'TypeError'>, TypeError('function takes at most 1 argument (2 given)',)) +vim.List(a=1):(<class 'TypeError'>, TypeError('list constructor does not accept keyword arguments',)) +>>> Testing *Iter* using vim.List(%s) +vim.List(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',)) +vim.List(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing StringToChars using vim.List([{%s : 1}]) +vim.List([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.List([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +vim.List([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using vim.List([{"abcF" : {%s : 1}}]) +vim.List([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.List([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +vim.List([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using vim.List([{"abcF" : Mapping({%s : 1})}]) +vim.List([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.List([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +vim.List([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using vim.List([{"abcF" : %s}]) +vim.List([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +vim.List([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using vim.List([{"abcF" : %s}]) +vim.List([{"abcF" : None}]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +vim.List([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +vim.List([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +vim.List([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +vim.List([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +vim.List([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing StringToChars using vim.List([Mapping({%s : 1})]) +vim.List([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.List([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +vim.List([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using vim.List([Mapping({"abcG" : {%s : 1}})]) +vim.List([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.List([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +vim.List([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using vim.List([Mapping({"abcG" : Mapping({%s : 1})})]) +vim.List([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.List([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +vim.List([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using vim.List([Mapping({"abcG" : %s})]) +vim.List([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +vim.List([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using vim.List([Mapping({"abcG" : %s})]) +vim.List([Mapping({"abcG" : None})]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +vim.List([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +vim.List([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +vim.List([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +vim.List([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +vim.List([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing *Iter* using vim.List([%s]) +vim.List([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +vim.List([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using vim.List([%s]) +vim.List([None]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +vim.List([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +vim.List([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +vim.List([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +vim.List([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +vim.List([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>> ListItem +l[1000]:(<class 'IndexError'>, IndexError('list index out of range',)) +>> ListAssItem +ll[1] = 2:(<class 'vim.error'>, error('list is locked',)) +l[1000] = 3:(<class 'IndexError'>, IndexError('list index out of range',)) +>> ListAssSlice +ll[1:100] = "abcJ":(<class 'vim.error'>, error('list is locked',)) +>>> Testing *Iter* using l[:] = %s +l[:] = FailingIter():(<class 'NotImplementedError'>, NotImplementedError('iter',)) +l[:] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +nel[1:10:2] = "abcK":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater then 2 to extended slice',)) +(b'a', b'b', b'c', b'O') +nel[1:10:2] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size 1 to extended slice of size 2',)) +(b'a', b'b', b'c', b'O') +nel[1:1:-1] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater then 0 to extended slice',)) +(b'a', b'b', b'c', b'O') +nel[:] = FailingIterNextN(2):(<class 'NotImplementedError'>, NotImplementedError('next N',)) +(b'a', b'b', b'c', b'O') +>>> Testing StringToChars using l[:] = [{%s : 1}] +l[:] = [{1 : 1}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l[:] = [{b"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l[:] = [{"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using l[:] = [{"abcF" : {%s : 1}}] +l[:] = [{"abcF" : {1 : 1}}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l[:] = [{"abcF" : {b"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l[:] = [{"abcF" : {"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using l[:] = [{"abcF" : Mapping({%s : 1})}] +l[:] = [{"abcF" : Mapping({1 : 1})}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l[:] = [{"abcF" : Mapping({b"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l[:] = [{"abcF" : Mapping({"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using l[:] = [{"abcF" : %s}] +l[:] = [{"abcF" : FailingIter()}]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +l[:] = [{"abcF" : FailingIterNext()}]:(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using l[:] = [{"abcF" : %s}] +l[:] = [{"abcF" : None}]:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +l[:] = [{"abcF" : {b"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l[:] = [{"abcF" : {"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l[:] = [{"abcF" : FailingMapping()}]:(<class 'NotImplementedError'>, NotImplementedError('keys',)) +l[:] = [{"abcF" : FailingMappingKey()}]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +l[:] = [{"abcF" : FailingNumber()}]:(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing StringToChars using l[:] = [Mapping({%s : 1})] +l[:] = [Mapping({1 : 1})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l[:] = [Mapping({b"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l[:] = [Mapping({"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using l[:] = [Mapping({"abcG" : {%s : 1}})] +l[:] = [Mapping({"abcG" : {1 : 1}})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l[:] = [Mapping({"abcG" : {b"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l[:] = [Mapping({"abcG" : {"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using l[:] = [Mapping({"abcG" : Mapping({%s : 1})})] +l[:] = [Mapping({"abcG" : Mapping({1 : 1})})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l[:] = [Mapping({"abcG" : Mapping({b"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l[:] = [Mapping({"abcG" : Mapping({"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})] +l[:] = [Mapping({"abcG" : FailingIter()})]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +l[:] = [Mapping({"abcG" : FailingIterNext()})]:(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using l[:] = [Mapping({"abcG" : %s})] +l[:] = [Mapping({"abcG" : None})]:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +l[:] = [Mapping({"abcG" : {b"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l[:] = [Mapping({"abcG" : {"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l[:] = [Mapping({"abcG" : FailingMapping()})]:(<class 'NotImplementedError'>, NotImplementedError('keys',)) +l[:] = [Mapping({"abcG" : FailingMappingKey()})]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +l[:] = [Mapping({"abcG" : FailingNumber()})]:(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing *Iter* using l[:] = [%s] +l[:] = [FailingIter()]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +l[:] = [FailingIterNext()]:(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using l[:] = [%s] +l[:] = [None]:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +l[:] = [{b"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l[:] = [{"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l[:] = [FailingMapping()]:(<class 'NotImplementedError'>, NotImplementedError('keys',)) +l[:] = [FailingMappingKey()]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +l[:] = [FailingNumber()]:(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>> ListConcatInPlace +>>> Testing *Iter* using l.extend(%s) +l.extend(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',)) +l.extend(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing StringToChars using l.extend([{%s : 1}]) +l.extend([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l.extend([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l.extend([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using l.extend([{"abcF" : {%s : 1}}]) +l.extend([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l.extend([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l.extend([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using l.extend([{"abcF" : Mapping({%s : 1})}]) +l.extend([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l.extend([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l.extend([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using l.extend([{"abcF" : %s}]) +l.extend([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +l.extend([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using l.extend([{"abcF" : %s}]) +l.extend([{"abcF" : None}]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +l.extend([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l.extend([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l.extend([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +l.extend([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +l.extend([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing StringToChars using l.extend([Mapping({%s : 1})]) +l.extend([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l.extend([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l.extend([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using l.extend([Mapping({"abcG" : {%s : 1}})]) +l.extend([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l.extend([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l.extend([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using l.extend([Mapping({"abcG" : Mapping({%s : 1})})]) +l.extend([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +l.extend([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +l.extend([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using l.extend([Mapping({"abcG" : %s})]) +l.extend([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +l.extend([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using l.extend([Mapping({"abcG" : %s})]) +l.extend([Mapping({"abcG" : None})]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +l.extend([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l.extend([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l.extend([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +l.extend([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +l.extend([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing *Iter* using l.extend([%s]) +l.extend([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +l.extend([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using l.extend([%s]) +l.extend([None]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +l.extend([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l.extend([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +l.extend([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +l.extend([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +l.extend([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>> ListSetattr +del l.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.List attributes',)) +l.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',)) +l.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',)) +> Function +>> FunctionConstructor +vim.Function("123"):(<class 'ValueError'>, ValueError('unnamed function 123 does not exist',)) +vim.Function("xxx_non_existent_function_xxx"):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx does not exist',)) +vim.Function("xxx#non#existent#function#xxx"):NOT FAILED +>> FunctionCall +>>> Testing StringToChars using f({%s : 1}) +f({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +f({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +f({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using f({"abcF" : {%s : 1}}) +f({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +f({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +f({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using f({"abcF" : Mapping({%s : 1})}) +f({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +f({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +f({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using f({"abcF" : %s}) +f({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +f({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using f({"abcF" : %s}) +f({"abcF" : None}):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +f({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +f({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +f({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +f({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +f({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing StringToChars using f(Mapping({%s : 1})) +f(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +f(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +f(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using f(Mapping({"abcG" : {%s : 1}})) +f(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +f(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +f(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using f(Mapping({"abcG" : Mapping({%s : 1})})) +f(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +f(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +f(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using f(Mapping({"abcG" : %s})) +f(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +f(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using f(Mapping({"abcG" : %s})) +f(Mapping({"abcG" : None})):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +f(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +f(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +f(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +f(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +f(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing *Iter* using f(%s) +f(FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +f(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using f(%s) +f(None):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +f({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +f({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +f(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +f(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +f(FailingNumber()):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing StringToChars using fd(self={%s : 1}) +fd(self={1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +fd(self={b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +fd(self={"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using fd(self={"abcF" : {%s : 1}}) +fd(self={"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +fd(self={"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +fd(self={"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using fd(self={"abcF" : Mapping({%s : 1})}) +fd(self={"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +fd(self={"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +fd(self={"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using fd(self={"abcF" : %s}) +fd(self={"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +fd(self={"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using fd(self={"abcF" : %s}) +fd(self={"abcF" : None}):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +fd(self={"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +fd(self={"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +fd(self={"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +fd(self={"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +fd(self={"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing StringToChars using fd(self=Mapping({%s : 1})) +fd(self=Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +fd(self=Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +fd(self=Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using fd(self=Mapping({"abcG" : {%s : 1}})) +fd(self=Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +fd(self=Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +fd(self=Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing StringToChars using fd(self=Mapping({"abcG" : Mapping({%s : 1})})) +fd(self=Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +fd(self=Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +fd(self=Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',)) +<<< Finished +>>> Testing *Iter* using fd(self=Mapping({"abcG" : %s})) +fd(self=Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',)) +fd(self=Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',)) +<<< Finished +>>> Testing ConvertFromPyObject using fd(self=Mapping({"abcG" : %s})) +fd(self=Mapping({"abcG" : None})):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',)) +fd(self=Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +fd(self=Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +fd(self=Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +fd(self=Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +fd(self=Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',)) +<<< Finished +>>> Testing *Iter* using fd(self=%s) +fd(self=FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim dictionary',)) +fd(self=FailingIterNext()):(<class 'TypeError'>, TypeError('unable to convert FailingIterNext to vim dictionary',)) +<<< Finished +>>> Testing ConvertFromPyObject using fd(self=%s) +fd(self=None):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim dictionary',)) +fd(self={b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +fd(self={"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',)) +fd(self=FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',)) +fd(self=FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',)) +fd(self=FailingNumber()):(<class 'TypeError'>, TypeError('unable to convert FailingNumber to vim dictionary',)) +<<< Finished +>>> Testing ConvertFromPyMapping using fd(self=%s) +fd(self=[]):(<class 'AttributeError'>, AttributeError('keys',)) +<<< Finished +> TabPage +>> TabPageAttr +vim.current.tabpage.xxx:(<class 'AttributeError'>, AttributeError("'vim.tabpage' object has no attribute 'xxx'",)) +> TabList +>> TabListItem +vim.tabpages[1000]:(<class 'IndexError'>, IndexError('no such tab page',)) +> Window +>> WindowAttr +vim.current.window.xxx:(<class 'AttributeError'>, AttributeError("'vim.window' object has no attribute 'xxx'",)) +>> WindowSetattr +vim.current.window.buffer = 0:(<class 'TypeError'>, TypeError('readonly attribute: buffer',)) +vim.current.window.cursor = (100000000, 100000000):(<class 'vim.error'>, error('cursor position outside buffer',)) +vim.current.window.cursor = True:(<class 'TypeError'>, TypeError('argument must be 2-item sequence, not bool',)) +>>> Testing NumberToLong using vim.current.window.height = %s +vim.current.window.height = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',)) +vim.current.window.height = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',)) +vim.current.window.height = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',)) +<<< Finished +>>> Testing NumberToLong using vim.current.window.width = %s +vim.current.window.width = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',)) +vim.current.window.width = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',)) +vim.current.window.width = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',)) +<<< Finished +vim.current.window.xxxxxx = True:(<class 'AttributeError'>, AttributeError('xxxxxx',)) +> WinList +>> WinListItem +vim.windows[1000]:(<class 'IndexError'>, IndexError('no such window',)) +> Buffer +>> StringToLine (indirect) +vim.current.buffer[0] = "\na":(<class 'vim.error'>, error('string cannot contain newlines',)) +vim.current.buffer[0] = b"\na":(<class 'vim.error'>, error('string cannot contain newlines',)) +>> SetBufferLine (indirect) +vim.current.buffer[0] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',)) +>> SetBufferLineList (indirect) +vim.current.buffer[:] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',)) +vim.current.buffer[:] = ["\na", "bc"]:(<class 'vim.error'>, error('string cannot contain newlines',)) +>> InsertBufferLines (indirect) +vim.current.buffer.append(None):(<class 'TypeError'>, TypeError('bad argument type for built-in operation',)) +vim.current.buffer.append(["\na", "bc"]):(<class 'vim.error'>, error('string cannot contain newlines',)) +vim.current.buffer.append("\nbc"):(<class 'vim.error'>, error('string cannot contain newlines',)) +>> RBItem +vim.current.buffer[100000000]:(<class 'IndexError'>, IndexError('line number out of range',)) +>> RBAsItem +vim.current.buffer[100000000] = "":(<class 'IndexError'>, IndexError('line number out of range',)) +>> BufferAttr +vim.current.buffer.xxx:(<class 'AttributeError'>, AttributeError("'vim.buffer' object has no attribute 'xxx'",)) +>> BufferSetattr +vim.current.buffer.name = True:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got bool',)) +vim.current.buffer.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',)) +>> BufferMark +vim.current.buffer.mark(0):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',)) +vim.current.buffer.mark("abcM"):(<class 'ValueError'>, ValueError('mark name must be a single character',)) +vim.current.buffer.mark("!"):(<class 'vim.error'>, error('invalid mark name',)) +>> BufferRange +vim.current.buffer.range(1, 2, 3):(<class 'TypeError'>, TypeError('function takes exactly 2 arguments (3 given)',)) +> BufMap +>> BufMapItem +vim.buffers[100000000]:(<class 'KeyError'>, KeyError(100000000,)) +>>> Testing NumberToLong using vim.buffers[%s] +vim.buffers[[]]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',)) +vim.buffers[None]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',)) +vim.buffers[-1]:(<class 'ValueError'>, ValueError('number must be greater then zero',)) +vim.buffers[0]:(<class 'ValueError'>, ValueError('number must be greater then zero',)) +<<< Finished +> Current +>> CurrentGetattr +vim.current.xxx:(<class 'AttributeError'>, AttributeError("'vim.currentdata' object has no attribute 'xxx'",)) +>> CurrentSetattr +vim.current.line = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',)) +vim.current.buffer = True:(<class 'TypeError'>, TypeError('expected vim.Buffer object, but got bool',)) +vim.current.window = True:(<class 'TypeError'>, TypeError('expected vim.Window object, but got bool',)) +vim.current.tabpage = True:(<class 'TypeError'>, TypeError('expected vim.TabPage object, but got bool',)) +vim.current.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',)) +['.'] +'.' +3,xx +before +after +pythonx/topmodule/__init__.py +pythonx/topmodule/submodule/__init__.py +pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py +vim.command("throw 'abcN'"):(<class 'vim.error'>, error('abcN',)) +Exe("throw 'def'"):(<class 'vim.error'>, error('def',)) +vim.eval("Exe('throw ''ghi''')"):(<class 'vim.error'>, error('ghi',)) +vim.eval("Exe('echoerr ''jkl''')"):(<class 'vim.error'>, error('Vim(echoerr):jkl',)) +vim.eval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',)) +vim.eval("xxx_unknown_function_xxx()"):(<class 'vim.error'>, error('Vim:E117: Unknown function: xxx_unknown_function_xxx',)) +vim.bindeval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',)) +Caught KeyboardInterrupt +Running :put +No exception + diff --git a/src/nvim/testdir/test88.in b/src/nvim/testdir/test88.in new file mode 100644 index 0000000000..c2e6a752fa --- /dev/null +++ b/src/nvim/testdir/test88.in @@ -0,0 +1,88 @@ +vim: set ft=vim + +Tests for correct display (cursor column position) with +conceal and +tabulators. + +STARTTEST +:so small.vim +:if !has('conceal') + e! test.ok + wq! test.out +:endif +:" Conceal settings. +:set conceallevel=2 +:set concealcursor=nc +:syntax match test /|/ conceal +:" Save current cursor position. Only works in <expr> mode, can't be used +:" with :normal because it moves the cursor to the command line. Thanks to ZyX +:" <zyx.vim@gmail.com> for the idea to use an <expr> mapping. +:let positions = [] +:nnoremap <expr> GG ":let positions += ['".screenrow().":".screencol()."']\n" +:" Start test. +/^start: +:normal ztj +GGk +:" We should end up in the same column when running these commands on the two +:" lines. +:normal ft +GGk +:normal $ +GGk +:normal 0j +GGk +:normal ft +GGk +:normal $ +GGk +:normal 0j0j +GGk +:" Same for next test block. +:normal ft +GGk +:normal $ +GGk +:normal 0j +GGk +:normal ft +GGk +:normal $ +GGk +:normal 0j0j +GGk +:" And check W with multiple tabs and conceals in a line. +:normal W +GGk +:normal W +GGk +:normal W +GGk +:normal $ +GGk +:normal 0j +GGk +:normal W +GGk +:normal W +GGk +:normal W +GGk +:normal $ +GGk +:set lbr +:normal $ +GGk +:" Display result. +:call append('$', 'end:') +:call append('$', positions) +:/^end/,$wq! test.out +ENDTEST + +start: +.concealed. text +|concealed| text + + .concealed. text + |concealed| text + +.a. .b. .c. .d. +|a| |b| |c| |d| diff --git a/src/nvim/testdir/test88.ok b/src/nvim/testdir/test88.ok new file mode 100644 index 0000000000..e29698b7bd --- /dev/null +++ b/src/nvim/testdir/test88.ok @@ -0,0 +1,24 @@ +end: +2:1 +2:17 +2:20 +3:1 +3:17 +3:20 +5:8 +5:25 +5:28 +6:8 +6:25 +6:28 +8:1 +8:9 +8:17 +8:25 +8:27 +9:1 +9:9 +9:17 +9:25 +9:26 +9:26 diff --git a/src/nvim/testdir/test89.in b/src/nvim/testdir/test89.in new file mode 100644 index 0000000000..1c3079f62f --- /dev/null +++ b/src/nvim/testdir/test89.in @@ -0,0 +1,71 @@ +- Some tests for setting 'number' and 'relativenumber' + This is not all that useful now that the options are no longer reset when + setting the other. +- Some tests for findfile() function + +STARTTEST +:so small.vim +:set hidden nocp nu rnu viminfo+=nviminfo +:redir @a | set nu? rnu? | redir END +:e! xx +:redir @b | set nu? rnu? | redir END +:e! # +:$put ='results:' +:$put a +:$put b +:" +:set nonu nornu +:setglobal nu +:setlocal rnu +:redir @c | setglobal nu? | redir END +:set nonu nornu +:setglobal rnu +:setlocal nu +:redir @d | setglobal rnu? | redir END +:$put =':setlocal must NOT reset the other global value' +:$put c +:$put d +:" +:set nonu nornu +:setglobal nu +:setglobal rnu +:redir @e | setglobal nu? | redir END +:set nonu nornu +:setglobal rnu +:setglobal nu +:redir @f | setglobal rnu? | redir END +:$put =':setglobal MUST reset the other global value' +:$put e +:$put f +:" +:set nonu nornu +:set nu +:set rnu +:redir @g | setglobal nu? | redir END +:set nonu nornu +:set rnu +:set nu +:redir @h | setglobal rnu? | redir END +:$put =':set MUST reset the other global value' +:$put g +:$put h +:" +:let cwd=getcwd() +:cd .. +:" Tests may be run from a shadow directory, so an extra cd needs to be done to +:" get above src/ +:if fnamemodify(getcwd(), ':t') != 'src' | cd ../.. | else | cd .. | endif +:$put ='' +:$put ='Testing findfile' +:$put ='' +:set ssl +:$put =findfile('test19.in','src/test*') +:exe "cd" cwd +:cd .. +:$put =findfile('test19.in','test*') +:$put =findfile('test19.in','testdir') +:exe "cd" cwd +:/^results/,$w! test.out +:q! +ENDTEST + diff --git a/src/nvim/testdir/test89.ok b/src/nvim/testdir/test89.ok new file mode 100644 index 0000000000..90034758d9 --- /dev/null +++ b/src/nvim/testdir/test89.ok @@ -0,0 +1,28 @@ +results: + + number + relativenumber + + number + relativenumber +:setlocal must NOT reset the other global value + + number + + relativenumber +:setglobal MUST reset the other global value + + number + + relativenumber +:set MUST reset the other global value + + number + + relativenumber + +Testing findfile + +src/testdir/test19.in +testdir/test19.in +testdir/test19.in diff --git a/src/nvim/testdir/test9.in b/src/nvim/testdir/test9.in new file mode 100644 index 0000000000..84e17943c7 --- /dev/null +++ b/src/nvim/testdir/test9.in @@ -0,0 +1,12 @@ +Test for Bufleave autocommand that deletes the buffer we are about to edit. + +STARTTEST +:so small.vim +:au BufLeave test9.in bwipe yy +:e yy +:/^start of/,$w! test.out " Write contents of this file +:qa! +ENDTEST + +start of test file xx +end of test file xx diff --git a/src/nvim/testdir/test9.ok b/src/nvim/testdir/test9.ok new file mode 100644 index 0000000000..cccb5f3ef2 --- /dev/null +++ b/src/nvim/testdir/test9.ok @@ -0,0 +1,2 @@ +start of test file xx +end of test file xx diff --git a/src/nvim/testdir/test90.in b/src/nvim/testdir/test90.in new file mode 100644 index 0000000000..6bac414f31 --- /dev/null +++ b/src/nvim/testdir/test90.in @@ -0,0 +1,53 @@ +Tests for sha256() function. vim: set ft=vim et ts=2 sw=2 : + +STARTTEST +:so small.vim +:if !has('cryptv') || !exists('*sha256') + e! test.ok + wq! test.out +:endif +:" +:let testcase='test for empty string: ' +:if sha256("") ==# 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' +: let res='ok' +:else +: let res='ng' +:endif +:$put =testcase.res +:" +:let testcase='test for 1 char: ' +:if sha256("a") ==# 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb' +: let res='ok' +:else +: let res='ng' +:endif +:$put =testcase.res +:" +:let testcase='test for 3 chars: ' +:if sha256("abc") ==# 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad' +: let res='ok' +:else +: let res='ng' +:endif +:$put =testcase.res +:" +:let testcase='test for contains meta char: ' +:if sha256("foo\nbar") ==# '807eff6267f3f926a21d234f7b0cf867a86f47e07a532f15e8cc39ed110ca776' +: let res='ok' +:else +: let res='ng' +:endif +:$put =testcase.res +:" +:let testcase='test for contains non-ascii char: ' +:if sha256("\xde\xad\xbe\xef") ==# '5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953' +: let res='ok' +:else +: let res='ng' +:endif +:$put =testcase.res +" +:/^start:/,$wq! test.out +ENDTEST + +start: diff --git a/src/nvim/testdir/test90.ok b/src/nvim/testdir/test90.ok new file mode 100644 index 0000000000..9a8e7fe961 --- /dev/null +++ b/src/nvim/testdir/test90.ok @@ -0,0 +1,6 @@ +start: +test for empty string: ok +test for 1 char: ok +test for 3 chars: ok +test for contains meta char: ok +test for contains non-ascii char: ok diff --git a/src/nvim/testdir/test91.in b/src/nvim/testdir/test91.in new file mode 100644 index 0000000000..e900a522df --- /dev/null +++ b/src/nvim/testdir/test91.in @@ -0,0 +1,111 @@ +Tests for getbufvar(), getwinvar(), gettabvar() and gettabwinvar(). +vim: set ft=vim : + +STARTTEST +:so small.vim +:so mbyte.vim +:" +:" Test for getbufvar() +:" Use strings to test for memory leaks. +:let b:var_num = '1234' +:let def_num = '5678' +:$put =string(getbufvar(1, 'var_num')) +:$put =string(getbufvar(1, 'var_num', def_num)) +:$put =string(getbufvar(1, '')) +:$put =string(getbufvar(1, '', def_num)) +:unlet b:var_num +:$put =string(getbufvar(1, 'var_num', def_num)) +:$put =string(getbufvar(1, '')) +:$put =string(getbufvar(1, '', def_num)) +:$put =string(getbufvar(9, '')) +:$put =string(getbufvar(9, '', def_num)) +:unlet def_num +:$put =string(getbufvar(1, '&autoindent')) +:$put =string(getbufvar(1, '&autoindent', 1)) +:" +:" Open new window with forced option values +:set fileformats=unix,dos +:new ++ff=dos ++bin ++enc=iso-8859-2 +:let otherff = getbufvar(bufnr('%'), '&fileformat') +:let otherbin = getbufvar(bufnr('%'), '&bin') +:let otherfenc = getbufvar(bufnr('%'), '&fenc') +:close +:$put =otherff +:$put =string(otherbin) +:$put =otherfenc +:unlet otherff otherbin otherfenc +:" test for getwinvar() +:let w:var_str = "Dance" +:let def_str = "Chance" +:$put =string(getwinvar(1, 'var_str')) +:$put =string(getwinvar(1, 'var_str', def_str)) +:$put =string(getwinvar(1, '')) +:$put =string(getwinvar(1, '', def_str)) +:unlet w:var_str +:$put =string(getwinvar(1, 'var_str', def_str)) +:$put =string(getwinvar(1, '')) +:$put =string(getwinvar(1, '', def_str)) +:$put =string(getwinvar(9, '')) +:$put =string(getwinvar(9, '', def_str)) +:$put =string(getwinvar(1, '&nu')) +:$put =string(getwinvar(1, '&nu', 1)) +:unlet def_str +:" +:" test for gettabvar() +:tabnew +:tabnew +:let t:var_list = [1, 2, 3] +:let def_list = [4, 5, 6, 7] +:tabrewind +:$put =string(gettabvar(3, 'var_list')) +:$put =string(gettabvar(3, 'var_list', def_list)) +:$put =string(gettabvar(3, '')) +:$put =string(gettabvar(3, '', def_list)) +:tablast +:unlet t:var_list +:tabrewind +:$put =string(gettabvar(3, 'var_list', def_list)) +:$put =string(gettabvar(9, '')) +:$put =string(gettabvar(9, '', def_list)) +:$put =string(gettabvar(3, '&nu')) +:$put =string(gettabvar(3, '&nu', def_list)) +:unlet def_list +:tabonly +:" +:" test for gettabwinvar() +:tabnew +:tabnew +:tabprev +:split +:split +:wincmd w +:vert split +:wincmd w +:let w:var_dict = {'dict': 'tabwin'} +:let def_dict = {'dict2': 'newval'} +:wincmd b +:tabrewind +:$put =string(gettabwinvar(2, 3, 'var_dict')) +:$put =string(gettabwinvar(2, 3, 'var_dict', def_dict)) +:$put =string(gettabwinvar(2, 3, '')) +:$put =string(gettabwinvar(2, 3, '', def_dict)) +:tabnext +:3wincmd w +:unlet w:var_dict +:tabrewind +:$put =string(gettabwinvar(2, 3, 'var_dict', def_dict)) +:$put =string(gettabwinvar(2, 3, '')) +:$put =string(gettabwinvar(2, 3, '', def_dict)) +:$put =string(gettabwinvar(2, 9, '')) +:$put =string(gettabwinvar(2, 9, '', def_dict)) +:$put =string(gettabwinvar(9, 3, '')) +:$put =string(gettabwinvar(9, 3, '', def_dict)) +:unlet def_dict +:$put =string(gettabwinvar(2, 3, '&nux')) +:$put =string(gettabwinvar(2, 3, '&nux', 1)) +:tabonly +:" +:/^start/,$wq! test.out +ENDTEST + +start: diff --git a/src/nvim/testdir/test91.ok b/src/nvim/testdir/test91.ok new file mode 100644 index 0000000000..22e1572209 --- /dev/null +++ b/src/nvim/testdir/test91.ok @@ -0,0 +1,48 @@ +start: +'1234' +'1234' +{'var_num': '1234'} +{'var_num': '1234'} +'5678' +{} +{} +'' +'5678' +0 +0 +dos +1 +iso-8859-2 +'Dance' +'Dance' +{'var_str': 'Dance'} +{'var_str': 'Dance'} +'Chance' +{} +{} +'' +'Chance' +0 +0 +[1, 2, 3] +[1, 2, 3] +'' +[4, 5, 6, 7] +[4, 5, 6, 7] +'' +[4, 5, 6, 7] +'' +[4, 5, 6, 7] +{'dict': 'tabwin'} +{'dict': 'tabwin'} +{'var_dict': {'dict': 'tabwin'}} +{'var_dict': {'dict': 'tabwin'}} +{'dict2': 'newval'} +{} +{} +'' +{'dict2': 'newval'} +'' +{'dict2': 'newval'} +'' +1 diff --git a/src/nvim/testdir/test92.in b/src/nvim/testdir/test92.in new file mode 100644 index 0000000000..9593aec4c7 --- /dev/null +++ b/src/nvim/testdir/test92.in @@ -0,0 +1,48 @@ +vim: set ft=vim fenc=utf-8: + +Tests if :mksession saves cursor columns correctly in presence of tab and +multibyte characters when fileencoding=utf-8. + +STARTTEST +:so mbyte.vim +:if !has('mksession') +: e! test.ok +: wq! test.out +:endif +:set sessionoptions=buffers splitbelow fileencoding=utf-8 +/^start: +:vsplit +j16|:split +j16|:split +j16|:split +j8|:split +j8|:split +j16|:split +j16|:split +j16|:wincmd l +/^start: +:set nowrap +j16|3zl:split +j016|3zl:split +j016|3zl:split +j08|3zl:split +j08|3zl:split +j016|3zl:split +j016|3zl:split +j016|3zl:split +:mksession! test.out +:new test.out +:v/\(^ *normal! 0\|^ *exe 'normal!\)/d +:w! test.out +:qa! +ENDTEST + +start: +no multibyte chAracter + one leaDing tab + four leadinG spaces +two consecutive tabs +two tabs in one line +one … multibyteCharacter +a “b” two multiByte characters +“c”1€ three mulTibyte characters diff --git a/src/nvim/testdir/test92.ok b/src/nvim/testdir/test92.ok new file mode 100644 index 0000000000..cca5ec487c --- /dev/null +++ b/src/nvim/testdir/test92.ok @@ -0,0 +1,26 @@ +normal! 016| +normal! 016| +normal! 016| +normal! 08| +normal! 08| +normal! 016| +normal! 016| +normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 8 . '|' + normal! 08| + exe 'normal! ' . s:c . '|zs' . 8 . '|' + normal! 08| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| diff --git a/src/nvim/testdir/test93.in b/src/nvim/testdir/test93.in new file mode 100644 index 0000000000..877838ce1b --- /dev/null +++ b/src/nvim/testdir/test93.in @@ -0,0 +1,48 @@ +vim: set ft=vim fenc=latin1: + +Tests if :mksession saves cursor columns correctly in presence of tab and +multibyte characters when fileencoding=latin1. + +STARTTEST +:so mbyte.vim +:if !has('mksession') +: e! test.ok +: wq! test.out +:endif +:set sessionoptions=buffers splitbelow fileencoding=latin1 +/^start: +:vsplit +j16|:split +j16|:split +j16|:split +j8|:split +j8|:split +j16|:split +j16|:split +j16|:wincmd l +/^start: +:set nowrap +j16|3zl:split +j016|3zl:split +j016|3zl:split +j08|3zl:split +j08|3zl:split +j016|3zl:split +j016|3zl:split +j016|3zl:split +:mksession! test.out +:new test.out +:v/\(^ *normal! 0\|^ *exe 'normal!\)/d +:w! test.out +:qa! +ENDTEST + +start: +no multibyte chAracter + one leaDing tab + four leadinG spaces +two consecutive tabs +two tabs in one line +one multibyteCharacter +a two multiByte characters +A three mulTibyte characters diff --git a/src/nvim/testdir/test93.ok b/src/nvim/testdir/test93.ok new file mode 100644 index 0000000000..cca5ec487c --- /dev/null +++ b/src/nvim/testdir/test93.ok @@ -0,0 +1,26 @@ +normal! 016| +normal! 016| +normal! 016| +normal! 08| +normal! 08| +normal! 016| +normal! 016| +normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 8 . '|' + normal! 08| + exe 'normal! ' . s:c . '|zs' . 8 . '|' + normal! 08| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| diff --git a/src/nvim/testdir/test94.in b/src/nvim/testdir/test94.in new file mode 100644 index 0000000000..dfa91d8340 --- /dev/null +++ b/src/nvim/testdir/test94.in @@ -0,0 +1,95 @@ +Test for Visual mode and operators + +Tests for the two kinds of operations: Those executed with Visual mode +followed by an operator and those executed via Operator-pending mode. Also +part of the test are mappings, counts, and repetition with the . command. + +Test cases: +- Visual modes (v V CTRL-V) followed by an operator; count; repeating +- Visual mode maps; count; repeating + - Simple + - With an Ex command (custom text object) +- Operator-pending mode maps + - Simple + - With Ex command moving the cursor + - With Ex command and Visual selection (custom text object) +- Patch 7.3.879: Properly abort Ex command in Operator-pending mode + +STARTTEST +:so small.vim +:set nocp viminfo+=nviminfo +: +:" User functions +:function MoveToCap() +: call search('\u', 'W') +:endfunction +:function SelectInCaps() +: let [line1, col1] = searchpos('\u', 'bcnW') +: let [line2, col2] = searchpos('.\u', 'nW') +: call setpos("'<", [0, line1, col1, 0]) +: call setpos("'>", [0, line2, col2, 0]) +: normal! gv +:endfunction +: +:" Visual modes followed by operator +/^apple +lvld.l3vd.: +/^line 1 +Vcnewlinej.j2Vd.: +/^xxxx +jlc l.l2c----l.: +: +:" Visual mode maps (movement and text object) +:vnoremap W /\u/s-1<CR> +:vnoremap iW :<C-U>call SelectInCaps()<CR> +/^Kiwi +vWcNol.fD2vd.: +/^Jambu +llviWc-l.l2vdl.: +: +:" Operator-pending mode maps (movement and text object) +:onoremap W /\u/<CR> +:onoremap <Leader>W :<C-U>call MoveToCap()<CR> +:onoremap iW :<C-U>call SelectInCaps()<CR> +/^Pineapple +cW-l.l2.l.: +/^Juniper +g?\WfD.: +/^Lemon +yiWPlciWNewfr.: +: +:" Patch 7.3.879: Properly abort Operator-pending mode for "dv:<Esc>" etc. +/^zzzz +dV:
dv:
:set noma | let v:errmsg = '' +d:
:set ma | put = v:errmsg =~# '^E21' ? 'ok' : 'failed' +dv:dV::set noma | let v:errmsg = '' +d::set ma | put = v:errmsg =~# '^E21' ? 'failed' : 'ok' +:/^start:/+2,$w! test.out +:q! +ENDTEST + +start: + +apple banana cherry + +line 1 line 1 +line 2 line 2 +line 3 line 3 +line 4 line 4 +line 5 line 5 +line 6 line 6 + +xxxxxxxxxxxxx +xxxxxxxxxxxxx +xxxxxxxxxxxxx +xxxxxxxxxxxxx + +KiwiRaspberryDateWatermelonPeach +JambuRambutanBananaTangerineMango + +PineappleQuinceLoganberryOrangeGrapefruitKiwiZ +JuniperDurianZ +LemonNectarineZ + +zzzz +zzzz diff --git a/src/nvim/testdir/test94.ok b/src/nvim/testdir/test94.ok new file mode 100644 index 0000000000..3996f2a3a4 --- /dev/null +++ b/src/nvim/testdir/test94.ok @@ -0,0 +1,20 @@ +a y + +newline +newline + + --------x + --------x +xxxx--------x +xxxx--------x + +NoNoberryach +--ago + +----Z +WhavcreQhevnaZ +LemonNewNewZ + +zzz +ok +ok diff --git a/src/nvim/testdir/test95.in b/src/nvim/testdir/test95.in new file mode 100644 index 0000000000..90fa69945a --- /dev/null +++ b/src/nvim/testdir/test95.in @@ -0,0 +1,135 @@ +Test for regexp patterns with multi-byte support, using utf-8. +See test64 for the non-multi-byte tests. + +A pattern that gives the expected result produces OK, so that we know it was +actually tried. + +STARTTEST +:so small.vim +:so mbyte.vim +:set nocp encoding=utf-8 viminfo+=nviminfo nomore +:" tl is a List of Lists with: +:" 2: test auto/old/new 0: test auto/old 1: test auto/new +:" regexp pattern +:" text to test the pattern on +:" expected match (optional) +:" expected submatch 1 (optional) +:" expected submatch 2 (optional) +:" etc. +:" When there is no match use only the first two items. +:let tl = [] + +:"""" Multi-byte character tests. These will fail unless vim is compiled +:"""" with Multibyte (FEAT_MBYTE) or BIG/HUGE features. +:call add(tl, [2, '[[:alpha:][=a=]]\+', '879 aiaãâaiuvna ', 'aiaãâaiuvna']) +:call add(tl, [2, '[[=a=]]\+', 'ddaãâbcd', 'aãâ']) " equivalence classes +:call add(tl, [2, '[^ม ]\+', 'มม oijasoifjos ifjoisj f osij j มมมมม abcd', 'oijasoifjos']) +:call add(tl, [2, ' [^ ]\+', 'start มabcdม ', ' มabcdม']) +:call add(tl, [2, '[ม[:alpha:][=a=]]\+', '879 aiaãมâมaiuvna ', 'aiaãมâมaiuvna']) + +:" this is not a normal "i" but 0xec +:call add(tl, [2, '\p\+', 'ìa', 'ìa']) +:call add(tl, [2, '\p*', 'aあ', 'aあ']) + +:"""" Test recognition of some character classes +:call add(tl, [2, '\i\+', '&*¨xx ', 'xx']) +:call add(tl, [2, '\f\+', '&*fname ', 'fname']) + +:"""" Test composing character matching +:call add(tl, [2, '.ม', 'xม่x yมy', 'yม']) +:call add(tl, [2, '.ม่', 'xม่x yมy', 'xม่']) +:call add(tl, [2, "\u05b9", " x\u05b9 ", "x\u05b9"]) +:call add(tl, [2, ".\u05b9", " x\u05b9 ", "x\u05b9"]) +:call add(tl, [2, "\u05b9\u05bb", " x\u05b9\u05bb ", "x\u05b9\u05bb"]) +:call add(tl, [2, ".\u05b9\u05bb", " x\u05b9\u05bb ", "x\u05b9\u05bb"]) +:call add(tl, [2, "\u05bb\u05b9", " x\u05b9\u05bb ", "x\u05b9\u05bb"]) +:call add(tl, [2, ".\u05bb\u05b9", " x\u05b9\u05bb ", "x\u05b9\u05bb"]) +:call add(tl, [2, "\u05b9", " y\u05bb x\u05b9 ", "x\u05b9"]) +:call add(tl, [2, ".\u05b9", " y\u05bb x\u05b9 ", "x\u05b9"]) +:call add(tl, [2, "\u05b9", " y\u05bb\u05b9 x\u05b9 ", "y\u05bb\u05b9"]) +:call add(tl, [2, ".\u05b9", " y\u05bb\u05b9 x\u05b9 ", "y\u05bb\u05b9"]) +:call add(tl, [1, "\u05b9\u05bb", " y\u05b9 x\u05b9\u05bb ", "x\u05b9\u05bb"]) +:call add(tl, [2, ".\u05b9\u05bb", " y\u05bb x\u05b9\u05bb ", "x\u05b9\u05bb"]) + + +:"""" Test \Z +:call add(tl, [2, 'ú\Z', 'x']) +:call add(tl, [2, 'יהוה\Z', 'יהוה', 'יהוה']) +:call add(tl, [2, 'יְהוָה\Z', 'יהוה', 'יהוה']) +:call add(tl, [2, 'יהוה\Z', 'יְהוָה', 'יְהוָה']) +:call add(tl, [2, 'יְהוָה\Z', 'יְהוָה', 'יְהוָה']) +:call add(tl, [2, 'יְ\Z', 'וְיַ', 'יַ']) +:call add(tl, [2, "ק\u200d\u05b9x\\Z", "xק\u200d\u05b9xy", "ק\u200d\u05b9x"]) +:call add(tl, [2, "ק\u200d\u05b9x\\Z", "xק\u200dxy", "ק\u200dx"]) +:call add(tl, [2, "ק\u200dx\\Z", "xק\u200d\u05b9xy", "ק\u200d\u05b9x"]) +:call add(tl, [2, "ק\u200dx\\Z", "xק\u200dxy", "ק\u200dx"]) +:call add(tl, [2, "\u05b9\\Z", "xyz"]) +:call add(tl, [2, "\\Z\u05b9", "xyz"]) +:call add(tl, [2, "\u05b9\\Z", "xy\u05b9z", "y\u05b9"]) +:call add(tl, [2, "\\Z\u05b9", "xy\u05b9z", "y\u05b9"]) +:call add(tl, [1, "\u05b9\\+\\Z", "xy\u05b9z\u05b9 ", "y\u05b9z\u05b9"]) +:call add(tl, [1, "\\Z\u05b9\\+", "xy\u05b9z\u05b9 ", "y\u05b9z\u05b9"]) + +:"""" Combining different tests and features +:call add(tl, [2, '[^[=a=]]\+', 'ddaãâbcd', 'dd']) + +:"""" Run the tests + +:" +:for t in tl +: let re = t[0] +: let pat = t[1] +: let text = t[2] +: let matchidx = 3 +: for engine in [0, 1, 2] +: if engine == 2 && re == 0 || engine == 1 && re == 1 +: continue +: endif +: let ®expengine = engine +: try +: let l = matchlist(text, pat) +: catch +: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", caused an exception: \"' . v:exception . '\"' +: endtry +:" check the match itself +: if len(l) == 0 && len(t) > matchidx +: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", did not match, expected: \"' . t[matchidx] . '\"' +: elseif len(l) > 0 && len(t) == matchidx +: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected no match' +: elseif len(t) > matchidx && l[0] != t[matchidx] +: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected: \"' . t[matchidx] . '\"' +: else +: $put ='OK ' . engine . ' - ' . pat +: endif +: if len(l) > 0 +:" check all the nine submatches +: for i in range(1, 9) +: if len(t) <= matchidx + i +: let e = '' +: else +: let e = t[matchidx + i] +: endif +: if l[i] != e +: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"' +: endif +: endfor +: unlet i +: endif +: endfor +:endfor +:unlet t tl e l + +:" check that 'ambiwidth' does not change the meaning of \p +:set regexpengine=1 ambiwidth=single +:$put ='eng 1 ambi single: ' . match(\"\u00EC\", '\p') +:set regexpengine=1 ambiwidth=double +:$put ='eng 1 ambi double: ' . match(\"\u00EC\", '\p') +:set regexpengine=2 ambiwidth=single +:$put ='eng 2 ambi single: ' . match(\"\u00EC\", '\p') +:set regexpengine=2 ambiwidth=double +:$put ='eng 2 ambi double: ' . match(\"\u00EC\", '\p') + +:/\%#=1^Results/,$wq! test.out +ENDTEST + +Results of test95: diff --git a/src/nvim/testdir/test95.ok b/src/nvim/testdir/test95.ok new file mode 100644 index 0000000000..c378221a70 --- /dev/null +++ b/src/nvim/testdir/test95.ok @@ -0,0 +1,122 @@ +Results of test95: +OK 0 - [[:alpha:][=a=]]\+ +OK 1 - [[:alpha:][=a=]]\+ +OK 2 - [[:alpha:][=a=]]\+ +OK 0 - [[=a=]]\+ +OK 1 - [[=a=]]\+ +OK 2 - [[=a=]]\+ +OK 0 - [^ม ]\+ +OK 1 - [^ม ]\+ +OK 2 - [^ม ]\+ +OK 0 - [^ ]\+ +OK 1 - [^ ]\+ +OK 2 - [^ ]\+ +OK 0 - [ม[:alpha:][=a=]]\+ +OK 1 - [ม[:alpha:][=a=]]\+ +OK 2 - [ม[:alpha:][=a=]]\+ +OK 0 - \p\+ +OK 1 - \p\+ +OK 2 - \p\+ +OK 0 - \p* +OK 1 - \p* +OK 2 - \p* +OK 0 - \i\+ +OK 1 - \i\+ +OK 2 - \i\+ +OK 0 - \f\+ +OK 1 - \f\+ +OK 2 - \f\+ +OK 0 - .ม +OK 1 - .ม +OK 2 - .ม +OK 0 - .ม่ +OK 1 - .ม่ +OK 2 - .ม่ +OK 0 - ֹ +OK 1 - ֹ +OK 2 - ֹ +OK 0 - .ֹ +OK 1 - .ֹ +OK 2 - .ֹ +OK 0 - ֹֻ +OK 1 - ֹֻ +OK 2 - ֹֻ +OK 0 - .ֹֻ +OK 1 - .ֹֻ +OK 2 - .ֹֻ +OK 0 - ֹֻ +OK 1 - ֹֻ +OK 2 - ֹֻ +OK 0 - .ֹֻ +OK 1 - .ֹֻ +OK 2 - .ֹֻ +OK 0 - ֹ +OK 1 - ֹ +OK 2 - ֹ +OK 0 - .ֹ +OK 1 - .ֹ +OK 2 - .ֹ +OK 0 - ֹ +OK 1 - ֹ +OK 2 - ֹ +OK 0 - .ֹ +OK 1 - .ֹ +OK 2 - .ֹ +OK 0 - ֹֻ +OK 2 - ֹֻ +OK 0 - .ֹֻ +OK 1 - .ֹֻ +OK 2 - .ֹֻ +OK 0 - ú\Z +OK 1 - ú\Z +OK 2 - ú\Z +OK 0 - יהוה\Z +OK 1 - יהוה\Z +OK 2 - יהוה\Z +OK 0 - יְהוָה\Z +OK 1 - יְהוָה\Z +OK 2 - יְהוָה\Z +OK 0 - יהוה\Z +OK 1 - יהוה\Z +OK 2 - יהוה\Z +OK 0 - יְהוָה\Z +OK 1 - יְהוָה\Z +OK 2 - יְהוָה\Z +OK 0 - יְ\Z +OK 1 - יְ\Z +OK 2 - יְ\Z +OK 0 - קֹx\Z +OK 1 - קֹx\Z +OK 2 - קֹx\Z +OK 0 - קֹx\Z +OK 1 - קֹx\Z +OK 2 - קֹx\Z +OK 0 - קx\Z +OK 1 - קx\Z +OK 2 - קx\Z +OK 0 - קx\Z +OK 1 - קx\Z +OK 2 - קx\Z +OK 0 - ֹ\Z +OK 1 - ֹ\Z +OK 2 - ֹ\Z +OK 0 - \Zֹ +OK 1 - \Zֹ +OK 2 - \Zֹ +OK 0 - ֹ\Z +OK 1 - ֹ\Z +OK 2 - ֹ\Z +OK 0 - \Zֹ +OK 1 - \Zֹ +OK 2 - \Zֹ +OK 0 - ֹ\+\Z +OK 2 - ֹ\+\Z +OK 0 - \Zֹ\+ +OK 2 - \Zֹ\+ +OK 0 - [^[=a=]]\+ +OK 1 - [^[=a=]]\+ +OK 2 - [^[=a=]]\+ +eng 1 ambi single: 0 +eng 1 ambi double: 0 +eng 2 ambi single: 0 +eng 2 ambi double: 0 diff --git a/src/nvim/testdir/test96.in b/src/nvim/testdir/test96.in new file mode 100644 index 0000000000..9d1a2c83a5 --- /dev/null +++ b/src/nvim/testdir/test96.in @@ -0,0 +1,142 @@ +This will test for problems in quickfix: +A. incorrectly copying location lists which caused the location list to show a + different name than the file that was actually being displayed. +B. not reusing the window for which the location list window is opened but + instead creating new windows. +C. make sure that the location list window is not reused instead of the window + it belongs to. + +Note: to debug a problem comment out the last ":b 1" in a test and testing will +stop at this point. + +STARTTEST +:so small.vim +: enew +: w! test.out +: b 1 +: " Set up the test environment: +: function! ReadTestProtocol(name) +: let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '') +: let word = substitute(base, '\v(.*)\..*', '\1', '') +: +: setl modifiable +: setl noreadonly +: setl noswapfile +: setl bufhidden=delete +: %del _ +: " For problem 2: +: " 'buftype' has to be set to reproduce the constant opening of new windows +: setl buftype=nofile +: +: call setline(1, word) +: +: setl nomodified +: setl nomodifiable +: setl readonly +: exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '') +: endfunction +: augroup testgroup +: au! +: autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>")) +: augroup END +: let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ] +: +: let qflist = [] +: for word in words +: call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', }) +: " NOTE: problem 1: +: " intentionally not setting 'lnum' so that the quickfix entries are not +: " valid +: call setloclist(0, qflist, ' ') +: endfor +ENDTEST + +Test A: +STARTTEST +:lrewind +:enew +:lopen +:lnext +:lnext +:lnext +:lnext +:vert split +:wincmd L +:lopen +:wincmd p +:lnext +:"b 1 +:let fileName = expand("%") +:wincmd p +:let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '') +:wincmd n +:wincmd K +:b test.out +:let fileName = substitute(fileName, '\\', '/', 'g') +:let locationListFileName = substitute(locationListFileName, '\\', '/', 'g') +:call append(line('$'), "Test A:") +:call append(line('$'), " - file name displayed: " . fileName) +:call append(line('$'), " - quickfix claims that the file name displayed is: " . locationListFileName) +:w +:wincmd o +:b 1 +ENDTEST + +Test B: +STARTTEST +:lrewind +:lopen +:2 +:exe "normal \<CR>" +:wincmd p +:3 +:exe "normal \<CR>" +:wincmd p +:4 +:exe "normal \<CR>" +:let numberOfWindowsOpen = winnr('$') +:wincmd n +:wincmd K +:b test.out +:call append(line('$'), "Test B:") +:call append(line('$'), " - number of window open: " . numberOfWindowsOpen) +:w +:wincmd o +:b 1 +ENDTEST + +Test C: +STARTTEST +:lrewind +:lopen +:" Let's move the location list window to the top to check whether it (the first +:" window found) will be reused when we try to open new windows: +:wincmd K +:2 +:exe "normal \<CR>" +:wincmd p +:3 +:exe "normal \<CR>" +:wincmd p +:4 +:exe "normal \<CR>" +:1wincmd w +:let locationListWindowBufType = &buftype +:2wincmd w +:let bufferName = expand("%") +:wincmd n +:wincmd K +:b test.out +:let bufferName = substitute(bufferName, '\\', '/', 'g') +:call append(line('$'), "Test C:") +:call append(line('$'), " - 'buftype' of the location list window: " . locationListWindowBufType) +:call append(line('$'), " - buffer displayed in the 2nd window: " . bufferName) +:w +:wincmd o +:b 1 +ENDTEST + +STARTTEST +:qa +ENDTEST + diff --git a/src/nvim/testdir/test96.ok b/src/nvim/testdir/test96.ok new file mode 100644 index 0000000000..3498e52f73 --- /dev/null +++ b/src/nvim/testdir/test96.ok @@ -0,0 +1,9 @@ + +Test A: + - file name displayed: test://bar.txt + - quickfix claims that the file name displayed is: test://bar.txt +Test B: + - number of window open: 2 +Test C: + - 'buftype' of the location list window: quickfix + - buffer displayed in the 2nd window: test://quux.txt diff --git a/src/nvim/testdir/test97.in b/src/nvim/testdir/test97.in new file mode 100644 index 0000000000..13e9dd5b6e --- /dev/null +++ b/src/nvim/testdir/test97.in @@ -0,0 +1,17 @@ +Test whether glob()/globpath() return correct results with certain escaped +characters. + +STARTTEST +:so small.vim +:set shell=doesnotexist +:e test.out +:put =glob('Xxx\{') +:put =glob('Xxx\$') +:w! Xxx{ +:w! Xxx\$ +:put =glob('Xxx\{') +:put =glob('Xxx\$') +:w +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test97.ok b/src/nvim/testdir/test97.ok new file mode 100644 index 0000000000..afa96a4de4 --- /dev/null +++ b/src/nvim/testdir/test97.ok @@ -0,0 +1,5 @@ + + + +Xxx{ +Xxx$ diff --git a/src/nvim/testdir/test98.in b/src/nvim/testdir/test98.in new file mode 100644 index 0000000000..83ccba09e9 --- /dev/null +++ b/src/nvim/testdir/test98.in @@ -0,0 +1,43 @@ +Test for 'scrollbind' causing an unexpected scroll of one of the windows. +STARTTEST +:so small.vim +:" We don't want the status line to cause problems: +:set laststatus=0 +:let g:totalLines = &lines * 20 +:let middle = g:totalLines / 2 +:wincmd n +:wincmd o +:for i in range(1, g:totalLines) +: call setline(i, 'LINE ' . i) +:endfor +:exe string(middle) +:normal zt +:normal M +:aboveleft vert new +:for i in range(1, g:totalLines) +: call setline(i, 'line ' . i) +:endfor +:exe string(middle) +:normal zt +:normal M +:" Execute the following two command at once to reproduce the problem. +:setl scb | wincmd p +:setl scb +:wincmd w +:let topLineLeft = line('w0') +:wincmd p +:let topLineRight = line('w0') +:setl noscrollbind +:wincmd p +:setl noscrollbind +:q! +:%del _ +:call setline(1, 'Difference between the top lines (left - right): ' . string(topLineLeft - topLineRight)) +:w! test.out +:brewind +ENDTEST + +STARTTEST +:qa! +ENDTEST + diff --git a/src/nvim/testdir/test98.ok b/src/nvim/testdir/test98.ok new file mode 100644 index 0000000000..356ddd8eac --- /dev/null +++ b/src/nvim/testdir/test98.ok @@ -0,0 +1 @@ +Difference between the top lines (left - right): 0 diff --git a/src/nvim/testdir/test99.in b/src/nvim/testdir/test99.in new file mode 100644 index 0000000000..77828f4b68 --- /dev/null +++ b/src/nvim/testdir/test99.in @@ -0,0 +1,68 @@ +Tests for regexp with multi-byte encoding and various magic settings. +Test matchstr() with a count and multi-byte chars. +See test44 for exactly the same test with re=1. + +STARTTEST +:so mbyte.vim +:set nocompatible encoding=utf-8 termencoding=latin1 viminfo+=nviminfo +:set re=2 +/^1 +/a*b\{2}c\+/e +x/\Md\*e\{2}f\+/e +x:set nomagic +/g\*h\{2}i\+/e +x/\mj*k\{2}l\+/e +x/\vm*n{2}o+/e +x/\V^aa$ +x:set magic +/\v(a)(b)\2\1\1/e +x/\V[ab]\(\[xy]\)\1 +x:" Now search for multi-byte without composing char +/ม +x:" Now search for multi-byte with composing char +/ม่ +x:" find word by change of word class +/ち\<カヨ\>は +x:" Test \%u, [\u] and friends +/\%u20ac +x/[\u4f7f\u5929]\+ +x/\%U12345678 +x/[\U1234abcd\u1234\uabcd] +x/\%d21879b +x/ [[=A=]]* [[=B=]]* [[=C=]]* [[=D=]]* [[=E=]]* [[=F=]]* [[=G=]]* [[=H=]]* [[=I=]]* [[=J=]]* [[=K=]]* [[=L=]]* [[=M=]]* [[=N=]]* [[=O=]]* [[=P=]]* [[=Q=]]* [[=R=]]* [[=S=]]* [[=T=]]* [[=U=]]* [[=V=]]* [[=W=]]* [[=X=]]* [[=Y=]]* [[=Z=]]*/e +x/ [[=a=]]* [[=b=]]* [[=c=]]* [[=d=]]* [[=e=]]* [[=f=]]* [[=g=]]* [[=h=]]* [[=i=]]* [[=j=]]* [[=k=]]* [[=l=]]* [[=m=]]* [[=n=]]* [[=o=]]* [[=p=]]* [[=q=]]* [[=r=]]* [[=s=]]* [[=t=]]* [[=u=]]* [[=v=]]* [[=w=]]* [[=x=]]* [[=y=]]* [[=z=]]*/e +x:" Test backwards search from a multi-byte char +/x +x?. +x:let @w=':%s#comb[i]nations#œ̄ṣ́m̥̄ᾱ̆́#g' +:@w +:?^1?,$w! test.out +:e! test.out +G:put =matchstr(\"אבגד\", \".\", 0, 2) " ב +:put =matchstr(\"אבגד\", \"..\", 0, 2) " בג +:put =matchstr(\"אבגד\", \".\", 0, 0) " א +:put =matchstr(\"אבגד\", \".\", 4, -1) " ג +:w! +:qa! +ENDTEST + +1 a aa abb abbccc +2 d dd dee deefff +3 g gg ghh ghhiii +4 j jj jkk jkklll +5 m mm mnn mnnooo +6 x ^aa$ x +7 (a)(b) abbaa +8 axx [ab]xx +9 หม่x อมx +a อมx หม่x +b ちカヨは +c x ¬€x +d 天使x +e y +f z +g a啷bb +h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐẔ +i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑẕ +j 0123❤x +k combinations diff --git a/src/nvim/testdir/test99.ok b/src/nvim/testdir/test99.ok new file mode 100644 index 0000000000..0bd0b8ab73 --- /dev/null +++ b/src/nvim/testdir/test99.ok @@ -0,0 +1,24 @@ +1 a aa abb abbcc +2 d dd dee deeff +3 g gg ghh ghhii +4 j jj jkk jkkll +5 m mm mnn mnnoo +6 x aa$ x +7 (a)(b) abba +8 axx ab]xx +9 หม่x อx +a อมx หx +b カヨは +c x ¬x +d 使x +e y +f z +g abb +h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐ +i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑ +j 012❤ +k œ̄ṣ́m̥̄ᾱ̆́ +ב +בג +א +ג diff --git a/src/nvim/testdir/test_eval.in b/src/nvim/testdir/test_eval.in new file mode 100644 index 0000000000..c34f5cb50e --- /dev/null +++ b/src/nvim/testdir/test_eval.in @@ -0,0 +1,57 @@ +STARTTEST + +:e test.out +:%d + +:" function name not starting with a capital +:try +: func! g:test() +: echo "test" +: endfunc +:catch +: $put =v:exception +:endtry + +:" function name folowed by # +:try +: func! test2() "# +: echo "test2" +: endfunc +:catch +: $put =v:exception +:endtry + +:" function name includes a colon +:try +: func! b:test() +: echo "test" +: endfunc +:catch +: $put =v:exception +:endtry + +:" function name starting with/without "g:", buffer-local funcref. +:function! g:Foo(n) +: $put ='called Foo(' . a:n . ')' +:endfunction +:let b:my_func = function('Foo') +:call b:my_func(1) +:echo g:Foo(2) +:echo Foo(3) + +:" script-local function used in Funcref must exist. +:so test_eval_func.vim + +:" using $ instead of '$' must give an error +:try +: call append($, 'foobar') +:catch +: $put =v:exception +:endtry + +:1d +:w +:qa! + +ENDTEST + diff --git a/src/nvim/testdir/test_eval.ok b/src/nvim/testdir/test_eval.ok new file mode 100644 index 0000000000..162e1b12fd --- /dev/null +++ b/src/nvim/testdir/test_eval.ok @@ -0,0 +1,11 @@ +Vim(function):E128: Function name must start with a capital or "s:": g:test() +Vim(function):E128: Function name must start with a capital or "s:": test2() "# +Vim(function):E128: Function name must start with a capital or "s:": b:test() +called Foo(1) +called Foo(2) +called Foo(3) +s:Testje exists: 0 +func s:Testje exists: 1 +Bar exists: 1 +func Bar exists: 1 +Vim(call):E116: Invalid arguments for function append diff --git a/src/nvim/testdir/test_eval_func.vim b/src/nvim/testdir/test_eval_func.vim new file mode 100644 index 0000000000..48d01df27d --- /dev/null +++ b/src/nvim/testdir/test_eval_func.vim @@ -0,0 +1,12 @@ +" Vim script used in test_eval.in. Needed for script-local function. + +func! s:Testje() + return "foo" +endfunc + +let Bar = function('s:Testje') + +$put ='s:Testje exists: ' . exists('s:Testje') +$put ='func s:Testje exists: ' . exists('*s:Testje') +$put ='Bar exists: ' . exists('Bar') +$put ='func Bar exists: ' . exists('*Bar') diff --git a/src/nvim/testdir/unix.vim b/src/nvim/testdir/unix.vim new file mode 100644 index 0000000000..f766e74c30 --- /dev/null +++ b/src/nvim/testdir/unix.vim @@ -0,0 +1,3 @@ +" Settings for test script execution +" Always use "sh", don't use the value of "$SHELL". +set shell=sh |