" Test for edit functions if exists("+t_kD") let &t_kD="[3;*~" endif source check.vim " Needed for testing basic rightleft: Test_edit_rightleft source view_util.vim " Needs to come first until the bug in getchar() is " fixed: https://groups.google.com/d/msg/vim_dev/fXL9yme4H4c/bOR-U6_bAQAJ func Test_edit_00b() new call setline(1, ['abc ']) inoreabbr h here some more call cursor(1, 4) " expands the abbreviation and ends insertmode call feedkeys(":set im\ h\:set noim\", 'tix') call assert_equal(['abc here some more '], getline(1,'$')) iunabbr h bw! endfunc func Test_edit_01() " set for Travis CI? " set nocp noesckeys new " 1) empty buffer call assert_equal([''], getline(1,'$')) " 2) delete in an empty line call feedkeys("i\\", 'tnix') call assert_equal([''], getline(1,'$')) %d " 3) delete one character call setline(1, 'a') call feedkeys("i\\", 'tnix') call assert_equal([''], getline(1,'$')) %d " 4) delete a multibyte character call setline(1, "\u0401") call feedkeys("i\\", 'tnix') call assert_equal([''], getline(1,'$')) %d " 5.1) delete linebreak with 'bs' option containing eol let _bs=&bs set bs=eol call setline(1, ["abc def", "ghi jkl"]) call cursor(1, 1) call feedkeys("A\\", 'tnix') call assert_equal(['abc defghi jkl'], getline(1, 2)) %d " 5.2) delete linebreak with backspace option w/out eol set bs= call setline(1, ["abc def", "ghi jkl"]) call cursor(1, 1) call feedkeys("A\\", 'tnix') call assert_equal(["abc def", "ghi jkl"], getline(1, 2)) let &bs=_bs bw! endfunc func Test_edit_02() " Change cursor position in InsertCharPre command new call setline(1, 'abc') call cursor(1, 1) fu! DoIt(...) call cursor(1, 4) if len(a:000) let v:char=a:1 endif endfu au InsertCharPre :call DoIt('y') call feedkeys("ix\", 'tnix') call assert_equal(['abcy'], getline(1, '$')) " Setting in InsertCharPre au! InsertCharPre :call DoIt("\n") call setline(1, 'abc') call cursor(1, 1) call feedkeys("ix\", 'tnix') call assert_equal(['abc', ''], getline(1, '$')) %d au! InsertCharPre " Change cursor position in InsertEnter command " 1) when setting v:char, keeps changed cursor position au! InsertEnter :call DoIt('y') call setline(1, 'abc') call cursor(1, 1) call feedkeys("ix\", 'tnix') call assert_equal(['abxc'], getline(1, '$')) " 2) when not setting v:char, restores changed cursor position au! InsertEnter :call DoIt() call setline(1, 'abc') call cursor(1, 1) call feedkeys("ix\", 'tnix') call assert_equal(['xabc'], getline(1, '$')) au! InsertEnter delfu DoIt bw! endfunc func Test_edit_03() " Change cursor after command to end of line new call setline(1, 'abc') call cursor(1, 1) call feedkeys("i\$y\", 'tnix') call assert_equal(['abcy'], getline(1, '$')) %d call setline(1, 'abc') call cursor(1, 1) call feedkeys("i\80|y\", 'tnix') call assert_equal(['abcy'], getline(1, '$')) %d call setline(1, 'abc') call feedkeys("Ad\:s/$/efg/\hij", 'tnix') call assert_equal(['hijabcdefg'], getline(1, '$')) bw! endfunc func Test_edit_04() " test for :stopinsert new call setline(1, 'abc') call cursor(1, 1) call feedkeys("i\:stopinsert\$", 'tnix') call feedkeys("aX\", 'tnix') call assert_equal(['abcX'], getline(1, '$')) %d bw! endfunc func Test_edit_05() " test for folds being opened new call setline(1, ['abcX', 'abcX', 'zzzZ']) call cursor(1, 1) set foldmethod=manual foldopen+=insert " create fold for those two lines norm! Vjzf call feedkeys("$ay\", 'tnix') call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$')) %d call setline(1, ['abcX', 'abcX', 'zzzZ']) call cursor(1, 1) set foldmethod=manual foldopen-=insert " create fold for those two lines norm! Vjzf call feedkeys("$ay\", 'tnix') call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$')) %d bw! endfunc func Test_edit_06() " Test in diff mode if !has("diff") || !executable("diff") return endif new call setline(1, ['abc', 'xxx', 'yyy']) vnew call setline(1, ['abc', 'zzz', 'xxx', 'yyy']) wincmd p diffthis wincmd p diffthis wincmd p call cursor(2, 1) norm! zt call feedkeys("Ozzz\", 'tnix') call assert_equal(['abc', 'zzz', 'xxx', 'yyy'], getline(1,'$')) bw! bw! endfunc func Test_edit_07() " 1) Test with completion when popupmenu is visible new call setline(1, 'J') func! ListMonths() call complete(col('.')-1, ['January', 'February', 'March', \ 'April', 'May', 'June', 'July', 'August', 'September', \ 'October', 'November', 'December']) return '' endfunc inoremap =ListMonths() call feedkeys("A\\". repeat("\", 6)."\\\\", 'tx') call assert_equal(['July'], getline(1,'$')) " 1) Test completion when InsertCharPre kicks in %d call setline(1, 'J') fu! DoIt() if v:char=='u' let v:char='an' endif endfu au InsertCharPre :call DoIt() call feedkeys("A\\u\\\", 'tx') call assert_equal(["Jan\",''], 1->getline('$')) %d call setline(1, 'J') call feedkeys("A\\u\\\", 'tx') call assert_equal(["January"], 1->getline('$')) delfu ListMonths delfu DoIt iunmap bw! endfunc func! Test_edit_08() throw 'skipped: moved to test/functional/legacy/edit_spec.lua' " reset insertmode from i_ctrl-r_= let g:bufnr = bufnr('%') new call setline(1, ['abc']) call cursor(1, 4) call feedkeys(":set im\ZZZ\=setbufvar(g:bufnr,'&im', 0)\",'tnix') call assert_equal(['abZZZc'], getline(1,'$')) call assert_equal([0, 1, 1, 0], getpos('.')) call assert_false(0, '&im') bw! unlet g:bufnr endfunc func Test_edit_09() " test i_CTRL-\ combinations new call setline(1, ['abc', 'def', 'ghi']) call cursor(1, 1) " 1) CTRL-\ CTLR-N call feedkeys(":set im\\\ccABC\", 'txin') call assert_equal(['ABC', 'def', 'ghi'], getline(1,'$')) call setline(1, ['ABC', 'def', 'ghi']) " 2) CTRL-\ CTLR-G call feedkeys("j0\\ZZZ\\", 'txin') call assert_equal(['ABC', 'ZZZ', 'def', 'ghi'], getline(1,'$')) call feedkeys("I\\YYY\", 'txin') call assert_equal(['ABC', 'ZZZ', 'YYYdef', 'ghi'], getline(1,'$')) set noinsertmode " 3) CTRL-\ CTRL-O call setline(1, ['ABC', 'ZZZ', 'def', 'ghi']) call cursor(1, 1) call feedkeys("A\ix", 'txin') call assert_equal(['ABxC', 'ZZZ', 'def', 'ghi'], getline(1,'$')) call feedkeys("A\\ix", 'txin') call assert_equal(['ABxCx', 'ZZZ', 'def', 'ghi'], getline(1,'$')) " 4) CTRL-\ a (should be inserted literally, not special after call setline(1, ['ABC', 'ZZZ', 'def', 'ghi']) call cursor(1, 1) call feedkeys("A\a", 'txin') call assert_equal(["ABC\a", 'ZZZ', 'def', 'ghi'], getline(1, '$')) bw! endfunc func Test_edit_10() " Test for starting selectmode new set selectmode=key keymodel=startsel call setline(1, ['abc', 'def', 'ghi']) call cursor(1, 4) call feedkeys("A\start\", 'txin') call assert_equal(['startdef', 'ghi'], getline(1, '$')) set selectmode= keymodel= bw! endfunc func Test_edit_11() " Test that indenting kicks in new set cindent call setline(1, ['{', '', '']) call cursor(2, 1) call feedkeys("i\int c;\", 'tnix') call cursor(3, 1) call feedkeys("i/* comment */", 'tnix') call assert_equal(['{', "\int c;", "/* comment */"], getline(1, '$')) " added changed cindentkeys slightly set cindent cinkeys+=*/ call setline(1, ['{', '', '']) call cursor(2, 1) call feedkeys("i\int c;\", 'tnix') call cursor(3, 1) call feedkeys("i/* comment */", 'tnix') call assert_equal(['{', "\int c;", "\/* comment */"], getline(1, '$')) set cindent cinkeys+==end call feedkeys("oend\\", 'tnix') call assert_equal(['{', "\int c;", "\/* comment */", "\tend", ''], getline(1, '$')) set cinkeys-==end %d " Use indentexpr instead of cindenting func! Do_Indent() if v:lnum == 3 return 3*shiftwidth() else return 2*shiftwidth() endif endfunc setl indentexpr=Do_Indent() indentkeys+=*/ call setline(1, ['{', '', '']) call cursor(2, 1) call feedkeys("i\int c;\", 'tnix') call cursor(3, 1) call feedkeys("i/* comment */", 'tnix') call assert_equal(['{', "\\int c;", "\\\/* comment */"], getline(1, '$')) set cinkeys&vim indentkeys&vim set nocindent indentexpr= delfu Do_Indent bw! endfunc func Test_edit_11_indentexpr() " Test that indenting kicks in new " Use indentexpr instead of cindenting func! Do_Indent() let pline=prevnonblank(v:lnum) if empty(getline(v:lnum)) if getline(pline) =~ 'if\|then' return shiftwidth() else return 0 endif else return 0 endif endfunc setl indentexpr=Do_Indent() indentkeys+=0=then,0=fi call setline(1, ['if [ $this ]']) call cursor(1, 1) call feedkeys("othen\that\fi", 'tnix') call assert_equal(['if [ $this ]', "then", "\that", "fi"], getline(1, '$')) set cinkeys&vim indentkeys&vim set nocindent indentexpr= delfu Do_Indent bw! endfunc func Test_edit_12() " Test changing indent in replace mode new call setline(1, ["\tabc", "\tdef"]) call cursor(2, 4) call feedkeys("R^\", 'tnix') call assert_equal(["\tabc", "def"], getline(1, '$')) call assert_equal([0, 2, 2, 0], '.'->getpos()) %d call setline(1, ["\tabc", "\t\tdef"]) call cursor(2, 2) call feedkeys("R^\", 'tnix') call assert_equal(["\tabc", "def"], getline(1, '$')) call assert_equal([0, 2, 1, 0], getpos('.')) %d call setline(1, ["\tabc", "\t\tdef"]) call cursor(2, 2) call feedkeys("R\", 'tnix') call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$')) call assert_equal([0, 2, 2, 0], getpos('.')) bw! 10vnew call setline(1, ["\tabc", "\t\tdef"]) call cursor(2, 2) call feedkeys("R\", 'tnix') call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$')) call assert_equal([0, 2, 2, 0], getpos('.')) %d set sw=4 call setline(1, ["\tabc", "\t\tdef"]) call cursor(2, 2) call feedkeys("R\\", 'tnix') call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$')) call assert_equal([0, 2, 2, 0], getpos('.')) %d call setline(1, ["\tabc", "\t\tdef"]) call cursor(2, 2) call feedkeys("R\\", 'tnix') call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$')) call assert_equal([0, 2, 2, 0], getpos('.')) set et set sw& et& %d call setline(1, ["\t/*"]) set formatoptions=croql call cursor(1, 3) call feedkeys("A\\/", 'tnix') call assert_equal(["\t/*", " *", " */"], getline(1, '$')) set formatoptions& bw! endfunc func Test_edit_13() " Test smartindenting if exists("+smartindent") new set smartindent autoindent call setline(1, ["\tabc"]) call feedkeys("A {\more\}\", 'tnix') call assert_equal(["\tabc {", "\t\tmore", "\t}"], getline(1, '$')) set smartindent& autoindent& bwipe! endif " Test autoindent removing indent of blank line. new call setline(1, ' foo bar baz') set autoindent exe "normal 0eea\\\" call assert_equal(" foo bar", getline(1)) call assert_equal("", getline(2)) call assert_equal(" baz", getline(3)) set autoindent& bwipe! endfunc func! Test_edit_CR() " Test for in insert mode " basically only in quickfix mode ist tested, the rest " has been taken care of by other tests if !has("quickfix") return endif botright new call writefile(range(1, 10), 'Xqflist.txt') call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}]) copen set modifiable call feedkeys("A\", 'tnix') call assert_equal('Xqflist.txt', bufname('')) call assert_equal(2, line('.')) cclose botright new call setloclist(0, [{'filename': 'Xqflist.txt', 'lnum': 10}]) lopen set modifiable call feedkeys("A\", 'tnix') call assert_equal('Xqflist.txt', bufname('')) call assert_equal(10, line('.')) call feedkeys("A\", 'tnix') call feedkeys("A\", 'tnix') call feedkeys("A\n", 'tnix') call feedkeys("A\r", 'tnix') call assert_equal(map(range(1, 10), 'string(v:val)') + ['', '', '', ''], getline(1, '$')) bw! lclose call delete('Xqflist.txt') endfunc func! Test_edit_CTRL_() " disabled for Windows builds, why? if !has("rightleft") || has("win32") return endif let _encoding=&encoding set encoding=utf-8 " Test for CTRL-_ new call setline(1, ['abc']) call cursor(1, 1) call feedkeys("i\xyz\", 'tnix') call assert_equal(["\xyzabc"], getline(1, '$')) call assert_false(&revins) set ari call setline(1, ['abc']) call cursor(1, 1) call feedkeys("i\xyz\", 'tnix') call assert_equal(["æèñabc"], getline(1, '$')) call assert_true(&revins) call setline(1, ['abc']) call cursor(1, 1) call feedkeys("i\xyz\", 'tnix') call assert_equal(["xyzabc"], getline(1, '$')) call assert_false(&revins) set noari let &encoding=_encoding bw! endfunc " needs to come first, to have the @. register empty func Test_edit_00a_CTRL_A() " Test pressing CTRL-A new call setline(1, repeat([''], 5)) call cursor(1, 1) try call feedkeys("A\", 'tnix') catch /^Vim\%((\a\+)\)\=:E29/ call assert_true(1, 'E29 error caught') endtry call cursor(1, 1) call feedkeys("Afoobar \", 'tnix') call cursor(2, 1) call feedkeys("A\more\", 'tnix') call cursor(3, 1) call feedkeys("A\and more\", 'tnix') call assert_equal(['foobar ', 'foobar more', 'foobar morend more', '', ''], getline(1, '$')) bw! endfunc func Test_edit_CTRL_EY() " Ctrl-E/ Ctrl-Y in insert mode completion to scroll 10new call setline(1, range(1, 100)) call cursor(30, 1) norm! z. call feedkeys("A\\\\\\", 'tnix') call assert_equal(30, winsaveview()['topline']) call assert_equal([0, 30, 2, 0], getpos('.')) call feedkeys("A\\\\\\", 'tnix') call feedkeys("A\".repeat("\", 10), 'tnix') call assert_equal(21, winsaveview()['topline']) call assert_equal([0, 30, 2, 0], getpos('.')) bw! endfunc func Test_edit_CTRL_G() new call setline(1, ['foobar', 'foobar', 'foobar']) call cursor(2, 4) call feedkeys("ioooooooo\k\.\", 'tnix') call assert_equal(['foooooooooobar', 'foooooooooobar', 'foobar'], getline(1, '$')) call assert_equal([0, 1, 11, 0], getpos('.')) call feedkeys("i\k\", 'tnix') call assert_equal([0, 1, 10, 0], getpos('.')) call cursor(2, 4) call feedkeys("i\jzzzz\", 'tnix') call assert_equal(['foooooooooobar', 'foooooooooobar', 'foozzzzbar'], getline(1, '$')) call assert_equal([0, 3, 7, 0], getpos('.')) call feedkeys("i\j\", 'tnix') call assert_equal([0, 3, 6, 0], getpos('.')) bw! endfunc func Test_edit_CTRL_I() " Tab in completion mode let path=expand("%:p:h") new call setline(1, [path. "/", '']) call feedkeys("Arunt\\\\\", 'tnix') call assert_match('runtest\.vim', getline(1)) %d call writefile(['one', 'two', 'three'], 'Xinclude.txt') let include='#include Xinclude.txt' call setline(1, [include, '']) call cursor(2, 1) call feedkeys("A\\\\", 'tnix') call assert_equal([include, 'one', ''], getline(1, '$')) call feedkeys("2ggC\\\\\", 'tnix') call assert_equal([include, 'two', ''], getline(1, '$')) call feedkeys("2ggC\\\\\\", 'tnix') call assert_equal([include, 'three', ''], getline(1, '$')) call feedkeys("2ggC\\\\\\\", 'tnix') call assert_equal([include, '', ''], getline(1, '$')) call delete("Xinclude.txt") bw! endfunc func Test_edit_CTRL_K() " Test pressing CTRL-K (basically only dictionary completion and digraphs " the rest is already covered call writefile(['A', 'AA', 'AAA', 'AAAA'], 'Xdictionary.txt') set dictionary=Xdictionary.txt new call setline(1, 'A') call cursor(1, 1) call feedkeys("A\\\\", 'tnix') call assert_equal(['AA', ''], getline(1, '$')) %d call setline(1, 'A') call cursor(1, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(['AAA'], getline(1, '$')) %d call setline(1, 'A') call cursor(1, 1) call feedkeys("A\\\\\\", 'tnix') call assert_equal(['AAAA'], getline(1, '$')) %d call setline(1, 'A') call cursor(1, 1) call feedkeys("A\\\\\\\", 'tnix') call assert_equal(['A'], getline(1, '$')) %d call setline(1, 'A') call cursor(1, 1) call feedkeys("A\\\\\\\\", 'tnix') call assert_equal(['AA'], getline(1, '$')) " press an unexecpted key after dictionary completion %d call setline(1, 'A') call cursor(1, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(['AA', ''], getline(1, '$')) %d call setline(1, 'A') call cursor(1, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(["AA\", ''], getline(1, '$')) %d call setline(1, 'A') call cursor(1, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(["AA\", ''], getline(1, '$')) set dictionary= %d call setline(1, 'A') call cursor(1, 1) let v:testing = 1 try call feedkeys("A\\\", 'tnix') catch " error sleeps 2 seconds, when v:testing is not set let v:testing = 0 endtry call delete('Xdictionary.txt') if exists('*test_override') call test_override("char_avail", 1) set showcmd %d call feedkeys("A\a:\", 'tnix') call assert_equal(['ä'], getline(1, '$')) call test_override("char_avail", 0) set noshowcmd endif bw! endfunc func Test_edit_CTRL_L() " Test Ctrl-X Ctrl-L (line completion) new set complete=. call setline(1, ['one', 'two', 'three', '', '', '', '']) call cursor(4, 1) call feedkeys("A\\\", 'tnix') call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$')) call feedkeys("cct\\\\", 'tnix') call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$')) call feedkeys("cct\\\\\", 'tnix') call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$')) call feedkeys("cct\\\\\\", 'tnix') call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$')) call feedkeys("cct\\\\\\\", 'tnix') call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$')) call feedkeys("cct\\\\", 'tnix') call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$')) call feedkeys("cct\\\\\", 'tnix') call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$')) call feedkeys("cct\\\\\\", 'tnix') call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$')) set complete= call cursor(5, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(['one', 'two', 'three', 'three', "\\\", '', ''], getline(1, '$')) set complete& %d if has("conceal") && has("syntax") && !has("nvim") call setline(1, ['foo', 'bar', 'foobar']) call test_override("char_avail", 1) set conceallevel=2 concealcursor=n syn on syn match ErrorMsg "^bar" call matchadd("Conceal", 'oo', 10, -1, {'conceal': 'X'}) func! DoIt() let g:change=1 endfunc au! TextChangedI :call DoIt() call cursor(2, 1) call assert_false(exists("g:change")) call feedkeys("A \", 'tnix') call assert_equal(['foo', 'bar ', 'foobar'], getline(1, '$')) call assert_equal(1, g:change) call test_override("char_avail", 0) call clearmatches() syn off au! TextChangedI delfu DoIt unlet! g:change endif bw! endfunc func Test_edit_CTRL_N() " Check keyword completion new set complete=. call setline(1, ['INFER', 'loWER', '', '', ]) call cursor(3, 1) call feedkeys("Ai\\\", "tnix") call feedkeys("ILO\\\", 'tnix') call assert_equal(['INFER', 'loWER', 'i', 'LO', '', ''], getline(1, '$')) %d call setline(1, ['INFER', 'loWER', '', '', ]) call cursor(3, 1) set ignorecase infercase call feedkeys("Ii\\\", "tnix") call feedkeys("ILO\\\", 'tnix') call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$')) set noignorecase noinfercase complete& bw! endfunc func Test_edit_CTRL_O() " Check for CTRL-O in insert mode new inoreabbr h here some more call setline(1, ['abc', 'def']) call cursor(1, 1) " Ctrl-O after an abbreviation exe "norm A h\:set nu\ text" call assert_equal(['abc here some more text', 'def'], getline(1, '$')) call assert_true(&nu) set nonu iunabbr h " Ctrl-O at end of line with 've'=onemore call cursor(1, 1) call feedkeys("A\:let g:a=getpos('.')\\", 'tnix') call assert_equal([0, 1, 23, 0], g:a) call cursor(1, 1) set ve=onemore call feedkeys("A\:let g:a=getpos('.')\\", 'tnix') call assert_equal([0, 1, 24, 0], g:a) set ve= unlet! g:a bw! endfunc func! Test_edit_CTRL_R() " Insert Register new " call test_override("ALL", 1) set showcmd call feedkeys("AFOOBAR eins zwei\", 'tnix') call feedkeys("O\.", 'tnix') call feedkeys("O\=10*500\\", 'tnix') call feedkeys("O\=getreg('=', 1)\\", 'tnix') call assert_equal(["getreg('=', 1)", '5000', "FOOBAR eins zwei", "FOOBAR eins zwei"], getline(1, '$')) " call test_override("ALL", 0) set noshowcmd bw! endfunc func Test_edit_CTRL_S() " Test pressing CTRL-S (basically only spellfile completion) " the rest is already covered new if !has("spell") call setline(1, 'vim') call feedkeys("A\ss\\", 'tnix') call assert_equal(['vims', ''], getline(1, '$')) bw! return endif call setline(1, 'vim') " spell option not yet set try call feedkeys("A\\\\", 'tnix') catch /^Vim\%((\a\+)\)\=:E756/ call assert_true(1, 'error caught') endtry call assert_equal(['vim', ''], getline(1, '$')) %d setl spell spelllang=en call setline(1, 'vim') call cursor(1, 1) call feedkeys("A\\\\", 'tnix') call assert_equal(['Vim', ''], getline(1, '$')) %d call setline(1, 'vim') call cursor(1, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(['Aim'], getline(1, '$')) %d call setline(1, 'vim') call cursor(1, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(['vim', ''], getline(1, '$')) %d " empty buffer call cursor(1, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(['', ''], getline(1, '$')) setl nospell bw! endfunc func Test_edit_CTRL_T() " Check for CTRL-T and CTRL-X CTRL-T in insert mode " 1) increase indent new call setline(1, "abc") call cursor(1, 1) call feedkeys("A\xyz", 'tnix') call assert_equal(["\abcxyz"], getline(1, '$')) " 2) also when paste option is set set paste call setline(1, "abc") call cursor(1, 1) call feedkeys("A\xyz", 'tnix') call assert_equal(["\abcxyz"], getline(1, '$')) set nopaste " CTRL-X CTRL-T (thesaurus complete) call writefile(['angry furious mad enraged'], 'Xthesaurus') set thesaurus=Xthesaurus call setline(1, 'mad') call cursor(1, 1) call feedkeys("A\\\\", 'tnix') call assert_equal(['mad', ''], getline(1, '$')) %d call setline(1, 'mad') call cursor(1, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(['angry', ''], getline(1, '$')) %d call setline(1, 'mad') call cursor(1, 1) call feedkeys("A\\\\\\", 'tnix') call assert_equal(['furious', ''], getline(1, '$')) %d call setline(1, 'mad') call cursor(1, 1) call feedkeys("A\\\\\\\", 'tnix') call assert_equal(['enraged', ''], getline(1, '$')) %d call setline(1, 'mad') call cursor(1, 1) call feedkeys("A\\\\\\\\", 'tnix') call assert_equal(['mad', ''], getline(1, '$')) %d call setline(1, 'mad') call cursor(1, 1) call feedkeys("A\\\\\\\\\", 'tnix') call assert_equal(['mad', ''], getline(1, '$')) " Using when 'complete' is empty set complete= %d call setline(1, 'mad') call cursor(1, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(['angry', ''], getline(1, '$')) %d call setline(1, 'mad') call cursor(1, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(['mad', ''], getline(1, '$')) set complete& set thesaurus= %d call setline(1, 'mad') call cursor(1, 1) let v:testing = 1 try call feedkeys("A\\\", 'tnix') catch " error sleeps 2 seconds, when v:testing is not set let v:testing = 0 endtry call assert_equal(['mad'], getline(1, '$')) call delete('Xthesaurus') bw! endfunc " Test 'thesaurusfunc' func MyThesaurus(findstart, base) let mythesaurus = [ \ #{word: "happy", \ synonyms: "cheerful,blissful,flying high,looking good,peppy"}, \ #{word: "kind", \ synonyms: "amiable,bleeding-heart,heart in right place"}] if a:findstart " locate the start of the word let line = getline('.') let start = col('.') - 1 while start > 0 && line[start - 1] =~ '\a' let start -= 1 endwhile return start else " find strings matching with "a:base" let res = [] for w in mythesaurus if w.word =~ '^' . a:base call add(res, w.word) call extend(res, split(w.synonyms, ",")) endif endfor return res endif endfunc func Test_thesaurus_func() new set thesaurus=notused set thesaurusfunc=NotUsed setlocal thesaurusfunc=MyThesaurus call setline(1, "an ki") call cursor(1, 1) call feedkeys("A\\\\\", 'tnix') call assert_equal(['an amiable', ''], getline(1, '$')) setlocal thesaurusfunc=NonExistingFunc call assert_fails("normal $a\\", 'E117:') setlocal thesaurusfunc= set thesaurusfunc=NonExistingFunc call assert_fails("normal $a\\", 'E117:') %bw! set thesaurusfunc= set thesaurus= endfunc func Test_edit_CTRL_U() " Test 'completefunc' new " -1, -2 and -3 are special return values let g:special=0 fun! CompleteMonths(findstart, base) if a:findstart " locate the start of the word return g:special else " find months matching with "a:base" let res = [] for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec") if m =~ '^\c'.a:base call add(res, {'word': m, 'abbr': m.' Month', 'icase': 0}) endif endfor return {'words': res, 'refresh': 'always'} endif endfun set completefunc=CompleteMonths call setline(1, ['', '']) call cursor(1, 1) call feedkeys("AX\\\\", 'tnix') call assert_equal(['X', '', ''], getline(1, '$')) %d let g:special=-1 call feedkeys("AX\\\\", 'tnix') call assert_equal(['XJan', ''], getline(1, '$')) %d let g:special=-2 call feedkeys("AX\\\\", 'tnix') call assert_equal(['X', ''], getline(1, '$')) %d let g:special=-3 call feedkeys("AX\\\\", 'tnix') call assert_equal(['X', ''], getline(1, '$')) %d let g:special=0 call feedkeys("AM\\\\", 'tnix') call assert_equal(['Mar', ''], getline(1, '$')) %d call feedkeys("AM\\\\\", 'tnix') call assert_equal(['May', ''], getline(1, '$')) %d call feedkeys("AM\\\\\\", 'tnix') call assert_equal(['M', ''], getline(1, '$')) delfu CompleteMonths %d try call feedkeys("A\\", 'tnix') call assert_fails(1, 'unknown completion function') catch /^Vim\%((\a\+)\)\=:E117/ call assert_true(1, 'E117 error caught') endtry set completefunc= bw! endfunc func Test_edit_CTRL_Z() " Ctrl-Z when insertmode is not set inserts it literally new call setline(1, 'abc') call feedkeys("A\\", 'tnix') call assert_equal(["abc\"], getline(1,'$')) bw! " TODO: How to Test Ctrl-Z in insert mode, e.g. suspend? endfunc func Test_edit_DROP() if !has("dnd") return endif new call setline(1, ['abc def ghi']) call cursor(1, 1) try call feedkeys("i\\", 'tnix') call assert_fails(1, 'Invalid register name') catch /^Vim\%((\a\+)\)\=:E353/ call assert_true(1, 'error caught') endtry bw! endfunc func Test_edit_CTRL_V() if has("ebcdic") return endif new call setline(1, ['abc']) call cursor(2, 1) " force some redraws set showmode showcmd "call test_override_char_avail(1) " call test_override('ALL', 1) call feedkeys("A\\\\\\\", 'tnix') call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$')) if has("rightleft") && exists("+rl") set rl call setline(1, ['abc']) call cursor(2, 1) call feedkeys("A\\\\\\\", 'tnix') call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$')) set norl endif " call test_override('ALL', 0) set noshowmode showcmd bw! endfunc func Test_edit_F1() " Pressing new call feedkeys(":set im\\\", 'tnix') set noinsertmode call assert_equal('help', &buftype) bw bw endfunc func Test_edit_F21() " Pressing " sends a netbeans command if has("netbeans_intg") new " I have no idea what this is supposed to do :) call feedkeys("A\\\", 'tnix') bw endif endfunc func Test_edit_HOME_END() " Test Home/End Keys new set foldopen+=hor call setline(1, ['abc', 'def']) call cursor(1, 1) call feedkeys("AX\Y\", 'tnix') call cursor(2, 1) call feedkeys("iZ\Y\", 'tnix') call assert_equal(['YabcX', 'ZdefY'], getline(1, '$')) set foldopen-=hor bw! endfunc func Test_edit_INS() " Test for Pressing new call setline(1, ['abc', 'def']) call cursor(1, 1) call feedkeys("i\ZYX>", 'tnix') call assert_equal(['ZYX>', 'def'], getline(1, '$')) call setline(1, ['abc', 'def']) call cursor(1, 1) call feedkeys("i\Z\YX>", 'tnix') call assert_equal(['ZYX>bc', 'def'], getline(1, '$')) bw! endfunc func Test_edit_LEFT_RIGHT() " Left, Shift-Left, Right, Shift-Right new call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX']) let _ww=&ww set ww= call cursor(2, 1) call feedkeys("i\\", 'tnix') call assert_equal([0, 2, 1, 0], getpos('.')) " Is this a bug, does not respect whichwrap option call feedkeys("i\\", 'tnix') call assert_equal([0, 1, 8, 0], getpos('.')) call feedkeys("i". repeat("\", 3). "\", 'tnix') call assert_equal([0, 1, 1, 0], getpos('.')) call feedkeys("i\\", 'tnix') call assert_equal([0, 1, 1, 0], getpos('.')) call feedkeys("i\\\", 'tnix') call assert_equal([0, 1, 2, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 1, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 2, 1, 0], getpos('.')) call feedkeys("i\\", 'tnix') call assert_equal([0, 2, 4, 0], getpos('.')) call cursor(3, 11) call feedkeys("A\\", 'tnix') call feedkeys("A\\", 'tnix') call assert_equal([0, 3, 11, 0], getpos('.')) call cursor(2, 11) " does not respect 'whichwrap' option call feedkeys("A\\", 'tnix') call assert_equal([0, 3, 1, 0], getpos('.')) " Check motion when 'whichwrap' contains cursor keys for insert mode set ww+=[,] call cursor(2, 1) call feedkeys("i\\", 'tnix') call assert_equal([0, 1, 11, 0], getpos('.')) call cursor(2, 11) call feedkeys("A\\", 'tnix') call assert_equal([0, 3, 1, 0], getpos('.')) call cursor(2, 11) call feedkeys("A\\", 'tnix') call assert_equal([0, 3, 1, 0], getpos('.')) let &ww = _ww bw! endfunc func Test_edit_MOUSE() " This is a simple test, since we not really using the mouse here if !has("mouse") return endif 10new call setline(1, range(1, 100)) call cursor(1, 1) set mouse=a call feedkeys("A\\", 'tnix') call assert_equal([0, 4, 1, 0], getpos('.')) " This should move by one pageDown, but only moves " by one line when the test is run... call feedkeys("A\\", 'tnix') call assert_equal([0, 5, 1, 0], getpos('.')) set nostartofline call feedkeys("A\\", 'tnix') call assert_equal([0, 6, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 6, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 6, 1, 0], getpos('.')) call cursor(1, 100) norm! zt " this should move by a screen up, but when the test " is run, it moves up to the top of the buffer... call feedkeys("A\\", 'tnix') call assert_equal([0, 1, 1, 0], getpos('.')) call cursor(1, 30) norm! zt call feedkeys("A\\", 'tnix') call assert_equal([0, 1, 1, 0], getpos('.')) call cursor(1, 30) norm! zt call feedkeys("A\\", 'tnix') call assert_equal([0, 1, 1, 0], getpos('.')) %d call setline(1, repeat(["12345678901234567890"], 100)) call cursor(2, 1) call feedkeys("A\\", 'tnix') call assert_equal([0, 2, 20, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 2, 20, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 2, 20, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 2, 20, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 2, 20, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 2, 20, 0], getpos('.')) set mouse& startofline bw! endfunc func Test_edit_PAGEUP_PAGEDOWN() 10new call setline(1, repeat(['abc def ghi'], 30)) call cursor(1, 1) call feedkeys("i\\", 'tnix') call assert_equal([0, 9, 1, 0], getpos('.')) call feedkeys("i\\", 'tnix') call assert_equal([0, 17, 1, 0], getpos('.')) call feedkeys("i\\", 'tnix') call assert_equal([0, 25, 1, 0], getpos('.')) call feedkeys("i\\", 'tnix') call assert_equal([0, 30, 1, 0], getpos('.')) call feedkeys("i\\", 'tnix') call assert_equal([0, 30, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 29, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 21, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 13, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 5, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 5, 11, 0], getpos('.')) " is the same as " is the same as call cursor(1, 1) call feedkeys("i\\", 'tnix') call assert_equal([0, 9, 1, 0], getpos('.')) call feedkeys("i\\", 'tnix') call assert_equal([0, 17, 1, 0], getpos('.')) call feedkeys("i\\", 'tnix') call assert_equal([0, 25, 1, 0], getpos('.')) call feedkeys("i\\", 'tnix') call assert_equal([0, 30, 1, 0], getpos('.')) call feedkeys("i\\", 'tnix') call assert_equal([0, 30, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 29, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 21, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 13, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 5, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 5, 11, 0], getpos('.')) set nostartofline call cursor(30, 11) norm! zt call feedkeys("A\\", 'tnix') call assert_equal([0, 29, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 21, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 13, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 5, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 5, 11, 0], getpos('.')) call cursor(1, 1) call feedkeys("A\\", 'tnix') call assert_equal([0, 9, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 17, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 25, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 30, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 30, 11, 0], getpos('.')) " is the same as " is the same as call cursor(30, 11) norm! zt call feedkeys("A\\", 'tnix') call assert_equal([0, 29, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 21, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 13, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 5, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 5, 11, 0], getpos('.')) call cursor(1, 1) call feedkeys("A\\", 'tnix') call assert_equal([0, 9, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 17, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 25, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 30, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') call assert_equal([0, 30, 11, 0], getpos('.')) bw! endfunc func Test_edit_forbidden() new " 1) edit in the sandbox is not allowed call setline(1, 'a') com! Sandbox :sandbox call feedkeys("i\\", 'tnix') call assert_fails(':Sandbox', 'E48:') com! Sandbox :sandbox exe "norm! i\" call assert_fails(':Sandbox', 'E48:') delcom Sandbox call assert_equal(['a'], getline(1,'$')) " 2) edit with textlock set fu! DoIt() call feedkeys("i\\", 'tnix') endfu au InsertCharPre :call DoIt() try call feedkeys("ix\", 'tnix') call assert_fails(1, 'textlock') catch /^Vim\%((\a\+)\)\=:E523/ " catch E523: not allowed here endtry " TODO: Might be a bug: should x really be inserted here call assert_equal(['xa'], getline(1, '$')) delfu DoIt try call feedkeys("ix\", 'tnix') call assert_fails(1, 'unknown function') catch /^Vim\%((\a\+)\)\=:E117/ " catch E117: unknown function endtry au! InsertCharPre " 3) edit when completion is shown fun! Complete(findstart, base) if a:findstart return col('.') else call feedkeys("i\\", 'tnix') return [] endif endfun set completefunc=Complete try call feedkeys("i\\\", 'tnix') call assert_fails(1, 'change in complete function') catch /^Vim\%((\a\+)\)\=:E523/ " catch E523 endtry delfu Complete set completefunc= if has("rightleft") && exists("+fkmap") " 4) 'R' when 'fkmap' and 'revins' is set. set revins fkmap try normal Ri call assert_fails(1, "R with 'fkmap' and 'ri' set") catch finally set norevins nofkmap endtry endif bw! endfunc func Test_edit_rightleft() " Cursor in rightleft mode moves differently if !exists("+rightleft") return endif call NewWindow(10, 20) call setline(1, ['abc', 'def', 'ghi']) call cursor(1, 2) set rightleft " Screen looks as expected let lines = ScreenLines([1, 4], winwidth(0)) let expect = [ \" cba", \" fed", \" ihg", \" ~"] call assert_equal(join(expect, "\n"), join(lines, "\n")) " 2) right moves to the left call feedkeys("i\\x", 'txin') call assert_equal(['bc', 'def', 'ghi'], getline(1,'$')) call cursor(1, 2) call feedkeys("i\\", 'txin') call cursor(1, 2) call feedkeys("i\\", 'txin') " Screen looks as expected let lines = ScreenLines([1, 4], winwidth(0)) let expect = [ \" cb", \" fed", \" ihg", \" ~"] call assert_equal(join(expect, "\n"), join(lines, "\n")) " 2) left moves to the right call setline(1, ['abc', 'def', 'ghi']) call cursor(1, 2) call feedkeys("i\\x", 'txin') call assert_equal(['ac', 'def', 'ghi'], getline(1,'$')) call cursor(1, 2) call feedkeys("i\\", 'txin') call cursor(1, 2) call feedkeys("i\\", 'txin') " Screen looks as expected let lines = ScreenLines([1, 4], winwidth(0)) let expect = [ \" ca", \" fed", \" ihg", \" ~"] call assert_equal(join(expect, "\n"), join(lines, "\n")) set norightleft bw! endfunc func Test_edit_backtick() next a\`b c call assert_equal('a`b', expand('%')) next call assert_equal('c', expand('%')) call assert_equal('a\`b c', expand('##')) endfunc func Test_edit_quit() edit foo.txt split new call setline(1, 'hello') 3wincmd w redraw! call assert_fails('1q', 'E37:') bwipe! foo.txt only endfunc func Test_edit_complete_very_long_name() if !has('unix') " Long directory names only work on Unix. return endif let dirname = getcwd() . "/Xdir" let longdirname = dirname . repeat('/' . repeat('d', 255), 4) try call mkdir(longdirname, 'p') catch /E739:/ " Long directory name probably not supported. call delete(dirname, 'rf') return endtry " Try to get the Vim window position before setting 'columns', so that we can " move the window back to where it was. let winposx = getwinposx() let winposy = getwinposy() if winposx >= 0 && winposy >= 0 && !has('gui_running') " We did get the window position, but xterm may report the wrong numbers. " Move the window to the reported position and compute any offset. exe 'winpos ' . winposx . ' ' . winposy sleep 100m let x = getwinposx() if x >= 0 let winposx += winposx - x endif let y = getwinposy() if y >= 0 let winposy += winposy - y endif endif let save_columns = &columns " Need at least about 1100 columns to reproduce the problem. set columns=2000 set noswapfile let longfilename = longdirname . '/' . repeat('a', 255) call writefile(['Totum', 'Table'], longfilename) new exe "next Xfile " . longfilename exe "normal iT\" bwipe! exe 'bwipe! ' . longfilename call delete(dirname, 'rf') let &columns = save_columns if winposx >= 0 && winposy >= 0 exe 'winpos ' . winposx . ' ' . winposy endif set swapfile& endfunc func Test_edit_alt() " Keeping the cursor line didn't happen when the first line has indent. new call setline(1, [' one', 'two', 'three']) w XAltFile $ call assert_equal(3, line('.')) e Xother e # call assert_equal(3, line('.')) bwipe XAltFile call delete('XAltFile') endfunc func Test_edit_InsertLeave() new au InsertLeavePre * let g:did_au_pre = 1 au InsertLeave * let g:did_au = 1 let g:did_au_pre = 0 let g:did_au = 0 call feedkeys("afoo\", 'tx') call assert_equal(1, g:did_au_pre) call assert_equal(1, g:did_au) call assert_equal('foo', getline(1)) let g:did_au_pre = 0 let g:did_au = 0 call feedkeys("Sbar\", 'tx') call assert_equal(1, g:did_au_pre) call assert_equal(0, g:did_au) call assert_equal('bar', getline(1)) inoremap x xx let g:did_au_pre = 0 let g:did_au = 0 call feedkeys("Saax", 'tx') call assert_equal(1, g:did_au_pre) call assert_equal(1, g:did_au) call assert_equal('aaxx', getline(1)) inoremap x xx let g:did_au_pre = 0 let g:did_au = 0 call feedkeys("Sbbx", 'tx') call assert_equal(1, g:did_au_pre) call assert_equal(0, g:did_au) call assert_equal('bbxx', getline(1)) bwipe! au! InsertLeave InsertLeavePre iunmap x endfunc func Test_edit_InsertLeave_undo() new XtestUndo set undofile au InsertLeave * wall exe "normal ofoo\" call assert_equal(2, line('$')) normal u call assert_equal(1, line('$')) bwipe! au! InsertLeave call delete('XtestUndo') set undofile& endfunc " Test for inserting characters using CTRL-V followed by a number. func Test_edit_special_chars() new if has("ebcdic") let t = "o\193\xc2\o303 \90a\xfg\o578\" else let t = "o\65\x42\o103 \33a\xfg\o78\" endif exe "normal " . t call assert_equal("ABC !a\g\8", getline(2)) close! endfunc func Test_edit_startinsert() new set backspace+=start call setline(1, 'foobar') call feedkeys("A\\", 'xt') call assert_equal('', getline(1)) call setline(1, 'foobar') call feedkeys(":startinsert!\\\", 'xt') call assert_equal('', getline(1)) set backspace& bwipe! endfunc func Test_edit_noesckeys() CheckNotGui new " moves cursor when 'esckeys' is set exe "set t_kl=\OD" " set esckeys call feedkeys("axyz\ODX", "xt") " call assert_equal("xyXz", getline(1)) " exits Insert mode when 'esckeys' is off " set noesckeys call setline(1, '') call feedkeys("axyz\ODX", "xt") call assert_equal(["DX", "xyz"], getline(1, 2)) bwipe! " set esckeys endfunc " Test for editing a directory func Test_edit_is_a_directory() CheckEnglish let dirname = getcwd() . "/Xdir" call mkdir(dirname, 'p') new redir => msg exe 'edit' dirname redir END call assert_match("is a directory$", split(msg, "\n")[0]) bwipe! let dirname .= '/' new redir => msg exe 'edit' dirname redir END call assert_match("is a directory$", split(msg, "\n")[0]) bwipe! call delete(dirname, 'rf') endfunc func Test_edit_browse() " in the GUI this opens a file picker, we only test the terminal behavior CheckNotGui " ":browse xxx" checks for the FileExplorer augroup and assumes editing "." " works then. augroup FileExplorer au! augroup END " When the USE_FNAME_CASE is defined this used to cause a crash. browse enew bwipe! browse split bwipe! endfunc func Test_read_invalid() " set encoding=latin1 " This was not properly checking for going past the end. call assert_fails('r`=', 'E484') set encoding=utf-8 endfunc " Test for ModeChanged pattern func Test_mode_changes() let g:count = 0 func! DoIt() let g:count += 1 endfunc let g:index = 0 let g:mode_seq = ['n', 'i', 'n', 'v', 'V', 'n', 'V', 'v', 'n'] func! TestMode() call assert_equal(g:mode_seq[g:index], get(v:event, "old_mode")) call assert_equal(g:mode_seq[g:index + 1], get(v:event, "new_mode")) call assert_equal(mode(1), get(v:event, "new_mode")) let g:index += 1 endfunc au ModeChanged * :call TestMode() au ModeChanged n:* :call DoIt() call feedkeys("i\vV\", 'tnix') call assert_equal(2, g:count) au ModeChanged V:v :call DoIt() call feedkeys("Vv\", 'tnix') call assert_equal(4, g:count) call assert_equal(len(g:mode_seq) - 1, g:index) let g:index = 0 let g:mode_seq = ['n', 'i', 'niI', 'i', 'n'] call feedkeys("a\l\", 'tnix') call assert_equal(len(g:mode_seq) - 1, g:index) au! ModeChanged delfunc TestMode unlet! g:mode_seq unlet! g:index delfunc DoIt unlet! g:count endfunc " vim: shiftwidth=2 sts=2 expandtab