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