| " Test for edit functions |
| |
| if exists("+t_kD") |
| let &t_kD="[3;*~" |
| endif |
| |
| source util/screendump.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 <buffer> h here some more |
| call cursor(1, 4) |
| " <c-l> expands the abbreviation and ends insertmode |
| call feedkeys(":set im\<cr> h\<c-l>:set noim\<cr>", 'tix') |
| call assert_equal(['abc here some more '], getline(1,'$')) |
| iunabbr <buffer> 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\<del>\<esc>", 'tnix') |
| call assert_equal([''], getline(1,'$')) |
| %d |
| " 3) delete one character |
| call setline(1, 'a') |
| call feedkeys("i\<del>\<esc>", 'tnix') |
| call assert_equal([''], getline(1,'$')) |
| %d |
| " 4) delete a multibyte character |
| call setline(1, "\u0401") |
| call feedkeys("i\<del>\<esc>", '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\<del>\<esc>", '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\<del>\<esc>", '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 <buffer> :call DoIt('y') |
| call feedkeys("ix\<esc>", 'tnix') |
| call assert_equal(['abcy'], getline(1, '$')) |
| " Setting <Enter> in InsertCharPre |
| au! InsertCharPre <buffer> :call DoIt("\n") |
| call setline(1, 'abc') |
| call cursor(1, 1) |
| call feedkeys("ix\<esc>", '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 <buffer> :call DoIt('y') |
| call setline(1, 'abc') |
| call cursor(1, 1) |
| call feedkeys("ix\<esc>", 'tnix') |
| call assert_equal(['abxc'], getline(1, '$')) |
| " 2) when not setting v:char, restores changed cursor position |
| au! InsertEnter <buffer> :call DoIt() |
| call setline(1, 'abc') |
| call cursor(1, 1) |
| call feedkeys("ix\<esc>", 'tnix') |
| call assert_equal(['xabc'], getline(1, '$')) |
| au! InsertEnter |
| delfu DoIt |
| bw! |
| endfunc |
| |
| func Test_edit_03() |
| " Change cursor after <c-o> command to end of line |
| new |
| call setline(1, 'abc') |
| call cursor(1, 1) |
| call feedkeys("i\<c-o>$y\<esc>", 'tnix') |
| call assert_equal(['abcy'], getline(1, '$')) |
| %d |
| call setline(1, 'abc') |
| call cursor(1, 1) |
| call feedkeys("i\<c-o>80|y\<esc>", 'tnix') |
| call assert_equal(['abcy'], getline(1, '$')) |
| %d |
| call setline(1, 'abc') |
| call feedkeys("Ad\<c-o>:s/$/efg/\<cr>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\<c-o>:stopinsert\<cr>$", 'tnix') |
| call feedkeys("aX\<esc>", '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\<esc>", '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\<esc>", 'tnix') |
| call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$')) |
| %d |
| bw! |
| endfunc |
| |
| func Test_edit_06() |
| " Test in diff mode |
| CheckFeature diff |
| CheckExecutable diff |
| 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\<esc>", 'tnix') |
| call assert_equal(['abc', 'zzz', 'xxx', 'yyy'], getline(1,'$')) |
| bw! |
| bw! |
| endfunc |
| |
| func Test_edit_07() |
| " 1) Test with completion <c-l> 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 <buffer> <F5> <C-R>=ListMonths()<CR> |
| |
| call feedkeys("A\<f5>\<c-p>". repeat("\<down>", 6)."\<c-l>\<down>\<c-l>\<cr>", '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 <buffer> :call DoIt() |
| call feedkeys("A\<f5>\<c-p>u\<C-Y>\<c-l>\<cr>", 'tx') |
| call assert_equal(["Jan\<c-l>",''], 1->getline('$')) |
| %d |
| call setline(1, 'J') |
| call feedkeys("A\<f5>\<c-p>u\<down>\<c-l>\<cr>", 'tx') |
| call assert_equal(["January"], 1->getline('$')) |
| |
| delfu ListMonths |
| delfu DoIt |
| iunmap <buffer> <f5> |
| bw! |
| endfunc |
| |
| func Test_edit_08() |
| " reset insertmode from i_ctrl-r_= |
| let g:bufnr = bufnr('%') |
| new |
| call setline(1, ['abc']) |
| call cursor(1, 4) |
| call feedkeys(":set im\<cr>ZZZ\<c-r>=setbufvar(g:bufnr,'&im', 0)\<cr>",'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\<cr>\<c-\>\<c-n>ccABC\<c-l>", 'txin') |
| call assert_equal(['ABC', 'def', 'ghi'], getline(1,'$')) |
| call setline(1, ['ABC', 'def', 'ghi']) |
| " 2) CTRL-\ CTLR-G |
| call feedkeys("j0\<c-\>\<c-g>ZZZ\<cr>\<c-l>", 'txin') |
| call assert_equal(['ABC', 'ZZZ', 'def', 'ghi'], getline(1,'$')) |
| call feedkeys("I\<c-\>\<c-g>YYY\<c-l>", '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\<c-o>ix", 'txin') |
| call assert_equal(['ABxC', 'ZZZ', 'def', 'ghi'], getline(1,'$')) |
| call feedkeys("A\<c-\>\<c-o>ix", 'txin') |
| call assert_equal(['ABxCx', 'ZZZ', 'def', 'ghi'], getline(1,'$')) |
| " 4) CTRL-\ a (should be inserted literally, not special after <c-\> |
| call setline(1, ['ABC', 'ZZZ', 'def', 'ghi']) |
| call cursor(1, 1) |
| call feedkeys("A\<c-\>a", 'txin') |
| call assert_equal(["ABC\<c-\>a", 'ZZZ', 'def', 'ghi'], getline(1, '$')) |
| bw! |
| endfunc |
| |
| func Test_edit_11() |
| " Test that indenting kicks in |
| new |
| set cindent |
| call setline(1, ['{', '', '']) |
| call cursor(2, 1) |
| call feedkeys("i\<c-f>int c;\<esc>", 'tnix') |
| call cursor(3, 1) |
| call feedkeys("\<Insert>/* comment */", 'tnix') |
| call assert_equal(['{', "\<tab>int c;", "/* comment */"], getline(1, '$')) |
| " added changed cindentkeys slightly |
| set cindent cinkeys+=*/ |
| call setline(1, ['{', '', '']) |
| call cursor(2, 1) |
| call feedkeys("i\<c-f>int c;\<esc>", 'tnix') |
| call cursor(3, 1) |
| call feedkeys("i/* comment */", 'tnix') |
| call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */"], getline(1, '$')) |
| set cindent cinkeys+==end |
| call feedkeys("oend\<cr>\<esc>", 'tnix') |
| call assert_equal(['{', "\<tab>int c;", "\<tab>/* 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\<c-f>int c;\<esc>", 'tnix') |
| call cursor(3, 1) |
| call feedkeys("i/* comment */", 'tnix') |
| call assert_equal(['{', "\<tab>\<tab>int c;", "\<tab>\<tab>\<tab>/* 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\<cr>that\<cr>fi", 'tnix') |
| call assert_equal(['if [ $this ]', "then", "\<tab>that", "fi"], getline(1, '$')) |
| set cinkeys&vim indentkeys&vim |
| set nocindent indentexpr= |
| delfu Do_Indent |
| |
| " Using a script-local function |
| func s:NewIndentExpr() |
| endfunc |
| set indentexpr=s:NewIndentExpr() |
| call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr) |
| call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr) |
| set indentexpr=<SID>NewIndentExpr() |
| call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr) |
| call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr) |
| setlocal indentexpr= |
| setglobal indentexpr=s:NewIndentExpr() |
| call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr) |
| call assert_equal('', &indentexpr) |
| new |
| call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr) |
| bw! |
| setglobal indentexpr=<SID>NewIndentExpr() |
| call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr) |
| call assert_equal('', &indentexpr) |
| new |
| call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr) |
| bw! |
| set indentexpr& |
| |
| bw! |
| endfunc |
| |
| " Test changing indent in replace mode |
| func Test_edit_12() |
| new |
| call setline(1, ["\tabc", "\tdef"]) |
| call cursor(2, 4) |
| call feedkeys("R^\<c-d>", '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^\<c-d>", '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\<c-t>", '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\<c-t>", '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\<c-t>\<c-t>", '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\<c-t>\<c-t>", 'tnix') |
| call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$')) |
| call assert_equal([0, 2, 2, 0], getpos('.')) |
| set sw& |
| |
| " In replace mode, after hitting enter in a line with tab characters, |
| " pressing backspace should restore the tab characters. |
| %d |
| setlocal autoindent backspace=2 |
| call setline(1, "\tone\t\ttwo") |
| exe "normal ggRred\<CR>six" .. repeat("\<BS>", 8) |
| call assert_equal(["\tone\t\ttwo"], getline(1, '$')) |
| bw! |
| endfunc |
| |
| func Test_edit_13() |
| " Test smartindenting |
| new |
| set smartindent autoindent |
| call setline(1, ["\tabc"]) |
| call feedkeys("A {\<cr>more\<cr>}\<esc>", 'tnix') |
| call assert_equal(["\tabc {", "\t\tmore", "\t}"], getline(1, '$')) |
| set smartindent& autoindent& |
| bwipe! |
| |
| " Test autoindent removing indent of blank line. |
| new |
| call setline(1, ' foo bar baz') |
| set autoindent |
| exe "normal 0eea\<CR>\<CR>\<Esc>" |
| call assert_equal(" foo bar", getline(1)) |
| call assert_equal("", getline(2)) |
| call assert_equal(" baz", getline(3)) |
| set autoindent& |
| |
| " pressing <C-U> to erase line should keep the indent with 'autoindent' |
| set backspace=2 autoindent |
| %d |
| exe "normal i\tone\<CR>three\<C-U>two" |
| call assert_equal(["\tone", "\ttwo"], getline(1, '$')) |
| set backspace& autoindent& |
| |
| bwipe! |
| endfunc |
| |
| " Test for autoindent removing indent when insert mode is stopped. Some parts |
| " of the code is exercised only when interactive mode is used. So use Vim in a |
| " terminal. |
| func Test_autoindent_remove_indent() |
| CheckRunVimInTerminal |
| let buf = RunVimInTerminal('-N Xarifile', {'rows': 6, 'cols' : 20}) |
| call TermWait(buf) |
| call term_sendkeys(buf, ":set autoindent\n") |
| " leaving insert mode in a new line with indent added by autoindent, should |
| " remove the indent. |
| call term_sendkeys(buf, "i\<Tab>foo\<CR>\<Esc>") |
| " Need to delay for some time, otherwise the code in getchar.c will not be |
| " exercised. |
| call TermWait(buf, 50) |
| " when a line is wrapped and the cursor is at the start of the second line, |
| " leaving insert mode, should move the cursor back to the first line. |
| call term_sendkeys(buf, "o" .. repeat('x', 20) .. "\<Esc>") |
| " Need to delay for some time, otherwise the code in getchar.c will not be |
| " exercised. |
| call TermWait(buf, 50) |
| call term_sendkeys(buf, ":w\n") |
| call TermWait(buf) |
| call StopVimInTerminal(buf) |
| call assert_equal(["\tfoo", '', repeat('x', 20)], readfile('Xarifile')) |
| call delete('Xarifile') |
| endfunc |
| |
| func Test_edit_esc_after_CR_autoindent() |
| new |
| setlocal autoindent |
| autocmd InsertLeavePre * let g:prev_cursor = getpos('.') |
| |
| call setline(1, 'foobar') |
| exe "normal! $hi\<CR>\<Esc>" |
| call assert_equal(['foob', 'ar'], getline(1, '$')) |
| call assert_equal([0, 2, 1, 0], getpos('.')) |
| call assert_equal([0, 2, 1, 0], getpos("'^")) |
| call assert_equal([0, 2, 1, 0], g:prev_cursor) |
| %d |
| |
| call setline(1, 'foobar') |
| exe "normal! $i\<CR>\<Esc>" |
| call assert_equal(['fooba', 'r'], getline(1, '$')) |
| call assert_equal([0, 2, 1, 0], getpos('.')) |
| call assert_equal([0, 2, 1, 0], getpos("'^")) |
| call assert_equal([0, 2, 1, 0], g:prev_cursor) |
| %d |
| |
| call setline(1, 'foobar') |
| exe "normal! A\<CR>\<Esc>" |
| call assert_equal(['foobar', ''], getline(1, '$')) |
| call assert_equal([0, 2, 1, 0], getpos('.')) |
| call assert_equal([0, 2, 1, 0], getpos("'^")) |
| call assert_equal([0, 2, 1, 0], g:prev_cursor) |
| %d |
| |
| call setline(1, ' foobar') |
| exe "normal! $hi\<CR>\<Esc>" |
| call assert_equal([' foob', ' ar'], getline(1, '$')) |
| call assert_equal([0, 2, 2, 0], getpos('.')) |
| call assert_equal([0, 2, 3, 0], getpos("'^")) |
| call assert_equal([0, 2, 3, 0], g:prev_cursor) |
| %d |
| |
| call setline(1, ' foobar') |
| exe "normal! $i\<CR>\<Esc>" |
| call assert_equal([' fooba', ' r'], getline(1, '$')) |
| call assert_equal([0, 2, 2, 0], getpos('.')) |
| call assert_equal([0, 2, 3, 0], getpos("'^")) |
| call assert_equal([0, 2, 3, 0], g:prev_cursor) |
| %d |
| |
| call setline(1, ' foobar') |
| exe "normal! A\<CR>\<Esc>" |
| call assert_equal([' foobar', ''], getline(1, '$')) |
| call assert_equal([0, 2, 1, 0], getpos('.')) |
| call assert_equal([0, 2, 1, 0], getpos("'^")) |
| call assert_equal([0, 2, 1, 0], g:prev_cursor) |
| %d |
| |
| autocmd! InsertLeavePre |
| unlet g:prev_cursor |
| bwipe! |
| endfunc |
| |
| func Test_edit_CR() |
| " Test for <CR> in insert mode |
| " basically only in quickfix mode it's tested, the rest |
| " has been taken care of by other tests |
| CheckFeature quickfix |
| botright new |
| call writefile(range(1, 10), 'Xqflist.txt', 'D') |
| call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}]) |
| copen |
| set modifiable |
| call feedkeys("A\<cr>", '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\<cr>", 'tnix') |
| call assert_equal('Xqflist.txt', bufname('')) |
| call assert_equal(10, line('.')) |
| call feedkeys("A\<Enter>", 'tnix') |
| call feedkeys("A\<kEnter>", '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 |
| endfunc |
| |
| func Test_edit_CTRL_() |
| CheckFeature rightleft |
| " disabled for Windows builds, why? |
| CheckNotMSWindows |
| let _encoding=&encoding |
| set encoding=utf-8 |
| " Test for CTRL-_ |
| new |
| call setline(1, ['abc']) |
| call cursor(1, 1) |
| call feedkeys("i\<c-_>xyz\<esc>", 'tnix') |
| call assert_equal(["\<C-_>xyzabc"], getline(1, '$')) |
| call assert_false(&revins) |
| set ari |
| call setline(1, ['abc']) |
| call cursor(1, 1) |
| call feedkeys("i\<c-_>xyz\<esc>", 'tnix') |
| call assert_equal(["æèñabc"], getline(1, '$')) |
| call assert_true(&revins) |
| call setline(1, ['abc']) |
| call cursor(1, 1) |
| call feedkeys("i\<c-_>xyz\<esc>", '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\<NUL>", 'tnix') |
| catch /^Vim\%((\a\+)\)\=:E29/ |
| call assert_true(1, 'E29 error caught') |
| endtry |
| call cursor(1, 1) |
| call feedkeys("Afoobar \<esc>", 'tnix') |
| call cursor(2, 1) |
| call feedkeys("A\<c-a>more\<esc>", 'tnix') |
| call cursor(3, 1) |
| call feedkeys("A\<NUL>and more\<esc>", '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\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix') |
| call assert_equal(30, winsaveview()['topline']) |
| call assert_equal([0, 30, 2, 0], getpos('.')) |
| call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix') |
| call feedkeys("A\<c-x>".repeat("\<c-y>", 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\<c-g>k\<c-r>.\<esc>", 'tnix') |
| call assert_equal(['foooooooooobar', 'foooooooooobar', 'foobar'], getline(1, '$')) |
| call assert_equal([0, 1, 11, 0], getpos('.')) |
| call feedkeys("i\<c-g>k\<esc>", 'tnix') |
| call assert_equal([0, 1, 10, 0], getpos('.')) |
| call cursor(2, 4) |
| call feedkeys("i\<c-g>jzzzz\<esc>", 'tnix') |
| call assert_equal(['foooooooooobar', 'foooooooooobar', 'foozzzzbar'], getline(1, '$')) |
| call assert_equal([0, 3, 7, 0], getpos('.')) |
| call feedkeys("i\<c-g>j\<esc>", 'tnix') |
| call assert_equal([0, 3, 6, 0], getpos('.')) |
| call assert_nobeep("normal! i\<c-g>\<esc>") |
| bw! |
| endfunc |
| |
| func Test_edit_CTRL_I() |
| " Tab in completion mode |
| let path=expand("%:p:h") |
| new |
| call setline(1, [path. "/", '']) |
| call feedkeys("Arunt\<c-x>\<c-f>\<tab>\<cr>\<esc>", 'tnix') |
| call assert_match('runtest\.vim', getline(1)) |
| %d |
| call writefile(['one', 'two', 'three'], 'Xinclude.txt', 'D') |
| let include='#include Xinclude.txt' |
| call setline(1, [include, '']) |
| call cursor(2, 1) |
| call feedkeys("A\<c-x>\<tab>\<cr>\<esc>", 'tnix') |
| call assert_equal([include, 'one', ''], getline(1, '$')) |
| call feedkeys("2ggC\<c-x>\<tab>\<down>\<cr>\<esc>", 'tnix') |
| call assert_equal([include, 'two', ''], getline(1, '$')) |
| call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<cr>\<esc>", 'tnix') |
| call assert_equal([include, 'three', ''], getline(1, '$')) |
| call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<down>\<cr>\<esc>", 'tnix') |
| call assert_equal([include, '', ''], getline(1, '$')) |
| 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', 'D') |
| set dictionary=Xdictionary.txt |
| new |
| call setline(1, 'A') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-k>\<cr>\<esc>", 'tnix') |
| call assert_equal(['AA', ''], getline(1, '$')) |
| %d |
| call setline(1, 'A') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-k>\<down>\<cr>\<esc>", 'tnix') |
| call assert_equal(['AAA'], getline(1, '$')) |
| %d |
| call setline(1, 'A') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<cr>\<esc>", 'tnix') |
| call assert_equal(['AAAA'], getline(1, '$')) |
| %d |
| call setline(1, 'A') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<cr>\<esc>", 'tnix') |
| call assert_equal(['A'], getline(1, '$')) |
| %d |
| call setline(1, 'A') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<down>\<cr>\<esc>", 'tnix') |
| call assert_equal(['AA'], getline(1, '$')) |
| |
| " press an unexpected key after dictionary completion |
| %d |
| call setline(1, 'A') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-k>\<c-]>\<cr>\<esc>", 'tnix') |
| call assert_equal(['AA', ''], getline(1, '$')) |
| %d |
| call setline(1, 'A') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-k>\<c-s>\<cr>\<esc>", 'tnix') |
| call assert_equal(["AA\<c-s>", ''], getline(1, '$')) |
| %d |
| call setline(1, 'A') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-k>\<c-f>\<cr>\<esc>", 'tnix') |
| call assert_equal(["AA\<c-f>", ''], getline(1, '$')) |
| |
| set dictionary= |
| %d |
| call setline(1, 'A') |
| call cursor(1, 1) |
| try |
| call feedkeys("A\<c-x>\<c-k>\<esc>", 'tnix') |
| catch |
| endtry |
| |
| call test_override("char_avail", 1) |
| set showcmd |
| %d |
| call feedkeys("A\<c-k>a:\<esc>", 'tnix') |
| call assert_equal(['ä'], getline(1, '$')) |
| call test_override("char_avail", 0) |
| set noshowcmd |
| |
| 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\<c-x>\<c-l>\<esc>", 'tnix') |
| call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$')) |
| call feedkeys("cct\<c-x>\<c-l>\<c-n>\<esc>", 'tnix') |
| call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$')) |
| call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<esc>", 'tnix') |
| call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$')) |
| call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix') |
| call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$')) |
| call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix') |
| call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$')) |
| call feedkeys("cct\<c-x>\<c-l>\<c-p>\<esc>", 'tnix') |
| call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$')) |
| call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<esc>", 'tnix') |
| call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$')) |
| call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<c-p>\<esc>", 'tnix') |
| call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$')) |
| set complete= |
| call cursor(5, 1) |
| call feedkeys("A\<c-x>\<c-l>\<c-p>\<c-n>\<esc>", 'tnix') |
| call assert_equal(['one', 'two', 'three', 'three', "\<c-l>\<c-p>\<c-n>", '', ''], getline(1, '$')) |
| set complete& |
| %d |
| if has("conceal") && has("syntax") |
| 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 <buffer> :call DoIt() |
| |
| call cursor(2, 1) |
| call assert_false(exists("g:change")) |
| call feedkeys("A \<esc>", '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 |
| for e in ['latin1', 'utf-8'] |
| exe 'set encoding=' .. e |
| new |
| set complete=. |
| call setline(1, ['INFER', 'loWER', '', '', ]) |
| call cursor(3, 1) |
| call feedkeys("Ai\<c-n>\<cr>\<esc>", "tnix") |
| call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix') |
| call assert_equal(['INFER', 'loWER', 'i', 'LO', '', ''], getline(1, '$'), e) |
| %d |
| call setline(1, ['INFER', 'loWER', '', '', ]) |
| call cursor(3, 1) |
| set ignorecase infercase |
| call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix") |
| call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix') |
| call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'), e) |
| set noignorecase noinfercase |
| %d |
| call setline(1, ['one word', 'two word']) |
| exe "normal! Goo\<C-P>\<C-X>\<C-P>" |
| call assert_equal('one word', getline(3)) |
| %d |
| set complete& |
| bw! |
| endfor |
| endfunc |
| |
| func Test_edit_CTRL_O() |
| " Check for CTRL-O in insert mode |
| new |
| inoreabbr <buffer> h here some more |
| call setline(1, ['abc', 'def']) |
| call cursor(1, 1) |
| " Ctrl-O after an abbreviation |
| exe "norm A h\<c-o>:set nu\<cr> text" |
| call assert_equal(['abc here some more text', 'def'], getline(1, '$')) |
| call assert_true(&nu) |
| set nonu |
| iunabbr <buffer> h |
| " Ctrl-O at end of line with 've'=onemore |
| call cursor(1, 1) |
| call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix') |
| call assert_equal([0, 1, 23, 0], g:a) |
| call cursor(1, 1) |
| set ve=onemore |
| call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", '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\<esc>", 'tnix') |
| call feedkeys("O\<c-r>.", 'tnix') |
| call feedkeys("O\<c-r>=10*500\<cr>\<esc>", 'tnix') |
| call feedkeys("O\<c-r>=getreg('=', 1)\<cr>\<esc>", '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\<c-x>ss\<cr>\<esc>", 'tnix') |
| call assert_equal(['vims', ''], getline(1, '$')) |
| bw! |
| return |
| endif |
| call setline(1, 'vim') |
| " spell option not yet set |
| try |
| call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", '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\<c-x>\<c-s>\<cr>\<esc>", 'tnix') |
| call assert_equal(['Vim', ''], getline(1, '$')) |
| %d |
| call setline(1, 'vim') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-s>\<down>\<cr>\<esc>", 'tnix') |
| call assert_equal(['Aim'], getline(1, '$')) |
| %d |
| call setline(1, 'vim') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix') |
| call assert_equal(['vim', ''], getline(1, '$')) |
| %d |
| " empty buffer |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", '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\<c-t>xyz", 'tnix') |
| call assert_equal(["\<tab>abcxyz"], getline(1, '$')) |
| " 2) also when paste option is set |
| set paste |
| call setline(1, "abc") |
| call cursor(1, 1) |
| call feedkeys("A\<c-t>xyz", 'tnix') |
| call assert_equal(["\<tab>abcxyz"], getline(1, '$')) |
| set nopaste |
| " CTRL-X CTRL-T (thesaurus complete) |
| call writefile(['angry furious mad enraged'], 'Xthesaurus', 'D') |
| set thesaurus=Xthesaurus |
| call setline(1, 'mad') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix') |
| call assert_equal(['mad', ''], getline(1, '$')) |
| %d |
| call setline(1, 'mad') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix') |
| call assert_equal(['angry', ''], getline(1, '$')) |
| %d |
| call setline(1, 'mad') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<cr>\<esc>", 'tnix') |
| call assert_equal(['furious', ''], getline(1, '$')) |
| %d |
| call setline(1, 'mad') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix') |
| call assert_equal(['enraged', ''], getline(1, '$')) |
| %d |
| call setline(1, 'mad') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix') |
| call assert_equal(['mad', ''], getline(1, '$')) |
| %d |
| call setline(1, 'mad') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix') |
| call assert_equal(['mad', ''], getline(1, '$')) |
| " Using <c-p> <c-n> when 'complete' is empty |
| set complete= |
| %d |
| call setline(1, 'mad') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix') |
| call assert_equal(['angry', ''], getline(1, '$')) |
| %d |
| call setline(1, 'mad') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-t>\<c-p>\<cr>\<esc>", 'tnix') |
| call assert_equal(['mad', ''], getline(1, '$')) |
| set complete& |
| |
| set thesaurus= |
| %d |
| call setline(1, 'mad') |
| call cursor(1, 1) |
| try |
| call feedkeys("A\<c-x>\<c-t>\<esc>", 'tnix') |
| catch |
| endtry |
| call assert_equal(['mad'], getline(1, '$')) |
| bw! |
| endfunc |
| |
| " Test thesaurus completion with different encodings |
| func Test_thesaurus_complete_with_encoding() |
| call writefile(['angry furious mad enraged'], 'Xthesaurus', 'D') |
| set thesaurus=Xthesaurus |
| for e in ['latin1', 'utf-8'] |
| exe 'set encoding=' .. e |
| new |
| call setline(1, 'mad') |
| call cursor(1, 1) |
| call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix') |
| call assert_equal(['mad', ''], getline(1, '$')) |
| bw! |
| endfor |
| set thesaurus= |
| 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\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix') |
| call assert_equal(['an amiable', ''], getline(1, '$')) |
| |
| setlocal thesaurusfunc=NonExistingFunc |
| call assert_fails("normal $a\<C-X>\<C-T>", 'E117:') |
| |
| setlocal thesaurusfunc= |
| set thesaurusfunc=NonExistingFunc |
| call assert_fails("normal $a\<C-X>\<C-T>", '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\<c-x>\<c-u>\<cr>\<esc>", 'tnix') |
| call assert_equal(['X', '', ''], getline(1, '$')) |
| %d |
| let g:special=-1 |
| call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix') |
| call assert_equal(['XJan', ''], getline(1, '$')) |
| %d |
| let g:special=-2 |
| call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix') |
| call assert_equal(['X', ''], getline(1, '$')) |
| %d |
| let g:special=-3 |
| call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix') |
| call assert_equal(['X', ''], getline(1, '$')) |
| %d |
| let g:special=0 |
| call feedkeys("AM\<c-x>\<c-u>\<cr>\<esc>", 'tnix') |
| call assert_equal(['Mar', ''], getline(1, '$')) |
| %d |
| call feedkeys("AM\<c-x>\<c-u>\<c-n>\<cr>\<esc>", 'tnix') |
| call assert_equal(['May', ''], getline(1, '$')) |
| %d |
| call feedkeys("AM\<c-x>\<c-u>\<c-n>\<c-n>\<cr>\<esc>", 'tnix') |
| call assert_equal(['M', ''], getline(1, '$')) |
| delfu CompleteMonths |
| %d |
| try |
| call feedkeys("A\<c-x>\<c-u>", '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_completefunc_delete() |
| func CompleteFunc(findstart, base) |
| if a:findstart == 1 |
| return col('.') - 1 |
| endif |
| normal dd |
| return ['a', 'b'] |
| endfunc |
| new |
| set completefunc=CompleteFunc |
| call setline(1, ['', 'abcd', '']) |
| 2d |
| call assert_fails("normal 2G$a\<C-X>\<C-U>", 'E565:') |
| bwipe! |
| endfunc |
| |
| |
| func Test_edit_CTRL_Z() |
| " Ctrl-Z when insertmode is not set inserts it literally |
| new |
| call setline(1, 'abc') |
| call feedkeys("A\<c-z>\<esc>", 'tnix') |
| call assert_equal(["abc\<c-z>"], getline(1,'$')) |
| bw! |
| " TODO: How to Test Ctrl-Z in insert mode, e.g. suspend? |
| endfunc |
| |
| func Test_edit_DROP() |
| CheckFeature dnd |
| new |
| call setline(1, ['abc def ghi']) |
| call cursor(1, 1) |
| try |
| call feedkeys("i\<Drop>\<Esc>", '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() |
| new |
| call setline(1, ['abc']) |
| call cursor(2, 1) |
| |
| " force some redraws |
| set showmode showcmd |
| call test_override('char_avail', 1) |
| |
| call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", '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\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix') |
| call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$')) |
| set norl |
| endif |
| |
| set noshowmode showcmd |
| call test_override('char_avail', 0) |
| |
| " No modifiers should be applied to the char typed using i_CTRL-V_digit. |
| call feedkeys(":append\<CR>\<C-V>76c\<C-V>76\<C-F2>\<C-V>u3c0j\<C-V>u3c0\<M-F3>\<CR>.\<CR>", 'tnix') |
| call assert_equal('LcL<C-F2>πjπ<M-F3>', getline(2)) |
| |
| if has('osx') |
| " A char with a modifier should not be a valid char for i_CTRL-V_digit. |
| call feedkeys("o\<C-V>\<D-j>\<C-V>\<D-1>\<C-V>\<D-o>\<C-V>\<D-x>\<C-V>\<D-u>", 'tnix') |
| call assert_equal('<D-j><D-1><D-o><D-x><D-u>', getline(3)) |
| endif |
| |
| bw! |
| endfunc |
| |
| func Test_edit_F1() |
| CheckFeature quickfix |
| |
| " Pressing <f1> |
| new |
| call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix') |
| set noinsertmode |
| call assert_equal('help', &buftype) |
| bw |
| bw |
| endfunc |
| |
| func Test_edit_F21() |
| " Pressing <f21> |
| " sends a netbeans command |
| CheckFeature netbeans_intg |
| new |
| " I have no idea what this is supposed to do :) |
| call feedkeys("A\<F21>\<F1>\<esc>", 'tnix') |
| bw |
| 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\<Home>Y\<esc>", 'tnix') |
| call cursor(2, 1) |
| call feedkeys("iZ\<End>Y\<esc>", 'tnix') |
| call assert_equal(['YabcX', 'ZdefY'], getline(1, '$')) |
| |
| set foldopen-=hor |
| bw! |
| endfunc |
| |
| func Test_edit_INS() |
| " Test for Pressing <Insert> |
| new |
| call setline(1, ['abc', 'def']) |
| call cursor(1, 1) |
| call feedkeys("i\<Insert>ZYX>", 'tnix') |
| call assert_equal(['ZYX>', 'def'], getline(1, '$')) |
| call setline(1, ['abc', 'def']) |
| call cursor(1, 1) |
| call feedkeys("i\<Insert>Z\<Insert>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\<left>\<esc>", 'tnix') |
| call assert_equal([0, 2, 1, 0], getpos('.')) |
| " Is this a bug, <s-left> does not respect whichwrap option |
| call feedkeys("i\<s-left>\<esc>", 'tnix') |
| call assert_equal([0, 1, 8, 0], getpos('.')) |
| call feedkeys("i". repeat("\<s-left>", 3). "\<esc>", 'tnix') |
| call assert_equal([0, 1, 1, 0], getpos('.')) |
| call feedkeys("i\<right>\<esc>", 'tnix') |
| call assert_equal([0, 1, 1, 0], getpos('.')) |
| call feedkeys("i\<right>\<right>\<esc>", 'tnix') |
| call assert_equal([0, 1, 2, 0], getpos('.')) |
| call feedkeys("A\<right>\<esc>", 'tnix') |
| call assert_equal([0, 1, 11, 0], getpos('.')) |
| call feedkeys("A\<s-right>\<esc>", 'tnix') |
| call assert_equal([0, 2, 1, 0], getpos('.')) |
| call feedkeys("i\<s-right>\<esc>", 'tnix') |
| call assert_equal([0, 2, 4, 0], getpos('.')) |
| call cursor(3, 11) |
| call feedkeys("A\<right>\<esc>", 'tnix') |
| call feedkeys("A\<s-right>\<esc>", 'tnix') |
| call assert_equal([0, 3, 11, 0], getpos('.')) |
| call cursor(2, 11) |
| " <S-Right> does not respect 'whichwrap' option |
| call feedkeys("A\<s-right>\<esc>", '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\<left>\<esc>", 'tnix') |
| call assert_equal([0, 1, 11, 0], getpos('.')) |
| call cursor(2, 11) |
| call feedkeys("A\<right>\<esc>", 'tnix') |
| call assert_equal([0, 3, 1, 0], getpos('.')) |
| call cursor(2, 11) |
| call feedkeys("A\<s-right>\<esc>", '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're not really using the mouse here |
| CheckFeature mouse |
| 10new |
| call setline(1, range(1, 100)) |
| call cursor(1, 1) |
| call assert_equal(1, line('w0')) |
| call assert_equal(10, line('w$')) |
| set mouse=a |
| " One scroll event moves three lines. |
| call feedkeys("A\<ScrollWheelDown>\<esc>", 'tnix') |
| call assert_equal(4, line('w0')) |
| call assert_equal(13, line('w$')) |
| " This should move by one page down. |
| call feedkeys("A\<S-ScrollWheelDown>\<esc>", 'tnix') |
| call assert_equal(14, line('w0')) |
| set nostartofline |
| " Another page down. |
| call feedkeys("A\<C-ScrollWheelDown>\<esc>", 'tnix') |
| call assert_equal(24, line('w0')) |
| |
| call assert_equal([0, 24, 2, 0], getpos('.')) |
| call test_setmouse(4, 3) |
| call feedkeys("A\<LeftMouse>\<esc>", 'tnix') |
| call assert_equal([0, 27, 2, 0], getpos('.')) |
| set mousemodel=extend |
| call test_setmouse(5, 3) |
| call feedkeys("A\<RightMouse>\<esc>\<esc>", 'tnix') |
| call assert_equal([0, 28, 2, 0], getpos('.')) |
| set mousemodel& |
| 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\<ScrollWheelUp>\<esc>", 'tnix') |
| call assert_equal([0, 1, 1, 0], getpos('.')) |
| call cursor(1, 30) |
| norm! zt |
| call feedkeys("A\<S-ScrollWheelUp>\<esc>", 'tnix') |
| call assert_equal([0, 1, 1, 0], getpos('.')) |
| call cursor(1, 30) |
| norm! zt |
| call feedkeys("A\<C-ScrollWheelUp>\<esc>", 'tnix') |
| call assert_equal([0, 1, 1, 0], getpos('.')) |
| %d |
| call setline(1, repeat(["12345678901234567890"], 100)) |
| call cursor(2, 1) |
| call feedkeys("A\<ScrollWheelRight>\<esc>", 'tnix') |
| call assert_equal([0, 2, 20, 0], getpos('.')) |
| call feedkeys("A\<ScrollWheelLeft>\<esc>", 'tnix') |
| call assert_equal([0, 2, 20, 0], getpos('.')) |
| call feedkeys("A\<S-ScrollWheelRight>\<esc>", 'tnix') |
| call assert_equal([0, 2, 20, 0], getpos('.')) |
| call feedkeys("A\<S-ScrollWheelLeft>\<esc>", 'tnix') |
| call assert_equal([0, 2, 20, 0], getpos('.')) |
| call feedkeys("A\<C-ScrollWheelRight>\<esc>", 'tnix') |
| call assert_equal([0, 2, 20, 0], getpos('.')) |
| call feedkeys("A\<C-ScrollWheelLeft>\<esc>", '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\<PageDown>\<esc>", 'tnix') |
| call assert_equal([0, 9, 1, 0], getpos('.')) |
| call feedkeys("i\<PageDown>\<esc>", 'tnix') |
| call assert_equal([0, 17, 1, 0], getpos('.')) |
| call feedkeys("i\<PageDown>\<esc>", 'tnix') |
| call assert_equal([0, 25, 1, 0], getpos('.')) |
| call feedkeys("i\<PageDown>\<esc>", 'tnix') |
| call assert_equal([0, 30, 1, 0], getpos('.')) |
| call feedkeys("i\<PageDown>\<esc>", 'tnix') |
| call assert_equal([0, 30, 1, 0], getpos('.')) |
| call feedkeys("A\<PageUp>\<esc>", 'tnix') |
| call assert_equal([0, 29, 1, 0], getpos('.')) |
| call feedkeys("A\<PageUp>\<esc>", 'tnix') |
| call assert_equal([0, 21, 1, 0], getpos('.')) |
| call feedkeys("A\<PageUp>\<esc>", 'tnix') |
| call assert_equal([0, 13, 1, 0], getpos('.')) |
| call feedkeys("A\<PageUp>\<esc>", 'tnix') |
| call assert_equal([0, 10, 1, 0], getpos('.')) |
| call feedkeys("A\<PageUp>\<esc>", 'tnix') |
| call assert_equal([0, 10, 11, 0], getpos('.')) |
| " <S-Up> is the same as <PageUp> |
| " <S-Down> is the same as <PageDown> |
| call cursor(1, 1) |
| call feedkeys("i\<S-Down>\<esc>", 'tnix') |
| call assert_equal([0, 9, 1, 0], getpos('.')) |
| call feedkeys("i\<S-Down>\<esc>", 'tnix') |
| call assert_equal([0, 17, 1, 0], getpos('.')) |
| call feedkeys("i\<S-Down>\<esc>", 'tnix') |
| call assert_equal([0, 25, 1, 0], getpos('.')) |
| call feedkeys("i\<S-Down>\<esc>", 'tnix') |
| call assert_equal([0, 30, 1, 0], getpos('.')) |
| call feedkeys("i\<S-Down>\<esc>", 'tnix') |
| call assert_equal([0, 30, 1, 0], getpos('.')) |
| call feedkeys("A\<S-Up>\<esc>", 'tnix') |
| call assert_equal([0, 29, 1, 0], getpos('.')) |
| call feedkeys("A\<S-Up>\<esc>", 'tnix') |
| call assert_equal([0, 21, 1, 0], getpos('.')) |
| call feedkeys("A\<S-Up>\<esc>", 'tnix') |
| call assert_equal([0, 13, 1, 0], getpos('.')) |
| call feedkeys("A\<S-Up>\<esc>", 'tnix') |
| call assert_equal([0, 10, 1, 0], getpos('.')) |
| call feedkeys("A\<S-Up>\<esc>", 'tnix') |
| call assert_equal([0, 10, 11, 0], getpos('.')) |
| set nostartofline |
| call cursor(30, 11) |
| norm! zt |
| call feedkeys("A\<PageUp>\<esc>", 'tnix') |
| call assert_equal([0, 29, 11, 0], getpos('.')) |
| call feedkeys("A\<PageUp>\<esc>", 'tnix') |
| call assert_equal([0, 21, 11, 0], getpos('.')) |
| call feedkeys("A\<PageUp>\<esc>", 'tnix') |
| call assert_equal([0, 13, 11, 0], getpos('.')) |
| call feedkeys("A\<PageUp>\<esc>", 'tnix') |
| call assert_equal([0, 10, 11, 0], getpos('.')) |
| call feedkeys("A\<PageUp>\<esc>", 'tnix') |
| call assert_equal([0, 10, 11, 0], getpos('.')) |
| call cursor(1, 1) |
| call feedkeys("A\<PageDown>\<esc>", 'tnix') |
| call assert_equal([0, 9, 11, 0], getpos('.')) |
| call feedkeys("A\<PageDown>\<esc>", 'tnix') |
| call assert_equal([0, 17, 11, 0], getpos('.')) |
| call feedkeys("A\<PageDown>\<esc>", 'tnix') |
| call assert_equal([0, 25, 11, 0], getpos('.')) |
| call feedkeys("A\<PageDown>\<esc>", 'tnix') |
| call assert_equal([0, 30, 11, 0], getpos('.')) |
| call feedkeys("A\<PageDown>\<esc>", 'tnix') |
| call assert_equal([0, 30, 11, 0], getpos('.')) |
| " <S-Up> is the same as <PageUp> |
| " <S-Down> is the same as <PageDown> |
| call cursor(30, 11) |
| norm! zt |
| call feedkeys("A\<S-Up>\<esc>", 'tnix') |
| call assert_equal([0, 29, 11, 0], getpos('.')) |
| call feedkeys("A\<S-Up>\<esc>", 'tnix') |
| call assert_equal([0, 21, 11, 0], getpos('.')) |
| call feedkeys("A\<S-Up>\<esc>", 'tnix') |
| call assert_equal([0, 13, 11, 0], getpos('.')) |
| call feedkeys("A\<S-Up>\<esc>", 'tnix') |
| call assert_equal([0, 10, 11, 0], getpos('.')) |
| call feedkeys("A\<S-Up>\<esc>", 'tnix') |
| call assert_equal([0, 10, 11, 0], getpos('.')) |
| call cursor(1, 1) |
| call feedkeys("A\<S-Down>\<esc>", 'tnix') |
| call assert_equal([0, 9, 11, 0], getpos('.')) |
| call feedkeys("A\<S-Down>\<esc>", 'tnix') |
| call assert_equal([0, 17, 11, 0], getpos('.')) |
| call feedkeys("A\<S-Down>\<esc>", 'tnix') |
| call assert_equal([0, 25, 11, 0], getpos('.')) |
| call feedkeys("A\<S-Down>\<esc>", 'tnix') |
| call assert_equal([0, 30, 11, 0], getpos('.')) |
| call feedkeys("A\<S-Down>\<esc>", '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\<del>\<esc>", 'tnix') |
| call assert_fails(':Sandbox', 'E48:') |
| com! Sandbox :sandbox exe "norm! i\<del>" |
| call assert_fails(':Sandbox', 'E48:') |
| delcom Sandbox |
| call assert_equal(['a'], getline(1,'$')) |
| |
| " 2) edit with textlock set |
| fu! DoIt() |
| call feedkeys("i\<del>\<esc>", 'tnix') |
| endfu |
| au InsertCharPre <buffer> :call DoIt() |
| try |
| call feedkeys("ix\<esc>", 'tnix') |
| call assert_fails(1, 'textlock') |
| catch /^Vim\%((\a\+)\)\=:E565/ " catch E565: 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\<esc>", '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\<del>\<esc>", 'tnix') |
| return [] |
| endif |
| endfun |
| set completefunc=Complete |
| try |
| call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix') |
| call assert_fails(1, 'change in complete function') |
| catch /^Vim\%((\a\+)\)\=:E565/ " catch E565 |
| 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 |
| CheckFeature rightleft |
| 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\<right>\<esc>x", 'txin') |
| call assert_equal(['bc', 'def', 'ghi'], getline(1,'$')) |
| call cursor(1, 2) |
| call feedkeys("i\<s-right>\<esc>", 'txin') |
| call cursor(1, 2) |
| call feedkeys("i\<c-right>\<esc>", '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\<left>\<esc>x", 'txin') |
| call assert_equal(['ac', 'def', 'ghi'], getline(1,'$')) |
| call cursor(1, 2) |
| call feedkeys("i\<s-left>\<esc>", 'txin') |
| call cursor(1, 2) |
| call feedkeys("i\<c-left>\<esc>", '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")) |
| %d _ |
| call test_override('redraw_flag', 1) |
| call test_override('char_avail', 1) |
| call feedkeys("a\<C-V>x41", "xt") |
| redraw! |
| call assert_equal(repeat(' ', 19) .. 'A', Screenline(1)) |
| call test_override('ALL', 0) |
| set norightleft |
| bw! |
| endfunc |
| |
| func Test_edit_complete_very_long_name() |
| " Long directory names only work on Unix. |
| CheckUnix |
| |
| let dirname = getcwd() . "/Xlongdir" |
| let longdirname = dirname . repeat('/' . repeat('d', 255), 4) |
| try |
| call mkdir(longdirname, 'pR') |
| 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 Xnofile " . longfilename |
| exe "normal iT\<C-N>" |
| |
| bwipe! |
| exe 'bwipe! ' . longfilename |
| let &columns = save_columns |
| if winposx >= 0 && winposy >= 0 |
| exe 'winpos ' . winposx . ' ' . winposy |
| endif |
| set swapfile& |
| 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_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\<Esc>", '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\<C-C>", '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<Esc> |
| 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<C-C> |
| 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\<Esc>" |
| call assert_equal(2, line('$')) |
| normal u |
| call assert_equal(1, line('$')) |
| |
| bwipe! |
| au! InsertLeave |
| call delete('XtestUndo') |
| call delete(undofile('XtestUndo')) |
| set undofile& |
| endfunc |
| |
| " Test for inserting characters using CTRL-V followed by a number. |
| func Test_edit_special_chars() |
| new |
| |
| let t = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>" |
| |
| exe "normal " . t |
| call assert_equal("ABC !a\<C-O>g\<C-G>8", getline(2)) |
| |
| close! |
| endfunc |
| |
| func Test_edit_startinsert() |
| new |
| set backspace+=start |
| call setline(1, 'foobar') |
| call feedkeys("A\<C-U>\<Esc>", 'xt') |
| call assert_equal('', getline(1)) |
| |
| call setline(1, 'foobar') |
| call feedkeys(":startinsert!\<CR>\<C-U>\<Esc>", 'xt') |
| call assert_equal('', getline(1)) |
| |
| set backspace& |
| bwipe! |
| endfunc |
| |
| " Test for :startreplace and :startgreplace |
| func Test_edit_startreplace() |
| new |
| call setline(1, 'abc') |
| call feedkeys("l:startreplace\<CR>xyz\e", 'xt') |
| call assert_equal('axyz', getline(1)) |
| call feedkeys("0:startreplace!\<CR>abc\e", 'xt') |
| call assert_equal('axyzabc', getline(1)) |
| call setline(1, "a\tb") |
| call feedkeys("0l:startgreplace\<CR>xyz\e", 'xt') |
| call assert_equal("axyz\tb", getline(1)) |
| call feedkeys("0i\<C-R>=execute('startreplace')\<CR>12\e", 'xt') |
| call assert_equal("12axyz\tb", getline(1)) |
| close! |
| endfunc |
| |
| func Test_edit_noesckeys() |
| CheckNotGui |
| new |
| |
| " <Left> moves cursor when 'esckeys' is set |
| exe "set t_kl=\<Esc>OD" |
| set esckeys |
| call feedkeys("axyz\<Esc>ODX", "xt") |
| call assert_equal("xyXz", getline(1)) |
| |
| " <Left> exits Insert mode when 'esckeys' is off |
| set noesckeys |
| call setline(1, '') |
| call feedkeys("axyz\<Esc>ODX", "xt") |
| call assert_equal(["DX", "xyz"], getline(1, 2)) |
| |
| bwipe! |
| set esckeys |
| endfunc |
| |
| " Test for running an invalid ex command in insert mode using CTRL-O |
| func Test_edit_ctrl_o_invalid_cmd() |
| new |
| set showmode showcmd |
| " Avoid a sleep of 3 seconds. Zero might have side effects. |
| call test_override('ui_delay', 50) |
| let caught_e492 = 0 |
| try |
| call feedkeys("i\<C-O>:invalid\<CR>abc\<Esc>", "xt") |
| catch /E492:/ |
| let caught_e492 = 1 |
| endtry |
| call assert_equal(1, caught_e492) |
| call assert_equal('abc', getline(1)) |
| set showmode& showcmd& |
| call test_override('ui_delay', 0) |
| close! |
| endfunc |
| |
| " Test for editing a file with a very long name |
| func Test_edit_illegal_filename() |
| CheckEnglish |
| new |
| redir => msg |
| exe 'edit ' . repeat('f', 5000) |
| redir END |
| call assert_match("Illegal file name$", split(msg, "\n")[0]) |
| close! |
| endfunc |
| |
| " Test for editing a directory |
| func Test_edit_is_a_directory() |
| CheckEnglish |
| let dirname = getcwd() . "/Xeditdir" |
| 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 |
| |
| " Test for editing a file using invalid file encoding |
| func Test_edit_invalid_encoding() |
| CheckEnglish |
| call writefile([], 'Xinvfile', 'D') |
| redir => msg |
| new ++enc=axbyc Xinvfile |
| redir END |
| call assert_match('\[NOT converted\]', msg) |
| close! |
| endfunc |
| |
| " Test for the "charconvert" option |
| func Test_edit_charconvert() |
| CheckEnglish |
| call writefile(['one', 'two'], 'Xccfile', 'D') |
| |
| " set 'charconvert' to a non-existing function |
| set charconvert=NonExitingFunc() |
| new |
| let caught_e117 = v:false |
| try |
| redir => msg |
| edit ++enc=axbyc Xccfile |
| catch /E117:/ |
| let caught_e117 = v:true |
| finally |
| redir END |
| endtry |
| call assert_true(caught_e117) |
| call assert_equal(['one', 'two'], getline(1, '$')) |
| call assert_match("Conversion with 'charconvert' failed", msg) |
| close! |
| set charconvert& |
| |
| " 'charconvert' function doesn't create an output file |
| func Cconv1() |
| endfunc |
| set charconvert=Cconv1() |
| new |
| redir => msg |
| edit ++enc=axbyc Xccfile |
| redir END |
| call assert_equal(['one', 'two'], getline(1, '$')) |
| call assert_match("can't read output of 'charconvert'", msg) |
| close! |
| delfunc Cconv1 |
| set charconvert& |
| |
| " 'charconvert' function to convert to upper case |
| func Cconv2() |
| let data = readfile(v:fname_in) |
| call map(data, 'toupper(v:val)') |
| call writefile(data, v:fname_out) |
| endfunc |
| set charconvert=Cconv2() |
| new Xccfile |
| write ++enc=ucase Xccfile1 |
| call assert_equal(['ONE', 'TWO'], readfile('Xccfile1')) |
| call delete('Xccfile1') |
| close! |
| delfunc Cconv2 |
| set charconvert& |
| |
| " 'charconvert' function removes the input file |
| func Cconv3() |
| call delete(v:fname_in) |
| endfunc |
| set charconvert=Cconv3() |
| new |
| call assert_fails('edit ++enc=lcase Xccfile', 'E202:') |
| call assert_equal([''], getline(1, '$')) |
| close! |
| delfunc Cconv3 |
| set charconvert& |
| endfunc |
| |
| " Test for editing a file without read permission |
| func Test_edit_file_no_read_perm() |
| CheckUnix |
| CheckNotRoot |
| |
| call writefile(['one', 'two'], 'Xnrpfile', 'D') |
| call setfperm('Xnrpfile', '-w-------') |
| new |
| redir => msg |
| edit Xnrpfile |
| redir END |
| call assert_equal(1, &readonly) |
| call assert_equal([''], getline(1, '$')) |
| call assert_match('\[Permission Denied\]', msg) |
| close! |
| endfunc |
| |
| " Using :edit without leaving 'insertmode' should not cause Insert mode to be |
| " re-entered immediately after <C-L> |
| func Test_edit_insertmode_ex_edit() |
| CheckRunVimInTerminal |
| |
| let lines =<< trim END |
| set insertmode noruler |
| inoremap <C-B> <Cmd>edit Xfoo<CR> |
| END |
| call writefile(lines, 'Xtest_edit_insertmode_ex_edit', 'D') |
| |
| let buf = RunVimInTerminal('-S Xtest_edit_insertmode_ex_edit', #{rows: 6, wait_for_ruler: 0}) |
| " Somehow when using valgrind "INSERT" does not show up unless we send |
| " something to the terminal. |
| for i in range(30) |
| if term_getline(buf, 6) =~ 'INSERT' |
| break |
| endif |
| call term_sendkeys(buf, "-") |
| sleep 100m |
| endfor |
| call WaitForAssert({-> assert_match('^-- INSERT --\s*$', term_getline(buf, 6))}) |
| call term_sendkeys(buf, "\<C-B>\<C-L>") |
| call WaitForAssert({-> assert_notmatch('^-- INSERT --\s*$', term_getline(buf, 6))}) |
| |
| " clean up |
| call StopVimInTerminal(buf) |
| endfunc |
| |
| " Pressing escape in 'insertmode' should beep |
| " FIXME: Execute this later, when using valgrind it makes the next test |
| " Test_edit_insertmode_ex_edit() fail. |
| func Test_z_edit_insertmode_esc_beeps() |
| new |
| set insertmode |
| call assert_beeps("call feedkeys(\"one\<Esc>\", 'xt')") |
| set insertmode& |
| " unsupported "CTRL-G l" command should beep in insert mode. |
| call assert_beeps("normal i\<C-G>l") |
| bwipe! |
| endfunc |
| |
| " Test for 'hkmap' and 'hkmapp' |
| func Test_edit_hkmap() |
| CheckFeature rightleft |
| if has('win32') && !has('gui') |
| throw 'Skipped: fails on the MS-Windows terminal version' |
| endif |
| new |
| |
| set revins hkmap |
| let str = 'abcdefghijklmnopqrstuvwxyz' |
| let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
| let str ..= '`/'',.;' |
| call feedkeys('i' .. str, 'xt') |
| let expected = "óõú,.;" |
| let expected ..= "ZYXWVUTSRQPONMLKJIHGFEDCBA" |
| let expected ..= "æèñ'äåà ãø/ôÃîöêìçïéòë÷âáðù" |
| call assert_equal(expected, getline(1)) |
| |
| %d |
| set revins hkmap hkmapp |
| let str = 'abcdefghijklmnopqrstuvwxyz' |
| let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
| call feedkeys('i' .. str, 'xt') |
| let expected = "õYXWVUTSRQóOïÃLKJIHGFEDêBA" |
| let expected ..= "öòXùåèúæø'ôñðîì÷çéäâóǟãëáà " |
| call assert_equal(expected, getline(1)) |
| |
| set revins& hkmap& hkmapp& |
| close! |
| endfunc |
| |
| " Test for 'allowrevins' and using CTRL-_ in insert mode |
| func Test_edit_allowrevins() |
| CheckFeature rightleft |
| new |
| set allowrevins |
| call feedkeys("iABC\<C-_>DEF\<C-_>GHI", 'xt') |
| call assert_equal('ABCFEDGHI', getline(1)) |
| set allowrevins& |
| close! |
| endfunc |
| |
| " Test for inserting a register in insert mode using CTRL-R |
| func Test_edit_insert_reg() |
| new |
| let g:Line = '' |
| func SaveFirstLine() |
| let g:Line = Screenline(1) |
| return 'r' |
| endfunc |
| inoremap <expr> <buffer> <F2> SaveFirstLine() |
| call test_override('redraw_flag', 1) |
| call test_override('char_avail', 1) |
| let @r = 'sample' |
| call feedkeys("a\<C-R>=SaveFirstLine()\<CR>", "xt") |
| call assert_equal('"', g:Line) |
| |
| " Test for inserting an null and an empty list |
| call feedkeys("a\<C-R>=test_null_list()\<CR>", "xt") |
| call feedkeys("a\<C-R>=[]\<CR>", "xt") |
| call assert_equal(['r'], getbufline('', 1, '$')) |
| call test_override('ALL', 0) |
| close! |
| endfunc |
| |
| " Test for positioning cursor after CTRL-R expression failed |
| func Test_edit_ctrl_r_failed() |
| CheckScreendump |
| CheckRunVimInTerminal |
| |
| let buf = RunVimInTerminal('', #{rows: 6, cols: 60}) |
| |
| " trying to insert a blob produces an error |
| call term_sendkeys(buf, "i\<C-R>=0z\<CR>") |
| |
| " ending Insert mode should put the cursor back on the ':' |
| call term_sendkeys(buf, ":\<Esc>") |
| call VerifyScreenDump(buf, 'Test_edit_ctlr_r_failed_1', {}) |
| |
| call StopVimInTerminal(buf) |
| endfunc |
| |
| " When a character is inserted at the last position of the last line in a |
| " window, the window contents should be scrolled one line up. If the top line |
| " is part of a fold, then the entire fold should be scrolled up. |
| func Test_edit_lastline_scroll() |
| new |
| let h = winheight(0) |
| let lines = ['one', 'two', 'three'] |
| let lines += repeat(['vim'], h - 4) |
| call setline(1, lines) |
| call setline(h, repeat('x', winwidth(0) - 1)) |
| call feedkeys("GAx", 'xt') |
| redraw! |
| call assert_equal(h - 1, winline()) |
| call assert_equal(2, line('w0')) |
| |
| " scroll with a fold |
| 1,2fold |
| normal gg |
| call setline(h + 1, repeat('x', winwidth(0) - 1)) |
| call feedkeys("GAx", 'xt') |
| redraw! |
| call assert_equal(h - 1, winline()) |
| call assert_equal(3, line('w0')) |
| |
| close! |
| 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 the 'revins' option |
| func Test_edit_revins() |
| CheckFeature rightleft |
| new |
| set revins |
| exe "normal! ione\ttwo three" |
| call assert_equal("eerht owt\teno", getline(1)) |
| call setline(1, "one\ttwo three") |
| normal! gg$bi a |
| call assert_equal("one\ttwo a three", getline(1)) |
| exe "normal! $bi\<BS>\<BS>" |
| call assert_equal("one\ttwo a ree", getline(1)) |
| exe "normal! 0wi\<C-W>" |
| call assert_equal("one\t a ree", getline(1)) |
| exe "normal! 0wi\<C-U>" |
| call assert_equal("one\t ", getline(1)) |
| " newline in insert mode starts at the end of the line |
| call setline(1, 'one two three') |
| exe "normal! wi\nfour" |
| call assert_equal(['one two three', 'ruof'], getline(1, '$')) |
| set backspace=indent,eol,start |
| exe "normal! ggA\<BS>:" |
| call assert_equal(['one two three:ruof'], getline(1, '$')) |
| set revins& backspace& |
| bw! |
| endfunc |
| |
| " Test for getting the character of the line below after "p" |
| func Test_edit_put_CTRL_E() |
| set encoding=latin1 |
| new |
| let @" = '' |
| sil! norm orggRx |
| sil! norm pr |
| call assert_equal(['r', 'r'], getline(1, 2)) |
| bwipe! |
| set encoding=utf-8 |
| endfunc |
| |
| " Test toggling of input method. See :help i_CTRL-^ |
| func Test_edit_CTRL_hat() |
| CheckFeature xim |
| |
| " FIXME: test fails with Motif GUI. |
| " test also fails when running in the GUI. |
| CheckFeature gui_gtk |
| CheckNotGui |
| |
| new |
| |
| call assert_equal(0, &iminsert) |
| call feedkeys("i\<C-^>", 'xt') |
| call assert_equal(2, &iminsert) |
| call feedkeys("i\<C-^>", 'xt') |
| call assert_equal(0, &iminsert) |
| |
| bwipe! |
| endfunc |
| |
| " Weird long file name was going over the end of NameBuff |
| func Test_edit_overlong_file_name() |
| CheckUnix |
| |
| file 0000000000000000000000000000 |
| file %%%%%%%%%%%%%%%%%%%%%%%%%% |
| file %%%%%% |
| set readonly |
| set ls=2 |
| |
| redraw! |
| set noreadonly ls& |
| bwipe! |
| endfunc |
| |
| func Test_edit_shift_bs() |
| CheckMSWindows |
| |
| " FIXME: this works interactively, but the test fails |
| throw 'Skipped: Shift-Backspace Test not working correctly :(' |
| |
| " Need to run this in Win32 Terminal, do not use CheckRunVimInTerminal |
| if !has("terminal") |
| return |
| endif |
| |
| " Shift Backspace should work like Backspace in insert mode |
| let lines =<< trim END |
| call setline(1, ['abc']) |
| END |
| call writefile(lines, 'Xtest_edit_shift_bs', 'D') |
| |
| let buf = RunVimInTerminal('-S Xtest_edit_shift_bs', #{rows: 3}) |
| call term_sendkeys(buf, "A\<S-BS>-\<esc>") |
| call TermWait(buf, 50) |
| call assert_equal('ab-', term_getline(buf, 1)) |
| |
| " clean up |
| call StopVimInTerminal(buf) |
| endfunc |
| |
| func Test_edit_Ctrl_RSB() |
| new |
| let g:triggered = [] |
| autocmd InsertCharPre <buffer> let g:triggered += [v:char] |
| |
| " i_CTRL-] should not trigger InsertCharPre |
| exe "normal! A\<C-]>" |
| call assert_equal([], g:triggered) |
| |
| " i_CTRL-] should expand abbreviations but not trigger InsertCharPre |
| inoreabbr <buffer> f foo |
| exe "normal! Af\<C-]>a" |
| call assert_equal(['f', 'f', 'o', 'o', 'a'], g:triggered) |
| call assert_equal('fooa', getline(1)) |
| |
| " CTRL-] followed by i_CTRL-V should not expand abbreviations |
| " i_CTRL-V doesn't trigger InsertCharPre |
| call setline(1, '') |
| exe "normal! Af\<C-V>\<C-]>" |
| call assert_equal("f\<C-]>", getline(1)) |
| |
| let g:triggered = [] |
| call setline(1, '') |
| |
| " Also test assigning to v:char |
| autocmd InsertCharPre <buffer> let v:char = 'f' |
| exe "normal! Ag\<C-]>h" |
| call assert_equal(['g', 'f', 'o', 'o', 'h'], g:triggered) |
| call assert_equal('ffff', getline(1)) |
| |
| autocmd! InsertCharPre |
| unlet g:triggered |
| bwipe! |
| endfunc |
| |
| func s:check_backspace(expected) |
| let g:actual = [] |
| inoremap <buffer> <F2> <Cmd>let g:actual += [getline('.')]<CR> |
| set backspace=indent,eol,start |
| |
| exe "normal i" .. repeat("\<BS>\<F2>", len(a:expected)) |
| call assert_equal(a:expected, g:actual) |
| |
| set backspace& |
| iunmap <buffer> <F2> |
| unlet g:actual |
| endfunc |
| |
| " Test that backspace works with 'smarttab' and mixed Tabs and spaces. |
| func Test_edit_backspace_smarttab_mixed() |
| set smarttab |
| call NewWindow(1, 30) |
| setlocal tabstop=4 shiftwidth=4 |
| |
| call setline(1, "\t \t \t a") |
| normal! $ |
| call s:check_backspace([ |
| \ "\t \t \ta", |
| \ "\t \t a", |
| \ "\t \t a", |
| \ "\t \ta", |
| \ "\t a", |
| \ "\ta", |
| \ "a", |
| \ ]) |
| |
| call CloseWindow() |
| set smarttab& |
| endfunc |
| |
| " Test that backspace works with 'smarttab' and 'varsofttabstop'. |
| func Test_edit_backspace_smarttab_varsofttabstop() |
| CheckFeature vartabs |
| |
| set smarttab |
| call NewWindow(1, 30) |
| setlocal tabstop=8 varsofttabstop=6,2,5,3 |
| |
| call setline(1, "a\t \t a") |
| normal! $ |
| call s:check_backspace([ |
| \ "a\t \ta", |
| \ "a\t a", |
| \ "a\ta", |
| \ "a a", |
| \ "aa", |
| \ "a", |
| \ ]) |
| |
| call CloseWindow() |
| set smarttab& |
| endfunc |
| |
| " Test that backspace works with 'smarttab' when a Tab is shown as "^I". |
| func Test_edit_backspace_smarttab_list() |
| set smarttab |
| call NewWindow(1, 30) |
| setlocal tabstop=4 shiftwidth=4 list listchars= |
| |
| call setline(1, "\t \t \t a") |
| normal! $ |
| call s:check_backspace([ |
| \ "\t \t a", |
| \ "\t \t a", |
| \ "\t \ta", |
| \ "\t a", |
| \ "a", |
| \ ]) |
| |
| call CloseWindow() |
| set smarttab& |
| endfunc |
| |
| " Test that backspace works with 'smarttab' and 'breakindent'. |
| func Test_edit_backspace_smarttab_breakindent() |
| CheckFeature linebreak |
| |
| set smarttab |
| call NewWindow(3, 17) |
| setlocal tabstop=4 shiftwidth=4 breakindent breakindentopt=min:5 |
| |
| call setline(1, "\t \t \t a") |
| normal! $ |
| call s:check_backspace([ |
| \ "\t \t \ta", |
| \ "\t \t a", |
| \ "\t \t a", |
| \ "\t \ta", |
| \ "\t a", |
| \ "\ta", |
| \ "a", |
| \ ]) |
| |
| call CloseWindow() |
| set smarttab& |
| endfunc |
| |
| " Test that backspace works with 'smarttab' and virtual text. |
| func Test_edit_backspace_smarttab_virtual_text() |
| CheckFeature textprop |
| |
| set smarttab |
| call NewWindow(1, 50) |
| setlocal tabstop=4 shiftwidth=4 |
| |
| call setline(1, "\t \t \t a") |
| call prop_type_add('theprop', {}) |
| call prop_add(1, 3, {'type': 'theprop', 'text': 'text'}) |
| normal! $ |
| call s:check_backspace([ |
| \ "\t \t \ta", |
| \ "\t \t a", |
| \ "\t \t a", |
| \ "\t \ta", |
| \ "\t a", |
| \ "\ta", |
| \ "a", |
| \ ]) |
| |
| call CloseWindow() |
| call prop_type_delete('theprop') |
| set smarttab& |
| endfunc |
| |
| func Test_edit_CAR() |
| set cot=menu,menuone,noselect |
| new |
| |
| call feedkeys("Shello hero\<CR>h\<C-x>\<C-N>e\<CR>", 'tx') |
| call assert_equal(['hello hero', 'he', ''], getline(1, '$')) |
| |
| bw! |
| set cot& |
| endfunc |
| |
| " vim: shiftwidth=2 sts=2 expandtab |