To: vim_dev@googlegroups.com Subject: Patch 8.0.0440 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0440 Problem: Not enough test coverage in Insert mode. Solution: Add lots of tests. Add test_override(). (Christian Brabandt, closes #1521) Files: runtime/doc/eval.txt, runtime/doc/usr_41.txt, src/edit.c, src/evalfunc.c, src/globals.h, src/screen.c, src/testdir/Make_all.mak, src/testdir/test_cursor_func.vim, src/testdir/test_edit.vim, src/testdir/test_search.vim, src/testdir/test_assert.vim, src/Makefile, src/testdir/runtest.vim *** ../vim-8.0.0439/runtime/doc/eval.txt 2017-03-04 14:37:14.649120059 +0100 --- runtime/doc/eval.txt 2017-03-09 17:24:24.028380217 +0100 *************** *** 2359,2365 **** test_alloc_fail({id}, {countdown}, {repeat}) none make memory allocation fail test_autochdir() none enable 'autochdir' during startup - test_disable_char_avail({expr}) none test without typeahead test_garbagecollect_now() none free memory right now for testing test_ignore_error({expr}) none ignore a specific error test_null_channel() Channel null value for testing --- 2362,2367 ---- *************** *** 2368,2373 **** --- 2370,2376 ---- test_null_list() List null value for testing test_null_partial() Funcref null value for testing test_null_string() String null value for testing + test_override({expr}, {val}) none test with Vim internal overrides test_settime({expr}) none set current time for testing timer_info([{id}]) List information about timers timer_pause({id}, {pause}) none pause or unpause a timer *************** *** 7826,7835 **** --- 7834,7857 ---- test_null_string() *test_null_string()* Return a String that is null. Only useful for testing. + test_override({name}, {val}) *test_override()* + Overrides certain parts of Vims internal processing to be able + to run tests. Only to be used for testing Vim! + The override is enabled when {val} is non-zero and removed + when {val} is zero. + Current supported values for name are: + + name effect when {val} is non-zero ~ + redraw disable the redrawing() function + char_avail disable the char_avail() function + ALL clear all overrides ({val} is not used) + test_settime({expr}) *test_settime()* Set the time Vim uses internally. Currently only used for timestamps in the history, as they are used in viminfo, and for undo. + Using a value of 1 makes Vim not sleep after a warning or + error message. {expr} must evaluate to a number. When the value is zero the normal behavior is restored. *** ../vim-8.0.0439/runtime/doc/usr_41.txt 2017-01-28 15:58:45.340197300 +0100 --- runtime/doc/usr_41.txt 2017-03-09 17:25:18.443999746 +0100 *************** *** 95,101 **** to the same variable. The example was given to explain the commands, but would you really want to ! make such a loop it can be written much more compact: > :for i in range(1, 4) : echo "count is" i --- 95,101 ---- to the same variable. The example was given to explain the commands, but would you really want to ! make such a loop, it can be written much more compact: > :for i in range(1, 4) : echo "count is" i *************** *** 693,698 **** --- 693,699 ---- Variables: *var-functions* type() type of a variable islocked() check if a variable is locked + funcref() get a Funcref for a function reference function() get a Funcref for a function name getbufvar() get a variable value from a specific buffer setbufvar() set a variable in a specific buffer *************** *** 884,889 **** --- 885,891 ---- getfontname() get name of current font being used getwinposx() X position of the GUI Vim window getwinposy() Y position of the GUI Vim window + balloon_show() set the balloon content Vim server: *server-functions* serverlist() return the list of server names *************** *** 920,933 **** assert_fails() assert that a function call fails test_alloc_fail() make memory allocation fail test_autochdir() enable 'autochdir' during startup ! test_disable_char_avail() test without typeahead ! test_garbagecollect_now() free memory right now test_null_channel() return a null Channel test_null_dict() return a null Dict test_null_job() return a null Job test_null_list() return a null List test_null_partial() return a null Partial function test_null_string() return a null String Inter-process communication: *channel-functions* ch_canread() check if there is something to read --- 922,937 ---- assert_fails() assert that a function call fails test_alloc_fail() make memory allocation fail test_autochdir() enable 'autochdir' during startup ! test_override() test with Vim internal overrides ! test_garbagecollect_now() free memory right now ! test_ignore_error() ignore a specific error message test_null_channel() return a null Channel test_null_dict() return a null Dict test_null_job() return a null Job test_null_list() return a null List test_null_partial() return a null Partial function test_null_string() return a null String + test_settime() set the time Vim uses internally Inter-process communication: *channel-functions* ch_canread() check if there is something to read *** ../vim-8.0.0439/src/edit.c 2017-03-05 21:18:21.877452188 +0100 --- src/edit.c 2017-03-09 17:17:07.567436001 +0100 *************** *** 2262,2268 **** vim_beep(BO_COMPL); setcursor(); out_flush(); ! ui_delay(2000L, FALSE); } return FALSE; } --- 2262,2271 ---- vim_beep(BO_COMPL); setcursor(); out_flush(); ! #ifdef FEAT_EVAL ! if (!get_vim_var_nr(VV_TESTING)) ! #endif ! ui_delay(2000L, FALSE); } return FALSE; } *** ../vim-8.0.0439/src/evalfunc.c 2017-03-02 22:11:28.479904237 +0100 --- src/evalfunc.c 2017-03-09 17:31:09.317546022 +0100 *************** *** 390,396 **** static void f_tempname(typval_T *argvars, typval_T *rettv); static void f_test_alloc_fail(typval_T *argvars, typval_T *rettv); static void f_test_autochdir(typval_T *argvars, typval_T *rettv); ! static void f_test_disable_char_avail(typval_T *argvars, typval_T *rettv); static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv); static void f_test_ignore_error(typval_T *argvars, typval_T *rettv); #ifdef FEAT_JOB_CHANNEL --- 390,396 ---- static void f_tempname(typval_T *argvars, typval_T *rettv); static void f_test_alloc_fail(typval_T *argvars, typval_T *rettv); static void f_test_autochdir(typval_T *argvars, typval_T *rettv); ! static void f_test_override(typval_T *argvars, typval_T *rettv); static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv); static void f_test_ignore_error(typval_T *argvars, typval_T *rettv); #ifdef FEAT_JOB_CHANNEL *************** *** 828,834 **** {"tempname", 0, 0, f_tempname}, {"test_alloc_fail", 3, 3, f_test_alloc_fail}, {"test_autochdir", 0, 0, f_test_autochdir}, - {"test_disable_char_avail", 1, 1, f_test_disable_char_avail}, {"test_garbagecollect_now", 0, 0, f_test_garbagecollect_now}, {"test_ignore_error", 1, 1, f_test_ignore_error}, #ifdef FEAT_JOB_CHANNEL --- 828,833 ---- *************** *** 841,846 **** --- 840,846 ---- {"test_null_list", 0, 0, f_test_null_list}, {"test_null_partial", 0, 0, f_test_null_partial}, {"test_null_string", 0, 0, f_test_null_string}, + {"test_override", 2, 2, f_test_override}, {"test_settime", 1, 1, f_test_settime}, #ifdef FEAT_TIMERS {"timer_info", 0, 1, f_timer_info}, *************** *** 12326,12337 **** } /* ! * "test_disable_char_avail({expr})" function */ static void ! f_test_disable_char_avail(typval_T *argvars, typval_T *rettv UNUSED) { ! disable_char_avail_for_testing = (int)get_tv_number(&argvars[0]); } /* --- 12326,12359 ---- } /* ! * "test_disable({name}, {val})" function */ static void ! f_test_override(typval_T *argvars, typval_T *rettv UNUSED) { ! char_u *name = (char_u *)""; ! int val; ! ! if (argvars[0].v_type != VAR_STRING ! || (argvars[1].v_type) != VAR_NUMBER) ! EMSG(_(e_invarg)); ! else ! { ! name = get_tv_string_chk(&argvars[0]); ! val = (int)get_tv_number(&argvars[1]); ! ! if (STRCMP(name, (char_u *)"redraw") == 0) ! disable_redraw_for_testing = val; ! else if (STRCMP(name, (char_u *)"char_avail") == 0) ! disable_char_avail_for_testing = val; ! else if (STRCMP(name, (char_u *)"ALL") == 0) ! { ! disable_char_avail_for_testing = FALSE; ! disable_redraw_for_testing = FALSE; ! } ! else ! EMSG2(_(e_invarg2), name); ! } } /* *** ../vim-8.0.0439/src/globals.h 2017-02-17 16:31:16.921294136 +0100 --- src/globals.h 2017-03-09 17:38:48.158336203 +0100 *************** *** 1648,1654 **** --- 1648,1656 ---- /* set by alloc_fail(), number of times alloc() returns NULL */ EXTERN int alloc_fail_repeat INIT(= 0); + /* flags set by test_override() */ EXTERN int disable_char_avail_for_testing INIT(= 0); + EXTERN int disable_redraw_for_testing INIT(= 0); EXTERN int in_free_unref_items INIT(= FALSE); #endif *** ../vim-8.0.0439/src/screen.c 2017-03-01 18:04:01.575277654 +0100 --- src/screen.c 2017-03-09 17:17:07.575435945 +0100 *************** *** 10580,10586 **** int redrawing(void) { ! return (!RedrawingDisabled && !(p_lz && char_avail() && !KeyTyped && !do_redraw)); } --- 10580,10591 ---- int redrawing(void) { ! #ifdef FEAT_EVAL ! if (disable_redraw_for_testing) ! return 0; ! else ! #endif ! return (!RedrawingDisabled && !(p_lz && char_avail() && !KeyTyped && !do_redraw)); } *** ../vim-8.0.0439/src/testdir/Make_all.mak 2017-03-08 00:01:31.489347798 +0100 --- src/testdir/Make_all.mak 2017-03-09 17:17:07.575435945 +0100 *************** *** 151,156 **** --- 151,157 ---- test_diffmode.res \ test_digraph.res \ test_display.res \ + test_edit.res \ test_farsi.res \ test_fnameescape.res \ test_fold.res \ *** ../vim-8.0.0439/src/testdir/test_cursor_func.vim 2016-05-25 20:53:31.000000000 +0200 --- src/testdir/test_cursor_func.vim 2017-03-09 17:17:07.575435945 +0100 *************** *** 44,52 **** new call setline(1, ['func()', '{', '}', '----']) autocmd! CursorMovedI * call s:Highlight_Matching_Pair() ! call test_disable_char_avail(1) exe "normal! 3Ga\X\" ! call test_disable_char_avail(0) call assert_equal('-X---', getline(4)) autocmd! CursorMovedI * quit! --- 44,52 ---- new call setline(1, ['func()', '{', '}', '----']) autocmd! CursorMovedI * call s:Highlight_Matching_Pair() ! call test_override("char_avail", 1) exe "normal! 3Ga\X\" ! call test_override("char_avail", 0) call assert_equal('-X---', getline(4)) autocmd! CursorMovedI * quit! *** ../vim-8.0.0439/src/testdir/test_edit.vim 2017-03-09 18:17:36.874092334 +0100 --- src/testdir/test_edit.vim 2017-03-09 17:17:07.575435945 +0100 *************** *** 0 **** --- 1,1324 ---- + " Test for edit functions + " + if exists("+t_kD") + let &t_kD="[3;*~" + endif + set belloff= + + " 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 + set belloff=backspace + " 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 + if has("multi_byte") + call setline(1, "\u0401") + call feedkeys("i\\", 'tnix') + call assert_equal([''], getline(1,'$')) + %d + endif + " 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)) + set belloff= + 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\",''], getline(1,'$')) + %d + call setline(1, 'J') + call feedkeys("A\\u\\\", 'tx') + call assert_equal(["January"], getline(1,'$')) + + delfu ListMonths + delfu DoIt + iunmap + bw! + endfunc + + func! Test_edit_08() + " reset insertmode from i_ctrl-r_= + new + call setline(1, ['abc']) + call cursor(1, 4) + call feedkeys(":set im\ZZZ\=setbufvar(1,'&im', 0)\",'tnix') + call assert_equal(['abZZZc'], getline(1,'$')) + call assert_equal([0, 1, 1, 0], getpos('.')) + call assert_false(0, '&im') + bw! + 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_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& + bw! + endif + 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("multi_byte") || !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) + set belloff=all + try + call feedkeys("A\", 'tnix') + catch /^Vim\%((\a\+)\)\=:E29/ + call assert_true(1, 'E29 error caught') + endtry + set belloff= + 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 + set belloff=all + 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('.')) + set belloff= + bw! + endfunc + + func! Test_edit_CTRL_I() + " Tab in completion mode + let path=expand("%:p:h") + new + call setline(1, [path."/", '']) + call feedkeys("Ate\\\\\", 'tnix') + call assert_match('test1\.in', 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) + set belloff=all + 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 + set belloff= + call delete('Xdictionary.txt') + + if has("multi_byte") + 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', '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', '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") + 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) + set belloff=all + 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 + set belloff= + call assert_equal(['mad'], getline(1, '$')) + call delete('Xthesaurus') + bw! + 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 + set belloff=all + 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 + set belloff= + 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() + set belloff=all + 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('.')) + set startofline belloff= + bw! + endfunc + + func! Test_edit_forbidden() + set belloff=error,esc + 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 + set belloff= + 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 *** ../vim-8.0.0439/src/testdir/test_search.vim 2017-03-08 22:55:14.914181221 +0100 --- src/testdir/test_search.vim 2017-03-09 17:17:07.575435945 +0100 *************** *** 7,13 **** endif " need to disable char_avail, " so that expansion of commandline works ! call test_disable_char_avail(1) new call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar']) " Test 1 --- 7,13 ---- endif " need to disable char_avail, " so that expansion of commandline works ! call test_override("char_avail", 1) new call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar']) " Test 1 *************** *** 194,200 **** call assert_equal(' 3 the', getline('.')) " clean up ! call test_disable_char_avail(0) bw! endfunc --- 194,200 ---- call assert_equal(' 3 the', getline('.')) " clean up ! call test_override("char_avail", 0) bw! endfunc *************** *** 204,210 **** endif " need to disable char_avail, " so that expansion of commandline works ! call test_disable_char_avail(1) new call setline(1, [' 1', ' 2 these', ' 3 the theother']) " Test 1 --- 204,210 ---- endif " need to disable char_avail, " so that expansion of commandline works ! call test_override("char_avail", 1) new call setline(1, [' 1', ' 2 these', ' 3 the theother']) " Test 1 *************** *** 266,272 **** " clean up set noincsearch ! call test_disable_char_avail(0) bw! endfunc --- 266,272 ---- " clean up set noincsearch ! call test_override("char_avail", 0) bw! endfunc *** ../vim-8.0.0439/src/testdir/test_assert.vim 2017-01-28 18:08:08.155009961 +0100 --- src/testdir/test_assert.vim 2017-03-09 17:36:18.279384806 +0100 *************** *** 127,132 **** --- 127,140 ---- call remove(v:errors, 0) endfunc + func Test_override() + call test_override('char_avail', 1) + call test_override('redraw', 1) + call test_override('ALL', 0) + call assert_fails("call test_override('xxx', 1)", 'E475') + call assert_fails("call test_override('redraw', 'yes')", 'E474') + endfunc + func Test_user_is_happy() smile sleep 300m *** ../vim-8.0.0439/src/Makefile 2017-03-08 22:39:46.536941572 +0100 --- src/Makefile 2017-03-09 17:39:33.582018380 +0100 *************** *** 2111,2116 **** --- 2110,2116 ---- test_digraph \ test_functions \ test_display \ + test_edit \ test_ex_undo \ test_execute_func \ test_expand \ *** ../vim-8.0.0439/src/testdir/runtest.vim 2017-03-05 14:30:48.372572724 +0100 --- src/testdir/runtest.vim 2017-03-09 17:40:37.097573956 +0100 *************** *** 49,55 **** " This also enables use of line continuation. set nocp viminfo+=nviminfo ! " Use utf-8 or latin1 be default, instead of whatever the system default " happens to be. Individual tests can overrule this at the top of the file. if has('multi_byte') set encoding=utf-8 --- 49,55 ---- " This also enables use of line continuation. set nocp viminfo+=nviminfo ! " Use utf-8 or latin1 by default, instead of whatever the system default " happens to be. Individual tests can overrule this at the top of the file. if has('multi_byte') set encoding=utf-8 *************** *** 96,101 **** --- 96,104 ---- " mode message. set noshowmode + " Clear any overrides. + call test_override('ALL', 0) + if exists("*SetUp") try call SetUp() *** ../vim-8.0.0439/src/version.c 2017-03-09 15:58:26.548668478 +0100 --- src/version.c 2017-03-09 17:18:40.966782129 +0100 *************** *** 766,767 **** --- 766,769 ---- { /* Add new patch number below this line */ + /**/ + 440, /**/ -- From "know your smileys": <>:-) Bishop /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///