xref: /vim-8.2.3635/src/testdir/test_edit.vim (revision 2387773d)
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  CheckFeature quickfix
986
987  " Pressing <f1>
988  new
989  call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix')
990  set noinsertmode
991  call assert_equal('help', &buftype)
992  bw
993  bw
994endfunc
995
996func Test_edit_F21()
997  " Pressing <f21>
998  " sends a netbeans command
999  if has("netbeans_intg")
1000    new
1001    " I have no idea what this is supposed to do :)
1002    call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
1003    bw
1004  endif
1005endfunc
1006
1007func Test_edit_HOME_END()
1008  " Test Home/End Keys
1009  new
1010  set foldopen+=hor
1011  call setline(1, ['abc', 'def'])
1012  call cursor(1, 1)
1013  call feedkeys("AX\<Home>Y\<esc>", 'tnix')
1014  call cursor(2, 1)
1015  call feedkeys("iZ\<End>Y\<esc>", 'tnix')
1016  call assert_equal(['YabcX', 'ZdefY'], getline(1, '$'))
1017
1018  set foldopen-=hor
1019  bw!
1020endfunc
1021
1022func Test_edit_INS()
1023  " Test for Pressing <Insert>
1024  new
1025  call setline(1, ['abc', 'def'])
1026  call cursor(1, 1)
1027  call feedkeys("i\<Insert>ZYX>", 'tnix')
1028  call assert_equal(['ZYX>', 'def'], getline(1, '$'))
1029  call setline(1, ['abc', 'def'])
1030  call cursor(1, 1)
1031  call feedkeys("i\<Insert>Z\<Insert>YX>", 'tnix')
1032  call assert_equal(['ZYX>bc', 'def'], getline(1, '$'))
1033  bw!
1034endfunc
1035
1036func Test_edit_LEFT_RIGHT()
1037  " Left, Shift-Left, Right, Shift-Right
1038  new
1039  call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX'])
1040  let _ww=&ww
1041  set ww=
1042  call cursor(2, 1)
1043  call feedkeys("i\<left>\<esc>", 'tnix')
1044  call assert_equal([0, 2, 1, 0], getpos('.'))
1045  " Is this a bug, <s-left> does not respect whichwrap option
1046  call feedkeys("i\<s-left>\<esc>", 'tnix')
1047  call assert_equal([0, 1, 8, 0], getpos('.'))
1048  call feedkeys("i". repeat("\<s-left>", 3). "\<esc>", 'tnix')
1049  call assert_equal([0, 1, 1, 0], getpos('.'))
1050  call feedkeys("i\<right>\<esc>", 'tnix')
1051  call assert_equal([0, 1, 1, 0], getpos('.'))
1052  call feedkeys("i\<right>\<right>\<esc>", 'tnix')
1053  call assert_equal([0, 1, 2, 0], getpos('.'))
1054  call feedkeys("A\<right>\<esc>", 'tnix')
1055  call assert_equal([0, 1, 11, 0], getpos('.'))
1056  call feedkeys("A\<s-right>\<esc>", 'tnix')
1057  call assert_equal([0, 2, 1, 0], getpos('.'))
1058  call feedkeys("i\<s-right>\<esc>", 'tnix')
1059  call assert_equal([0, 2, 4, 0], getpos('.'))
1060  call cursor(3, 11)
1061  call feedkeys("A\<right>\<esc>", 'tnix')
1062  call feedkeys("A\<s-right>\<esc>", 'tnix')
1063  call assert_equal([0, 3, 11, 0], getpos('.'))
1064  call cursor(2, 11)
1065  " <S-Right> does not respect 'whichwrap' option
1066  call feedkeys("A\<s-right>\<esc>", 'tnix')
1067  call assert_equal([0, 3, 1, 0], getpos('.'))
1068  " Check motion when 'whichwrap' contains cursor keys for insert mode
1069  set ww+=[,]
1070  call cursor(2, 1)
1071  call feedkeys("i\<left>\<esc>", 'tnix')
1072  call assert_equal([0, 1, 11, 0], getpos('.'))
1073  call cursor(2, 11)
1074  call feedkeys("A\<right>\<esc>", 'tnix')
1075  call assert_equal([0, 3, 1, 0], getpos('.'))
1076  call cursor(2, 11)
1077  call feedkeys("A\<s-right>\<esc>", 'tnix')
1078  call assert_equal([0, 3, 1, 0], getpos('.'))
1079  let &ww = _ww
1080  bw!
1081endfunc
1082
1083func Test_edit_MOUSE()
1084  " This is a simple test, since we not really using the mouse here
1085  if !has("mouse")
1086    return
1087  endif
1088  10new
1089  call setline(1, range(1, 100))
1090  call cursor(1, 1)
1091  set mouse=a
1092  call feedkeys("A\<ScrollWheelDown>\<esc>", 'tnix')
1093  call assert_equal([0, 4, 1, 0], getpos('.'))
1094  " This should move by one pageDown, but only moves
1095  " by one line when the test is run...
1096  call feedkeys("A\<S-ScrollWheelDown>\<esc>", 'tnix')
1097  call assert_equal([0, 5, 1, 0], getpos('.'))
1098  set nostartofline
1099  call feedkeys("A\<C-ScrollWheelDown>\<esc>", 'tnix')
1100  call assert_equal([0, 6, 1, 0], getpos('.'))
1101  call feedkeys("A\<LeftMouse>\<esc>", 'tnix')
1102  call assert_equal([0, 6, 1, 0], getpos('.'))
1103  call feedkeys("A\<RightMouse>\<esc>", 'tnix')
1104  call assert_equal([0, 6, 1, 0], getpos('.'))
1105  call cursor(1, 100)
1106  norm! zt
1107  " this should move by a screen up, but when the test
1108  " is run, it moves up to the top of the buffer...
1109  call feedkeys("A\<ScrollWheelUp>\<esc>", 'tnix')
1110  call assert_equal([0, 1, 1, 0], getpos('.'))
1111  call cursor(1, 30)
1112  norm! zt
1113  call feedkeys("A\<S-ScrollWheelUp>\<esc>", 'tnix')
1114  call assert_equal([0, 1, 1, 0], getpos('.'))
1115  call cursor(1, 30)
1116  norm! zt
1117  call feedkeys("A\<C-ScrollWheelUp>\<esc>", 'tnix')
1118  call assert_equal([0, 1, 1, 0], getpos('.'))
1119  %d
1120  call setline(1, repeat(["12345678901234567890"], 100))
1121  call cursor(2, 1)
1122  call feedkeys("A\<ScrollWheelRight>\<esc>", 'tnix')
1123  call assert_equal([0, 2, 20, 0], getpos('.'))
1124  call feedkeys("A\<ScrollWheelLeft>\<esc>", 'tnix')
1125  call assert_equal([0, 2, 20, 0], getpos('.'))
1126  call feedkeys("A\<S-ScrollWheelRight>\<esc>", 'tnix')
1127  call assert_equal([0, 2, 20, 0], getpos('.'))
1128  call feedkeys("A\<S-ScrollWheelLeft>\<esc>", 'tnix')
1129  call assert_equal([0, 2, 20, 0], getpos('.'))
1130  call feedkeys("A\<C-ScrollWheelRight>\<esc>", 'tnix')
1131  call assert_equal([0, 2, 20, 0], getpos('.'))
1132  call feedkeys("A\<C-ScrollWheelLeft>\<esc>", 'tnix')
1133  call assert_equal([0, 2, 20, 0], getpos('.'))
1134  set mouse& startofline
1135  bw!
1136endfunc
1137
1138func Test_edit_PAGEUP_PAGEDOWN()
1139  10new
1140  call setline(1, repeat(['abc def ghi'], 30))
1141  call cursor(1, 1)
1142  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1143  call assert_equal([0, 9, 1, 0], getpos('.'))
1144  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1145  call assert_equal([0, 17, 1, 0], getpos('.'))
1146  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1147  call assert_equal([0, 25, 1, 0], getpos('.'))
1148  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1149  call assert_equal([0, 30, 1, 0], getpos('.'))
1150  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1151  call assert_equal([0, 30, 1, 0], getpos('.'))
1152  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1153  call assert_equal([0, 29, 1, 0], getpos('.'))
1154  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1155  call assert_equal([0, 21, 1, 0], getpos('.'))
1156  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1157  call assert_equal([0, 13, 1, 0], getpos('.'))
1158  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1159  call assert_equal([0, 5, 1, 0], getpos('.'))
1160  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1161  call assert_equal([0, 5, 11, 0], getpos('.'))
1162  " <S-Up> is the same as <PageUp>
1163  " <S-Down> is the same as <PageDown>
1164  call cursor(1, 1)
1165  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1166  call assert_equal([0, 9, 1, 0], getpos('.'))
1167  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1168  call assert_equal([0, 17, 1, 0], getpos('.'))
1169  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1170  call assert_equal([0, 25, 1, 0], getpos('.'))
1171  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1172  call assert_equal([0, 30, 1, 0], getpos('.'))
1173  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1174  call assert_equal([0, 30, 1, 0], getpos('.'))
1175  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1176  call assert_equal([0, 29, 1, 0], getpos('.'))
1177  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1178  call assert_equal([0, 21, 1, 0], getpos('.'))
1179  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1180  call assert_equal([0, 13, 1, 0], getpos('.'))
1181  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1182  call assert_equal([0, 5, 1, 0], getpos('.'))
1183  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1184  call assert_equal([0, 5, 11, 0], getpos('.'))
1185  set nostartofline
1186  call cursor(30, 11)
1187  norm! zt
1188  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1189  call assert_equal([0, 29, 11, 0], getpos('.'))
1190  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1191  call assert_equal([0, 21, 11, 0], getpos('.'))
1192  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1193  call assert_equal([0, 13, 11, 0], getpos('.'))
1194  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1195  call assert_equal([0, 5, 11, 0], getpos('.'))
1196  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1197  call assert_equal([0, 5, 11, 0], getpos('.'))
1198  call cursor(1, 1)
1199  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1200  call assert_equal([0, 9, 11, 0], getpos('.'))
1201  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1202  call assert_equal([0, 17, 11, 0], getpos('.'))
1203  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1204  call assert_equal([0, 25, 11, 0], getpos('.'))
1205  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1206  call assert_equal([0, 30, 11, 0], getpos('.'))
1207  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1208  call assert_equal([0, 30, 11, 0], getpos('.'))
1209  " <S-Up> is the same as <PageUp>
1210  " <S-Down> is the same as <PageDown>
1211  call cursor(30, 11)
1212  norm! zt
1213  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1214  call assert_equal([0, 29, 11, 0], getpos('.'))
1215  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1216  call assert_equal([0, 21, 11, 0], getpos('.'))
1217  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1218  call assert_equal([0, 13, 11, 0], getpos('.'))
1219  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1220  call assert_equal([0, 5, 11, 0], getpos('.'))
1221  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1222  call assert_equal([0, 5, 11, 0], getpos('.'))
1223  call cursor(1, 1)
1224  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1225  call assert_equal([0, 9, 11, 0], getpos('.'))
1226  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1227  call assert_equal([0, 17, 11, 0], getpos('.'))
1228  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1229  call assert_equal([0, 25, 11, 0], getpos('.'))
1230  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1231  call assert_equal([0, 30, 11, 0], getpos('.'))
1232  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1233  call assert_equal([0, 30, 11, 0], getpos('.'))
1234  bw!
1235endfunc
1236
1237func Test_edit_forbidden()
1238  new
1239  " 1) edit in the sandbox is not allowed
1240  call setline(1, 'a')
1241  com! Sandbox :sandbox call feedkeys("i\<del>\<esc>", 'tnix')
1242  call assert_fails(':Sandbox', 'E48:')
1243  com! Sandbox :sandbox exe "norm! i\<del>"
1244  call assert_fails(':Sandbox', 'E48:')
1245  delcom Sandbox
1246  call assert_equal(['a'], getline(1,'$'))
1247  " 2) edit with textlock set
1248  fu! DoIt()
1249    call feedkeys("i\<del>\<esc>", 'tnix')
1250  endfu
1251  au InsertCharPre <buffer> :call DoIt()
1252  try
1253    call feedkeys("ix\<esc>", 'tnix')
1254    call assert_fails(1, 'textlock')
1255  catch /^Vim\%((\a\+)\)\=:E523/ " catch E523: not allowed here
1256  endtry
1257  " TODO: Might be a bug: should x really be inserted here
1258  call assert_equal(['xa'], getline(1, '$'))
1259  delfu DoIt
1260  try
1261    call feedkeys("ix\<esc>", 'tnix')
1262    call assert_fails(1, 'unknown function')
1263  catch /^Vim\%((\a\+)\)\=:E117/ " catch E117: unknown function
1264  endtry
1265  au! InsertCharPre
1266  " 3) edit when completion is shown
1267  fun! Complete(findstart, base)
1268    if a:findstart
1269      return col('.')
1270    else
1271      call feedkeys("i\<del>\<esc>", 'tnix')
1272      return []
1273    endif
1274  endfun
1275  set completefunc=Complete
1276  try
1277    call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
1278    call assert_fails(1, 'change in complete function')
1279  catch /^Vim\%((\a\+)\)\=:E523/ " catch E523
1280  endtry
1281  delfu Complete
1282  set completefunc=
1283  if has("rightleft") && exists("+fkmap")
1284    " 4) 'R' when 'fkmap' and 'revins' is set.
1285    set revins fkmap
1286    try
1287      normal Ri
1288      call assert_fails(1, "R with 'fkmap' and 'ri' set")
1289    catch
1290    finally
1291      set norevins nofkmap
1292    endtry
1293  endif
1294  bw!
1295endfunc
1296
1297func Test_edit_rightleft()
1298  " Cursor in rightleft mode moves differently
1299  if !exists("+rightleft")
1300    return
1301  endif
1302  call NewWindow(10, 20)
1303  call setline(1, ['abc', 'def', 'ghi'])
1304  call cursor(1, 2)
1305  set rightleft
1306  " Screen looks as expected
1307  let lines = ScreenLines([1, 4], winwidth(0))
1308  let expect = [
1309        \"                 cba",
1310        \"                 fed",
1311        \"                 ihg",
1312        \"                   ~"]
1313  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1314  " 2) right moves to the left
1315  call feedkeys("i\<right>\<esc>x", 'txin')
1316  call assert_equal(['bc', 'def', 'ghi'], getline(1,'$'))
1317  call cursor(1, 2)
1318  call feedkeys("i\<s-right>\<esc>", 'txin')
1319  call cursor(1, 2)
1320  call feedkeys("i\<c-right>\<esc>", 'txin')
1321  " Screen looks as expected
1322  let lines = ScreenLines([1, 4], winwidth(0))
1323  let expect = [
1324        \"                  cb",
1325        \"                 fed",
1326        \"                 ihg",
1327        \"                   ~"]
1328  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1329  " 2) left moves to the right
1330  call setline(1, ['abc', 'def', 'ghi'])
1331  call cursor(1, 2)
1332  call feedkeys("i\<left>\<esc>x", 'txin')
1333  call assert_equal(['ac', 'def', 'ghi'], getline(1,'$'))
1334  call cursor(1, 2)
1335  call feedkeys("i\<s-left>\<esc>", 'txin')
1336  call cursor(1, 2)
1337  call feedkeys("i\<c-left>\<esc>", 'txin')
1338  " Screen looks as expected
1339  let lines = ScreenLines([1, 4], winwidth(0))
1340  let expect = [
1341        \"                  ca",
1342        \"                 fed",
1343        \"                 ihg",
1344        \"                   ~"]
1345  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1346  set norightleft
1347  bw!
1348endfunc
1349
1350func Test_edit_complete_very_long_name()
1351  if !has('unix')
1352    " Long directory names only work on Unix.
1353    return
1354  endif
1355
1356  let dirname = getcwd() . "/Xdir"
1357  let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
1358  try
1359    call mkdir(longdirname, 'p')
1360  catch /E739:/
1361    " Long directory name probably not supported.
1362    call delete(dirname, 'rf')
1363    return
1364  endtry
1365
1366  " Try to get the Vim window position before setting 'columns', so that we can
1367  " move the window back to where it was.
1368  let winposx = getwinposx()
1369  let winposy = getwinposy()
1370
1371  if winposx >= 0 && winposy >= 0 && !has('gui_running')
1372    " We did get the window position, but xterm may report the wrong numbers.
1373    " Move the window to the reported position and compute any offset.
1374    exe 'winpos ' . winposx . ' ' . winposy
1375    sleep 100m
1376    let x = getwinposx()
1377    if x >= 0
1378      let winposx += winposx - x
1379    endif
1380    let y = getwinposy()
1381    if y >= 0
1382      let winposy += winposy - y
1383    endif
1384  endif
1385
1386  let save_columns = &columns
1387  " Need at least about 1100 columns to reproduce the problem.
1388  set columns=2000
1389  set noswapfile
1390
1391  let longfilename = longdirname . '/' . repeat('a', 255)
1392  call writefile(['Totum', 'Table'], longfilename)
1393  new
1394  exe "next Xfile " . longfilename
1395  exe "normal iT\<C-N>"
1396
1397  bwipe!
1398  exe 'bwipe! ' . longfilename
1399  call delete(dirname, 'rf')
1400  let &columns = save_columns
1401  if winposx >= 0 && winposy >= 0
1402    exe 'winpos ' . winposx . ' ' . winposy
1403  endif
1404  set swapfile&
1405endfunc
1406
1407func Test_edit_backtick()
1408  next a\`b c
1409  call assert_equal('a`b', expand('%'))
1410  next
1411  call assert_equal('c', expand('%'))
1412  call assert_equal('a\`b c', expand('##'))
1413endfunc
1414
1415func Test_edit_quit()
1416  edit foo.txt
1417  split
1418  new
1419  call setline(1, 'hello')
1420  3wincmd w
1421  redraw!
1422  call assert_fails('1q', 'E37:')
1423  bwipe! foo.txt
1424  only
1425endfunc
1426
1427func Test_edit_alt()
1428  " Keeping the cursor line didn't happen when the first line has indent.
1429  new
1430  call setline(1, ['  one', 'two', 'three'])
1431  w XAltFile
1432  $
1433  call assert_equal(3, line('.'))
1434  e Xother
1435  e #
1436  call assert_equal(3, line('.'))
1437
1438  bwipe XAltFile
1439  call delete('XAltFile')
1440endfunc
1441
1442func Test_leave_insert_autocmd()
1443  new
1444  au InsertLeave * let g:did_au = 1
1445  let g:did_au = 0
1446  call feedkeys("afoo\<Esc>", 'tx')
1447  call assert_equal(1, g:did_au)
1448  call assert_equal('foo', getline(1))
1449
1450  let g:did_au = 0
1451  call feedkeys("Sbar\<C-C>", 'tx')
1452  call assert_equal(0, g:did_au)
1453  call assert_equal('bar', getline(1))
1454
1455  inoremap x xx<Esc>
1456  let g:did_au = 0
1457  call feedkeys("Saax", 'tx')
1458  call assert_equal(1, g:did_au)
1459  call assert_equal('aaxx', getline(1))
1460
1461  inoremap x xx<C-C>
1462  let g:did_au = 0
1463  call feedkeys("Sbbx", 'tx')
1464  call assert_equal(0, g:did_au)
1465  call assert_equal('bbxx', getline(1))
1466
1467  bwipe!
1468  au! InsertLeave
1469  iunmap x
1470endfunc
1471
1472" Test for inserting characters using CTRL-V followed by a number.
1473func Test_edit_special_chars()
1474  new
1475
1476  if has("ebcdic")
1477    let t = "o\<C-V>193\<C-V>xc2\<C-V>o303 \<C-V>90a\<C-V>xfg\<C-V>o578\<Esc>"
1478  else
1479    let t = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>"
1480  endif
1481
1482  exe "normal " . t
1483  call assert_equal("ABC !a\<C-O>g\<C-G>8", getline(2))
1484
1485  close!
1486endfunc
1487
1488func Test_edit_startinsert()
1489  new
1490  set backspace+=start
1491  call setline(1, 'foobar')
1492  call feedkeys("A\<C-U>\<Esc>", 'xt')
1493  call assert_equal('', getline(1))
1494
1495  call setline(1, 'foobar')
1496  call feedkeys(":startinsert!\<CR>\<C-U>\<Esc>", 'xt')
1497  call assert_equal('', getline(1))
1498
1499  set backspace&
1500  bwipe!
1501endfunc
1502
1503func Test_edit_noesckeys()
1504  CheckNotGui
1505  new
1506
1507  " <Left> moves cursor when 'esckeys' is set
1508  exe "set t_kl=\<Esc>OD"
1509  set esckeys
1510  call feedkeys("axyz\<Esc>ODX", "xt")
1511  call assert_equal("xyXz", getline(1))
1512
1513  " <Left> exits Insert mode when 'esckeys' is off
1514  set noesckeys
1515  call setline(1, '')
1516  call feedkeys("axyz\<Esc>ODX", "xt")
1517  call assert_equal(["DX", "xyz"], getline(1, 2))
1518
1519  bwipe!
1520  set esckeys
1521endfunc
1522