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