xref: /vim-8.2.3635/src/testdir/test_edit.vim (revision f9a343f8)
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
331" Test changing indent in replace mode
332func Test_edit_12()
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 sw&
372
373  " In replace mode, after hitting enter in a line with tab characters,
374  " pressing backspace should restore the tab characters.
375  %d
376  setlocal autoindent backspace=2
377  call setline(1, "\tone\t\ttwo")
378  exe "normal ggRred\<CR>six" .. repeat("\<BS>", 8)
379  call assert_equal(["\tone\t\ttwo"], getline(1, '$'))
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
405  " pressing <C-U> to erase line should keep the indent with 'autoindent'
406  set backspace=2 autoindent
407  %d
408  exe "normal i\tone\<CR>three\<C-U>two"
409  call assert_equal(["\tone", "\ttwo"], getline(1, '$'))
410  set backspace& autoindent&
411
412  bwipe!
413endfunc
414
415func Test_edit_CR()
416  " Test for <CR> in insert mode
417  " basically only in quickfix mode ist tested, the rest
418  " has been taken care of by other tests
419  if !has("quickfix")
420    return
421  endif
422  botright new
423  call writefile(range(1, 10), 'Xqflist.txt')
424  call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}])
425  copen
426  set modifiable
427  call feedkeys("A\<cr>", 'tnix')
428  call assert_equal('Xqflist.txt', bufname(''))
429  call assert_equal(2, line('.'))
430  cclose
431  botright new
432  call setloclist(0, [{'filename': 'Xqflist.txt', 'lnum': 10}])
433  lopen
434  set modifiable
435  call feedkeys("A\<cr>", 'tnix')
436  call assert_equal('Xqflist.txt', bufname(''))
437  call assert_equal(10, line('.'))
438  call feedkeys("A\<Enter>", 'tnix')
439  call feedkeys("A\<kEnter>", 'tnix')
440  call feedkeys("A\n", 'tnix')
441  call feedkeys("A\r", 'tnix')
442  call assert_equal(map(range(1, 10), 'string(v:val)') + ['', '', '', ''], getline(1, '$'))
443  bw!
444  lclose
445  call delete('Xqflist.txt')
446endfunc
447
448func Test_edit_CTRL_()
449  " disabled for Windows builds, why?
450  if !has("rightleft") || has("win32")
451    return
452  endif
453  let _encoding=&encoding
454  set encoding=utf-8
455  " Test for CTRL-_
456  new
457  call setline(1, ['abc'])
458  call cursor(1, 1)
459  call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
460  call assert_equal(["\<C-_>xyzabc"], getline(1, '$'))
461  call assert_false(&revins)
462  set ari
463  call setline(1, ['abc'])
464  call cursor(1, 1)
465  call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
466  call assert_equal(["æèñabc"], getline(1, '$'))
467  call assert_true(&revins)
468  call setline(1, ['abc'])
469  call cursor(1, 1)
470  call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
471  call assert_equal(["xyzabc"], getline(1, '$'))
472  call assert_false(&revins)
473  set noari
474  let &encoding=_encoding
475  bw!
476endfunc
477
478" needs to come first, to have the @. register empty
479func Test_edit_00a_CTRL_A()
480  " Test pressing CTRL-A
481  new
482  call setline(1, repeat([''], 5))
483  call cursor(1, 1)
484  try
485    call feedkeys("A\<NUL>", 'tnix')
486  catch /^Vim\%((\a\+)\)\=:E29/
487    call assert_true(1, 'E29 error caught')
488  endtry
489  call cursor(1, 1)
490  call feedkeys("Afoobar \<esc>", 'tnix')
491  call cursor(2, 1)
492  call feedkeys("A\<c-a>more\<esc>", 'tnix')
493  call cursor(3, 1)
494  call feedkeys("A\<NUL>and more\<esc>", 'tnix')
495  call assert_equal(['foobar ', 'foobar more', 'foobar morend more', '', ''], getline(1, '$'))
496  bw!
497endfunc
498
499func Test_edit_CTRL_EY()
500  " Ctrl-E/ Ctrl-Y in insert mode completion to scroll
501  10new
502  call setline(1, range(1, 100))
503  call cursor(30, 1)
504  norm! z.
505  call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
506  call assert_equal(30, winsaveview()['topline'])
507  call assert_equal([0, 30, 2, 0], getpos('.'))
508  call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
509  call feedkeys("A\<c-x>".repeat("\<c-y>", 10), 'tnix')
510  call assert_equal(21, winsaveview()['topline'])
511  call assert_equal([0, 30, 2, 0], getpos('.'))
512  bw!
513endfunc
514
515func Test_edit_CTRL_G()
516  new
517  call setline(1, ['foobar', 'foobar', 'foobar'])
518  call cursor(2, 4)
519  call feedkeys("ioooooooo\<c-g>k\<c-r>.\<esc>", 'tnix')
520  call assert_equal(['foooooooooobar', 'foooooooooobar', 'foobar'], getline(1, '$'))
521  call assert_equal([0, 1, 11, 0], getpos('.'))
522  call feedkeys("i\<c-g>k\<esc>", 'tnix')
523  call assert_equal([0, 1, 10, 0], getpos('.'))
524  call cursor(2, 4)
525  call feedkeys("i\<c-g>jzzzz\<esc>", 'tnix')
526  call assert_equal(['foooooooooobar', 'foooooooooobar', 'foozzzzbar'], getline(1, '$'))
527  call assert_equal([0, 3, 7, 0], getpos('.'))
528  call feedkeys("i\<c-g>j\<esc>", 'tnix')
529  call assert_equal([0, 3, 6, 0], getpos('.'))
530  bw!
531endfunc
532
533func Test_edit_CTRL_I()
534  " Tab in completion mode
535  let path=expand("%:p:h")
536  new
537  call setline(1, [path. "/", ''])
538  call feedkeys("Arunt\<c-x>\<c-f>\<tab>\<cr>\<esc>", 'tnix')
539  call assert_match('runtest\.vim', getline(1))
540  %d
541  call writefile(['one', 'two', 'three'], 'Xinclude.txt')
542  let include='#include Xinclude.txt'
543  call setline(1, [include, ''])
544  call cursor(2, 1)
545  call feedkeys("A\<c-x>\<tab>\<cr>\<esc>", 'tnix')
546  call assert_equal([include, 'one', ''], getline(1, '$'))
547  call feedkeys("2ggC\<c-x>\<tab>\<down>\<cr>\<esc>", 'tnix')
548  call assert_equal([include, 'two', ''], getline(1, '$'))
549  call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<cr>\<esc>", 'tnix')
550  call assert_equal([include, 'three', ''], getline(1, '$'))
551  call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
552  call assert_equal([include, '', ''], getline(1, '$'))
553  call delete("Xinclude.txt")
554  bw!
555endfunc
556
557func Test_edit_CTRL_K()
558  " Test pressing CTRL-K (basically only dictionary completion and digraphs
559  " the rest is already covered
560  call writefile(['A', 'AA', 'AAA', 'AAAA'], 'Xdictionary.txt')
561  set dictionary=Xdictionary.txt
562  new
563  call setline(1, 'A')
564  call cursor(1, 1)
565  call feedkeys("A\<c-x>\<c-k>\<cr>\<esc>", 'tnix')
566  call assert_equal(['AA', ''], getline(1, '$'))
567  %d
568  call setline(1, 'A')
569  call cursor(1, 1)
570  call feedkeys("A\<c-x>\<c-k>\<down>\<cr>\<esc>", 'tnix')
571  call assert_equal(['AAA'], getline(1, '$'))
572  %d
573  call setline(1, 'A')
574  call cursor(1, 1)
575  call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<cr>\<esc>", 'tnix')
576  call assert_equal(['AAAA'], getline(1, '$'))
577  %d
578  call setline(1, 'A')
579  call cursor(1, 1)
580  call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
581  call assert_equal(['A'], getline(1, '$'))
582  %d
583  call setline(1, 'A')
584  call cursor(1, 1)
585  call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
586  call assert_equal(['AA'], getline(1, '$'))
587
588  " press an unexpected key after dictionary completion
589  %d
590  call setline(1, 'A')
591  call cursor(1, 1)
592  call feedkeys("A\<c-x>\<c-k>\<c-]>\<cr>\<esc>", 'tnix')
593  call assert_equal(['AA', ''], getline(1, '$'))
594  %d
595  call setline(1, 'A')
596  call cursor(1, 1)
597  call feedkeys("A\<c-x>\<c-k>\<c-s>\<cr>\<esc>", 'tnix')
598  call assert_equal(["AA\<c-s>", ''], getline(1, '$'))
599  %d
600  call setline(1, 'A')
601  call cursor(1, 1)
602  call feedkeys("A\<c-x>\<c-k>\<c-f>\<cr>\<esc>", 'tnix')
603  call assert_equal(["AA\<c-f>", ''], getline(1, '$'))
604
605  set dictionary=
606  %d
607  call setline(1, 'A')
608  call cursor(1, 1)
609  let v:testing = 1
610  try
611    call feedkeys("A\<c-x>\<c-k>\<esc>", 'tnix')
612  catch
613    " error sleeps 2 seconds, when v:testing is not set
614    let v:testing = 0
615  endtry
616  call delete('Xdictionary.txt')
617
618  call test_override("char_avail", 1)
619  set showcmd
620  %d
621  call feedkeys("A\<c-k>a:\<esc>", 'tnix')
622  call assert_equal(['ä'], getline(1, '$'))
623  call test_override("char_avail", 0)
624  set noshowcmd
625
626  bw!
627endfunc
628
629func Test_edit_CTRL_L()
630  " Test Ctrl-X Ctrl-L (line completion)
631  new
632  set complete=.
633  call setline(1, ['one', 'two', 'three', '', '', '', ''])
634  call cursor(4, 1)
635  call feedkeys("A\<c-x>\<c-l>\<esc>", 'tnix')
636  call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
637  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<esc>", 'tnix')
638  call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
639  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<esc>", 'tnix')
640  call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
641  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
642  call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
643  call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
644  call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
645  call feedkeys("cct\<c-x>\<c-l>\<c-p>\<esc>", 'tnix')
646  call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
647  call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<esc>", 'tnix')
648  call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
649  call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<c-p>\<esc>", 'tnix')
650  call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
651  set complete=
652  call cursor(5, 1)
653  call feedkeys("A\<c-x>\<c-l>\<c-p>\<c-n>\<esc>", 'tnix')
654  call assert_equal(['one', 'two', 'three', 'three', "\<c-l>\<c-p>\<c-n>", '', ''], getline(1, '$'))
655  set complete&
656  %d
657  if has("conceal") && has("syntax")
658    call setline(1, ['foo', 'bar', 'foobar'])
659    call test_override("char_avail", 1)
660    set conceallevel=2 concealcursor=n
661    syn on
662    syn match ErrorMsg "^bar"
663    call matchadd("Conceal", 'oo', 10, -1, {'conceal': 'X'})
664    func! DoIt()
665      let g:change=1
666    endfunc
667    au! TextChangedI <buffer> :call DoIt()
668
669    call cursor(2, 1)
670    call assert_false(exists("g:change"))
671    call feedkeys("A \<esc>", 'tnix')
672    call assert_equal(['foo', 'bar ', 'foobar'], getline(1, '$'))
673    call assert_equal(1, g:change)
674
675    call test_override("char_avail", 0)
676    call clearmatches()
677    syn off
678    au! TextChangedI
679    delfu DoIt
680    unlet! g:change
681  endif
682  bw!
683endfunc
684
685func Test_edit_CTRL_N()
686  " Check keyword completion
687  new
688  set complete=.
689  call setline(1, ['INFER', 'loWER', '', '', ])
690  call cursor(3, 1)
691  call feedkeys("Ai\<c-n>\<cr>\<esc>", "tnix")
692  call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
693  call assert_equal(['INFER', 'loWER', 'i', 'LO', '', ''], getline(1, '$'))
694  %d
695  call setline(1, ['INFER', 'loWER', '', '', ])
696  call cursor(3, 1)
697  set ignorecase infercase
698  call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix")
699  call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
700  call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'))
701
702  set noignorecase noinfercase complete&
703  bw!
704endfunc
705
706func Test_edit_CTRL_O()
707  " Check for CTRL-O in insert mode
708  new
709  inoreabbr <buffer> h here some more
710  call setline(1, ['abc', 'def'])
711  call cursor(1, 1)
712  " Ctrl-O after an abbreviation
713  exe "norm A h\<c-o>:set nu\<cr> text"
714  call assert_equal(['abc here some more text', 'def'], getline(1, '$'))
715  call assert_true(&nu)
716  set nonu
717  iunabbr <buffer> h
718  " Ctrl-O at end of line with 've'=onemore
719  call cursor(1, 1)
720  call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
721  call assert_equal([0, 1, 23, 0], g:a)
722  call cursor(1, 1)
723  set ve=onemore
724  call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
725  call assert_equal([0, 1, 24, 0], g:a)
726  set ve=
727  unlet! g:a
728  bw!
729endfunc
730
731func Test_edit_CTRL_R()
732  " Insert Register
733  new
734  call test_override("ALL", 1)
735  set showcmd
736  call feedkeys("AFOOBAR eins zwei\<esc>", 'tnix')
737  call feedkeys("O\<c-r>.", 'tnix')
738  call feedkeys("O\<c-r>=10*500\<cr>\<esc>", 'tnix')
739  call feedkeys("O\<c-r>=getreg('=', 1)\<cr>\<esc>", 'tnix')
740  call assert_equal(["getreg('=', 1)", '5000', "FOOBAR eins zwei", "FOOBAR eins zwei"], getline(1, '$'))
741  call test_override("ALL", 0)
742  set noshowcmd
743  bw!
744endfunc
745
746func Test_edit_CTRL_S()
747  " Test pressing CTRL-S (basically only spellfile completion)
748  " the rest is already covered
749  new
750  if !has("spell")
751    call setline(1, 'vim')
752    call feedkeys("A\<c-x>ss\<cr>\<esc>", 'tnix')
753    call assert_equal(['vims', ''], getline(1, '$'))
754    bw!
755    return
756  endif
757  call setline(1, 'vim')
758  " spell option not yet set
759  try
760    call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
761  catch /^Vim\%((\a\+)\)\=:E756/
762    call assert_true(1, 'error caught')
763  endtry
764  call assert_equal(['vim', ''], getline(1, '$'))
765  %d
766  setl spell spelllang=en
767  call setline(1, 'vim')
768  call cursor(1, 1)
769  call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
770  call assert_equal(['Vim', ''], getline(1, '$'))
771  %d
772  call setline(1, 'vim')
773  call cursor(1, 1)
774  call feedkeys("A\<c-x>\<c-s>\<down>\<cr>\<esc>", 'tnix')
775  call assert_equal(['Aim'], getline(1, '$'))
776  %d
777  call setline(1, 'vim')
778  call cursor(1, 1)
779  call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
780  call assert_equal(['vim', ''], getline(1, '$'))
781  %d
782  " empty buffer
783  call cursor(1, 1)
784  call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
785  call assert_equal(['', ''], getline(1, '$'))
786  setl nospell
787  bw!
788endfunc
789
790func Test_edit_CTRL_T()
791  " Check for CTRL-T and CTRL-X CTRL-T in insert mode
792  " 1) increase indent
793  new
794  call setline(1, "abc")
795  call cursor(1, 1)
796  call feedkeys("A\<c-t>xyz", 'tnix')
797  call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
798  " 2) also when paste option is set
799  set paste
800  call setline(1, "abc")
801  call cursor(1, 1)
802  call feedkeys("A\<c-t>xyz", 'tnix')
803  call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
804  set nopaste
805  " CTRL-X CTRL-T (thesaurus complete)
806  call writefile(['angry furious mad enraged'], 'Xthesaurus')
807  set thesaurus=Xthesaurus
808  call setline(1, 'mad')
809  call cursor(1, 1)
810  call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
811  call assert_equal(['mad', ''], getline(1, '$'))
812  %d
813  call setline(1, 'mad')
814  call cursor(1, 1)
815  call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
816  call assert_equal(['angry', ''], getline(1, '$'))
817  %d
818  call setline(1, 'mad')
819  call cursor(1, 1)
820  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
821  call assert_equal(['furious', ''], getline(1, '$'))
822  %d
823  call setline(1, 'mad')
824  call cursor(1, 1)
825  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
826  call assert_equal(['enraged', ''], getline(1, '$'))
827  %d
828  call setline(1, 'mad')
829  call cursor(1, 1)
830  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
831  call assert_equal(['mad', ''], getline(1, '$'))
832  %d
833  call setline(1, 'mad')
834  call cursor(1, 1)
835  call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
836  call assert_equal(['mad', ''], getline(1, '$'))
837  " Using <c-p> <c-n> when 'complete' is empty
838  set complete=
839  %d
840  call setline(1, 'mad')
841  call cursor(1, 1)
842  call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
843  call assert_equal(['angry', ''], getline(1, '$'))
844  %d
845  call setline(1, 'mad')
846  call cursor(1, 1)
847  call feedkeys("A\<c-x>\<c-t>\<c-p>\<cr>\<esc>", 'tnix')
848  call assert_equal(['mad', ''], getline(1, '$'))
849  set complete&
850
851  set thesaurus=
852  %d
853  call setline(1, 'mad')
854  call cursor(1, 1)
855  let v:testing = 1
856  try
857    call feedkeys("A\<c-x>\<c-t>\<esc>", 'tnix')
858  catch
859    " error sleeps 2 seconds, when v:testing is not set
860    let v:testing = 0
861  endtry
862  call assert_equal(['mad'], getline(1, '$'))
863  call delete('Xthesaurus')
864  bw!
865endfunc
866
867func Test_edit_CTRL_U()
868  " Test 'completefunc'
869  new
870  " -1, -2 and -3 are special return values
871  let g:special=0
872  fun! CompleteMonths(findstart, base)
873    if a:findstart
874      " locate the start of the word
875      return g:special
876    else
877      " find months matching with "a:base"
878      let res = []
879      for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
880        if m =~ '^\c'.a:base
881          call add(res, {'word': m, 'abbr': m.' Month', 'icase': 0})
882        endif
883      endfor
884      return {'words': res, 'refresh': 'always'}
885    endif
886  endfun
887  set completefunc=CompleteMonths
888  call setline(1, ['', ''])
889  call cursor(1, 1)
890  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
891  call assert_equal(['X', '', ''], getline(1, '$'))
892  %d
893  let g:special=-1
894  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
895  call assert_equal(['XJan', ''], getline(1, '$'))
896  %d
897  let g:special=-2
898  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
899  call assert_equal(['X', ''], getline(1, '$'))
900  %d
901  let g:special=-3
902  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
903  call assert_equal(['X', ''], getline(1, '$'))
904  %d
905  let g:special=0
906  call feedkeys("AM\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
907  call assert_equal(['Mar', ''], getline(1, '$'))
908  %d
909  call feedkeys("AM\<c-x>\<c-u>\<c-n>\<cr>\<esc>", 'tnix')
910  call assert_equal(['May', ''], getline(1, '$'))
911  %d
912  call feedkeys("AM\<c-x>\<c-u>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
913  call assert_equal(['M', ''], getline(1, '$'))
914  delfu CompleteMonths
915  %d
916  try
917    call feedkeys("A\<c-x>\<c-u>", 'tnix')
918    call assert_fails(1, 'unknown completion function')
919  catch /^Vim\%((\a\+)\)\=:E117/
920    call assert_true(1, 'E117 error caught')
921  endtry
922  set completefunc=
923  bw!
924endfunc
925
926func Test_edit_completefunc_delete()
927  func CompleteFunc(findstart, base)
928    if a:findstart == 1
929      return col('.') - 1
930    endif
931    normal dd
932    return ['a', 'b']
933  endfunc
934  new
935  set completefunc=CompleteFunc
936  call setline(1, ['', 'abcd', ''])
937  2d
938  call assert_fails("normal 2G$a\<C-X>\<C-U>", 'E578:')
939  bwipe!
940endfunc
941
942
943func Test_edit_CTRL_Z()
944  " Ctrl-Z when insertmode is not set inserts it literally
945  new
946  call setline(1, 'abc')
947  call feedkeys("A\<c-z>\<esc>", 'tnix')
948  call assert_equal(["abc\<c-z>"], getline(1,'$'))
949  bw!
950  " TODO: How to Test Ctrl-Z in insert mode, e.g. suspend?
951endfunc
952
953func Test_edit_DROP()
954  if !has("dnd")
955    return
956  endif
957  new
958  call setline(1, ['abc def ghi'])
959  call cursor(1, 1)
960  try
961    call feedkeys("i\<Drop>\<Esc>", 'tnix')
962    call assert_fails(1, 'Invalid register name')
963  catch /^Vim\%((\a\+)\)\=:E353/
964    call assert_true(1, 'error caught')
965  endtry
966  bw!
967endfunc
968
969func Test_edit_CTRL_V()
970  if has("ebcdic")
971    return
972  endif
973  new
974  call setline(1, ['abc'])
975  call cursor(2, 1)
976  " force some redraws
977  set showmode showcmd
978  "call test_override_char_avail(1)
979  call test_override('ALL', 1)
980  call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
981  call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
982
983  if has("rightleft") && exists("+rl")
984    set rl
985    call setline(1, ['abc'])
986    call cursor(2, 1)
987    call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
988    call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
989    set norl
990  endif
991
992  call test_override('ALL', 0)
993  set noshowmode showcmd
994  bw!
995endfunc
996
997func Test_edit_F1()
998  CheckFeature quickfix
999
1000  " Pressing <f1>
1001  new
1002  call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix')
1003  set noinsertmode
1004  call assert_equal('help', &buftype)
1005  bw
1006  bw
1007endfunc
1008
1009func Test_edit_F21()
1010  " Pressing <f21>
1011  " sends a netbeans command
1012  if has("netbeans_intg")
1013    new
1014    " I have no idea what this is supposed to do :)
1015    call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
1016    bw
1017  endif
1018endfunc
1019
1020func Test_edit_HOME_END()
1021  " Test Home/End Keys
1022  new
1023  set foldopen+=hor
1024  call setline(1, ['abc', 'def'])
1025  call cursor(1, 1)
1026  call feedkeys("AX\<Home>Y\<esc>", 'tnix')
1027  call cursor(2, 1)
1028  call feedkeys("iZ\<End>Y\<esc>", 'tnix')
1029  call assert_equal(['YabcX', 'ZdefY'], getline(1, '$'))
1030
1031  set foldopen-=hor
1032  bw!
1033endfunc
1034
1035func Test_edit_INS()
1036  " Test for Pressing <Insert>
1037  new
1038  call setline(1, ['abc', 'def'])
1039  call cursor(1, 1)
1040  call feedkeys("i\<Insert>ZYX>", 'tnix')
1041  call assert_equal(['ZYX>', 'def'], getline(1, '$'))
1042  call setline(1, ['abc', 'def'])
1043  call cursor(1, 1)
1044  call feedkeys("i\<Insert>Z\<Insert>YX>", 'tnix')
1045  call assert_equal(['ZYX>bc', 'def'], getline(1, '$'))
1046  bw!
1047endfunc
1048
1049func Test_edit_LEFT_RIGHT()
1050  " Left, Shift-Left, Right, Shift-Right
1051  new
1052  call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX'])
1053  let _ww=&ww
1054  set ww=
1055  call cursor(2, 1)
1056  call feedkeys("i\<left>\<esc>", 'tnix')
1057  call assert_equal([0, 2, 1, 0], getpos('.'))
1058  " Is this a bug, <s-left> does not respect whichwrap option
1059  call feedkeys("i\<s-left>\<esc>", 'tnix')
1060  call assert_equal([0, 1, 8, 0], getpos('.'))
1061  call feedkeys("i". repeat("\<s-left>", 3). "\<esc>", 'tnix')
1062  call assert_equal([0, 1, 1, 0], getpos('.'))
1063  call feedkeys("i\<right>\<esc>", 'tnix')
1064  call assert_equal([0, 1, 1, 0], getpos('.'))
1065  call feedkeys("i\<right>\<right>\<esc>", 'tnix')
1066  call assert_equal([0, 1, 2, 0], getpos('.'))
1067  call feedkeys("A\<right>\<esc>", 'tnix')
1068  call assert_equal([0, 1, 11, 0], getpos('.'))
1069  call feedkeys("A\<s-right>\<esc>", 'tnix')
1070  call assert_equal([0, 2, 1, 0], getpos('.'))
1071  call feedkeys("i\<s-right>\<esc>", 'tnix')
1072  call assert_equal([0, 2, 4, 0], getpos('.'))
1073  call cursor(3, 11)
1074  call feedkeys("A\<right>\<esc>", 'tnix')
1075  call feedkeys("A\<s-right>\<esc>", 'tnix')
1076  call assert_equal([0, 3, 11, 0], getpos('.'))
1077  call cursor(2, 11)
1078  " <S-Right> does not respect 'whichwrap' option
1079  call feedkeys("A\<s-right>\<esc>", 'tnix')
1080  call assert_equal([0, 3, 1, 0], getpos('.'))
1081  " Check motion when 'whichwrap' contains cursor keys for insert mode
1082  set ww+=[,]
1083  call cursor(2, 1)
1084  call feedkeys("i\<left>\<esc>", 'tnix')
1085  call assert_equal([0, 1, 11, 0], getpos('.'))
1086  call cursor(2, 11)
1087  call feedkeys("A\<right>\<esc>", 'tnix')
1088  call assert_equal([0, 3, 1, 0], getpos('.'))
1089  call cursor(2, 11)
1090  call feedkeys("A\<s-right>\<esc>", 'tnix')
1091  call assert_equal([0, 3, 1, 0], getpos('.'))
1092  let &ww = _ww
1093  bw!
1094endfunc
1095
1096func Test_edit_MOUSE()
1097  " This is a simple test, since we not really using the mouse here
1098  if !has("mouse")
1099    return
1100  endif
1101  10new
1102  call setline(1, range(1, 100))
1103  call cursor(1, 1)
1104  set mouse=a
1105  call feedkeys("A\<ScrollWheelDown>\<esc>", 'tnix')
1106  call assert_equal([0, 4, 1, 0], getpos('.'))
1107  " This should move by one pageDown, but only moves
1108  " by one line when the test is run...
1109  call feedkeys("A\<S-ScrollWheelDown>\<esc>", 'tnix')
1110  call assert_equal([0, 5, 1, 0], getpos('.'))
1111  set nostartofline
1112  call feedkeys("A\<C-ScrollWheelDown>\<esc>", 'tnix')
1113  call assert_equal([0, 6, 1, 0], getpos('.'))
1114  call feedkeys("A\<LeftMouse>\<esc>", 'tnix')
1115  call assert_equal([0, 6, 1, 0], getpos('.'))
1116  call feedkeys("A\<RightMouse>\<esc>", 'tnix')
1117  call assert_equal([0, 6, 1, 0], getpos('.'))
1118  call cursor(1, 100)
1119  norm! zt
1120  " this should move by a screen up, but when the test
1121  " is run, it moves up to the top of the buffer...
1122  call feedkeys("A\<ScrollWheelUp>\<esc>", 'tnix')
1123  call assert_equal([0, 1, 1, 0], getpos('.'))
1124  call cursor(1, 30)
1125  norm! zt
1126  call feedkeys("A\<S-ScrollWheelUp>\<esc>", 'tnix')
1127  call assert_equal([0, 1, 1, 0], getpos('.'))
1128  call cursor(1, 30)
1129  norm! zt
1130  call feedkeys("A\<C-ScrollWheelUp>\<esc>", 'tnix')
1131  call assert_equal([0, 1, 1, 0], getpos('.'))
1132  %d
1133  call setline(1, repeat(["12345678901234567890"], 100))
1134  call cursor(2, 1)
1135  call feedkeys("A\<ScrollWheelRight>\<esc>", 'tnix')
1136  call assert_equal([0, 2, 20, 0], getpos('.'))
1137  call feedkeys("A\<ScrollWheelLeft>\<esc>", 'tnix')
1138  call assert_equal([0, 2, 20, 0], getpos('.'))
1139  call feedkeys("A\<S-ScrollWheelRight>\<esc>", 'tnix')
1140  call assert_equal([0, 2, 20, 0], getpos('.'))
1141  call feedkeys("A\<S-ScrollWheelLeft>\<esc>", 'tnix')
1142  call assert_equal([0, 2, 20, 0], getpos('.'))
1143  call feedkeys("A\<C-ScrollWheelRight>\<esc>", 'tnix')
1144  call assert_equal([0, 2, 20, 0], getpos('.'))
1145  call feedkeys("A\<C-ScrollWheelLeft>\<esc>", 'tnix')
1146  call assert_equal([0, 2, 20, 0], getpos('.'))
1147  set mouse& startofline
1148  bw!
1149endfunc
1150
1151func Test_edit_PAGEUP_PAGEDOWN()
1152  10new
1153  call setline(1, repeat(['abc def ghi'], 30))
1154  call cursor(1, 1)
1155  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1156  call assert_equal([0, 9, 1, 0], getpos('.'))
1157  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1158  call assert_equal([0, 17, 1, 0], getpos('.'))
1159  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1160  call assert_equal([0, 25, 1, 0], getpos('.'))
1161  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1162  call assert_equal([0, 30, 1, 0], getpos('.'))
1163  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1164  call assert_equal([0, 30, 1, 0], getpos('.'))
1165  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1166  call assert_equal([0, 29, 1, 0], getpos('.'))
1167  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1168  call assert_equal([0, 21, 1, 0], getpos('.'))
1169  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1170  call assert_equal([0, 13, 1, 0], getpos('.'))
1171  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1172  call assert_equal([0, 5, 1, 0], getpos('.'))
1173  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1174  call assert_equal([0, 5, 11, 0], getpos('.'))
1175  " <S-Up> is the same as <PageUp>
1176  " <S-Down> is the same as <PageDown>
1177  call cursor(1, 1)
1178  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1179  call assert_equal([0, 9, 1, 0], getpos('.'))
1180  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1181  call assert_equal([0, 17, 1, 0], getpos('.'))
1182  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1183  call assert_equal([0, 25, 1, 0], getpos('.'))
1184  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1185  call assert_equal([0, 30, 1, 0], getpos('.'))
1186  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1187  call assert_equal([0, 30, 1, 0], getpos('.'))
1188  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1189  call assert_equal([0, 29, 1, 0], getpos('.'))
1190  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1191  call assert_equal([0, 21, 1, 0], getpos('.'))
1192  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1193  call assert_equal([0, 13, 1, 0], getpos('.'))
1194  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1195  call assert_equal([0, 5, 1, 0], getpos('.'))
1196  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1197  call assert_equal([0, 5, 11, 0], getpos('.'))
1198  set nostartofline
1199  call cursor(30, 11)
1200  norm! zt
1201  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1202  call assert_equal([0, 29, 11, 0], getpos('.'))
1203  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1204  call assert_equal([0, 21, 11, 0], getpos('.'))
1205  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1206  call assert_equal([0, 13, 11, 0], getpos('.'))
1207  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1208  call assert_equal([0, 5, 11, 0], getpos('.'))
1209  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1210  call assert_equal([0, 5, 11, 0], getpos('.'))
1211  call cursor(1, 1)
1212  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1213  call assert_equal([0, 9, 11, 0], getpos('.'))
1214  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1215  call assert_equal([0, 17, 11, 0], getpos('.'))
1216  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1217  call assert_equal([0, 25, 11, 0], getpos('.'))
1218  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1219  call assert_equal([0, 30, 11, 0], getpos('.'))
1220  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1221  call assert_equal([0, 30, 11, 0], getpos('.'))
1222  " <S-Up> is the same as <PageUp>
1223  " <S-Down> is the same as <PageDown>
1224  call cursor(30, 11)
1225  norm! zt
1226  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1227  call assert_equal([0, 29, 11, 0], getpos('.'))
1228  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1229  call assert_equal([0, 21, 11, 0], getpos('.'))
1230  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1231  call assert_equal([0, 13, 11, 0], getpos('.'))
1232  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1233  call assert_equal([0, 5, 11, 0], getpos('.'))
1234  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1235  call assert_equal([0, 5, 11, 0], getpos('.'))
1236  call cursor(1, 1)
1237  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1238  call assert_equal([0, 9, 11, 0], getpos('.'))
1239  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1240  call assert_equal([0, 17, 11, 0], getpos('.'))
1241  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1242  call assert_equal([0, 25, 11, 0], getpos('.'))
1243  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1244  call assert_equal([0, 30, 11, 0], getpos('.'))
1245  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1246  call assert_equal([0, 30, 11, 0], getpos('.'))
1247  bw!
1248endfunc
1249
1250func Test_edit_forbidden()
1251  new
1252  " 1) edit in the sandbox is not allowed
1253  call setline(1, 'a')
1254  com! Sandbox :sandbox call feedkeys("i\<del>\<esc>", 'tnix')
1255  call assert_fails(':Sandbox', 'E48:')
1256  com! Sandbox :sandbox exe "norm! i\<del>"
1257  call assert_fails(':Sandbox', 'E48:')
1258  delcom Sandbox
1259  call assert_equal(['a'], getline(1,'$'))
1260  " 2) edit with textlock set
1261  fu! DoIt()
1262    call feedkeys("i\<del>\<esc>", 'tnix')
1263  endfu
1264  au InsertCharPre <buffer> :call DoIt()
1265  try
1266    call feedkeys("ix\<esc>", 'tnix')
1267    call assert_fails(1, 'textlock')
1268  catch /^Vim\%((\a\+)\)\=:E565/ " catch E565: not allowed here
1269  endtry
1270  " TODO: Might be a bug: should x really be inserted here
1271  call assert_equal(['xa'], getline(1, '$'))
1272  delfu DoIt
1273  try
1274    call feedkeys("ix\<esc>", 'tnix')
1275    call assert_fails(1, 'unknown function')
1276  catch /^Vim\%((\a\+)\)\=:E117/ " catch E117: unknown function
1277  endtry
1278  au! InsertCharPre
1279  " 3) edit when completion is shown
1280  fun! Complete(findstart, base)
1281    if a:findstart
1282      return col('.')
1283    else
1284      call feedkeys("i\<del>\<esc>", 'tnix')
1285      return []
1286    endif
1287  endfun
1288  set completefunc=Complete
1289  try
1290    call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
1291    call assert_fails(1, 'change in complete function')
1292  catch /^Vim\%((\a\+)\)\=:E565/ " catch E565
1293  endtry
1294  delfu Complete
1295  set completefunc=
1296  if has("rightleft") && exists("+fkmap")
1297    " 4) 'R' when 'fkmap' and 'revins' is set.
1298    set revins fkmap
1299    try
1300      normal Ri
1301      call assert_fails(1, "R with 'fkmap' and 'ri' set")
1302    catch
1303    finally
1304      set norevins nofkmap
1305    endtry
1306  endif
1307  bw!
1308endfunc
1309
1310func Test_edit_rightleft()
1311  " Cursor in rightleft mode moves differently
1312  CheckFeature rightleft
1313  call NewWindow(10, 20)
1314  call setline(1, ['abc', 'def', 'ghi'])
1315  call cursor(1, 2)
1316  set rightleft
1317  " Screen looks as expected
1318  let lines = ScreenLines([1, 4], winwidth(0))
1319  let expect = [
1320        \"                 cba",
1321        \"                 fed",
1322        \"                 ihg",
1323        \"                   ~"]
1324  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1325  " 2) right moves to the left
1326  call feedkeys("i\<right>\<esc>x", 'txin')
1327  call assert_equal(['bc', 'def', 'ghi'], getline(1,'$'))
1328  call cursor(1, 2)
1329  call feedkeys("i\<s-right>\<esc>", 'txin')
1330  call cursor(1, 2)
1331  call feedkeys("i\<c-right>\<esc>", 'txin')
1332  " Screen looks as expected
1333  let lines = ScreenLines([1, 4], winwidth(0))
1334  let expect = [
1335        \"                  cb",
1336        \"                 fed",
1337        \"                 ihg",
1338        \"                   ~"]
1339  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1340  " 2) left moves to the right
1341  call setline(1, ['abc', 'def', 'ghi'])
1342  call cursor(1, 2)
1343  call feedkeys("i\<left>\<esc>x", 'txin')
1344  call assert_equal(['ac', 'def', 'ghi'], getline(1,'$'))
1345  call cursor(1, 2)
1346  call feedkeys("i\<s-left>\<esc>", 'txin')
1347  call cursor(1, 2)
1348  call feedkeys("i\<c-left>\<esc>", 'txin')
1349  " Screen looks as expected
1350  let lines = ScreenLines([1, 4], winwidth(0))
1351  let expect = [
1352        \"                  ca",
1353        \"                 fed",
1354        \"                 ihg",
1355        \"                   ~"]
1356  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1357  %d _
1358  call test_override('redraw_flag', 1)
1359  call test_override('char_avail', 1)
1360  call feedkeys("a\<C-V>x41", "xt")
1361  redraw!
1362  call assert_equal(repeat(' ', 19) .. 'A', Screenline(1))
1363  call test_override('ALL', 0)
1364  set norightleft
1365  bw!
1366endfunc
1367
1368func Test_edit_complete_very_long_name()
1369  if !has('unix')
1370    " Long directory names only work on Unix.
1371    return
1372  endif
1373
1374  let dirname = getcwd() . "/Xdir"
1375  let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
1376  try
1377    call mkdir(longdirname, 'p')
1378  catch /E739:/
1379    " Long directory name probably not supported.
1380    call delete(dirname, 'rf')
1381    return
1382  endtry
1383
1384  " Try to get the Vim window position before setting 'columns', so that we can
1385  " move the window back to where it was.
1386  let winposx = getwinposx()
1387  let winposy = getwinposy()
1388
1389  if winposx >= 0 && winposy >= 0 && !has('gui_running')
1390    " We did get the window position, but xterm may report the wrong numbers.
1391    " Move the window to the reported position and compute any offset.
1392    exe 'winpos ' . winposx . ' ' . winposy
1393    sleep 100m
1394    let x = getwinposx()
1395    if x >= 0
1396      let winposx += winposx - x
1397    endif
1398    let y = getwinposy()
1399    if y >= 0
1400      let winposy += winposy - y
1401    endif
1402  endif
1403
1404  let save_columns = &columns
1405  " Need at least about 1100 columns to reproduce the problem.
1406  set columns=2000
1407  set noswapfile
1408
1409  let longfilename = longdirname . '/' . repeat('a', 255)
1410  call writefile(['Totum', 'Table'], longfilename)
1411  new
1412  exe "next Xfile " . longfilename
1413  exe "normal iT\<C-N>"
1414
1415  bwipe!
1416  exe 'bwipe! ' . longfilename
1417  call delete(dirname, 'rf')
1418  let &columns = save_columns
1419  if winposx >= 0 && winposy >= 0
1420    exe 'winpos ' . winposx . ' ' . winposy
1421  endif
1422  set swapfile&
1423endfunc
1424
1425func Test_edit_backtick()
1426  next a\`b c
1427  call assert_equal('a`b', expand('%'))
1428  next
1429  call assert_equal('c', expand('%'))
1430  call assert_equal('a\`b c', expand('##'))
1431endfunc
1432
1433func Test_edit_quit()
1434  edit foo.txt
1435  split
1436  new
1437  call setline(1, 'hello')
1438  3wincmd w
1439  redraw!
1440  call assert_fails('1q', 'E37:')
1441  bwipe! foo.txt
1442  only
1443endfunc
1444
1445func Test_edit_alt()
1446  " Keeping the cursor line didn't happen when the first line has indent.
1447  new
1448  call setline(1, ['  one', 'two', 'three'])
1449  w XAltFile
1450  $
1451  call assert_equal(3, line('.'))
1452  e Xother
1453  e #
1454  call assert_equal(3, line('.'))
1455
1456  bwipe XAltFile
1457  call delete('XAltFile')
1458endfunc
1459
1460func Test_edit_InsertLeave()
1461  new
1462  au InsertLeave * let g:did_au = 1
1463  let g:did_au = 0
1464  call feedkeys("afoo\<Esc>", 'tx')
1465  call assert_equal(1, g:did_au)
1466  call assert_equal('foo', getline(1))
1467
1468  let g:did_au = 0
1469  call feedkeys("Sbar\<C-C>", 'tx')
1470  call assert_equal(0, g:did_au)
1471  call assert_equal('bar', getline(1))
1472
1473  inoremap x xx<Esc>
1474  let g:did_au = 0
1475  call feedkeys("Saax", 'tx')
1476  call assert_equal(1, g:did_au)
1477  call assert_equal('aaxx', getline(1))
1478
1479  inoremap x xx<C-C>
1480  let g:did_au = 0
1481  call feedkeys("Sbbx", 'tx')
1482  call assert_equal(0, g:did_au)
1483  call assert_equal('bbxx', getline(1))
1484
1485  bwipe!
1486  au! InsertLeave
1487  iunmap x
1488endfunc
1489
1490func Test_edit_InsertLeave_undo()
1491  new XtestUndo
1492  set undofile
1493  au InsertLeave * wall
1494  exe "normal ofoo\<Esc>"
1495  call assert_equal(2, line('$'))
1496  normal u
1497  call assert_equal(1, line('$'))
1498
1499  bwipe!
1500  au! InsertLeave
1501  call delete('XtestUndo')
1502  call delete(undofile('XtestUndo'))
1503  set undofile&
1504endfunc
1505
1506" Test for inserting characters using CTRL-V followed by a number.
1507func Test_edit_special_chars()
1508  new
1509
1510  if has("ebcdic")
1511    let t = "o\<C-V>193\<C-V>xc2\<C-V>o303 \<C-V>90a\<C-V>xfg\<C-V>o578\<Esc>"
1512  else
1513    let t = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>"
1514  endif
1515
1516  exe "normal " . t
1517  call assert_equal("ABC !a\<C-O>g\<C-G>8", getline(2))
1518
1519  close!
1520endfunc
1521
1522func Test_edit_startinsert()
1523  new
1524  set backspace+=start
1525  call setline(1, 'foobar')
1526  call feedkeys("A\<C-U>\<Esc>", 'xt')
1527  call assert_equal('', getline(1))
1528
1529  call setline(1, 'foobar')
1530  call feedkeys(":startinsert!\<CR>\<C-U>\<Esc>", 'xt')
1531  call assert_equal('', getline(1))
1532
1533  set backspace&
1534  bwipe!
1535endfunc
1536
1537" Test for :startreplace and :startgreplace
1538func Test_edit_startreplace()
1539  new
1540  call setline(1, 'abc')
1541  call feedkeys("l:startreplace\<CR>xyz\e", 'xt')
1542  call assert_equal('axyz', getline(1))
1543  call feedkeys("0:startreplace!\<CR>abc\e", 'xt')
1544  call assert_equal('axyzabc', getline(1))
1545  call setline(1, "a\tb")
1546  call feedkeys("0l:startgreplace\<CR>xyz\e", 'xt')
1547  call assert_equal("axyz\tb", getline(1))
1548  call feedkeys("0i\<C-R>=execute('startreplace')\<CR>12\e", 'xt')
1549  call assert_equal("12axyz\tb", getline(1))
1550  close!
1551endfunc
1552
1553func Test_edit_noesckeys()
1554  CheckNotGui
1555  new
1556
1557  " <Left> moves cursor when 'esckeys' is set
1558  exe "set t_kl=\<Esc>OD"
1559  set esckeys
1560  call feedkeys("axyz\<Esc>ODX", "xt")
1561  call assert_equal("xyXz", getline(1))
1562
1563  " <Left> exits Insert mode when 'esckeys' is off
1564  set noesckeys
1565  call setline(1, '')
1566  call feedkeys("axyz\<Esc>ODX", "xt")
1567  call assert_equal(["DX", "xyz"], getline(1, 2))
1568
1569  bwipe!
1570  set esckeys
1571endfunc
1572
1573" Test for running an invalid ex command in insert mode using CTRL-O
1574func Test_edit_ctrl_o_invalid_cmd()
1575  new
1576  set showmode showcmd
1577  " Avoid a sleep of 3 seconds. Zero might have side effects.
1578  call test_override('ui_delay', 50)
1579  let caught_e492 = 0
1580  try
1581    call feedkeys("i\<C-O>:invalid\<CR>abc\<Esc>", "xt")
1582  catch /E492:/
1583    let caught_e492 = 1
1584  endtry
1585  call assert_equal(1, caught_e492)
1586  call assert_equal('abc', getline(1))
1587  set showmode& showcmd&
1588  call test_override('ui_delay', 0)
1589  close!
1590endfunc
1591
1592" Test for editing a file with a very long name
1593func Test_edit_illegal_filename()
1594  CheckEnglish
1595  new
1596  redir => msg
1597  exe 'edit ' . repeat('f', 5000)
1598  redir END
1599  call assert_match("Illegal file name$", split(msg, "\n")[0])
1600  close!
1601endfunc
1602
1603" Test for editing a file using invalid file encoding
1604func Test_edit_invalid_encoding()
1605  CheckEnglish
1606  call writefile([], 'Xfile')
1607  redir => msg
1608  new ++enc=axbyc Xfile
1609  redir END
1610  call assert_match('\[NOT converted\]', msg)
1611  call delete('Xfile')
1612  close!
1613endfunc
1614
1615" Test for the "charconvert" option
1616func Test_edit_charconvert()
1617  CheckEnglish
1618  call writefile(['one', 'two'], 'Xfile')
1619
1620  " set 'charconvert' to a non-existing function
1621  set charconvert=NonExitingFunc()
1622  new
1623  let caught_e117 = v:false
1624  try
1625    redir => msg
1626    edit ++enc=axbyc Xfile
1627  catch /E117:/
1628    let caught_e117 = v:true
1629  finally
1630    redir END
1631  endtry
1632  call assert_true(caught_e117)
1633  call assert_equal(['one', 'two'], getline(1, '$'))
1634  call assert_match("Conversion with 'charconvert' failed", msg)
1635  close!
1636  set charconvert&
1637
1638  " 'charconvert' function doesn't create a output file
1639  func Cconv1()
1640  endfunc
1641  set charconvert=Cconv1()
1642  new
1643  redir => msg
1644  edit ++enc=axbyc Xfile
1645  redir END
1646  call assert_equal(['one', 'two'], getline(1, '$'))
1647  call assert_match("can't read output of 'charconvert'", msg)
1648  close!
1649  delfunc Cconv1
1650  set charconvert&
1651
1652  " 'charconvert' function to convert to upper case
1653  func Cconv2()
1654    let data = readfile(v:fname_in)
1655    call map(data, 'toupper(v:val)')
1656    call writefile(data, v:fname_out)
1657  endfunc
1658  set charconvert=Cconv2()
1659  new Xfile
1660  write ++enc=ucase Xfile1
1661  call assert_equal(['ONE', 'TWO'], readfile('Xfile1'))
1662  call delete('Xfile1')
1663  close!
1664  delfunc Cconv2
1665  set charconvert&
1666
1667  " 'charconvert' function removes the input file
1668  func Cconv3()
1669    call delete(v:fname_in)
1670  endfunc
1671  set charconvert=Cconv3()
1672  new
1673  call assert_fails('edit ++enc=lcase Xfile', 'E202:')
1674  call assert_equal([''], getline(1, '$'))
1675  close!
1676  delfunc Cconv3
1677  set charconvert&
1678
1679  call delete('Xfile')
1680endfunc
1681
1682" Test for editing a file without read permission
1683func Test_edit_file_no_read_perm()
1684  CheckUnix
1685  CheckNotBSD
1686  call writefile(['one', 'two'], 'Xfile')
1687  call setfperm('Xfile', '-w-------')
1688  new
1689  redir => msg
1690  edit Xfile
1691  redir END
1692  call assert_equal(1, &readonly)
1693  call assert_equal([''], getline(1, '$'))
1694  call assert_match('\[Permission Denied\]', msg)
1695  close!
1696  call delete('Xfile')
1697endfunc
1698
1699" Pressing escape in 'insertmode' should beep
1700func Test_edit_insertmode_esc_beeps()
1701  new
1702  set insertmode
1703  call assert_beeps("call feedkeys(\"one\<Esc>\", 'xt')")
1704  set insertmode&
1705  " unsupported CTRL-G command should beep in insert mode.
1706  call assert_beeps("normal i\<C-G>l")
1707  close!
1708endfunc
1709
1710" Test for 'hkmap' and 'hkmapp'
1711func Test_edit_hkmap()
1712  CheckFeature rightleft
1713  if has('win32') && !has('gui')
1714    " Test fails on the MS-Windows terminal version
1715    return
1716  endif
1717  new
1718
1719  set revins hkmap
1720  let str = 'abcdefghijklmnopqrstuvwxyz'
1721  let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1722  let str ..= '`/'',.;'
1723  call feedkeys('i' .. str, 'xt')
1724  let expected = "óõú,.;"
1725  let expected ..= "ZYXWVUTSRQPONMLKJIHGFEDCBA"
1726  let expected ..= "æèñ'äåàãø/ôíîöêìçïéòë÷âáðù"
1727  call assert_equal(expected, getline(1))
1728
1729  %d
1730  set revins hkmap hkmapp
1731  let str = 'abcdefghijklmnopqrstuvwxyz'
1732  let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1733  call feedkeys('i' .. str, 'xt')
1734  let expected = "õYXWVUTSRQóOïíLKJIHGFEDêBA"
1735  let expected ..= "öòXùåèúæø'ôñðîì÷çéäâóǟãëáà"
1736  call assert_equal(expected, getline(1))
1737
1738  set revins& hkmap& hkmapp&
1739  close!
1740endfunc
1741
1742" Test for 'allowrevins' and using CTRL-_ in insert mode
1743func Test_edit_allowrevins()
1744  CheckFeature rightleft
1745  new
1746  set allowrevins
1747  call feedkeys("iABC\<C-_>DEF\<C-_>GHI", 'xt')
1748  call assert_equal('ABCFEDGHI', getline(1))
1749  set allowrevins&
1750  close!
1751endfunc
1752
1753" Test for inserting a register in insert mode using CTRL-R
1754func Test_edit_insert_reg()
1755  new
1756  let g:Line = ''
1757  func SaveFirstLine()
1758    let g:Line = Screenline(1)
1759    return 'r'
1760  endfunc
1761  inoremap <expr> <buffer> <F2> SaveFirstLine()
1762  call test_override('redraw_flag', 1)
1763  call test_override('char_avail', 1)
1764  let @r = 'sample'
1765  call feedkeys("a\<C-R>=SaveFirstLine()\<CR>", "xt")
1766  call assert_equal('"', g:Line)
1767  call test_override('ALL', 0)
1768  close!
1769endfunc
1770
1771" When a character is inserted at the last position of the last line in a
1772" window, the window contents should be scrolled one line up. If the top line
1773" is part of a fold, then the entire fold should be scrolled up.
1774func Test_edit_lastline_scroll()
1775  new
1776  let h = winheight(0)
1777  let lines = ['one', 'two', 'three']
1778  let lines += repeat(['vim'], h - 4)
1779  call setline(1, lines)
1780  call setline(h, repeat('x', winwidth(0) - 1))
1781  call feedkeys("GAx", 'xt')
1782  redraw!
1783  call assert_equal(h - 1, winline())
1784  call assert_equal(2, line('w0'))
1785
1786  " scroll with a fold
1787  1,2fold
1788  normal gg
1789  call setline(h + 1, repeat('x', winwidth(0) - 1))
1790  call feedkeys("GAx", 'xt')
1791  redraw!
1792  call assert_equal(h - 1, winline())
1793  call assert_equal(3, line('w0'))
1794
1795  close!
1796endfunc
1797
1798" vim: shiftwidth=2 sts=2 expandtab
1799