xref: /vim-8.2.3635/src/testdir/test_edit.vim (revision 5ef1c6a4)
1" Test for edit functions
2
3if exists("+t_kD")
4  let &t_kD="[3;*~"
5endif
6
7source check.vim
8
9" Needed for testing basic rightleft: Test_edit_rightleft
10source view_util.vim
11
12" Needs to come first until the bug in getchar() is
13" fixed: https://groups.google.com/d/msg/vim_dev/fXL9yme4H4c/bOR-U6_bAQAJ
14func Test_edit_00b()
15  new
16  call setline(1, ['abc '])
17  inoreabbr <buffer> h here some more
18  call cursor(1, 4)
19  " <c-l> expands the abbreviation and ends insertmode
20  call feedkeys(":set im\<cr> h\<c-l>:set noim\<cr>", 'tix')
21  call assert_equal(['abc here some more '], getline(1,'$'))
22  iunabbr <buffer> h
23  bw!
24endfunc
25
26func Test_edit_01()
27  " set for Travis CI?
28  "  set nocp noesckeys
29  new
30  " 1) empty buffer
31  call assert_equal([''], getline(1,'$'))
32  " 2) delete in an empty line
33  call feedkeys("i\<del>\<esc>", 'tnix')
34  call assert_equal([''], getline(1,'$'))
35  %d
36  " 3) delete one character
37  call setline(1, 'a')
38  call feedkeys("i\<del>\<esc>", 'tnix')
39  call assert_equal([''], getline(1,'$'))
40  %d
41  " 4) delete a multibyte character
42  call setline(1, "\u0401")
43  call feedkeys("i\<del>\<esc>", 'tnix')
44  call assert_equal([''], getline(1,'$'))
45  %d
46  " 5.1) delete linebreak with 'bs' option containing eol
47  let _bs=&bs
48  set bs=eol
49  call setline(1, ["abc def", "ghi jkl"])
50  call cursor(1, 1)
51  call feedkeys("A\<del>\<esc>", 'tnix')
52  call assert_equal(['abc defghi jkl'], getline(1, 2))
53  %d
54  " 5.2) delete linebreak with backspace option w/out eol
55  set bs=
56  call setline(1, ["abc def", "ghi jkl"])
57  call cursor(1, 1)
58  call feedkeys("A\<del>\<esc>", 'tnix')
59  call assert_equal(["abc def", "ghi jkl"], getline(1, 2))
60  let &bs=_bs
61  bw!
62endfunc
63
64func Test_edit_02()
65  " Change cursor position in InsertCharPre command
66  new
67  call setline(1, 'abc')
68  call cursor(1, 1)
69  fu! DoIt(...)
70    call cursor(1, 4)
71    if len(a:000)
72      let v:char=a:1
73    endif
74  endfu
75  au InsertCharPre <buffer> :call DoIt('y')
76  call feedkeys("ix\<esc>", 'tnix')
77  call assert_equal(['abcy'], getline(1, '$'))
78  " Setting <Enter> in InsertCharPre
79  au! InsertCharPre <buffer> :call DoIt("\n")
80  call setline(1, 'abc')
81  call cursor(1, 1)
82  call feedkeys("ix\<esc>", 'tnix')
83  call assert_equal(['abc', ''], getline(1, '$'))
84  %d
85  au! InsertCharPre
86  " Change cursor position in InsertEnter command
87  " 1) when setting v:char, keeps changed cursor position
88  au! InsertEnter <buffer> :call DoIt('y')
89  call setline(1, 'abc')
90  call cursor(1, 1)
91  call feedkeys("ix\<esc>", 'tnix')
92  call assert_equal(['abxc'], getline(1, '$'))
93  " 2) when not setting v:char, restores changed cursor position
94  au! InsertEnter <buffer> :call DoIt()
95  call setline(1, 'abc')
96  call cursor(1, 1)
97  call feedkeys("ix\<esc>", 'tnix')
98  call assert_equal(['xabc'], getline(1, '$'))
99  au! InsertEnter
100  delfu DoIt
101  bw!
102endfunc
103
104func Test_edit_03()
105  " Change cursor after <c-o> command to end of line
106  new
107  call setline(1, 'abc')
108  call cursor(1, 1)
109  call feedkeys("i\<c-o>$y\<esc>", 'tnix')
110  call assert_equal(['abcy'], getline(1, '$'))
111  %d
112  call setline(1, 'abc')
113  call cursor(1, 1)
114  call feedkeys("i\<c-o>80|y\<esc>", 'tnix')
115  call assert_equal(['abcy'], getline(1, '$'))
116  %d
117  call setline(1, 'abc')
118  call feedkeys("Ad\<c-o>:s/$/efg/\<cr>hij", 'tnix')
119  call assert_equal(['hijabcdefg'], getline(1, '$'))
120  bw!
121endfunc
122
123func Test_edit_04()
124  " test for :stopinsert
125  new
126  call setline(1, 'abc')
127  call cursor(1, 1)
128  call feedkeys("i\<c-o>:stopinsert\<cr>$", 'tnix')
129  call feedkeys("aX\<esc>", 'tnix')
130  call assert_equal(['abcX'], getline(1, '$'))
131  %d
132  bw!
133endfunc
134
135func Test_edit_05()
136  " test for folds being opened
137  new
138  call setline(1, ['abcX', 'abcX', 'zzzZ'])
139  call cursor(1, 1)
140  set foldmethod=manual foldopen+=insert
141  " create fold for those two lines
142  norm! Vjzf
143  call feedkeys("$ay\<esc>", 'tnix')
144  call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
145  %d
146  call setline(1, ['abcX', 'abcX', 'zzzZ'])
147  call cursor(1, 1)
148  set foldmethod=manual foldopen-=insert
149  " create fold for those two lines
150  norm! Vjzf
151  call feedkeys("$ay\<esc>", 'tnix')
152  call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
153  %d
154  bw!
155endfunc
156
157func Test_edit_06()
158  " Test in diff mode
159  if !has("diff") || !executable("diff")
160    return
161  endif
162  new
163  call setline(1, ['abc', 'xxx', 'yyy'])
164  vnew
165  call setline(1, ['abc', 'zzz', 'xxx', 'yyy'])
166  wincmd p
167  diffthis
168  wincmd p
169  diffthis
170  wincmd p
171  call cursor(2, 1)
172  norm! zt
173  call feedkeys("Ozzz\<esc>", 'tnix')
174  call assert_equal(['abc', 'zzz', 'xxx', 'yyy'], getline(1,'$'))
175  bw!
176  bw!
177endfunc
178
179func Test_edit_07()
180  " 1) Test with completion <c-l> when popupmenu is visible
181  new
182  call setline(1, 'J')
183
184  func! ListMonths()
185    call complete(col('.')-1, ['January', 'February', 'March',
186    \ 'April', 'May', 'June', 'July', 'August', 'September',
187    \ 'October', 'November', 'December'])
188    return ''
189  endfunc
190  inoremap <buffer> <F5> <C-R>=ListMonths()<CR>
191
192  call feedkeys("A\<f5>\<c-p>". repeat("\<down>", 6)."\<c-l>\<down>\<c-l>\<cr>", 'tx')
193  call assert_equal(['July'], getline(1,'$'))
194  " 1) Test completion when InsertCharPre kicks in
195  %d
196  call setline(1, 'J')
197  fu! DoIt()
198    if v:char=='u'
199      let v:char='an'
200    endif
201  endfu
202  au InsertCharPre <buffer> :call DoIt()
203  call feedkeys("A\<f5>\<c-p>u\<cr>\<c-l>\<cr>", 'tx')
204  call assert_equal(["Jan\<c-l>",''], 1->getline('$'))
205  %d
206  call setline(1, 'J')
207  call feedkeys("A\<f5>\<c-p>u\<down>\<c-l>\<cr>", 'tx')
208  call assert_equal(["January"], 1->getline('$'))
209
210  delfu ListMonths
211  delfu DoIt
212  iunmap <buffer> <f5>
213  bw!
214endfunc
215
216func Test_edit_08()
217  " reset insertmode from i_ctrl-r_=
218  let g:bufnr = bufnr('%')
219  new
220  call setline(1, ['abc'])
221  call cursor(1, 4)
222  call feedkeys(":set im\<cr>ZZZ\<c-r>=setbufvar(g:bufnr,'&im', 0)\<cr>",'tnix')
223  call assert_equal(['abZZZc'], getline(1,'$'))
224  call assert_equal([0, 1, 1, 0], getpos('.'))
225  call assert_false(0, '&im')
226  bw!
227  unlet g:bufnr
228endfunc
229
230func Test_edit_09()
231  " test i_CTRL-\ combinations
232  new
233  call setline(1, ['abc', 'def', 'ghi'])
234  call cursor(1, 1)
235  " 1) CTRL-\ CTLR-N
236  call feedkeys(":set im\<cr>\<c-\>\<c-n>ccABC\<c-l>", 'txin')
237  call assert_equal(['ABC', 'def', 'ghi'], getline(1,'$'))
238  call setline(1, ['ABC', 'def', 'ghi'])
239  " 2) CTRL-\ CTLR-G
240  call feedkeys("j0\<c-\>\<c-g>ZZZ\<cr>\<c-l>", 'txin')
241  call assert_equal(['ABC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
242  call feedkeys("I\<c-\>\<c-g>YYY\<c-l>", 'txin')
243  call assert_equal(['ABC', 'ZZZ', 'YYYdef', 'ghi'], getline(1,'$'))
244  set noinsertmode
245  " 3) CTRL-\ CTRL-O
246  call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
247  call cursor(1, 1)
248  call feedkeys("A\<c-o>ix", 'txin')
249  call assert_equal(['ABxC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
250  call feedkeys("A\<c-\>\<c-o>ix", 'txin')
251  call assert_equal(['ABxCx', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
252  " 4) CTRL-\ a (should be inserted literally, not special after <c-\>
253  call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
254  call cursor(1, 1)
255  call feedkeys("A\<c-\>a", 'txin')
256  call assert_equal(["ABC\<c-\>a", 'ZZZ', 'def', 'ghi'], getline(1, '$'))
257  bw!
258endfunc
259
260func Test_edit_10()
261  " Test for starting selectmode
262  new
263  set selectmode=key keymodel=startsel
264  call setline(1, ['abc', 'def', 'ghi'])
265  call cursor(1, 4)
266  call feedkeys("A\<s-home>start\<esc>", 'txin')
267  call assert_equal(['startdef', 'ghi'], getline(1, '$'))
268  set selectmode= keymodel=
269  bw!
270endfunc
271
272func Test_edit_11()
273  " Test that indenting kicks in
274  new
275  set cindent
276  call setline(1, ['{', '', ''])
277  call cursor(2, 1)
278  call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
279  call cursor(3, 1)
280  call feedkeys("i/* comment */", 'tnix')
281  call assert_equal(['{', "\<tab>int c;", "/* comment */"], getline(1, '$'))
282  " added changed cindentkeys slightly
283  set cindent cinkeys+=*/
284  call setline(1, ['{', '', ''])
285  call cursor(2, 1)
286  call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
287  call cursor(3, 1)
288  call feedkeys("i/* comment */", 'tnix')
289  call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */"], getline(1, '$'))
290  set cindent cinkeys+==end
291  call feedkeys("oend\<cr>\<esc>", 'tnix')
292  call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */", "\tend", ''], getline(1, '$'))
293  set cinkeys-==end
294  %d
295  " Use indentexpr instead of cindenting
296  func! Do_Indent()
297    if v:lnum == 3
298      return 3*shiftwidth()
299    else
300      return 2*shiftwidth()
301    endif
302  endfunc
303  setl indentexpr=Do_Indent() indentkeys+=*/
304  call setline(1, ['{', '', ''])
305  call cursor(2, 1)
306  call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
307  call cursor(3, 1)
308  call feedkeys("i/* comment */", 'tnix')
309  call assert_equal(['{', "\<tab>\<tab>int c;", "\<tab>\<tab>\<tab>/* comment */"], getline(1, '$'))
310  set cinkeys&vim indentkeys&vim
311  set nocindent indentexpr=
312  delfu Do_Indent
313  bw!
314endfunc
315
316func Test_edit_11_indentexpr()
317  " Test that indenting kicks in
318  new
319  " Use indentexpr instead of cindenting
320  func! Do_Indent()
321    let pline=prevnonblank(v:lnum)
322    if empty(getline(v:lnum))
323      if getline(pline) =~ 'if\|then'
324        return shiftwidth()
325      else
326        return 0
327      endif
328    else
329        return 0
330    endif
331  endfunc
332  setl indentexpr=Do_Indent() indentkeys+=0=then,0=fi
333  call setline(1, ['if [ $this ]'])
334  call cursor(1, 1)
335  call feedkeys("othen\<cr>that\<cr>fi", 'tnix')
336  call assert_equal(['if [ $this ]', "then", "\<tab>that", "fi"], getline(1, '$'))
337  set cinkeys&vim indentkeys&vim
338  set nocindent indentexpr=
339  delfu Do_Indent
340  bw!
341endfunc
342
343func Test_edit_12()
344  " Test changing indent in replace mode
345  new
346  call setline(1, ["\tabc", "\tdef"])
347  call cursor(2, 4)
348  call feedkeys("R^\<c-d>", 'tnix')
349  call assert_equal(["\tabc", "def"], getline(1, '$'))
350  call assert_equal([0, 2, 2, 0], '.'->getpos())
351  %d
352  call setline(1, ["\tabc", "\t\tdef"])
353  call cursor(2, 2)
354  call feedkeys("R^\<c-d>", 'tnix')
355  call assert_equal(["\tabc", "def"], getline(1, '$'))
356  call assert_equal([0, 2, 1, 0], getpos('.'))
357  %d
358  call setline(1, ["\tabc", "\t\tdef"])
359  call cursor(2, 2)
360  call feedkeys("R\<c-t>", 'tnix')
361  call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
362  call assert_equal([0, 2, 2, 0], getpos('.'))
363  bw!
364  10vnew
365  call setline(1, ["\tabc", "\t\tdef"])
366  call cursor(2, 2)
367  call feedkeys("R\<c-t>", 'tnix')
368  call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
369  call assert_equal([0, 2, 2, 0], getpos('.'))
370  %d
371  set sw=4
372  call setline(1, ["\tabc", "\t\tdef"])
373  call cursor(2, 2)
374  call feedkeys("R\<c-t>\<c-t>", 'tnix')
375  call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
376  call assert_equal([0, 2, 2, 0], getpos('.'))
377  %d
378  call setline(1, ["\tabc", "\t\tdef"])
379  call cursor(2, 2)
380  call feedkeys("R\<c-t>\<c-t>", 'tnix')
381  call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
382  call assert_equal([0, 2, 2, 0], getpos('.'))
383  set et
384  set sw& et&
385  %d
386  call setline(1, ["\t/*"])
387  set formatoptions=croql
388  call cursor(1, 3)
389  call feedkeys("A\<cr>\<cr>/", 'tnix')
390  call assert_equal(["\t/*", " *", " */"], getline(1, '$'))
391  set formatoptions&
392  bw!
393endfunc
394
395func Test_edit_13()
396  " Test smartindenting
397  if exists("+smartindent")
398    new
399    set smartindent autoindent
400    call setline(1, ["\tabc"])
401    call feedkeys("A {\<cr>more\<cr>}\<esc>", 'tnix')
402    call assert_equal(["\tabc {", "\t\tmore", "\t}"], getline(1, '$'))
403    set smartindent& autoindent&
404    bwipe!
405  endif
406
407  " Test autoindent removing indent of blank line.
408  new
409  call setline(1, '    foo bar baz')
410  set autoindent
411  exe "normal 0eea\<CR>\<CR>\<Esc>"
412  call assert_equal("    foo bar", getline(1))
413  call assert_equal("", getline(2))
414  call assert_equal("    baz", getline(3))
415  set autoindent&
416  bwipe!
417endfunc
418
419func Test_edit_CR()
420  " Test for <CR> in insert mode
421  " basically only in quickfix mode ist tested, the rest
422  " has been taken care of by other tests
423  if !has("quickfix")
424    return
425  endif
426  botright new
427  call writefile(range(1, 10), 'Xqflist.txt')
428  call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}])
429  copen
430  set modifiable
431  call feedkeys("A\<cr>", 'tnix')
432  call assert_equal('Xqflist.txt', bufname(''))
433  call assert_equal(2, line('.'))
434  cclose
435  botright new
436  call setloclist(0, [{'filename': 'Xqflist.txt', 'lnum': 10}])
437  lopen
438  set modifiable
439  call feedkeys("A\<cr>", 'tnix')
440  call assert_equal('Xqflist.txt', bufname(''))
441  call assert_equal(10, line('.'))
442  call feedkeys("A\<Enter>", 'tnix')
443  call feedkeys("A\<kEnter>", 'tnix')
444  call feedkeys("A\n", 'tnix')
445  call feedkeys("A\r", 'tnix')
446  call assert_equal(map(range(1, 10), 'string(v:val)') + ['', '', '', ''], getline(1, '$'))
447  bw!
448  lclose
449  call delete('Xqflist.txt')
450endfunc
451
452func Test_edit_CTRL_()
453  " disabled for Windows builds, why?
454  if !has("rightleft") || has("win32")
455    return
456  endif
457  let _encoding=&encoding
458  set encoding=utf-8
459  " Test for CTRL-_
460  new
461  call setline(1, ['abc'])
462  call cursor(1, 1)
463  call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
464  call assert_equal(["\<C-_>xyzabc"], getline(1, '$'))
465  call assert_false(&revins)
466  set ari
467  call setline(1, ['abc'])
468  call cursor(1, 1)
469  call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
470  call assert_equal(["æèñabc"], getline(1, '$'))
471  call assert_true(&revins)
472  call setline(1, ['abc'])
473  call cursor(1, 1)
474  call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
475  call assert_equal(["xyzabc"], getline(1, '$'))
476  call assert_false(&revins)
477  set noari
478  let &encoding=_encoding
479  bw!
480endfunc
481
482" needs to come first, to have the @. register empty
483func Test_edit_00a_CTRL_A()
484  " Test pressing CTRL-A
485  new
486  call setline(1, repeat([''], 5))
487  call cursor(1, 1)
488  try
489    call feedkeys("A\<NUL>", 'tnix')
490  catch /^Vim\%((\a\+)\)\=:E29/
491    call assert_true(1, 'E29 error caught')
492  endtry
493  call cursor(1, 1)
494  call feedkeys("Afoobar \<esc>", 'tnix')
495  call cursor(2, 1)
496  call feedkeys("A\<c-a>more\<esc>", 'tnix')
497  call cursor(3, 1)
498  call feedkeys("A\<NUL>and more\<esc>", 'tnix')
499  call assert_equal(['foobar ', 'foobar more', 'foobar morend more', '', ''], getline(1, '$'))
500  bw!
501endfunc
502
503func Test_edit_CTRL_EY()
504  " Ctrl-E/ Ctrl-Y in insert mode completion to scroll
505  10new
506  call setline(1, range(1, 100))
507  call cursor(30, 1)
508  norm! z.
509  call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
510  call assert_equal(30, winsaveview()['topline'])
511  call assert_equal([0, 30, 2, 0], getpos('.'))
512  call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
513  call feedkeys("A\<c-x>".repeat("\<c-y>", 10), 'tnix')
514  call assert_equal(21, winsaveview()['topline'])
515  call assert_equal([0, 30, 2, 0], getpos('.'))
516  bw!
517endfunc
518
519func Test_edit_CTRL_G()
520  new
521  call setline(1, ['foobar', 'foobar', 'foobar'])
522  call cursor(2, 4)
523  call feedkeys("ioooooooo\<c-g>k\<c-r>.\<esc>", 'tnix')
524  call assert_equal(['foooooooooobar', 'foooooooooobar', 'foobar'], getline(1, '$'))
525  call assert_equal([0, 1, 11, 0], getpos('.'))
526  call feedkeys("i\<c-g>k\<esc>", 'tnix')
527  call assert_equal([0, 1, 10, 0], getpos('.'))
528  call cursor(2, 4)
529  call feedkeys("i\<c-g>jzzzz\<esc>", 'tnix')
530  call assert_equal(['foooooooooobar', 'foooooooooobar', 'foozzzzbar'], getline(1, '$'))
531  call assert_equal([0, 3, 7, 0], getpos('.'))
532  call feedkeys("i\<c-g>j\<esc>", 'tnix')
533  call assert_equal([0, 3, 6, 0], getpos('.'))
534  bw!
535endfunc
536
537func Test_edit_CTRL_I()
538  " Tab in completion mode
539  let path=expand("%:p:h")
540  new
541  call setline(1, [path. "/", ''])
542  call feedkeys("Arunt\<c-x>\<c-f>\<tab>\<cr>\<esc>", 'tnix')
543  call assert_match('runtest\.vim', getline(1))
544  %d
545  call writefile(['one', 'two', 'three'], 'Xinclude.txt')
546  let include='#include Xinclude.txt'
547  call setline(1, [include, ''])
548  call cursor(2, 1)
549  call feedkeys("A\<c-x>\<tab>\<cr>\<esc>", 'tnix')
550  call assert_equal([include, 'one', ''], getline(1, '$'))
551  call feedkeys("2ggC\<c-x>\<tab>\<down>\<cr>\<esc>", 'tnix')
552  call assert_equal([include, 'two', ''], getline(1, '$'))
553  call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<cr>\<esc>", 'tnix')
554  call assert_equal([include, 'three', ''], getline(1, '$'))
555  call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
556  call assert_equal([include, '', ''], getline(1, '$'))
557  call delete("Xinclude.txt")
558  bw!
559endfunc
560
561func Test_edit_CTRL_K()
562  " Test pressing CTRL-K (basically only dictionary completion and digraphs
563  " the rest is already covered
564  call writefile(['A', 'AA', 'AAA', 'AAAA'], 'Xdictionary.txt')
565  set dictionary=Xdictionary.txt
566  new
567  call setline(1, 'A')
568  call cursor(1, 1)
569  call feedkeys("A\<c-x>\<c-k>\<cr>\<esc>", 'tnix')
570  call assert_equal(['AA', ''], getline(1, '$'))
571  %d
572  call setline(1, 'A')
573  call cursor(1, 1)
574  call feedkeys("A\<c-x>\<c-k>\<down>\<cr>\<esc>", 'tnix')
575  call assert_equal(['AAA'], getline(1, '$'))
576  %d
577  call setline(1, 'A')
578  call cursor(1, 1)
579  call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<cr>\<esc>", 'tnix')
580  call assert_equal(['AAAA'], getline(1, '$'))
581  %d
582  call setline(1, 'A')
583  call cursor(1, 1)
584  call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
585  call assert_equal(['A'], getline(1, '$'))
586  %d
587  call setline(1, 'A')
588  call cursor(1, 1)
589  call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
590  call assert_equal(['AA'], getline(1, '$'))
591
592  " press an unexecpted key after dictionary completion
593  %d
594  call setline(1, 'A')
595  call cursor(1, 1)
596  call feedkeys("A\<c-x>\<c-k>\<c-]>\<cr>\<esc>", 'tnix')
597  call assert_equal(['AA', ''], getline(1, '$'))
598  %d
599  call setline(1, 'A')
600  call cursor(1, 1)
601  call feedkeys("A\<c-x>\<c-k>\<c-s>\<cr>\<esc>", 'tnix')
602  call assert_equal(["AA\<c-s>", ''], getline(1, '$'))
603  %d
604  call setline(1, 'A')
605  call cursor(1, 1)
606  call feedkeys("A\<c-x>\<c-k>\<c-f>\<cr>\<esc>", 'tnix')
607  call assert_equal(["AA\<c-f>", ''], getline(1, '$'))
608
609  set dictionary=
610  %d
611  call setline(1, 'A')
612  call cursor(1, 1)
613  let v:testing = 1
614  try
615    call feedkeys("A\<c-x>\<c-k>\<esc>", 'tnix')
616  catch
617    " error sleeps 2 seconds, when v:testing is not set
618    let v:testing = 0
619  endtry
620  call delete('Xdictionary.txt')
621
622  call test_override("char_avail", 1)
623  set showcmd
624  %d
625  call feedkeys("A\<c-k>a:\<esc>", 'tnix')
626  call assert_equal(['ä'], getline(1, '$'))
627  call test_override("char_avail", 0)
628  set noshowcmd
629
630  bw!
631endfunc
632
633func Test_edit_CTRL_L()
634  " Test Ctrl-X Ctrl-L (line completion)
635  new
636  set complete=.
637  call setline(1, ['one', 'two', 'three', '', '', '', ''])
638  call cursor(4, 1)
639  call feedkeys("A\<c-x>\<c-l>\<esc>", 'tnix')
640  call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
641  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<esc>", 'tnix')
642  call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
643  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<esc>", 'tnix')
644  call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
645  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
646  call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
647  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
648  call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
649  call feedkeys("cct\<c-x>\<c-l>\<c-p>\<esc>", 'tnix')
650  call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
651  call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<esc>", 'tnix')
652  call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
653  call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<c-p>\<esc>", 'tnix')
654  call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
655  set complete=
656  call cursor(5, 1)
657  call feedkeys("A\<c-x>\<c-l>\<c-p>\<c-n>\<esc>", 'tnix')
658  call assert_equal(['one', 'two', 'three', 'three', "\<c-l>\<c-p>\<c-n>", '', ''], getline(1, '$'))
659  set complete&
660  %d
661  if has("conceal") && has("syntax")
662    call setline(1, ['foo', 'bar', 'foobar'])
663    call test_override("char_avail", 1)
664    set conceallevel=2 concealcursor=n
665    syn on
666    syn match ErrorMsg "^bar"
667    call matchadd("Conceal", 'oo', 10, -1, {'conceal': 'X'})
668    func! DoIt()
669      let g:change=1
670    endfunc
671    au! TextChangedI <buffer> :call DoIt()
672
673    call cursor(2, 1)
674    call assert_false(exists("g:change"))
675    call feedkeys("A \<esc>", 'tnix')
676    call assert_equal(['foo', 'bar ', 'foobar'], getline(1, '$'))
677    call assert_equal(1, g:change)
678
679    call test_override("char_avail", 0)
680    call clearmatches()
681    syn off
682    au! TextChangedI
683    delfu DoIt
684    unlet! g:change
685  endif
686  bw!
687endfunc
688
689func Test_edit_CTRL_N()
690  " Check keyword completion
691  new
692  set complete=.
693  call setline(1, ['INFER', 'loWER', '', '', ])
694  call cursor(3, 1)
695  call feedkeys("Ai\<c-n>\<cr>\<esc>", "tnix")
696  call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
697  call assert_equal(['INFER', 'loWER', 'i', 'LO', '', ''], getline(1, '$'))
698  %d
699  call setline(1, ['INFER', 'loWER', '', '', ])
700  call cursor(3, 1)
701  set ignorecase infercase
702  call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix")
703  call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
704  call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'))
705
706  set noignorecase noinfercase complete&
707  bw!
708endfunc
709
710func Test_edit_CTRL_O()
711  " Check for CTRL-O in insert mode
712  new
713  inoreabbr <buffer> h here some more
714  call setline(1, ['abc', 'def'])
715  call cursor(1, 1)
716  " Ctrl-O after an abbreviation
717  exe "norm A h\<c-o>:set nu\<cr> text"
718  call assert_equal(['abc here some more text', 'def'], getline(1, '$'))
719  call assert_true(&nu)
720  set nonu
721  iunabbr <buffer> h
722  " Ctrl-O at end of line with 've'=onemore
723  call cursor(1, 1)
724  call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
725  call assert_equal([0, 1, 23, 0], g:a)
726  call cursor(1, 1)
727  set ve=onemore
728  call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
729  call assert_equal([0, 1, 24, 0], g:a)
730  set ve=
731  unlet! g:a
732  bw!
733endfunc
734
735func Test_edit_CTRL_R()
736  " Insert Register
737  new
738  call test_override("ALL", 1)
739  set showcmd
740  call feedkeys("AFOOBAR eins zwei\<esc>", 'tnix')
741  call feedkeys("O\<c-r>.", 'tnix')
742  call feedkeys("O\<c-r>=10*500\<cr>\<esc>", 'tnix')
743  call feedkeys("O\<c-r>=getreg('=', 1)\<cr>\<esc>", 'tnix')
744  call assert_equal(["getreg('=', 1)", '5000', "FOOBAR eins zwei", "FOOBAR eins zwei"], getline(1, '$'))
745  call test_override("ALL", 0)
746  set noshowcmd
747  bw!
748endfunc
749
750func Test_edit_CTRL_S()
751  " Test pressing CTRL-S (basically only spellfile completion)
752  " the rest is already covered
753  new
754  if !has("spell")
755    call setline(1, 'vim')
756    call feedkeys("A\<c-x>ss\<cr>\<esc>", 'tnix')
757    call assert_equal(['vims', ''], getline(1, '$'))
758    bw!
759    return
760  endif
761  call setline(1, 'vim')
762  " spell option not yet set
763  try
764    call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
765  catch /^Vim\%((\a\+)\)\=:E756/
766    call assert_true(1, 'error caught')
767  endtry
768  call assert_equal(['vim', ''], getline(1, '$'))
769  %d
770  setl spell spelllang=en
771  call setline(1, 'vim')
772  call cursor(1, 1)
773  call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
774  call assert_equal(['Vim', ''], getline(1, '$'))
775  %d
776  call setline(1, 'vim')
777  call cursor(1, 1)
778  call feedkeys("A\<c-x>\<c-s>\<down>\<cr>\<esc>", 'tnix')
779  call assert_equal(['Aim'], getline(1, '$'))
780  %d
781  call setline(1, 'vim')
782  call cursor(1, 1)
783  call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
784  call assert_equal(['vim', ''], getline(1, '$'))
785  %d
786  " empty buffer
787  call cursor(1, 1)
788  call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
789  call assert_equal(['', ''], getline(1, '$'))
790  setl nospell
791  bw!
792endfunc
793
794func Test_edit_CTRL_T()
795  " Check for CTRL-T and CTRL-X CTRL-T in insert mode
796  " 1) increase indent
797  new
798  call setline(1, "abc")
799  call cursor(1, 1)
800  call feedkeys("A\<c-t>xyz", 'tnix')
801  call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
802  " 2) also when paste option is set
803  set paste
804  call setline(1, "abc")
805  call cursor(1, 1)
806  call feedkeys("A\<c-t>xyz", 'tnix')
807  call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
808  set nopaste
809  " CTRL-X CTRL-T (thesaurus complete)
810  call writefile(['angry furious mad enraged'], 'Xthesaurus')
811  set thesaurus=Xthesaurus
812  call setline(1, 'mad')
813  call cursor(1, 1)
814  call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
815  call assert_equal(['mad', ''], getline(1, '$'))
816  %d
817  call setline(1, 'mad')
818  call cursor(1, 1)
819  call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
820  call assert_equal(['angry', ''], getline(1, '$'))
821  %d
822  call setline(1, 'mad')
823  call cursor(1, 1)
824  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
825  call assert_equal(['furious', ''], getline(1, '$'))
826  %d
827  call setline(1, 'mad')
828  call cursor(1, 1)
829  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
830  call assert_equal(['enraged', ''], getline(1, '$'))
831  %d
832  call setline(1, 'mad')
833  call cursor(1, 1)
834  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
835  call assert_equal(['mad', ''], getline(1, '$'))
836  %d
837  call setline(1, 'mad')
838  call cursor(1, 1)
839  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
840  call assert_equal(['mad', ''], getline(1, '$'))
841  " Using <c-p> <c-n> when 'complete' is empty
842  set complete=
843  %d
844  call setline(1, 'mad')
845  call cursor(1, 1)
846  call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
847  call assert_equal(['angry', ''], getline(1, '$'))
848  %d
849  call setline(1, 'mad')
850  call cursor(1, 1)
851  call feedkeys("A\<c-x>\<c-t>\<c-p>\<cr>\<esc>", 'tnix')
852  call assert_equal(['mad', ''], getline(1, '$'))
853  set complete&
854
855  set thesaurus=
856  %d
857  call setline(1, 'mad')
858  call cursor(1, 1)
859  let v:testing = 1
860  try
861    call feedkeys("A\<c-x>\<c-t>\<esc>", 'tnix')
862  catch
863    " error sleeps 2 seconds, when v:testing is not set
864    let v:testing = 0
865  endtry
866  call assert_equal(['mad'], getline(1, '$'))
867  call delete('Xthesaurus')
868  bw!
869endfunc
870
871func Test_edit_CTRL_U()
872  " Test 'completefunc'
873  new
874  " -1, -2 and -3 are special return values
875  let g:special=0
876  fun! CompleteMonths(findstart, base)
877    if a:findstart
878      " locate the start of the word
879      return g:special
880    else
881      " find months matching with "a:base"
882      let res = []
883      for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
884        if m =~ '^\c'.a:base
885          call add(res, {'word': m, 'abbr': m.' Month', 'icase': 0})
886        endif
887      endfor
888      return {'words': res, 'refresh': 'always'}
889    endif
890  endfun
891  set completefunc=CompleteMonths
892  call setline(1, ['', ''])
893  call cursor(1, 1)
894  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
895  call assert_equal(['X', '', ''], getline(1, '$'))
896  %d
897  let g:special=-1
898  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
899  call assert_equal(['XJan', ''], getline(1, '$'))
900  %d
901  let g:special=-2
902  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
903  call assert_equal(['X', ''], getline(1, '$'))
904  %d
905  let g:special=-3
906  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
907  call assert_equal(['X', ''], getline(1, '$'))
908  %d
909  let g:special=0
910  call feedkeys("AM\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
911  call assert_equal(['Mar', ''], getline(1, '$'))
912  %d
913  call feedkeys("AM\<c-x>\<c-u>\<c-n>\<cr>\<esc>", 'tnix')
914  call assert_equal(['May', ''], getline(1, '$'))
915  %d
916  call feedkeys("AM\<c-x>\<c-u>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
917  call assert_equal(['M', ''], getline(1, '$'))
918  delfu CompleteMonths
919  %d
920  try
921    call feedkeys("A\<c-x>\<c-u>", 'tnix')
922    call assert_fails(1, 'unknown completion function')
923  catch /^Vim\%((\a\+)\)\=:E117/
924    call assert_true(1, 'E117 error caught')
925  endtry
926  set completefunc=
927  bw!
928endfunc
929
930func Test_edit_CTRL_Z()
931  " Ctrl-Z when insertmode is not set inserts it literally
932  new
933  call setline(1, 'abc')
934  call feedkeys("A\<c-z>\<esc>", 'tnix')
935  call assert_equal(["abc\<c-z>"], getline(1,'$'))
936  bw!
937  " TODO: How to Test Ctrl-Z in insert mode, e.g. suspend?
938endfunc
939
940func Test_edit_DROP()
941  if !has("dnd")
942    return
943  endif
944  new
945  call setline(1, ['abc def ghi'])
946  call cursor(1, 1)
947  try
948    call feedkeys("i\<Drop>\<Esc>", 'tnix')
949    call assert_fails(1, 'Invalid register name')
950  catch /^Vim\%((\a\+)\)\=:E353/
951    call assert_true(1, 'error caught')
952  endtry
953  bw!
954endfunc
955
956func Test_edit_CTRL_V()
957  if has("ebcdic")
958    return
959  endif
960  new
961  call setline(1, ['abc'])
962  call cursor(2, 1)
963  " force some redraws
964  set showmode showcmd
965  "call test_override_char_avail(1)
966  call test_override('ALL', 1)
967  call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
968  call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
969
970  if has("rightleft") && exists("+rl")
971    set rl
972    call setline(1, ['abc'])
973    call cursor(2, 1)
974    call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
975    call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
976    set norl
977  endif
978
979  call test_override('ALL', 0)
980  set noshowmode showcmd
981  bw!
982endfunc
983
984func Test_edit_F1()
985  " Pressing <f1>
986  new
987  call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix')
988  set noinsertmode
989  call assert_equal('help', &buftype)
990  bw
991  bw
992endfunc
993
994func Test_edit_F21()
995  " Pressing <f21>
996  " sends a netbeans command
997  if has("netbeans_intg")
998    new
999    " I have no idea what this is supposed to do :)
1000    call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
1001    bw
1002  endif
1003endfunc
1004
1005func Test_edit_HOME_END()
1006  " Test Home/End Keys
1007  new
1008  set foldopen+=hor
1009  call setline(1, ['abc', 'def'])
1010  call cursor(1, 1)
1011  call feedkeys("AX\<Home>Y\<esc>", 'tnix')
1012  call cursor(2, 1)
1013  call feedkeys("iZ\<End>Y\<esc>", 'tnix')
1014  call assert_equal(['YabcX', 'ZdefY'], getline(1, '$'))
1015
1016  set foldopen-=hor
1017  bw!
1018endfunc
1019
1020func Test_edit_INS()
1021  " Test for Pressing <Insert>
1022  new
1023  call setline(1, ['abc', 'def'])
1024  call cursor(1, 1)
1025  call feedkeys("i\<Insert>ZYX>", 'tnix')
1026  call assert_equal(['ZYX>', 'def'], getline(1, '$'))
1027  call setline(1, ['abc', 'def'])
1028  call cursor(1, 1)
1029  call feedkeys("i\<Insert>Z\<Insert>YX>", 'tnix')
1030  call assert_equal(['ZYX>bc', 'def'], getline(1, '$'))
1031  bw!
1032endfunc
1033
1034func Test_edit_LEFT_RIGHT()
1035  " Left, Shift-Left, Right, Shift-Right
1036  new
1037  call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX'])
1038  let _ww=&ww
1039  set ww=
1040  call cursor(2, 1)
1041  call feedkeys("i\<left>\<esc>", 'tnix')
1042  call assert_equal([0, 2, 1, 0], getpos('.'))
1043  " Is this a bug, <s-left> does not respect whichwrap option
1044  call feedkeys("i\<s-left>\<esc>", 'tnix')
1045  call assert_equal([0, 1, 8, 0], getpos('.'))
1046  call feedkeys("i". repeat("\<s-left>", 3). "\<esc>", 'tnix')
1047  call assert_equal([0, 1, 1, 0], getpos('.'))
1048  call feedkeys("i\<right>\<esc>", 'tnix')
1049  call assert_equal([0, 1, 1, 0], getpos('.'))
1050  call feedkeys("i\<right>\<right>\<esc>", 'tnix')
1051  call assert_equal([0, 1, 2, 0], getpos('.'))
1052  call feedkeys("A\<right>\<esc>", 'tnix')
1053  call assert_equal([0, 1, 11, 0], getpos('.'))
1054  call feedkeys("A\<s-right>\<esc>", 'tnix')
1055  call assert_equal([0, 2, 1, 0], getpos('.'))
1056  call feedkeys("i\<s-right>\<esc>", 'tnix')
1057  call assert_equal([0, 2, 4, 0], getpos('.'))
1058  call cursor(3, 11)
1059  call feedkeys("A\<right>\<esc>", 'tnix')
1060  call feedkeys("A\<s-right>\<esc>", 'tnix')
1061  call assert_equal([0, 3, 11, 0], getpos('.'))
1062  call cursor(2, 11)
1063  " <S-Right> does not respect 'whichwrap' option
1064  call feedkeys("A\<s-right>\<esc>", 'tnix')
1065  call assert_equal([0, 3, 1, 0], getpos('.'))
1066  " Check motion when 'whichwrap' contains cursor keys for insert mode
1067  set ww+=[,]
1068  call cursor(2, 1)
1069  call feedkeys("i\<left>\<esc>", 'tnix')
1070  call assert_equal([0, 1, 11, 0], getpos('.'))
1071  call cursor(2, 11)
1072  call feedkeys("A\<right>\<esc>", 'tnix')
1073  call assert_equal([0, 3, 1, 0], getpos('.'))
1074  call cursor(2, 11)
1075  call feedkeys("A\<s-right>\<esc>", 'tnix')
1076  call assert_equal([0, 3, 1, 0], getpos('.'))
1077  let &ww = _ww
1078  bw!
1079endfunc
1080
1081func Test_edit_MOUSE()
1082  " This is a simple test, since we not really using the mouse here
1083  if !has("mouse")
1084    return
1085  endif
1086  10new
1087  call setline(1, range(1, 100))
1088  call cursor(1, 1)
1089  set mouse=a
1090  call feedkeys("A\<ScrollWheelDown>\<esc>", 'tnix')
1091  call assert_equal([0, 4, 1, 0], getpos('.'))
1092  " This should move by one pageDown, but only moves
1093  " by one line when the test is run...
1094  call feedkeys("A\<S-ScrollWheelDown>\<esc>", 'tnix')
1095  call assert_equal([0, 5, 1, 0], getpos('.'))
1096  set nostartofline
1097  call feedkeys("A\<C-ScrollWheelDown>\<esc>", 'tnix')
1098  call assert_equal([0, 6, 1, 0], getpos('.'))
1099  call feedkeys("A\<LeftMouse>\<esc>", 'tnix')
1100  call assert_equal([0, 6, 1, 0], getpos('.'))
1101  call feedkeys("A\<RightMouse>\<esc>", 'tnix')
1102  call assert_equal([0, 6, 1, 0], getpos('.'))
1103  call cursor(1, 100)
1104  norm! zt
1105  " this should move by a screen up, but when the test
1106  " is run, it moves up to the top of the buffer...
1107  call feedkeys("A\<ScrollWheelUp>\<esc>", 'tnix')
1108  call assert_equal([0, 1, 1, 0], getpos('.'))
1109  call cursor(1, 30)
1110  norm! zt
1111  call feedkeys("A\<S-ScrollWheelUp>\<esc>", 'tnix')
1112  call assert_equal([0, 1, 1, 0], getpos('.'))
1113  call cursor(1, 30)
1114  norm! zt
1115  call feedkeys("A\<C-ScrollWheelUp>\<esc>", 'tnix')
1116  call assert_equal([0, 1, 1, 0], getpos('.'))
1117  %d
1118  call setline(1, repeat(["12345678901234567890"], 100))
1119  call cursor(2, 1)
1120  call feedkeys("A\<ScrollWheelRight>\<esc>", 'tnix')
1121  call assert_equal([0, 2, 20, 0], getpos('.'))
1122  call feedkeys("A\<ScrollWheelLeft>\<esc>", 'tnix')
1123  call assert_equal([0, 2, 20, 0], getpos('.'))
1124  call feedkeys("A\<S-ScrollWheelRight>\<esc>", 'tnix')
1125  call assert_equal([0, 2, 20, 0], getpos('.'))
1126  call feedkeys("A\<S-ScrollWheelLeft>\<esc>", 'tnix')
1127  call assert_equal([0, 2, 20, 0], getpos('.'))
1128  call feedkeys("A\<C-ScrollWheelRight>\<esc>", 'tnix')
1129  call assert_equal([0, 2, 20, 0], getpos('.'))
1130  call feedkeys("A\<C-ScrollWheelLeft>\<esc>", 'tnix')
1131  call assert_equal([0, 2, 20, 0], getpos('.'))
1132  set mouse& startofline
1133  bw!
1134endfunc
1135
1136func Test_edit_PAGEUP_PAGEDOWN()
1137  10new
1138  call setline(1, repeat(['abc def ghi'], 30))
1139  call cursor(1, 1)
1140  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1141  call assert_equal([0, 9, 1, 0], getpos('.'))
1142  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1143  call assert_equal([0, 17, 1, 0], getpos('.'))
1144  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1145  call assert_equal([0, 25, 1, 0], getpos('.'))
1146  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1147  call assert_equal([0, 30, 1, 0], getpos('.'))
1148  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1149  call assert_equal([0, 30, 1, 0], getpos('.'))
1150  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1151  call assert_equal([0, 29, 1, 0], getpos('.'))
1152  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1153  call assert_equal([0, 21, 1, 0], getpos('.'))
1154  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1155  call assert_equal([0, 13, 1, 0], getpos('.'))
1156  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1157  call assert_equal([0, 5, 1, 0], getpos('.'))
1158  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1159  call assert_equal([0, 5, 11, 0], getpos('.'))
1160  " <S-Up> is the same as <PageUp>
1161  " <S-Down> is the same as <PageDown>
1162  call cursor(1, 1)
1163  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1164  call assert_equal([0, 9, 1, 0], getpos('.'))
1165  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1166  call assert_equal([0, 17, 1, 0], getpos('.'))
1167  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1168  call assert_equal([0, 25, 1, 0], getpos('.'))
1169  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1170  call assert_equal([0, 30, 1, 0], getpos('.'))
1171  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1172  call assert_equal([0, 30, 1, 0], getpos('.'))
1173  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1174  call assert_equal([0, 29, 1, 0], getpos('.'))
1175  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1176  call assert_equal([0, 21, 1, 0], getpos('.'))
1177  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1178  call assert_equal([0, 13, 1, 0], getpos('.'))
1179  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1180  call assert_equal([0, 5, 1, 0], getpos('.'))
1181  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1182  call assert_equal([0, 5, 11, 0], getpos('.'))
1183  set nostartofline
1184  call cursor(30, 11)
1185  norm! zt
1186  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1187  call assert_equal([0, 29, 11, 0], getpos('.'))
1188  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1189  call assert_equal([0, 21, 11, 0], getpos('.'))
1190  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1191  call assert_equal([0, 13, 11, 0], getpos('.'))
1192  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1193  call assert_equal([0, 5, 11, 0], getpos('.'))
1194  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1195  call assert_equal([0, 5, 11, 0], getpos('.'))
1196  call cursor(1, 1)
1197  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1198  call assert_equal([0, 9, 11, 0], getpos('.'))
1199  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1200  call assert_equal([0, 17, 11, 0], getpos('.'))
1201  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1202  call assert_equal([0, 25, 11, 0], getpos('.'))
1203  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1204  call assert_equal([0, 30, 11, 0], getpos('.'))
1205  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1206  call assert_equal([0, 30, 11, 0], getpos('.'))
1207  " <S-Up> is the same as <PageUp>
1208  " <S-Down> is the same as <PageDown>
1209  call cursor(30, 11)
1210  norm! zt
1211  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1212  call assert_equal([0, 29, 11, 0], getpos('.'))
1213  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1214  call assert_equal([0, 21, 11, 0], getpos('.'))
1215  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1216  call assert_equal([0, 13, 11, 0], getpos('.'))
1217  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1218  call assert_equal([0, 5, 11, 0], getpos('.'))
1219  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1220  call assert_equal([0, 5, 11, 0], getpos('.'))
1221  call cursor(1, 1)
1222  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1223  call assert_equal([0, 9, 11, 0], getpos('.'))
1224  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1225  call assert_equal([0, 17, 11, 0], getpos('.'))
1226  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1227  call assert_equal([0, 25, 11, 0], getpos('.'))
1228  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1229  call assert_equal([0, 30, 11, 0], getpos('.'))
1230  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1231  call assert_equal([0, 30, 11, 0], getpos('.'))
1232  bw!
1233endfunc
1234
1235func Test_edit_forbidden()
1236  new
1237  " 1) edit in the sandbox is not allowed
1238  call setline(1, 'a')
1239  com! Sandbox :sandbox call feedkeys("i\<del>\<esc>", 'tnix')
1240  call assert_fails(':Sandbox', 'E48:')
1241  com! Sandbox :sandbox exe "norm! i\<del>"
1242  call assert_fails(':Sandbox', 'E48:')
1243  delcom Sandbox
1244  call assert_equal(['a'], getline(1,'$'))
1245  " 2) edit with textlock set
1246  fu! DoIt()
1247    call feedkeys("i\<del>\<esc>", 'tnix')
1248  endfu
1249  au InsertCharPre <buffer> :call DoIt()
1250  try
1251    call feedkeys("ix\<esc>", 'tnix')
1252    call assert_fails(1, 'textlock')
1253  catch /^Vim\%((\a\+)\)\=:E523/ " catch E523: not allowed here
1254  endtry
1255  " TODO: Might be a bug: should x really be inserted here
1256  call assert_equal(['xa'], getline(1, '$'))
1257  delfu DoIt
1258  try
1259    call feedkeys("ix\<esc>", 'tnix')
1260    call assert_fails(1, 'unknown function')
1261  catch /^Vim\%((\a\+)\)\=:E117/ " catch E117: unknown function
1262  endtry
1263  au! InsertCharPre
1264  " 3) edit when completion is shown
1265  fun! Complete(findstart, base)
1266    if a:findstart
1267      return col('.')
1268    else
1269      call feedkeys("i\<del>\<esc>", 'tnix')
1270      return []
1271    endif
1272  endfun
1273  set completefunc=Complete
1274  try
1275    call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
1276    call assert_fails(1, 'change in complete function')
1277  catch /^Vim\%((\a\+)\)\=:E523/ " catch E523
1278  endtry
1279  delfu Complete
1280  set completefunc=
1281  if has("rightleft") && exists("+fkmap")
1282    " 4) 'R' when 'fkmap' and 'revins' is set.
1283    set revins fkmap
1284    try
1285      normal Ri
1286      call assert_fails(1, "R with 'fkmap' and 'ri' set")
1287    catch
1288    finally
1289      set norevins nofkmap
1290    endtry
1291  endif
1292  bw!
1293endfunc
1294
1295func Test_edit_rightleft()
1296  " Cursor in rightleft mode moves differently
1297  if !exists("+rightleft")
1298    return
1299  endif
1300  call NewWindow(10, 20)
1301  call setline(1, ['abc', 'def', 'ghi'])
1302  call cursor(1, 2)
1303  set rightleft
1304  " Screen looks as expected
1305  let lines = ScreenLines([1, 4], winwidth(0))
1306  let expect = [
1307        \"                 cba",
1308        \"                 fed",
1309        \"                 ihg",
1310        \"                   ~"]
1311  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1312  " 2) right moves to the left
1313  call feedkeys("i\<right>\<esc>x", 'txin')
1314  call assert_equal(['bc', 'def', 'ghi'], getline(1,'$'))
1315  call cursor(1, 2)
1316  call feedkeys("i\<s-right>\<esc>", 'txin')
1317  call cursor(1, 2)
1318  call feedkeys("i\<c-right>\<esc>", 'txin')
1319  " Screen looks as expected
1320  let lines = ScreenLines([1, 4], winwidth(0))
1321  let expect = [
1322        \"                  cb",
1323        \"                 fed",
1324        \"                 ihg",
1325        \"                   ~"]
1326  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1327  " 2) left moves to the right
1328  call setline(1, ['abc', 'def', 'ghi'])
1329  call cursor(1, 2)
1330  call feedkeys("i\<left>\<esc>x", 'txin')
1331  call assert_equal(['ac', 'def', 'ghi'], getline(1,'$'))
1332  call cursor(1, 2)
1333  call feedkeys("i\<s-left>\<esc>", 'txin')
1334  call cursor(1, 2)
1335  call feedkeys("i\<c-left>\<esc>", 'txin')
1336  " Screen looks as expected
1337  let lines = ScreenLines([1, 4], winwidth(0))
1338  let expect = [
1339        \"                  ca",
1340        \"                 fed",
1341        \"                 ihg",
1342        \"                   ~"]
1343  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1344  set norightleft
1345  bw!
1346endfunc
1347
1348func Test_edit_complete_very_long_name()
1349  if !has('unix')
1350    " Long directory names only work on Unix.
1351    return
1352  endif
1353
1354  let dirname = getcwd() . "/Xdir"
1355  let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
1356  try
1357    call mkdir(longdirname, 'p')
1358  catch /E739:/
1359    " Long directory name probably not supported.
1360    call delete(dirname, 'rf')
1361    return
1362  endtry
1363
1364  " Try to get the Vim window position before setting 'columns', so that we can
1365  " move the window back to where it was.
1366  let winposx = getwinposx()
1367  let winposy = getwinposy()
1368
1369  if winposx >= 0 && winposy >= 0 && !has('gui_running')
1370    " We did get the window position, but xterm may report the wrong numbers.
1371    " Move the window to the reported position and compute any offset.
1372    exe 'winpos ' . winposx . ' ' . winposy
1373    sleep 100m
1374    let x = getwinposx()
1375    if x >= 0
1376      let winposx += winposx - x
1377    endif
1378    let y = getwinposy()
1379    if y >= 0
1380      let winposy += winposy - y
1381    endif
1382  endif
1383
1384  let save_columns = &columns
1385  " Need at least about 1100 columns to reproduce the problem.
1386  set columns=2000
1387  set noswapfile
1388
1389  let longfilename = longdirname . '/' . repeat('a', 255)
1390  call writefile(['Totum', 'Table'], longfilename)
1391  new
1392  exe "next Xfile " . longfilename
1393  exe "normal iT\<C-N>"
1394
1395  bwipe!
1396  exe 'bwipe! ' . longfilename
1397  call delete(dirname, 'rf')
1398  let &columns = save_columns
1399  if winposx >= 0 && winposy >= 0
1400    exe 'winpos ' . winposx . ' ' . winposy
1401  endif
1402  set swapfile&
1403endfunc
1404
1405func Test_edit_backtick()
1406  next a\`b c
1407  call assert_equal('a`b', expand('%'))
1408  next
1409  call assert_equal('c', expand('%'))
1410  call assert_equal('a\`b c', expand('##'))
1411endfunc
1412
1413func Test_edit_quit()
1414  edit foo.txt
1415  split
1416  new
1417  call setline(1, 'hello')
1418  3wincmd w
1419  redraw!
1420  call assert_fails('1q', 'E37:')
1421  bwipe! foo.txt
1422  only
1423endfunc
1424
1425func Test_edit_alt()
1426  " Keeping the cursor line didn't happen when the first line has indent.
1427  new
1428  call setline(1, ['  one', 'two', 'three'])
1429  w XAltFile
1430  $
1431  call assert_equal(3, line('.'))
1432  e Xother
1433  e #
1434  call assert_equal(3, line('.'))
1435
1436  bwipe XAltFile
1437  call delete('XAltFile')
1438endfunc
1439
1440func Test_leave_insert_autocmd()
1441  new
1442  au InsertLeave * let g:did_au = 1
1443  let g:did_au = 0
1444  call feedkeys("afoo\<Esc>", 'tx')
1445  call assert_equal(1, g:did_au)
1446  call assert_equal('foo', getline(1))
1447
1448  let g:did_au = 0
1449  call feedkeys("Sbar\<C-C>", 'tx')
1450  call assert_equal(0, g:did_au)
1451  call assert_equal('bar', getline(1))
1452
1453  inoremap x xx<Esc>
1454  let g:did_au = 0
1455  call feedkeys("Saax", 'tx')
1456  call assert_equal(1, g:did_au)
1457  call assert_equal('aaxx', getline(1))
1458
1459  inoremap x xx<C-C>
1460  let g:did_au = 0
1461  call feedkeys("Sbbx", 'tx')
1462  call assert_equal(0, g:did_au)
1463  call assert_equal('bbxx', getline(1))
1464
1465  bwipe!
1466  au! InsertLeave
1467  iunmap x
1468endfunc
1469
1470" Test for inserting characters using CTRL-V followed by a number.
1471func Test_edit_special_chars()
1472  new
1473
1474  if has("ebcdic")
1475    let t = "o\<C-V>193\<C-V>xc2\<C-V>o303 \<C-V>90a\<C-V>xfg\<C-V>o578\<Esc>"
1476  else
1477    let t = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>"
1478  endif
1479
1480  exe "normal " . t
1481  call assert_equal("ABC !a\<C-O>g\<C-G>8", getline(2))
1482
1483  close!
1484endfunc
1485
1486func Test_edit_startinsert()
1487  new
1488  set backspace+=start
1489  call setline(1, 'foobar')
1490  call feedkeys("A\<C-U>\<Esc>", 'xt')
1491  call assert_equal('', getline(1))
1492
1493  call setline(1, 'foobar')
1494  call feedkeys(":startinsert!\<CR>\<C-U>\<Esc>", 'xt')
1495  call assert_equal('', getline(1))
1496
1497  set backspace&
1498  bwipe!
1499endfunc
1500
1501func Test_edit_noesckeys()
1502  CheckNotGui
1503  new
1504
1505  " <Left> moves cursor when 'esckeys' is set
1506  exe "set t_kl=\<Esc>OD"
1507  set esckeys
1508  call feedkeys("axyz\<Esc>ODX", "xt")
1509  call assert_equal("xyXz", getline(1))
1510
1511  " <Left> exits Insert mode when 'esckeys' is off
1512  set noesckeys
1513  call setline(1, '')
1514  call feedkeys("axyz\<Esc>ODX", "xt")
1515  call assert_equal(["DX", "xyz"], getline(1, 2))
1516
1517  bwipe!
1518  set esckeys
1519endfunc
1520