xref: /vim-8.2.3635/src/testdir/test_edit.vim (revision 851c7a69)
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
893" Test 'thesaurusfunc'
894func MyThesaurus(findstart, base)
895  let mythesaurus = [
896        \ #{word: "happy",
897        \   synonyms: "cheerful,blissful,flying high,looking good,peppy"},
898        \ #{word: "kind",
899        \   synonyms: "amiable,bleeding-heart,heart in right place"}]
900  if a:findstart
901    " locate the start of the word
902    let line = getline('.')
903    let start = col('.') - 1
904    while start > 0 && line[start - 1] =~ '\a'
905      let start -= 1
906    endwhile
907    return start
908  else
909    " find strings matching with "a:base"
910    let res = []
911    for w in mythesaurus
912      if w.word =~ '^' . a:base
913        call add(res, w.word)
914        call extend(res, split(w.synonyms, ","))
915      endif
916    endfor
917    return res
918  endif
919endfunc
920
921func Test_thesaurus_func()
922  new
923  set thesaurus=notused
924  set thesaurusfunc=NotUsed
925  setlocal thesaurusfunc=MyThesaurus
926  call setline(1, "an ki")
927  call cursor(1, 1)
928  call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
929  call assert_equal(['an amiable', ''], getline(1, '$'))
930
931  setlocal thesaurusfunc=NonExistingFunc
932  call assert_fails("normal $a\<C-X>\<C-T>", 'E117:')
933
934  setlocal thesaurusfunc=
935  set thesaurusfunc=NonExistingFunc
936  call assert_fails("normal $a\<C-X>\<C-T>", 'E117:')
937  %bw!
938
939  set thesaurusfunc=
940  set thesaurus=
941endfunc
942
943func Test_edit_CTRL_U()
944  " Test 'completefunc'
945  new
946  " -1, -2 and -3 are special return values
947  let g:special=0
948  fun! CompleteMonths(findstart, base)
949    if a:findstart
950      " locate the start of the word
951      return g:special
952    else
953      " find months matching with "a:base"
954      let res = []
955      for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
956        if m =~ '^\c'.a:base
957          call add(res, {'word': m, 'abbr': m.' Month', 'icase': 0})
958        endif
959      endfor
960      return {'words': res, 'refresh': 'always'}
961    endif
962  endfun
963  set completefunc=CompleteMonths
964  call setline(1, ['', ''])
965  call cursor(1, 1)
966  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
967  call assert_equal(['X', '', ''], getline(1, '$'))
968  %d
969  let g:special=-1
970  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
971  call assert_equal(['XJan', ''], getline(1, '$'))
972  %d
973  let g:special=-2
974  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
975  call assert_equal(['X', ''], getline(1, '$'))
976  %d
977  let g:special=-3
978  call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
979  call assert_equal(['X', ''], getline(1, '$'))
980  %d
981  let g:special=0
982  call feedkeys("AM\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
983  call assert_equal(['Mar', ''], getline(1, '$'))
984  %d
985  call feedkeys("AM\<c-x>\<c-u>\<c-n>\<cr>\<esc>", 'tnix')
986  call assert_equal(['May', ''], getline(1, '$'))
987  %d
988  call feedkeys("AM\<c-x>\<c-u>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
989  call assert_equal(['M', ''], getline(1, '$'))
990  delfu CompleteMonths
991  %d
992  try
993    call feedkeys("A\<c-x>\<c-u>", 'tnix')
994    call assert_fails(1, 'unknown completion function')
995  catch /^Vim\%((\a\+)\)\=:E117/
996    call assert_true(1, 'E117 error caught')
997  endtry
998  set completefunc=
999  bw!
1000endfunc
1001
1002func Test_edit_completefunc_delete()
1003  func CompleteFunc(findstart, base)
1004    if a:findstart == 1
1005      return col('.') - 1
1006    endif
1007    normal dd
1008    return ['a', 'b']
1009  endfunc
1010  new
1011  set completefunc=CompleteFunc
1012  call setline(1, ['', 'abcd', ''])
1013  2d
1014  call assert_fails("normal 2G$a\<C-X>\<C-U>", 'E578:')
1015  bwipe!
1016endfunc
1017
1018
1019func Test_edit_CTRL_Z()
1020  " Ctrl-Z when insertmode is not set inserts it literally
1021  new
1022  call setline(1, 'abc')
1023  call feedkeys("A\<c-z>\<esc>", 'tnix')
1024  call assert_equal(["abc\<c-z>"], getline(1,'$'))
1025  bw!
1026  " TODO: How to Test Ctrl-Z in insert mode, e.g. suspend?
1027endfunc
1028
1029func Test_edit_DROP()
1030  CheckFeature dnd
1031  new
1032  call setline(1, ['abc def ghi'])
1033  call cursor(1, 1)
1034  try
1035    call feedkeys("i\<Drop>\<Esc>", 'tnix')
1036    call assert_fails(1, 'Invalid register name')
1037  catch /^Vim\%((\a\+)\)\=:E353/
1038    call assert_true(1, 'error caught')
1039  endtry
1040  bw!
1041endfunc
1042
1043func Test_edit_CTRL_V()
1044  CheckFeature ebcdic
1045  new
1046  call setline(1, ['abc'])
1047  call cursor(2, 1)
1048  " force some redraws
1049  set showmode showcmd
1050  "call test_override_char_avail(1)
1051  call test_override('ALL', 1)
1052  call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
1053  call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
1054
1055  if has("rightleft") && exists("+rl")
1056    set rl
1057    call setline(1, ['abc'])
1058    call cursor(2, 1)
1059    call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
1060    call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
1061    set norl
1062  endif
1063
1064  call test_override('ALL', 0)
1065  set noshowmode showcmd
1066  bw!
1067endfunc
1068
1069func Test_edit_F1()
1070  CheckFeature quickfix
1071
1072  " Pressing <f1>
1073  new
1074  call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix')
1075  set noinsertmode
1076  call assert_equal('help', &buftype)
1077  bw
1078  bw
1079endfunc
1080
1081func Test_edit_F21()
1082  " Pressing <f21>
1083  " sends a netbeans command
1084  CheckFeature netbeans_intg
1085  new
1086  " I have no idea what this is supposed to do :)
1087  call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
1088  bw
1089endfunc
1090
1091func Test_edit_HOME_END()
1092  " Test Home/End Keys
1093  new
1094  set foldopen+=hor
1095  call setline(1, ['abc', 'def'])
1096  call cursor(1, 1)
1097  call feedkeys("AX\<Home>Y\<esc>", 'tnix')
1098  call cursor(2, 1)
1099  call feedkeys("iZ\<End>Y\<esc>", 'tnix')
1100  call assert_equal(['YabcX', 'ZdefY'], getline(1, '$'))
1101
1102  set foldopen-=hor
1103  bw!
1104endfunc
1105
1106func Test_edit_INS()
1107  " Test for Pressing <Insert>
1108  new
1109  call setline(1, ['abc', 'def'])
1110  call cursor(1, 1)
1111  call feedkeys("i\<Insert>ZYX>", 'tnix')
1112  call assert_equal(['ZYX>', 'def'], getline(1, '$'))
1113  call setline(1, ['abc', 'def'])
1114  call cursor(1, 1)
1115  call feedkeys("i\<Insert>Z\<Insert>YX>", 'tnix')
1116  call assert_equal(['ZYX>bc', 'def'], getline(1, '$'))
1117  bw!
1118endfunc
1119
1120func Test_edit_LEFT_RIGHT()
1121  " Left, Shift-Left, Right, Shift-Right
1122  new
1123  call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX'])
1124  let _ww=&ww
1125  set ww=
1126  call cursor(2, 1)
1127  call feedkeys("i\<left>\<esc>", 'tnix')
1128  call assert_equal([0, 2, 1, 0], getpos('.'))
1129  " Is this a bug, <s-left> does not respect whichwrap option
1130  call feedkeys("i\<s-left>\<esc>", 'tnix')
1131  call assert_equal([0, 1, 8, 0], getpos('.'))
1132  call feedkeys("i". repeat("\<s-left>", 3). "\<esc>", 'tnix')
1133  call assert_equal([0, 1, 1, 0], getpos('.'))
1134  call feedkeys("i\<right>\<esc>", 'tnix')
1135  call assert_equal([0, 1, 1, 0], getpos('.'))
1136  call feedkeys("i\<right>\<right>\<esc>", 'tnix')
1137  call assert_equal([0, 1, 2, 0], getpos('.'))
1138  call feedkeys("A\<right>\<esc>", 'tnix')
1139  call assert_equal([0, 1, 11, 0], getpos('.'))
1140  call feedkeys("A\<s-right>\<esc>", 'tnix')
1141  call assert_equal([0, 2, 1, 0], getpos('.'))
1142  call feedkeys("i\<s-right>\<esc>", 'tnix')
1143  call assert_equal([0, 2, 4, 0], getpos('.'))
1144  call cursor(3, 11)
1145  call feedkeys("A\<right>\<esc>", 'tnix')
1146  call feedkeys("A\<s-right>\<esc>", 'tnix')
1147  call assert_equal([0, 3, 11, 0], getpos('.'))
1148  call cursor(2, 11)
1149  " <S-Right> does not respect 'whichwrap' option
1150  call feedkeys("A\<s-right>\<esc>", 'tnix')
1151  call assert_equal([0, 3, 1, 0], getpos('.'))
1152  " Check motion when 'whichwrap' contains cursor keys for insert mode
1153  set ww+=[,]
1154  call cursor(2, 1)
1155  call feedkeys("i\<left>\<esc>", 'tnix')
1156  call assert_equal([0, 1, 11, 0], getpos('.'))
1157  call cursor(2, 11)
1158  call feedkeys("A\<right>\<esc>", 'tnix')
1159  call assert_equal([0, 3, 1, 0], getpos('.'))
1160  call cursor(2, 11)
1161  call feedkeys("A\<s-right>\<esc>", 'tnix')
1162  call assert_equal([0, 3, 1, 0], getpos('.'))
1163  let &ww = _ww
1164  bw!
1165endfunc
1166
1167func Test_edit_MOUSE()
1168  " This is a simple test, since we not really using the mouse here
1169  CheckFeature mouse
1170  10new
1171  call setline(1, range(1, 100))
1172  call cursor(1, 1)
1173  set mouse=a
1174  call feedkeys("A\<ScrollWheelDown>\<esc>", 'tnix')
1175  call assert_equal([0, 4, 1, 0], getpos('.'))
1176  " This should move by one pageDown, but only moves
1177  " by one line when the test is run...
1178  call feedkeys("A\<S-ScrollWheelDown>\<esc>", 'tnix')
1179  call assert_equal([0, 5, 1, 0], getpos('.'))
1180  set nostartofline
1181  call feedkeys("A\<C-ScrollWheelDown>\<esc>", 'tnix')
1182  call assert_equal([0, 6, 1, 0], getpos('.'))
1183  call feedkeys("A\<LeftMouse>\<esc>", 'tnix')
1184  call assert_equal([0, 6, 1, 0], getpos('.'))
1185  call feedkeys("A\<RightMouse>\<esc>", 'tnix')
1186  call assert_equal([0, 6, 1, 0], getpos('.'))
1187  call cursor(1, 100)
1188  norm! zt
1189  " this should move by a screen up, but when the test
1190  " is run, it moves up to the top of the buffer...
1191  call feedkeys("A\<ScrollWheelUp>\<esc>", 'tnix')
1192  call assert_equal([0, 1, 1, 0], getpos('.'))
1193  call cursor(1, 30)
1194  norm! zt
1195  call feedkeys("A\<S-ScrollWheelUp>\<esc>", 'tnix')
1196  call assert_equal([0, 1, 1, 0], getpos('.'))
1197  call cursor(1, 30)
1198  norm! zt
1199  call feedkeys("A\<C-ScrollWheelUp>\<esc>", 'tnix')
1200  call assert_equal([0, 1, 1, 0], getpos('.'))
1201  %d
1202  call setline(1, repeat(["12345678901234567890"], 100))
1203  call cursor(2, 1)
1204  call feedkeys("A\<ScrollWheelRight>\<esc>", 'tnix')
1205  call assert_equal([0, 2, 20, 0], getpos('.'))
1206  call feedkeys("A\<ScrollWheelLeft>\<esc>", 'tnix')
1207  call assert_equal([0, 2, 20, 0], getpos('.'))
1208  call feedkeys("A\<S-ScrollWheelRight>\<esc>", 'tnix')
1209  call assert_equal([0, 2, 20, 0], getpos('.'))
1210  call feedkeys("A\<S-ScrollWheelLeft>\<esc>", 'tnix')
1211  call assert_equal([0, 2, 20, 0], getpos('.'))
1212  call feedkeys("A\<C-ScrollWheelRight>\<esc>", 'tnix')
1213  call assert_equal([0, 2, 20, 0], getpos('.'))
1214  call feedkeys("A\<C-ScrollWheelLeft>\<esc>", 'tnix')
1215  call assert_equal([0, 2, 20, 0], getpos('.'))
1216  set mouse& startofline
1217  bw!
1218endfunc
1219
1220func Test_edit_PAGEUP_PAGEDOWN()
1221  10new
1222  call setline(1, repeat(['abc def ghi'], 30))
1223  call cursor(1, 1)
1224  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1225  call assert_equal([0, 9, 1, 0], getpos('.'))
1226  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1227  call assert_equal([0, 17, 1, 0], getpos('.'))
1228  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1229  call assert_equal([0, 25, 1, 0], getpos('.'))
1230  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1231  call assert_equal([0, 30, 1, 0], getpos('.'))
1232  call feedkeys("i\<PageDown>\<esc>", 'tnix')
1233  call assert_equal([0, 30, 1, 0], getpos('.'))
1234  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1235  call assert_equal([0, 29, 1, 0], getpos('.'))
1236  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1237  call assert_equal([0, 21, 1, 0], getpos('.'))
1238  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1239  call assert_equal([0, 13, 1, 0], getpos('.'))
1240  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1241  call assert_equal([0, 5, 1, 0], getpos('.'))
1242  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1243  call assert_equal([0, 5, 11, 0], getpos('.'))
1244  " <S-Up> is the same as <PageUp>
1245  " <S-Down> is the same as <PageDown>
1246  call cursor(1, 1)
1247  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1248  call assert_equal([0, 9, 1, 0], getpos('.'))
1249  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1250  call assert_equal([0, 17, 1, 0], getpos('.'))
1251  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1252  call assert_equal([0, 25, 1, 0], getpos('.'))
1253  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1254  call assert_equal([0, 30, 1, 0], getpos('.'))
1255  call feedkeys("i\<S-Down>\<esc>", 'tnix')
1256  call assert_equal([0, 30, 1, 0], getpos('.'))
1257  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1258  call assert_equal([0, 29, 1, 0], getpos('.'))
1259  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1260  call assert_equal([0, 21, 1, 0], getpos('.'))
1261  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1262  call assert_equal([0, 13, 1, 0], getpos('.'))
1263  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1264  call assert_equal([0, 5, 1, 0], getpos('.'))
1265  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1266  call assert_equal([0, 5, 11, 0], getpos('.'))
1267  set nostartofline
1268  call cursor(30, 11)
1269  norm! zt
1270  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1271  call assert_equal([0, 29, 11, 0], getpos('.'))
1272  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1273  call assert_equal([0, 21, 11, 0], getpos('.'))
1274  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1275  call assert_equal([0, 13, 11, 0], getpos('.'))
1276  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1277  call assert_equal([0, 5, 11, 0], getpos('.'))
1278  call feedkeys("A\<PageUp>\<esc>", 'tnix')
1279  call assert_equal([0, 5, 11, 0], getpos('.'))
1280  call cursor(1, 1)
1281  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1282  call assert_equal([0, 9, 11, 0], getpos('.'))
1283  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1284  call assert_equal([0, 17, 11, 0], getpos('.'))
1285  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1286  call assert_equal([0, 25, 11, 0], getpos('.'))
1287  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1288  call assert_equal([0, 30, 11, 0], getpos('.'))
1289  call feedkeys("A\<PageDown>\<esc>", 'tnix')
1290  call assert_equal([0, 30, 11, 0], getpos('.'))
1291  " <S-Up> is the same as <PageUp>
1292  " <S-Down> is the same as <PageDown>
1293  call cursor(30, 11)
1294  norm! zt
1295  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1296  call assert_equal([0, 29, 11, 0], getpos('.'))
1297  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1298  call assert_equal([0, 21, 11, 0], getpos('.'))
1299  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1300  call assert_equal([0, 13, 11, 0], getpos('.'))
1301  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1302  call assert_equal([0, 5, 11, 0], getpos('.'))
1303  call feedkeys("A\<S-Up>\<esc>", 'tnix')
1304  call assert_equal([0, 5, 11, 0], getpos('.'))
1305  call cursor(1, 1)
1306  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1307  call assert_equal([0, 9, 11, 0], getpos('.'))
1308  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1309  call assert_equal([0, 17, 11, 0], getpos('.'))
1310  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1311  call assert_equal([0, 25, 11, 0], getpos('.'))
1312  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1313  call assert_equal([0, 30, 11, 0], getpos('.'))
1314  call feedkeys("A\<S-Down>\<esc>", 'tnix')
1315  call assert_equal([0, 30, 11, 0], getpos('.'))
1316  bw!
1317endfunc
1318
1319func Test_edit_forbidden()
1320  new
1321  " 1) edit in the sandbox is not allowed
1322  call setline(1, 'a')
1323  com! Sandbox :sandbox call feedkeys("i\<del>\<esc>", 'tnix')
1324  call assert_fails(':Sandbox', 'E48:')
1325  com! Sandbox :sandbox exe "norm! i\<del>"
1326  call assert_fails(':Sandbox', 'E48:')
1327  delcom Sandbox
1328  call assert_equal(['a'], getline(1,'$'))
1329  " 2) edit with textlock set
1330  fu! DoIt()
1331    call feedkeys("i\<del>\<esc>", 'tnix')
1332  endfu
1333  au InsertCharPre <buffer> :call DoIt()
1334  try
1335    call feedkeys("ix\<esc>", 'tnix')
1336    call assert_fails(1, 'textlock')
1337  catch /^Vim\%((\a\+)\)\=:E565/ " catch E565: not allowed here
1338  endtry
1339  " TODO: Might be a bug: should x really be inserted here
1340  call assert_equal(['xa'], getline(1, '$'))
1341  delfu DoIt
1342  try
1343    call feedkeys("ix\<esc>", 'tnix')
1344    call assert_fails(1, 'unknown function')
1345  catch /^Vim\%((\a\+)\)\=:E117/ " catch E117: unknown function
1346  endtry
1347  au! InsertCharPre
1348  " 3) edit when completion is shown
1349  fun! Complete(findstart, base)
1350    if a:findstart
1351      return col('.')
1352    else
1353      call feedkeys("i\<del>\<esc>", 'tnix')
1354      return []
1355    endif
1356  endfun
1357  set completefunc=Complete
1358  try
1359    call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
1360    call assert_fails(1, 'change in complete function')
1361  catch /^Vim\%((\a\+)\)\=:E565/ " catch E565
1362  endtry
1363  delfu Complete
1364  set completefunc=
1365  if has("rightleft") && exists("+fkmap")
1366    " 4) 'R' when 'fkmap' and 'revins' is set.
1367    set revins fkmap
1368    try
1369      normal Ri
1370      call assert_fails(1, "R with 'fkmap' and 'ri' set")
1371    catch
1372    finally
1373      set norevins nofkmap
1374    endtry
1375  endif
1376  bw!
1377endfunc
1378
1379func Test_edit_rightleft()
1380  " Cursor in rightleft mode moves differently
1381  CheckFeature rightleft
1382  call NewWindow(10, 20)
1383  call setline(1, ['abc', 'def', 'ghi'])
1384  call cursor(1, 2)
1385  set rightleft
1386  " Screen looks as expected
1387  let lines = ScreenLines([1, 4], winwidth(0))
1388  let expect = [
1389        \"                 cba",
1390        \"                 fed",
1391        \"                 ihg",
1392        \"                   ~"]
1393  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1394  " 2) right moves to the left
1395  call feedkeys("i\<right>\<esc>x", 'txin')
1396  call assert_equal(['bc', 'def', 'ghi'], getline(1,'$'))
1397  call cursor(1, 2)
1398  call feedkeys("i\<s-right>\<esc>", 'txin')
1399  call cursor(1, 2)
1400  call feedkeys("i\<c-right>\<esc>", 'txin')
1401  " Screen looks as expected
1402  let lines = ScreenLines([1, 4], winwidth(0))
1403  let expect = [
1404        \"                  cb",
1405        \"                 fed",
1406        \"                 ihg",
1407        \"                   ~"]
1408  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1409  " 2) left moves to the right
1410  call setline(1, ['abc', 'def', 'ghi'])
1411  call cursor(1, 2)
1412  call feedkeys("i\<left>\<esc>x", 'txin')
1413  call assert_equal(['ac', 'def', 'ghi'], getline(1,'$'))
1414  call cursor(1, 2)
1415  call feedkeys("i\<s-left>\<esc>", 'txin')
1416  call cursor(1, 2)
1417  call feedkeys("i\<c-left>\<esc>", 'txin')
1418  " Screen looks as expected
1419  let lines = ScreenLines([1, 4], winwidth(0))
1420  let expect = [
1421        \"                  ca",
1422        \"                 fed",
1423        \"                 ihg",
1424        \"                   ~"]
1425  call assert_equal(join(expect, "\n"), join(lines, "\n"))
1426  %d _
1427  call test_override('redraw_flag', 1)
1428  call test_override('char_avail', 1)
1429  call feedkeys("a\<C-V>x41", "xt")
1430  redraw!
1431  call assert_equal(repeat(' ', 19) .. 'A', Screenline(1))
1432  call test_override('ALL', 0)
1433  set norightleft
1434  bw!
1435endfunc
1436
1437func Test_edit_complete_very_long_name()
1438  " Long directory names only work on Unix.
1439  CheckUnix
1440
1441  let dirname = getcwd() . "/Xdir"
1442  let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
1443  try
1444    call mkdir(longdirname, 'p')
1445  catch /E739:/
1446    " Long directory name probably not supported.
1447    call delete(dirname, 'rf')
1448    return
1449  endtry
1450
1451  " Try to get the Vim window position before setting 'columns', so that we can
1452  " move the window back to where it was.
1453  let winposx = getwinposx()
1454  let winposy = getwinposy()
1455
1456  if winposx >= 0 && winposy >= 0 && !has('gui_running')
1457    " We did get the window position, but xterm may report the wrong numbers.
1458    " Move the window to the reported position and compute any offset.
1459    exe 'winpos ' . winposx . ' ' . winposy
1460    sleep 100m
1461    let x = getwinposx()
1462    if x >= 0
1463      let winposx += winposx - x
1464    endif
1465    let y = getwinposy()
1466    if y >= 0
1467      let winposy += winposy - y
1468    endif
1469  endif
1470
1471  let save_columns = &columns
1472  " Need at least about 1100 columns to reproduce the problem.
1473  set columns=2000
1474  set noswapfile
1475
1476  let longfilename = longdirname . '/' . repeat('a', 255)
1477  call writefile(['Totum', 'Table'], longfilename)
1478  new
1479  exe "next Xfile " . longfilename
1480  exe "normal iT\<C-N>"
1481
1482  bwipe!
1483  exe 'bwipe! ' . longfilename
1484  call delete(dirname, 'rf')
1485  let &columns = save_columns
1486  if winposx >= 0 && winposy >= 0
1487    exe 'winpos ' . winposx . ' ' . winposy
1488  endif
1489  set swapfile&
1490endfunc
1491
1492func Test_edit_backtick()
1493  next a\`b c
1494  call assert_equal('a`b', expand('%'))
1495  next
1496  call assert_equal('c', expand('%'))
1497  call assert_equal('a\`b c', expand('##'))
1498endfunc
1499
1500func Test_edit_quit()
1501  edit foo.txt
1502  split
1503  new
1504  call setline(1, 'hello')
1505  3wincmd w
1506  redraw!
1507  call assert_fails('1q', 'E37:')
1508  bwipe! foo.txt
1509  only
1510endfunc
1511
1512func Test_edit_alt()
1513  " Keeping the cursor line didn't happen when the first line has indent.
1514  new
1515  call setline(1, ['  one', 'two', 'three'])
1516  w XAltFile
1517  $
1518  call assert_equal(3, line('.'))
1519  e Xother
1520  e #
1521  call assert_equal(3, line('.'))
1522
1523  bwipe XAltFile
1524  call delete('XAltFile')
1525endfunc
1526
1527func Test_edit_InsertLeave()
1528  new
1529  au InsertLeavePre * let g:did_au_pre = 1
1530  au InsertLeave * let g:did_au = 1
1531  let g:did_au_pre = 0
1532  let g:did_au = 0
1533  call feedkeys("afoo\<Esc>", 'tx')
1534  call assert_equal(1, g:did_au_pre)
1535  call assert_equal(1, g:did_au)
1536  call assert_equal('foo', getline(1))
1537
1538  let g:did_au_pre = 0
1539  let g:did_au = 0
1540  call feedkeys("Sbar\<C-C>", 'tx')
1541  call assert_equal(1, g:did_au_pre)
1542  call assert_equal(0, g:did_au)
1543  call assert_equal('bar', getline(1))
1544
1545  inoremap x xx<Esc>
1546  let g:did_au_pre = 0
1547  let g:did_au = 0
1548  call feedkeys("Saax", 'tx')
1549  call assert_equal(1, g:did_au_pre)
1550  call assert_equal(1, g:did_au)
1551  call assert_equal('aaxx', getline(1))
1552
1553  inoremap x xx<C-C>
1554  let g:did_au_pre = 0
1555  let g:did_au = 0
1556  call feedkeys("Sbbx", 'tx')
1557  call assert_equal(1, g:did_au_pre)
1558  call assert_equal(0, g:did_au)
1559  call assert_equal('bbxx', getline(1))
1560
1561  bwipe!
1562  au! InsertLeave InsertLeavePre
1563  iunmap x
1564endfunc
1565
1566func Test_edit_InsertLeave_undo()
1567  new XtestUndo
1568  set undofile
1569  au InsertLeave * wall
1570  exe "normal ofoo\<Esc>"
1571  call assert_equal(2, line('$'))
1572  normal u
1573  call assert_equal(1, line('$'))
1574
1575  bwipe!
1576  au! InsertLeave
1577  call delete('XtestUndo')
1578  call delete(undofile('XtestUndo'))
1579  set undofile&
1580endfunc
1581
1582" Test for inserting characters using CTRL-V followed by a number.
1583func Test_edit_special_chars()
1584  new
1585
1586  if has("ebcdic")
1587    let t = "o\<C-V>193\<C-V>xc2\<C-V>o303 \<C-V>90a\<C-V>xfg\<C-V>o578\<Esc>"
1588  else
1589    let t = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>"
1590  endif
1591
1592  exe "normal " . t
1593  call assert_equal("ABC !a\<C-O>g\<C-G>8", getline(2))
1594
1595  close!
1596endfunc
1597
1598func Test_edit_startinsert()
1599  new
1600  set backspace+=start
1601  call setline(1, 'foobar')
1602  call feedkeys("A\<C-U>\<Esc>", 'xt')
1603  call assert_equal('', getline(1))
1604
1605  call setline(1, 'foobar')
1606  call feedkeys(":startinsert!\<CR>\<C-U>\<Esc>", 'xt')
1607  call assert_equal('', getline(1))
1608
1609  set backspace&
1610  bwipe!
1611endfunc
1612
1613" Test for :startreplace and :startgreplace
1614func Test_edit_startreplace()
1615  new
1616  call setline(1, 'abc')
1617  call feedkeys("l:startreplace\<CR>xyz\e", 'xt')
1618  call assert_equal('axyz', getline(1))
1619  call feedkeys("0:startreplace!\<CR>abc\e", 'xt')
1620  call assert_equal('axyzabc', getline(1))
1621  call setline(1, "a\tb")
1622  call feedkeys("0l:startgreplace\<CR>xyz\e", 'xt')
1623  call assert_equal("axyz\tb", getline(1))
1624  call feedkeys("0i\<C-R>=execute('startreplace')\<CR>12\e", 'xt')
1625  call assert_equal("12axyz\tb", getline(1))
1626  close!
1627endfunc
1628
1629func Test_edit_noesckeys()
1630  CheckNotGui
1631  new
1632
1633  " <Left> moves cursor when 'esckeys' is set
1634  exe "set t_kl=\<Esc>OD"
1635  set esckeys
1636  call feedkeys("axyz\<Esc>ODX", "xt")
1637  call assert_equal("xyXz", getline(1))
1638
1639  " <Left> exits Insert mode when 'esckeys' is off
1640  set noesckeys
1641  call setline(1, '')
1642  call feedkeys("axyz\<Esc>ODX", "xt")
1643  call assert_equal(["DX", "xyz"], getline(1, 2))
1644
1645  bwipe!
1646  set esckeys
1647endfunc
1648
1649" Test for running an invalid ex command in insert mode using CTRL-O
1650func Test_edit_ctrl_o_invalid_cmd()
1651  new
1652  set showmode showcmd
1653  " Avoid a sleep of 3 seconds. Zero might have side effects.
1654  call test_override('ui_delay', 50)
1655  let caught_e492 = 0
1656  try
1657    call feedkeys("i\<C-O>:invalid\<CR>abc\<Esc>", "xt")
1658  catch /E492:/
1659    let caught_e492 = 1
1660  endtry
1661  call assert_equal(1, caught_e492)
1662  call assert_equal('abc', getline(1))
1663  set showmode& showcmd&
1664  call test_override('ui_delay', 0)
1665  close!
1666endfunc
1667
1668" Test for editing a file with a very long name
1669func Test_edit_illegal_filename()
1670  CheckEnglish
1671  new
1672  redir => msg
1673  exe 'edit ' . repeat('f', 5000)
1674  redir END
1675  call assert_match("Illegal file name$", split(msg, "\n")[0])
1676  close!
1677endfunc
1678
1679" Test for editing a directory
1680func Test_edit_is_a_directory()
1681  CheckEnglish
1682  let dirname = getcwd() . "/Xdir"
1683  call mkdir(dirname, 'p')
1684
1685  new
1686  redir => msg
1687  exe 'edit' dirname
1688  redir END
1689  call assert_match("is a directory$", split(msg, "\n")[0])
1690  bwipe!
1691
1692  let dirname .= '/'
1693
1694  new
1695  redir => msg
1696  exe 'edit' dirname
1697  redir END
1698  call assert_match("is a directory$", split(msg, "\n")[0])
1699  bwipe!
1700
1701  call delete(dirname, 'rf')
1702endfunc
1703
1704" Test for editing a file using invalid file encoding
1705func Test_edit_invalid_encoding()
1706  CheckEnglish
1707  call writefile([], 'Xfile')
1708  redir => msg
1709  new ++enc=axbyc Xfile
1710  redir END
1711  call assert_match('\[NOT converted\]', msg)
1712  call delete('Xfile')
1713  close!
1714endfunc
1715
1716" Test for the "charconvert" option
1717func Test_edit_charconvert()
1718  CheckEnglish
1719  call writefile(['one', 'two'], 'Xfile')
1720
1721  " set 'charconvert' to a non-existing function
1722  set charconvert=NonExitingFunc()
1723  new
1724  let caught_e117 = v:false
1725  try
1726    redir => msg
1727    edit ++enc=axbyc Xfile
1728  catch /E117:/
1729    let caught_e117 = v:true
1730  finally
1731    redir END
1732  endtry
1733  call assert_true(caught_e117)
1734  call assert_equal(['one', 'two'], getline(1, '$'))
1735  call assert_match("Conversion with 'charconvert' failed", msg)
1736  close!
1737  set charconvert&
1738
1739  " 'charconvert' function doesn't create a output file
1740  func Cconv1()
1741  endfunc
1742  set charconvert=Cconv1()
1743  new
1744  redir => msg
1745  edit ++enc=axbyc Xfile
1746  redir END
1747  call assert_equal(['one', 'two'], getline(1, '$'))
1748  call assert_match("can't read output of 'charconvert'", msg)
1749  close!
1750  delfunc Cconv1
1751  set charconvert&
1752
1753  " 'charconvert' function to convert to upper case
1754  func Cconv2()
1755    let data = readfile(v:fname_in)
1756    call map(data, 'toupper(v:val)')
1757    call writefile(data, v:fname_out)
1758  endfunc
1759  set charconvert=Cconv2()
1760  new Xfile
1761  write ++enc=ucase Xfile1
1762  call assert_equal(['ONE', 'TWO'], readfile('Xfile1'))
1763  call delete('Xfile1')
1764  close!
1765  delfunc Cconv2
1766  set charconvert&
1767
1768  " 'charconvert' function removes the input file
1769  func Cconv3()
1770    call delete(v:fname_in)
1771  endfunc
1772  set charconvert=Cconv3()
1773  new
1774  call assert_fails('edit ++enc=lcase Xfile', 'E202:')
1775  call assert_equal([''], getline(1, '$'))
1776  close!
1777  delfunc Cconv3
1778  set charconvert&
1779
1780  call delete('Xfile')
1781endfunc
1782
1783" Test for editing a file without read permission
1784func Test_edit_file_no_read_perm()
1785  CheckUnix
1786  CheckNotRoot
1787
1788  call writefile(['one', 'two'], 'Xfile')
1789  call setfperm('Xfile', '-w-------')
1790  new
1791  redir => msg
1792  edit Xfile
1793  redir END
1794  call assert_equal(1, &readonly)
1795  call assert_equal([''], getline(1, '$'))
1796  call assert_match('\[Permission Denied\]', msg)
1797  close!
1798  call delete('Xfile')
1799endfunc
1800
1801" Pressing escape in 'insertmode' should beep
1802func Test_edit_insertmode_esc_beeps()
1803  new
1804  set insertmode
1805  call assert_beeps("call feedkeys(\"one\<Esc>\", 'xt')")
1806  set insertmode&
1807  " unsupported CTRL-G command should beep in insert mode.
1808  call assert_beeps("normal i\<C-G>l")
1809  close!
1810endfunc
1811
1812" Test for 'hkmap' and 'hkmapp'
1813func Test_edit_hkmap()
1814  CheckFeature rightleft
1815  if has('win32') && !has('gui')
1816    throw 'Skipped: fails on the MS-Windows terminal version'
1817  endif
1818  new
1819
1820  set revins hkmap
1821  let str = 'abcdefghijklmnopqrstuvwxyz'
1822  let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1823  let str ..= '`/'',.;'
1824  call feedkeys('i' .. str, 'xt')
1825  let expected = "óõú,.;"
1826  let expected ..= "ZYXWVUTSRQPONMLKJIHGFEDCBA"
1827  let expected ..= "æèñ'äåàãø/ôíîöêìçïéòë÷âáðù"
1828  call assert_equal(expected, getline(1))
1829
1830  %d
1831  set revins hkmap hkmapp
1832  let str = 'abcdefghijklmnopqrstuvwxyz'
1833  let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1834  call feedkeys('i' .. str, 'xt')
1835  let expected = "õYXWVUTSRQóOïíLKJIHGFEDêBA"
1836  let expected ..= "öòXùåèúæø'ôñðîì÷çéäâóǟãëáà"
1837  call assert_equal(expected, getline(1))
1838
1839  set revins& hkmap& hkmapp&
1840  close!
1841endfunc
1842
1843" Test for 'allowrevins' and using CTRL-_ in insert mode
1844func Test_edit_allowrevins()
1845  CheckFeature rightleft
1846  new
1847  set allowrevins
1848  call feedkeys("iABC\<C-_>DEF\<C-_>GHI", 'xt')
1849  call assert_equal('ABCFEDGHI', getline(1))
1850  set allowrevins&
1851  close!
1852endfunc
1853
1854" Test for inserting a register in insert mode using CTRL-R
1855func Test_edit_insert_reg()
1856  new
1857  let g:Line = ''
1858  func SaveFirstLine()
1859    let g:Line = Screenline(1)
1860    return 'r'
1861  endfunc
1862  inoremap <expr> <buffer> <F2> SaveFirstLine()
1863  call test_override('redraw_flag', 1)
1864  call test_override('char_avail', 1)
1865  let @r = 'sample'
1866  call feedkeys("a\<C-R>=SaveFirstLine()\<CR>", "xt")
1867  call assert_equal('"', g:Line)
1868  call test_override('ALL', 0)
1869  close!
1870endfunc
1871
1872" When a character is inserted at the last position of the last line in a
1873" window, the window contents should be scrolled one line up. If the top line
1874" is part of a fold, then the entire fold should be scrolled up.
1875func Test_edit_lastline_scroll()
1876  new
1877  let h = winheight(0)
1878  let lines = ['one', 'two', 'three']
1879  let lines += repeat(['vim'], h - 4)
1880  call setline(1, lines)
1881  call setline(h, repeat('x', winwidth(0) - 1))
1882  call feedkeys("GAx", 'xt')
1883  redraw!
1884  call assert_equal(h - 1, winline())
1885  call assert_equal(2, line('w0'))
1886
1887  " scroll with a fold
1888  1,2fold
1889  normal gg
1890  call setline(h + 1, repeat('x', winwidth(0) - 1))
1891  call feedkeys("GAx", 'xt')
1892  redraw!
1893  call assert_equal(h - 1, winline())
1894  call assert_equal(3, line('w0'))
1895
1896  close!
1897endfunc
1898
1899func Test_edit_browse()
1900  " in the GUI this opens a file picker, we only test the terminal behavior
1901  CheckNotGui
1902
1903  " ":browse xxx" checks for the FileExplorer augroup and assumes editing "."
1904  " works then.
1905  augroup FileExplorer
1906    au!
1907  augroup END
1908
1909  " When the USE_FNAME_CASE is defined this used to cause a crash.
1910  browse enew
1911  bwipe!
1912
1913  browse split
1914  bwipe!
1915endfunc
1916
1917func Test_read_invalid()
1918  set encoding=latin1
1919  " This was not properly checking for going past the end.
1920  call assert_fails('r`=', 'E484')
1921  set encoding=utf-8
1922endfunc
1923
1924" Test for the 'revins' option
1925func Test_edit_revins()
1926  CheckFeature rightleft
1927  new
1928  set revins
1929  exe "normal! ione\ttwo three"
1930  call assert_equal("eerht owt\teno", getline(1))
1931  call setline(1, "one\ttwo three")
1932  normal! gg$bi a
1933  call assert_equal("one\ttwo a three", getline(1))
1934  exe "normal! $bi\<BS>\<BS>"
1935  call assert_equal("one\ttwo a ree", getline(1))
1936  exe "normal! 0wi\<C-W>"
1937  call assert_equal("one\t a ree", getline(1))
1938  exe "normal! 0wi\<C-U>"
1939  call assert_equal("one\t ", getline(1))
1940  " newline in insert mode starts at the end of the line
1941  call setline(1, 'one two three')
1942  exe "normal! wi\nfour"
1943  call assert_equal(['one two three', 'ruof'], getline(1, '$'))
1944  set revins&
1945  bw!
1946endfunc
1947
1948" Test for getting the character of the line below after "p"
1949func Test_edit_put_CTRL_E()
1950  set encoding=latin1
1951  new
1952  let @" = ''
1953  sil! norm orggRx
1954  sil! norm pr
1955  call assert_equal(['r', 'r'], getline(1, 2))
1956  bwipe!
1957  set encoding=utf-8
1958endfunc
1959
1960" Test for ModeChanged pattern
1961func Test_mode_changes()
1962  let g:index = 0
1963  let g:mode_seq = ['n', 'i', 'n', 'v', 'V', 'i', 'ix', 'i', 'ic', 'i', 'n', 'no', 'n', 'V', 'v', 's', 'n']
1964  func! TestMode()
1965    call assert_equal(g:mode_seq[g:index], get(v:event, "old_mode"))
1966    call assert_equal(g:mode_seq[g:index + 1], get(v:event, "new_mode"))
1967    call assert_equal(mode(1), get(v:event, "new_mode"))
1968    let g:index += 1
1969  endfunc
1970
1971  au ModeChanged * :call TestMode()
1972  let g:n_to_any = 0
1973  au ModeChanged n:* let g:n_to_any += 1
1974  call feedkeys("i\<esc>vVca\<CR>\<C-X>\<C-L>\<esc>ggdG", 'tnix')
1975
1976  let g:V_to_v = 0
1977  au ModeChanged V:v let g:V_to_v += 1
1978  call feedkeys("Vv\<C-G>\<esc>", 'tnix')
1979  call assert_equal(len(filter(g:mode_seq[1:], {idx, val -> val == 'n'})), g:n_to_any)
1980  call assert_equal(1, g:V_to_v)
1981  call assert_equal(len(g:mode_seq) - 1, g:index)
1982
1983  let g:n_to_i = 0
1984  au ModeChanged n:i let g:n_to_i += 1
1985  let g:n_to_niI = 0
1986  au ModeChanged i:niI let g:n_to_niI += 1
1987  let g:niI_to_i = 0
1988  au ModeChanged niI:i let g:niI_to_i += 1
1989  let g:nany_to_i = 0
1990  au ModeChanged n*:i let g:nany_to_i += 1
1991  let g:i_to_n = 0
1992  au ModeChanged i:n let g:i_to_n += 1
1993  let g:nori_to_any = 0
1994  au ModeChanged [ni]:* let g:nori_to_any += 1
1995  let g:i_to_any = 0
1996  au ModeChanged i:* let g:i_to_any += 1
1997  let g:index = 0
1998  let g:mode_seq = ['n', 'i', 'niI', 'i', 'n']
1999  call feedkeys("a\<C-O>l\<esc>", 'tnix')
2000  call assert_equal(len(g:mode_seq) - 1, g:index)
2001  call assert_equal(1, g:n_to_i)
2002  call assert_equal(1, g:n_to_niI)
2003  call assert_equal(1, g:niI_to_i)
2004  call assert_equal(2, g:nany_to_i)
2005  call assert_equal(1, g:i_to_n)
2006  call assert_equal(2, g:i_to_any)
2007  call assert_equal(3, g:nori_to_any)
2008
2009  if has('terminal')
2010    let g:mode_seq += ['c', 'n', 't', 'nt', 'c', 'nt', 'n']
2011    call feedkeys(":term\<CR>\<C-W>N:bd!\<CR>", 'tnix')
2012    call assert_equal(len(g:mode_seq) - 1, g:index)
2013    call assert_equal(1, g:n_to_i)
2014    call assert_equal(1, g:n_to_niI)
2015    call assert_equal(1, g:niI_to_i)
2016    call assert_equal(2, g:nany_to_i)
2017    call assert_equal(1, g:i_to_n)
2018    call assert_equal(2, g:i_to_any)
2019    call assert_equal(5, g:nori_to_any)
2020  endif
2021
2022  au! ModeChanged
2023  delfunc TestMode
2024  unlet! g:mode_seq
2025  unlet! g:index
2026  unlet! g:n_to_any
2027  unlet! g:V_to_v
2028  unlet! g:n_to_i
2029  unlet! g:n_to_niI
2030  unlet! g:niI_to_i
2031  unlet! g:nany_to_i
2032  unlet! g:i_to_n
2033  unlet! g:nori_to_any
2034  unlet! g:i_to_any
2035endfunc
2036
2037func Test_recursive_ModeChanged()
2038  au! ModeChanged * norm 0u
2039  sil! norm 
2040  au! ModeChanged
2041endfunc
2042
2043func Test_ModeChanged_starts_visual()
2044  " This was triggering ModeChanged before setting VIsual, causing a crash.
2045  au! ModeChanged * norm 0u
2046  sil! norm 
2047
2048  au! ModeChanged
2049endfunc
2050
2051" Test toggling of input method. See :help i_CTRL-^
2052func Test_edit_CTRL_hat()
2053  CheckFeature xim
2054
2055  " FIXME: test fails with Athena and Motif GUI.
2056  "        test also fails when running in the GUI.
2057  CheckFeature gui_gtk
2058  CheckNotGui
2059
2060  new
2061
2062  call assert_equal(0, &iminsert)
2063  call feedkeys("i\<C-^>", 'xt')
2064  call assert_equal(2, &iminsert)
2065  call feedkeys("i\<C-^>", 'xt')
2066  call assert_equal(0, &iminsert)
2067
2068  bwipe!
2069endfunc
2070
2071
2072" vim: shiftwidth=2 sts=2 expandtab
2073