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