blob: d662f4a0f1478ea0b83b6fa0361a249b77444f5a [file] [log] [blame]
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001" Test for edit functions
Bram Moolenaar215ba3b2019-11-06 15:07:07 +01002
Bram Moolenaareb992cb2017-03-09 18:20:16 +01003if exists("+t_kD")
4 let &t_kD="[3;*~"
5endif
Bram Moolenaareb992cb2017-03-09 18:20:16 +01006
Bram Moolenaar215ba3b2019-11-06 15:07:07 +01007source check.vim
Bram Moolenaarc174c2e2023-03-25 20:06:49 +00008source screendump.vim
Bram Moolenaar215ba3b2019-11-06 15:07:07 +01009
Bram Moolenaareb992cb2017-03-09 18:20:16 +010010" Needed for testing basic rightleft: Test_edit_rightleft
11source view_util.vim
12
13" Needs to come first until the bug in getchar() is
14" fixed: https://groups.google.com/d/msg/vim_dev/fXL9yme4H4c/bOR-U6_bAQAJ
Bram Moolenaar1e115362019-01-09 23:01:02 +010015func Test_edit_00b()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010016 new
17 call setline(1, ['abc '])
18 inoreabbr <buffer> h here some more
19 call cursor(1, 4)
20 " <c-l> expands the abbreviation and ends insertmode
21 call feedkeys(":set im\<cr> h\<c-l>:set noim\<cr>", 'tix')
22 call assert_equal(['abc here some more '], getline(1,'$'))
23 iunabbr <buffer> h
24 bw!
25endfunc
26
Bram Moolenaar1e115362019-01-09 23:01:02 +010027func Test_edit_01()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010028 " set for Travis CI?
29 " set nocp noesckeys
30 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +010031 " 1) empty buffer
32 call assert_equal([''], getline(1,'$'))
33 " 2) delete in an empty line
34 call feedkeys("i\<del>\<esc>", 'tnix')
35 call assert_equal([''], getline(1,'$'))
36 %d
37 " 3) delete one character
38 call setline(1, 'a')
39 call feedkeys("i\<del>\<esc>", 'tnix')
40 call assert_equal([''], getline(1,'$'))
41 %d
42 " 4) delete a multibyte character
Bram Moolenaar30276f22019-01-24 17:59:39 +010043 call setline(1, "\u0401")
44 call feedkeys("i\<del>\<esc>", 'tnix')
45 call assert_equal([''], getline(1,'$'))
46 %d
Bram Moolenaareb992cb2017-03-09 18:20:16 +010047 " 5.1) delete linebreak with 'bs' option containing eol
48 let _bs=&bs
49 set bs=eol
50 call setline(1, ["abc def", "ghi jkl"])
51 call cursor(1, 1)
52 call feedkeys("A\<del>\<esc>", 'tnix')
53 call assert_equal(['abc defghi jkl'], getline(1, 2))
54 %d
55 " 5.2) delete linebreak with backspace option w/out eol
56 set bs=
57 call setline(1, ["abc def", "ghi jkl"])
58 call cursor(1, 1)
59 call feedkeys("A\<del>\<esc>", 'tnix')
60 call assert_equal(["abc def", "ghi jkl"], getline(1, 2))
Bram Moolenaareb992cb2017-03-09 18:20:16 +010061 let &bs=_bs
62 bw!
63endfunc
64
Bram Moolenaar1e115362019-01-09 23:01:02 +010065func Test_edit_02()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010066 " Change cursor position in InsertCharPre command
67 new
68 call setline(1, 'abc')
69 call cursor(1, 1)
70 fu! DoIt(...)
71 call cursor(1, 4)
72 if len(a:000)
73 let v:char=a:1
74 endif
75 endfu
76 au InsertCharPre <buffer> :call DoIt('y')
77 call feedkeys("ix\<esc>", 'tnix')
78 call assert_equal(['abcy'], getline(1, '$'))
79 " Setting <Enter> in InsertCharPre
80 au! InsertCharPre <buffer> :call DoIt("\n")
81 call setline(1, 'abc')
82 call cursor(1, 1)
83 call feedkeys("ix\<esc>", 'tnix')
84 call assert_equal(['abc', ''], getline(1, '$'))
85 %d
86 au! InsertCharPre
87 " Change cursor position in InsertEnter command
88 " 1) when setting v:char, keeps changed cursor position
89 au! InsertEnter <buffer> :call DoIt('y')
90 call setline(1, 'abc')
91 call cursor(1, 1)
92 call feedkeys("ix\<esc>", 'tnix')
93 call assert_equal(['abxc'], getline(1, '$'))
94 " 2) when not setting v:char, restores changed cursor position
95 au! InsertEnter <buffer> :call DoIt()
96 call setline(1, 'abc')
97 call cursor(1, 1)
98 call feedkeys("ix\<esc>", 'tnix')
99 call assert_equal(['xabc'], getline(1, '$'))
100 au! InsertEnter
101 delfu DoIt
102 bw!
103endfunc
104
Bram Moolenaar1e115362019-01-09 23:01:02 +0100105func Test_edit_03()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100106 " Change cursor after <c-o> command to end of line
107 new
108 call setline(1, 'abc')
109 call cursor(1, 1)
110 call feedkeys("i\<c-o>$y\<esc>", 'tnix')
111 call assert_equal(['abcy'], getline(1, '$'))
112 %d
113 call setline(1, 'abc')
114 call cursor(1, 1)
115 call feedkeys("i\<c-o>80|y\<esc>", 'tnix')
116 call assert_equal(['abcy'], getline(1, '$'))
117 %d
118 call setline(1, 'abc')
119 call feedkeys("Ad\<c-o>:s/$/efg/\<cr>hij", 'tnix')
120 call assert_equal(['hijabcdefg'], getline(1, '$'))
121 bw!
122endfunc
123
Bram Moolenaar1e115362019-01-09 23:01:02 +0100124func Test_edit_04()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100125 " test for :stopinsert
126 new
127 call setline(1, 'abc')
128 call cursor(1, 1)
129 call feedkeys("i\<c-o>:stopinsert\<cr>$", 'tnix')
130 call feedkeys("aX\<esc>", 'tnix')
131 call assert_equal(['abcX'], getline(1, '$'))
132 %d
133 bw!
134endfunc
135
Bram Moolenaar1e115362019-01-09 23:01:02 +0100136func Test_edit_05()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100137 " test for folds being opened
138 new
139 call setline(1, ['abcX', 'abcX', 'zzzZ'])
140 call cursor(1, 1)
141 set foldmethod=manual foldopen+=insert
142 " create fold for those two lines
143 norm! Vjzf
144 call feedkeys("$ay\<esc>", 'tnix')
145 call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
146 %d
147 call setline(1, ['abcX', 'abcX', 'zzzZ'])
148 call cursor(1, 1)
149 set foldmethod=manual foldopen-=insert
150 " create fold for those two lines
151 norm! Vjzf
152 call feedkeys("$ay\<esc>", 'tnix')
153 call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
154 %d
155 bw!
156endfunc
157
Bram Moolenaar1e115362019-01-09 23:01:02 +0100158func Test_edit_06()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100159 " Test in diff mode
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200160 CheckFeature diff
161 CheckExecutable diff
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100162 new
163 call setline(1, ['abc', 'xxx', 'yyy'])
164 vnew
165 call setline(1, ['abc', 'zzz', 'xxx', 'yyy'])
166 wincmd p
167 diffthis
168 wincmd p
169 diffthis
170 wincmd p
171 call cursor(2, 1)
172 norm! zt
173 call feedkeys("Ozzz\<esc>", 'tnix')
174 call assert_equal(['abc', 'zzz', 'xxx', 'yyy'], getline(1,'$'))
175 bw!
176 bw!
177endfunc
178
Bram Moolenaar1e115362019-01-09 23:01:02 +0100179func Test_edit_07()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100180 " 1) Test with completion <c-l> when popupmenu is visible
181 new
182 call setline(1, 'J')
183
184 func! ListMonths()
185 call complete(col('.')-1, ['January', 'February', 'March',
186 \ 'April', 'May', 'June', 'July', 'August', 'September',
187 \ 'October', 'November', 'December'])
188 return ''
189 endfunc
190 inoremap <buffer> <F5> <C-R>=ListMonths()<CR>
191
192 call feedkeys("A\<f5>\<c-p>". repeat("\<down>", 6)."\<c-l>\<down>\<c-l>\<cr>", 'tx')
193 call assert_equal(['July'], getline(1,'$'))
194 " 1) Test completion when InsertCharPre kicks in
195 %d
196 call setline(1, 'J')
197 fu! DoIt()
198 if v:char=='u'
199 let v:char='an'
200 endif
201 endfu
202 au InsertCharPre <buffer> :call DoIt()
203 call feedkeys("A\<f5>\<c-p>u\<cr>\<c-l>\<cr>", 'tx')
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200204 call assert_equal(["Jan\<c-l>",''], 1->getline('$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100205 %d
206 call setline(1, 'J')
207 call feedkeys("A\<f5>\<c-p>u\<down>\<c-l>\<cr>", 'tx')
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200208 call assert_equal(["January"], 1->getline('$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100209
210 delfu ListMonths
211 delfu DoIt
212 iunmap <buffer> <f5>
213 bw!
214endfunc
215
Bram Moolenaar1e115362019-01-09 23:01:02 +0100216func Test_edit_08()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100217 " reset insertmode from i_ctrl-r_=
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200218 let g:bufnr = bufnr('%')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100219 new
220 call setline(1, ['abc'])
221 call cursor(1, 4)
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200222 call feedkeys(":set im\<cr>ZZZ\<c-r>=setbufvar(g:bufnr,'&im', 0)\<cr>",'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100223 call assert_equal(['abZZZc'], getline(1,'$'))
224 call assert_equal([0, 1, 1, 0], getpos('.'))
225 call assert_false(0, '&im')
226 bw!
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200227 unlet g:bufnr
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100228endfunc
229
Bram Moolenaar1e115362019-01-09 23:01:02 +0100230func Test_edit_09()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100231 " test i_CTRL-\ combinations
232 new
233 call setline(1, ['abc', 'def', 'ghi'])
234 call cursor(1, 1)
235 " 1) CTRL-\ CTLR-N
236 call feedkeys(":set im\<cr>\<c-\>\<c-n>ccABC\<c-l>", 'txin')
237 call assert_equal(['ABC', 'def', 'ghi'], getline(1,'$'))
238 call setline(1, ['ABC', 'def', 'ghi'])
239 " 2) CTRL-\ CTLR-G
240 call feedkeys("j0\<c-\>\<c-g>ZZZ\<cr>\<c-l>", 'txin')
241 call assert_equal(['ABC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
242 call feedkeys("I\<c-\>\<c-g>YYY\<c-l>", 'txin')
243 call assert_equal(['ABC', 'ZZZ', 'YYYdef', 'ghi'], getline(1,'$'))
244 set noinsertmode
245 " 3) CTRL-\ CTRL-O
246 call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
247 call cursor(1, 1)
248 call feedkeys("A\<c-o>ix", 'txin')
249 call assert_equal(['ABxC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
250 call feedkeys("A\<c-\>\<c-o>ix", 'txin')
251 call assert_equal(['ABxCx', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
252 " 4) CTRL-\ a (should be inserted literally, not special after <c-\>
253 call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
254 call cursor(1, 1)
255 call feedkeys("A\<c-\>a", 'txin')
256 call assert_equal(["ABC\<c-\>a", 'ZZZ', 'def', 'ghi'], getline(1, '$'))
257 bw!
258endfunc
259
Bram Moolenaar1e115362019-01-09 23:01:02 +0100260func Test_edit_11()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100261 " Test that indenting kicks in
262 new
263 set cindent
264 call setline(1, ['{', '', ''])
265 call cursor(2, 1)
266 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
267 call cursor(3, 1)
Bram Moolenaar1671f442020-03-10 07:48:13 +0100268 call feedkeys("\<Insert>/* comment */", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100269 call assert_equal(['{', "\<tab>int c;", "/* comment */"], getline(1, '$'))
270 " added changed cindentkeys slightly
271 set cindent cinkeys+=*/
272 call setline(1, ['{', '', ''])
273 call cursor(2, 1)
274 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
275 call cursor(3, 1)
276 call feedkeys("i/* comment */", 'tnix')
277 call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */"], getline(1, '$'))
278 set cindent cinkeys+==end
279 call feedkeys("oend\<cr>\<esc>", 'tnix')
280 call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */", "\tend", ''], getline(1, '$'))
281 set cinkeys-==end
282 %d
283 " Use indentexpr instead of cindenting
284 func! Do_Indent()
285 if v:lnum == 3
286 return 3*shiftwidth()
287 else
288 return 2*shiftwidth()
289 endif
290 endfunc
291 setl indentexpr=Do_Indent() indentkeys+=*/
292 call setline(1, ['{', '', ''])
293 call cursor(2, 1)
294 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
295 call cursor(3, 1)
296 call feedkeys("i/* comment */", 'tnix')
297 call assert_equal(['{', "\<tab>\<tab>int c;", "\<tab>\<tab>\<tab>/* comment */"], getline(1, '$'))
298 set cinkeys&vim indentkeys&vim
299 set nocindent indentexpr=
300 delfu Do_Indent
301 bw!
302endfunc
303
Bram Moolenaar1e115362019-01-09 23:01:02 +0100304func Test_edit_11_indentexpr()
Bram Moolenaar1b383442017-09-26 20:04:54 +0200305 " Test that indenting kicks in
306 new
307 " Use indentexpr instead of cindenting
308 func! Do_Indent()
309 let pline=prevnonblank(v:lnum)
310 if empty(getline(v:lnum))
311 if getline(pline) =~ 'if\|then'
312 return shiftwidth()
313 else
314 return 0
315 endif
316 else
317 return 0
318 endif
319 endfunc
320 setl indentexpr=Do_Indent() indentkeys+=0=then,0=fi
321 call setline(1, ['if [ $this ]'])
322 call cursor(1, 1)
323 call feedkeys("othen\<cr>that\<cr>fi", 'tnix')
324 call assert_equal(['if [ $this ]', "then", "\<tab>that", "fi"], getline(1, '$'))
325 set cinkeys&vim indentkeys&vim
326 set nocindent indentexpr=
327 delfu Do_Indent
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000328
329 " Using a script-local function
330 func s:NewIndentExpr()
331 endfunc
332 set indentexpr=s:NewIndentExpr()
333 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000334 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000335 set indentexpr=<SID>NewIndentExpr()
336 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000337 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
338 setlocal indentexpr=
339 setglobal indentexpr=s:NewIndentExpr()
340 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
341 call assert_equal('', &indentexpr)
342 new
343 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
344 bw!
345 setglobal indentexpr=<SID>NewIndentExpr()
346 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
347 call assert_equal('', &indentexpr)
348 new
349 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
350 bw!
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000351 set indentexpr&
352
Bram Moolenaar1b383442017-09-26 20:04:54 +0200353 bw!
354endfunc
355
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200356" Test changing indent in replace mode
Bram Moolenaar1e115362019-01-09 23:01:02 +0100357func Test_edit_12()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100358 new
359 call setline(1, ["\tabc", "\tdef"])
360 call cursor(2, 4)
361 call feedkeys("R^\<c-d>", 'tnix')
362 call assert_equal(["\tabc", "def"], getline(1, '$'))
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200363 call assert_equal([0, 2, 2, 0], '.'->getpos())
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100364 %d
365 call setline(1, ["\tabc", "\t\tdef"])
366 call cursor(2, 2)
367 call feedkeys("R^\<c-d>", 'tnix')
368 call assert_equal(["\tabc", "def"], getline(1, '$'))
369 call assert_equal([0, 2, 1, 0], getpos('.'))
370 %d
371 call setline(1, ["\tabc", "\t\tdef"])
372 call cursor(2, 2)
373 call feedkeys("R\<c-t>", 'tnix')
374 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
375 call assert_equal([0, 2, 2, 0], getpos('.'))
376 bw!
377 10vnew
378 call setline(1, ["\tabc", "\t\tdef"])
379 call cursor(2, 2)
380 call feedkeys("R\<c-t>", 'tnix')
381 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
382 call assert_equal([0, 2, 2, 0], getpos('.'))
383 %d
384 set sw=4
385 call setline(1, ["\tabc", "\t\tdef"])
386 call cursor(2, 2)
387 call feedkeys("R\<c-t>\<c-t>", 'tnix')
388 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
389 call assert_equal([0, 2, 2, 0], getpos('.'))
390 %d
391 call setline(1, ["\tabc", "\t\tdef"])
392 call cursor(2, 2)
393 call feedkeys("R\<c-t>\<c-t>", 'tnix')
394 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
395 call assert_equal([0, 2, 2, 0], getpos('.'))
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200396 set sw&
397
398 " In replace mode, after hitting enter in a line with tab characters,
399 " pressing backspace should restore the tab characters.
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100400 %d
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200401 setlocal autoindent backspace=2
402 call setline(1, "\tone\t\ttwo")
403 exe "normal ggRred\<CR>six" .. repeat("\<BS>", 8)
404 call assert_equal(["\tone\t\ttwo"], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100405 bw!
406endfunc
407
Bram Moolenaar1e115362019-01-09 23:01:02 +0100408func Test_edit_13()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100409 " Test smartindenting
Bram Moolenaar8e145b82022-05-21 20:17:31 +0100410 new
411 set smartindent autoindent
412 call setline(1, ["\tabc"])
413 call feedkeys("A {\<cr>more\<cr>}\<esc>", 'tnix')
414 call assert_equal(["\tabc {", "\t\tmore", "\t}"], getline(1, '$'))
415 set smartindent& autoindent&
416 bwipe!
Bram Moolenaar2ba42382019-03-16 18:11:07 +0100417
418 " Test autoindent removing indent of blank line.
419 new
420 call setline(1, ' foo bar baz')
421 set autoindent
422 exe "normal 0eea\<CR>\<CR>\<Esc>"
423 call assert_equal(" foo bar", getline(1))
424 call assert_equal("", getline(2))
425 call assert_equal(" baz", getline(3))
426 set autoindent&
Bram Moolenaar845e0ee2020-06-20 16:05:32 +0200427
428 " pressing <C-U> to erase line should keep the indent with 'autoindent'
429 set backspace=2 autoindent
430 %d
431 exe "normal i\tone\<CR>three\<C-U>two"
432 call assert_equal(["\tone", "\ttwo"], getline(1, '$'))
433 set backspace& autoindent&
434
Bram Moolenaar2ba42382019-03-16 18:11:07 +0100435 bwipe!
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100436endfunc
437
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100438" Test for autoindent removing indent when insert mode is stopped. Some parts
439" of the code is exercised only when interactive mode is used. So use Vim in a
440" terminal.
441func Test_autoindent_remove_indent()
442 CheckRunVimInTerminal
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100443 let buf = RunVimInTerminal('-N Xarifile', {'rows': 6, 'cols' : 20})
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100444 call TermWait(buf)
445 call term_sendkeys(buf, ":set autoindent\n")
446 " leaving insert mode in a new line with indent added by autoindent, should
447 " remove the indent.
448 call term_sendkeys(buf, "i\<Tab>foo\<CR>\<Esc>")
Dominique Pelle923dce22021-11-21 11:36:04 +0000449 " Need to delay for some time, otherwise the code in getchar.c will not be
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100450 " exercised.
451 call TermWait(buf, 50)
452 " when a line is wrapped and the cursor is at the start of the second line,
453 " leaving insert mode, should move the cursor back to the first line.
454 call term_sendkeys(buf, "o" .. repeat('x', 20) .. "\<Esc>")
Dominique Pelle923dce22021-11-21 11:36:04 +0000455 " Need to delay for some time, otherwise the code in getchar.c will not be
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100456 " exercised.
457 call TermWait(buf, 50)
458 call term_sendkeys(buf, ":w\n")
459 call TermWait(buf)
460 call StopVimInTerminal(buf)
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100461 call assert_equal(["\tfoo", '', repeat('x', 20)], readfile('Xarifile'))
462 call delete('Xarifile')
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100463endfunc
464
Bram Moolenaar1e115362019-01-09 23:01:02 +0100465func Test_edit_CR()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100466 " Test for <CR> in insert mode
Dominique Pelle923dce22021-11-21 11:36:04 +0000467 " basically only in quickfix mode it's tested, the rest
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100468 " has been taken care of by other tests
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200469 CheckFeature quickfix
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100470 botright new
Bram Moolenaar14f91762022-09-21 15:13:52 +0100471 call writefile(range(1, 10), 'Xqflist.txt', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100472 call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}])
473 copen
474 set modifiable
475 call feedkeys("A\<cr>", 'tnix')
476 call assert_equal('Xqflist.txt', bufname(''))
477 call assert_equal(2, line('.'))
478 cclose
479 botright new
480 call setloclist(0, [{'filename': 'Xqflist.txt', 'lnum': 10}])
481 lopen
482 set modifiable
483 call feedkeys("A\<cr>", 'tnix')
484 call assert_equal('Xqflist.txt', bufname(''))
485 call assert_equal(10, line('.'))
486 call feedkeys("A\<Enter>", 'tnix')
487 call feedkeys("A\<kEnter>", 'tnix')
488 call feedkeys("A\n", 'tnix')
489 call feedkeys("A\r", 'tnix')
490 call assert_equal(map(range(1, 10), 'string(v:val)') + ['', '', '', ''], getline(1, '$'))
Bram Moolenaar14f91762022-09-21 15:13:52 +0100491
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100492 bw!
493 lclose
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100494endfunc
495
Bram Moolenaar1e115362019-01-09 23:01:02 +0100496func Test_edit_CTRL_()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200497 CheckFeature rightleft
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100498 " disabled for Windows builds, why?
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200499 CheckNotMSWindows
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100500 let _encoding=&encoding
501 set encoding=utf-8
502 " Test for CTRL-_
503 new
504 call setline(1, ['abc'])
505 call cursor(1, 1)
506 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
507 call assert_equal(["\<C-_>xyzabc"], getline(1, '$'))
508 call assert_false(&revins)
509 set ari
510 call setline(1, ['abc'])
511 call cursor(1, 1)
512 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
513 call assert_equal(["æèñabc"], getline(1, '$'))
514 call assert_true(&revins)
515 call setline(1, ['abc'])
516 call cursor(1, 1)
517 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
518 call assert_equal(["xyzabc"], getline(1, '$'))
519 call assert_false(&revins)
520 set noari
521 let &encoding=_encoding
522 bw!
523endfunc
524
525" needs to come first, to have the @. register empty
Bram Moolenaar1e115362019-01-09 23:01:02 +0100526func Test_edit_00a_CTRL_A()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100527 " Test pressing CTRL-A
528 new
529 call setline(1, repeat([''], 5))
530 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100531 try
532 call feedkeys("A\<NUL>", 'tnix')
533 catch /^Vim\%((\a\+)\)\=:E29/
534 call assert_true(1, 'E29 error caught')
535 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100536 call cursor(1, 1)
537 call feedkeys("Afoobar \<esc>", 'tnix')
538 call cursor(2, 1)
539 call feedkeys("A\<c-a>more\<esc>", 'tnix')
540 call cursor(3, 1)
541 call feedkeys("A\<NUL>and more\<esc>", 'tnix')
542 call assert_equal(['foobar ', 'foobar more', 'foobar morend more', '', ''], getline(1, '$'))
543 bw!
544endfunc
545
Bram Moolenaar1e115362019-01-09 23:01:02 +0100546func Test_edit_CTRL_EY()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100547 " Ctrl-E/ Ctrl-Y in insert mode completion to scroll
548 10new
549 call setline(1, range(1, 100))
550 call cursor(30, 1)
551 norm! z.
552 call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
553 call assert_equal(30, winsaveview()['topline'])
554 call assert_equal([0, 30, 2, 0], getpos('.'))
555 call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
556 call feedkeys("A\<c-x>".repeat("\<c-y>", 10), 'tnix')
557 call assert_equal(21, winsaveview()['topline'])
558 call assert_equal([0, 30, 2, 0], getpos('.'))
559 bw!
560endfunc
561
Bram Moolenaar1e115362019-01-09 23:01:02 +0100562func Test_edit_CTRL_G()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100563 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100564 call setline(1, ['foobar', 'foobar', 'foobar'])
565 call cursor(2, 4)
566 call feedkeys("ioooooooo\<c-g>k\<c-r>.\<esc>", 'tnix')
567 call assert_equal(['foooooooooobar', 'foooooooooobar', 'foobar'], getline(1, '$'))
568 call assert_equal([0, 1, 11, 0], getpos('.'))
569 call feedkeys("i\<c-g>k\<esc>", 'tnix')
570 call assert_equal([0, 1, 10, 0], getpos('.'))
571 call cursor(2, 4)
572 call feedkeys("i\<c-g>jzzzz\<esc>", 'tnix')
573 call assert_equal(['foooooooooobar', 'foooooooooobar', 'foozzzzbar'], getline(1, '$'))
574 call assert_equal([0, 3, 7, 0], getpos('.'))
575 call feedkeys("i\<c-g>j\<esc>", 'tnix')
576 call assert_equal([0, 3, 6, 0], getpos('.'))
zeertzjq4f026ea2023-02-26 14:47:24 +0000577 call assert_nobeep("normal! i\<c-g>\<esc>")
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100578 bw!
579endfunc
580
Bram Moolenaar1e115362019-01-09 23:01:02 +0100581func Test_edit_CTRL_I()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100582 " Tab in completion mode
583 let path=expand("%:p:h")
584 new
Bram Moolenaarca851592018-06-06 21:04:07 +0200585 call setline(1, [path. "/", ''])
Bram Moolenaarc5379472017-03-16 22:38:00 +0100586 call feedkeys("Arunt\<c-x>\<c-f>\<tab>\<cr>\<esc>", 'tnix')
587 call assert_match('runtest\.vim', getline(1))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100588 %d
Bram Moolenaar14f91762022-09-21 15:13:52 +0100589 call writefile(['one', 'two', 'three'], 'Xinclude.txt', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100590 let include='#include Xinclude.txt'
591 call setline(1, [include, ''])
592 call cursor(2, 1)
593 call feedkeys("A\<c-x>\<tab>\<cr>\<esc>", 'tnix')
594 call assert_equal([include, 'one', ''], getline(1, '$'))
595 call feedkeys("2ggC\<c-x>\<tab>\<down>\<cr>\<esc>", 'tnix')
596 call assert_equal([include, 'two', ''], getline(1, '$'))
597 call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<cr>\<esc>", 'tnix')
598 call assert_equal([include, 'three', ''], getline(1, '$'))
599 call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
600 call assert_equal([include, '', ''], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100601 bw!
602endfunc
603
Bram Moolenaar1e115362019-01-09 23:01:02 +0100604func Test_edit_CTRL_K()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100605 " Test pressing CTRL-K (basically only dictionary completion and digraphs
606 " the rest is already covered
Bram Moolenaar14f91762022-09-21 15:13:52 +0100607 call writefile(['A', 'AA', 'AAA', 'AAAA'], 'Xdictionary.txt', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100608 set dictionary=Xdictionary.txt
609 new
610 call setline(1, 'A')
611 call cursor(1, 1)
612 call feedkeys("A\<c-x>\<c-k>\<cr>\<esc>", 'tnix')
613 call assert_equal(['AA', ''], getline(1, '$'))
614 %d
615 call setline(1, 'A')
616 call cursor(1, 1)
617 call feedkeys("A\<c-x>\<c-k>\<down>\<cr>\<esc>", 'tnix')
618 call assert_equal(['AAA'], getline(1, '$'))
619 %d
620 call setline(1, 'A')
621 call cursor(1, 1)
622 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<cr>\<esc>", 'tnix')
623 call assert_equal(['AAAA'], getline(1, '$'))
624 %d
625 call setline(1, 'A')
626 call cursor(1, 1)
627 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
628 call assert_equal(['A'], getline(1, '$'))
629 %d
630 call setline(1, 'A')
631 call cursor(1, 1)
632 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
633 call assert_equal(['AA'], getline(1, '$'))
634
Bram Moolenaar4b96df52020-01-26 22:00:26 +0100635 " press an unexpected key after dictionary completion
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100636 %d
637 call setline(1, 'A')
638 call cursor(1, 1)
639 call feedkeys("A\<c-x>\<c-k>\<c-]>\<cr>\<esc>", 'tnix')
640 call assert_equal(['AA', ''], getline(1, '$'))
641 %d
642 call setline(1, 'A')
643 call cursor(1, 1)
644 call feedkeys("A\<c-x>\<c-k>\<c-s>\<cr>\<esc>", 'tnix')
645 call assert_equal(["AA\<c-s>", ''], getline(1, '$'))
646 %d
647 call setline(1, 'A')
648 call cursor(1, 1)
649 call feedkeys("A\<c-x>\<c-k>\<c-f>\<cr>\<esc>", 'tnix')
650 call assert_equal(["AA\<c-f>", ''], getline(1, '$'))
651
652 set dictionary=
653 %d
654 call setline(1, 'A')
655 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100656 let v:testing = 1
657 try
658 call feedkeys("A\<c-x>\<c-k>\<esc>", 'tnix')
659 catch
660 " error sleeps 2 seconds, when v:testing is not set
661 let v:testing = 0
662 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100663
Bram Moolenaar30276f22019-01-24 17:59:39 +0100664 call test_override("char_avail", 1)
665 set showcmd
666 %d
667 call feedkeys("A\<c-k>a:\<esc>", 'tnix')
668 call assert_equal(['ä'], getline(1, '$'))
669 call test_override("char_avail", 0)
670 set noshowcmd
671
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100672 bw!
673endfunc
674
Bram Moolenaar1e115362019-01-09 23:01:02 +0100675func Test_edit_CTRL_L()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100676 " Test Ctrl-X Ctrl-L (line completion)
677 new
678 set complete=.
679 call setline(1, ['one', 'two', 'three', '', '', '', ''])
680 call cursor(4, 1)
681 call feedkeys("A\<c-x>\<c-l>\<esc>", 'tnix')
682 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
683 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<esc>", 'tnix')
684 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
685 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100686 call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
Bram Moolenaar02ae9b42018-02-09 15:06:02 +0100687 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100688 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
Bram Moolenaar02ae9b42018-02-09 15:06:02 +0100689 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
690 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100691 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<esc>", 'tnix')
692 call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
693 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<esc>", 'tnix')
694 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
695 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<c-p>\<esc>", 'tnix')
696 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
697 set complete=
698 call cursor(5, 1)
699 call feedkeys("A\<c-x>\<c-l>\<c-p>\<c-n>\<esc>", 'tnix')
700 call assert_equal(['one', 'two', 'three', 'three', "\<c-l>\<c-p>\<c-n>", '', ''], getline(1, '$'))
701 set complete&
702 %d
703 if has("conceal") && has("syntax")
704 call setline(1, ['foo', 'bar', 'foobar'])
705 call test_override("char_avail", 1)
706 set conceallevel=2 concealcursor=n
707 syn on
708 syn match ErrorMsg "^bar"
709 call matchadd("Conceal", 'oo', 10, -1, {'conceal': 'X'})
710 func! DoIt()
711 let g:change=1
712 endfunc
713 au! TextChangedI <buffer> :call DoIt()
714
715 call cursor(2, 1)
716 call assert_false(exists("g:change"))
717 call feedkeys("A \<esc>", 'tnix')
718 call assert_equal(['foo', 'bar ', 'foobar'], getline(1, '$'))
719 call assert_equal(1, g:change)
720
721 call test_override("char_avail", 0)
722 call clearmatches()
723 syn off
724 au! TextChangedI
725 delfu DoIt
726 unlet! g:change
727 endif
728 bw!
729endfunc
730
Bram Moolenaar1e115362019-01-09 23:01:02 +0100731func Test_edit_CTRL_N()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100732 " Check keyword completion
Bram Moolenaara1070ea2021-02-20 19:21:36 +0100733 for e in ['latin1', 'utf-8']
734 exe 'set encoding=' .. e
735 new
736 set complete=.
737 call setline(1, ['INFER', 'loWER', '', '', ])
738 call cursor(3, 1)
739 call feedkeys("Ai\<c-n>\<cr>\<esc>", "tnix")
740 call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
741 call assert_equal(['INFER', 'loWER', 'i', 'LO', '', ''], getline(1, '$'), e)
742 %d
743 call setline(1, ['INFER', 'loWER', '', '', ])
744 call cursor(3, 1)
745 set ignorecase infercase
746 call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix")
747 call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
748 call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'), e)
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000749 set noignorecase noinfercase
750 %d
751 call setline(1, ['one word', 'two word'])
752 exe "normal! Goo\<C-P>\<C-X>\<C-P>"
753 call assert_equal('one word', getline(3))
754 %d
755 set complete&
Bram Moolenaara1070ea2021-02-20 19:21:36 +0100756 bw!
757 endfor
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100758endfunc
759
Bram Moolenaar1e115362019-01-09 23:01:02 +0100760func Test_edit_CTRL_O()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100761 " Check for CTRL-O in insert mode
762 new
763 inoreabbr <buffer> h here some more
764 call setline(1, ['abc', 'def'])
765 call cursor(1, 1)
766 " Ctrl-O after an abbreviation
767 exe "norm A h\<c-o>:set nu\<cr> text"
768 call assert_equal(['abc here some more text', 'def'], getline(1, '$'))
769 call assert_true(&nu)
770 set nonu
771 iunabbr <buffer> h
772 " Ctrl-O at end of line with 've'=onemore
773 call cursor(1, 1)
774 call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
775 call assert_equal([0, 1, 23, 0], g:a)
776 call cursor(1, 1)
777 set ve=onemore
778 call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
779 call assert_equal([0, 1, 24, 0], g:a)
780 set ve=
781 unlet! g:a
782 bw!
783endfunc
784
Bram Moolenaar1e115362019-01-09 23:01:02 +0100785func Test_edit_CTRL_R()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100786 " Insert Register
787 new
788 call test_override("ALL", 1)
789 set showcmd
790 call feedkeys("AFOOBAR eins zwei\<esc>", 'tnix')
791 call feedkeys("O\<c-r>.", 'tnix')
792 call feedkeys("O\<c-r>=10*500\<cr>\<esc>", 'tnix')
793 call feedkeys("O\<c-r>=getreg('=', 1)\<cr>\<esc>", 'tnix')
794 call assert_equal(["getreg('=', 1)", '5000', "FOOBAR eins zwei", "FOOBAR eins zwei"], getline(1, '$'))
795 call test_override("ALL", 0)
796 set noshowcmd
797 bw!
798endfunc
799
Bram Moolenaar1e115362019-01-09 23:01:02 +0100800func Test_edit_CTRL_S()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100801 " Test pressing CTRL-S (basically only spellfile completion)
802 " the rest is already covered
803 new
804 if !has("spell")
805 call setline(1, 'vim')
806 call feedkeys("A\<c-x>ss\<cr>\<esc>", 'tnix')
807 call assert_equal(['vims', ''], getline(1, '$'))
808 bw!
809 return
810 endif
811 call setline(1, 'vim')
812 " spell option not yet set
813 try
814 call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
815 catch /^Vim\%((\a\+)\)\=:E756/
816 call assert_true(1, 'error caught')
817 endtry
818 call assert_equal(['vim', ''], getline(1, '$'))
819 %d
820 setl spell spelllang=en
821 call setline(1, 'vim')
822 call cursor(1, 1)
823 call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
824 call assert_equal(['Vim', ''], getline(1, '$'))
825 %d
826 call setline(1, 'vim')
827 call cursor(1, 1)
828 call feedkeys("A\<c-x>\<c-s>\<down>\<cr>\<esc>", 'tnix')
829 call assert_equal(['Aim'], getline(1, '$'))
830 %d
831 call setline(1, 'vim')
832 call cursor(1, 1)
833 call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
834 call assert_equal(['vim', ''], getline(1, '$'))
835 %d
836 " empty buffer
837 call cursor(1, 1)
838 call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
839 call assert_equal(['', ''], getline(1, '$'))
840 setl nospell
841 bw!
842endfunc
843
Bram Moolenaar1e115362019-01-09 23:01:02 +0100844func Test_edit_CTRL_T()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100845 " Check for CTRL-T and CTRL-X CTRL-T in insert mode
846 " 1) increase indent
847 new
848 call setline(1, "abc")
849 call cursor(1, 1)
850 call feedkeys("A\<c-t>xyz", 'tnix')
851 call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
852 " 2) also when paste option is set
853 set paste
854 call setline(1, "abc")
855 call cursor(1, 1)
856 call feedkeys("A\<c-t>xyz", 'tnix')
857 call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
858 set nopaste
859 " CTRL-X CTRL-T (thesaurus complete)
Bram Moolenaar14f91762022-09-21 15:13:52 +0100860 call writefile(['angry furious mad enraged'], 'Xthesaurus', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100861 set thesaurus=Xthesaurus
862 call setline(1, 'mad')
863 call cursor(1, 1)
864 call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
865 call assert_equal(['mad', ''], getline(1, '$'))
866 %d
867 call setline(1, 'mad')
868 call cursor(1, 1)
869 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
870 call assert_equal(['angry', ''], getline(1, '$'))
871 %d
872 call setline(1, 'mad')
873 call cursor(1, 1)
874 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
875 call assert_equal(['furious', ''], getline(1, '$'))
876 %d
877 call setline(1, 'mad')
878 call cursor(1, 1)
879 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
880 call assert_equal(['enraged', ''], getline(1, '$'))
881 %d
882 call setline(1, 'mad')
883 call cursor(1, 1)
884 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
885 call assert_equal(['mad', ''], getline(1, '$'))
886 %d
887 call setline(1, 'mad')
888 call cursor(1, 1)
889 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
890 call assert_equal(['mad', ''], getline(1, '$'))
891 " Using <c-p> <c-n> when 'complete' is empty
892 set complete=
893 %d
894 call setline(1, 'mad')
895 call cursor(1, 1)
896 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
897 call assert_equal(['angry', ''], getline(1, '$'))
898 %d
899 call setline(1, 'mad')
900 call cursor(1, 1)
901 call feedkeys("A\<c-x>\<c-t>\<c-p>\<cr>\<esc>", 'tnix')
902 call assert_equal(['mad', ''], getline(1, '$'))
903 set complete&
904
905 set thesaurus=
906 %d
907 call setline(1, 'mad')
908 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100909 let v:testing = 1
910 try
911 call feedkeys("A\<c-x>\<c-t>\<esc>", 'tnix')
912 catch
913 " error sleeps 2 seconds, when v:testing is not set
914 let v:testing = 0
915 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100916 call assert_equal(['mad'], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100917 bw!
918endfunc
919
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000920" Test thesaurus completion with different encodings
921func Test_thesaurus_complete_with_encoding()
Bram Moolenaar14f91762022-09-21 15:13:52 +0100922 call writefile(['angry furious mad enraged'], 'Xthesaurus', 'D')
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000923 set thesaurus=Xthesaurus
924 for e in ['latin1', 'utf-8']
925 exe 'set encoding=' .. e
926 new
927 call setline(1, 'mad')
928 call cursor(1, 1)
929 call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
930 call assert_equal(['mad', ''], getline(1, '$'))
931 bw!
932 endfor
933 set thesaurus=
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000934endfunc
935
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100936" Test 'thesaurusfunc'
937func MyThesaurus(findstart, base)
938 let mythesaurus = [
939 \ #{word: "happy",
940 \ synonyms: "cheerful,blissful,flying high,looking good,peppy"},
941 \ #{word: "kind",
942 \ synonyms: "amiable,bleeding-heart,heart in right place"}]
943 if a:findstart
944 " locate the start of the word
945 let line = getline('.')
946 let start = col('.') - 1
947 while start > 0 && line[start - 1] =~ '\a'
948 let start -= 1
949 endwhile
950 return start
951 else
952 " find strings matching with "a:base"
953 let res = []
954 for w in mythesaurus
955 if w.word =~ '^' . a:base
956 call add(res, w.word)
957 call extend(res, split(w.synonyms, ","))
958 endif
959 endfor
960 return res
961 endif
962endfunc
963
964func Test_thesaurus_func()
965 new
Bram Moolenaarf4d8b762021-10-17 14:13:09 +0100966 set thesaurus=notused
967 set thesaurusfunc=NotUsed
968 setlocal thesaurusfunc=MyThesaurus
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100969 call setline(1, "an ki")
970 call cursor(1, 1)
971 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
972 call assert_equal(['an amiable', ''], getline(1, '$'))
Bram Moolenaarf4d8b762021-10-17 14:13:09 +0100973
974 setlocal thesaurusfunc=NonExistingFunc
975 call assert_fails("normal $a\<C-X>\<C-T>", 'E117:')
976
977 setlocal thesaurusfunc=
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100978 set thesaurusfunc=NonExistingFunc
979 call assert_fails("normal $a\<C-X>\<C-T>", 'E117:')
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100980 %bw!
Bram Moolenaarf4d8b762021-10-17 14:13:09 +0100981
982 set thesaurusfunc=
983 set thesaurus=
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100984endfunc
985
Bram Moolenaar1e115362019-01-09 23:01:02 +0100986func Test_edit_CTRL_U()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100987 " Test 'completefunc'
988 new
989 " -1, -2 and -3 are special return values
990 let g:special=0
991 fun! CompleteMonths(findstart, base)
992 if a:findstart
993 " locate the start of the word
994 return g:special
995 else
996 " find months matching with "a:base"
997 let res = []
998 for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
999 if m =~ '^\c'.a:base
1000 call add(res, {'word': m, 'abbr': m.' Month', 'icase': 0})
1001 endif
1002 endfor
1003 return {'words': res, 'refresh': 'always'}
1004 endif
1005 endfun
1006 set completefunc=CompleteMonths
1007 call setline(1, ['', ''])
1008 call cursor(1, 1)
1009 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1010 call assert_equal(['X', '', ''], getline(1, '$'))
1011 %d
1012 let g:special=-1
1013 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1014 call assert_equal(['XJan', ''], getline(1, '$'))
1015 %d
1016 let g:special=-2
1017 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1018 call assert_equal(['X', ''], getline(1, '$'))
1019 %d
1020 let g:special=-3
1021 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1022 call assert_equal(['X', ''], getline(1, '$'))
1023 %d
1024 let g:special=0
1025 call feedkeys("AM\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1026 call assert_equal(['Mar', ''], getline(1, '$'))
1027 %d
1028 call feedkeys("AM\<c-x>\<c-u>\<c-n>\<cr>\<esc>", 'tnix')
1029 call assert_equal(['May', ''], getline(1, '$'))
1030 %d
1031 call feedkeys("AM\<c-x>\<c-u>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
1032 call assert_equal(['M', ''], getline(1, '$'))
1033 delfu CompleteMonths
1034 %d
1035 try
1036 call feedkeys("A\<c-x>\<c-u>", 'tnix')
1037 call assert_fails(1, 'unknown completion function')
1038 catch /^Vim\%((\a\+)\)\=:E117/
1039 call assert_true(1, 'E117 error caught')
1040 endtry
1041 set completefunc=
1042 bw!
1043endfunc
1044
Bram Moolenaarff06f282020-04-21 22:01:14 +02001045func Test_edit_completefunc_delete()
1046 func CompleteFunc(findstart, base)
1047 if a:findstart == 1
1048 return col('.') - 1
1049 endif
1050 normal dd
1051 return ['a', 'b']
1052 endfunc
1053 new
1054 set completefunc=CompleteFunc
1055 call setline(1, ['', 'abcd', ''])
1056 2d
zeertzjqcfe45652022-05-27 17:26:55 +01001057 call assert_fails("normal 2G$a\<C-X>\<C-U>", 'E565:')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001058 bwipe!
1059endfunc
1060
1061
Bram Moolenaar1e115362019-01-09 23:01:02 +01001062func Test_edit_CTRL_Z()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001063 " Ctrl-Z when insertmode is not set inserts it literally
1064 new
1065 call setline(1, 'abc')
1066 call feedkeys("A\<c-z>\<esc>", 'tnix')
1067 call assert_equal(["abc\<c-z>"], getline(1,'$'))
1068 bw!
1069 " TODO: How to Test Ctrl-Z in insert mode, e.g. suspend?
1070endfunc
1071
Bram Moolenaar1e115362019-01-09 23:01:02 +01001072func Test_edit_DROP()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001073 CheckFeature dnd
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001074 new
1075 call setline(1, ['abc def ghi'])
1076 call cursor(1, 1)
1077 try
1078 call feedkeys("i\<Drop>\<Esc>", 'tnix')
1079 call assert_fails(1, 'Invalid register name')
1080 catch /^Vim\%((\a\+)\)\=:E353/
1081 call assert_true(1, 'error caught')
1082 endtry
1083 bw!
1084endfunc
1085
Bram Moolenaar1e115362019-01-09 23:01:02 +01001086func Test_edit_CTRL_V()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001087 new
1088 call setline(1, ['abc'])
1089 call cursor(2, 1)
zeertzjq502d8ae2022-01-24 15:27:50 +00001090
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001091 " force some redraws
1092 set showmode showcmd
zeertzjq502d8ae2022-01-24 15:27:50 +00001093 call test_override('char_avail', 1)
1094
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001095 call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
1096 call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
1097
1098 if has("rightleft") && exists("+rl")
1099 set rl
1100 call setline(1, ['abc'])
1101 call cursor(2, 1)
1102 call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
1103 call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
1104 set norl
1105 endif
1106
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001107 set noshowmode showcmd
zeertzjq502d8ae2022-01-24 15:27:50 +00001108 call test_override('char_avail', 0)
1109
1110 " No modifiers should be applied to the char typed using i_CTRL-V_digit.
1111 call feedkeys(":append\<CR>\<C-V>76c\<C-V>76\<C-F2>\<C-V>u3c0j\<C-V>u3c0\<M-F3>\<CR>.\<CR>", 'tnix')
1112 call assert_equal('LcL<C-F2>πjπ<M-F3>', getline(2))
1113
1114 if has('osx')
1115 " A char with a modifier should not be a valid char for i_CTRL-V_digit.
1116 call feedkeys("o\<C-V>\<D-j>\<C-V>\<D-1>\<C-V>\<D-o>\<C-V>\<D-x>\<C-V>\<D-u>", 'tnix')
1117 call assert_equal('<D-j><D-1><D-o><D-x><D-u>', getline(3))
1118 endif
1119
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001120 bw!
1121endfunc
1122
Bram Moolenaar1e115362019-01-09 23:01:02 +01001123func Test_edit_F1()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001124 CheckFeature quickfix
1125
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001126 " Pressing <f1>
1127 new
1128 call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix')
1129 set noinsertmode
1130 call assert_equal('help', &buftype)
1131 bw
1132 bw
1133endfunc
1134
Bram Moolenaar1e115362019-01-09 23:01:02 +01001135func Test_edit_F21()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001136 " Pressing <f21>
1137 " sends a netbeans command
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001138 CheckFeature netbeans_intg
1139 new
1140 " I have no idea what this is supposed to do :)
1141 call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
1142 bw
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001143endfunc
1144
Bram Moolenaar1e115362019-01-09 23:01:02 +01001145func Test_edit_HOME_END()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001146 " Test Home/End Keys
1147 new
1148 set foldopen+=hor
1149 call setline(1, ['abc', 'def'])
1150 call cursor(1, 1)
1151 call feedkeys("AX\<Home>Y\<esc>", 'tnix')
1152 call cursor(2, 1)
1153 call feedkeys("iZ\<End>Y\<esc>", 'tnix')
1154 call assert_equal(['YabcX', 'ZdefY'], getline(1, '$'))
1155
1156 set foldopen-=hor
1157 bw!
1158endfunc
1159
Bram Moolenaar1e115362019-01-09 23:01:02 +01001160func Test_edit_INS()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001161 " Test for Pressing <Insert>
1162 new
1163 call setline(1, ['abc', 'def'])
1164 call cursor(1, 1)
1165 call feedkeys("i\<Insert>ZYX>", 'tnix')
1166 call assert_equal(['ZYX>', 'def'], getline(1, '$'))
1167 call setline(1, ['abc', 'def'])
1168 call cursor(1, 1)
1169 call feedkeys("i\<Insert>Z\<Insert>YX>", 'tnix')
1170 call assert_equal(['ZYX>bc', 'def'], getline(1, '$'))
1171 bw!
1172endfunc
1173
Bram Moolenaar1e115362019-01-09 23:01:02 +01001174func Test_edit_LEFT_RIGHT()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001175 " Left, Shift-Left, Right, Shift-Right
1176 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001177 call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX'])
1178 let _ww=&ww
1179 set ww=
1180 call cursor(2, 1)
1181 call feedkeys("i\<left>\<esc>", 'tnix')
1182 call assert_equal([0, 2, 1, 0], getpos('.'))
1183 " Is this a bug, <s-left> does not respect whichwrap option
1184 call feedkeys("i\<s-left>\<esc>", 'tnix')
1185 call assert_equal([0, 1, 8, 0], getpos('.'))
1186 call feedkeys("i". repeat("\<s-left>", 3). "\<esc>", 'tnix')
1187 call assert_equal([0, 1, 1, 0], getpos('.'))
1188 call feedkeys("i\<right>\<esc>", 'tnix')
1189 call assert_equal([0, 1, 1, 0], getpos('.'))
1190 call feedkeys("i\<right>\<right>\<esc>", 'tnix')
1191 call assert_equal([0, 1, 2, 0], getpos('.'))
1192 call feedkeys("A\<right>\<esc>", 'tnix')
1193 call assert_equal([0, 1, 11, 0], getpos('.'))
1194 call feedkeys("A\<s-right>\<esc>", 'tnix')
1195 call assert_equal([0, 2, 1, 0], getpos('.'))
1196 call feedkeys("i\<s-right>\<esc>", 'tnix')
1197 call assert_equal([0, 2, 4, 0], getpos('.'))
1198 call cursor(3, 11)
1199 call feedkeys("A\<right>\<esc>", 'tnix')
1200 call feedkeys("A\<s-right>\<esc>", 'tnix')
1201 call assert_equal([0, 3, 11, 0], getpos('.'))
1202 call cursor(2, 11)
1203 " <S-Right> does not respect 'whichwrap' option
1204 call feedkeys("A\<s-right>\<esc>", 'tnix')
1205 call assert_equal([0, 3, 1, 0], getpos('.'))
1206 " Check motion when 'whichwrap' contains cursor keys for insert mode
1207 set ww+=[,]
1208 call cursor(2, 1)
1209 call feedkeys("i\<left>\<esc>", 'tnix')
1210 call assert_equal([0, 1, 11, 0], getpos('.'))
1211 call cursor(2, 11)
1212 call feedkeys("A\<right>\<esc>", 'tnix')
1213 call assert_equal([0, 3, 1, 0], getpos('.'))
1214 call cursor(2, 11)
1215 call feedkeys("A\<s-right>\<esc>", 'tnix')
1216 call assert_equal([0, 3, 1, 0], getpos('.'))
1217 let &ww = _ww
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001218 bw!
1219endfunc
1220
Bram Moolenaar1e115362019-01-09 23:01:02 +01001221func Test_edit_MOUSE()
Christian Brabandtee17b6f2023-09-09 11:23:50 +02001222 " This is a simple test, since we're not really using the mouse here
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001223 CheckFeature mouse
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001224 10new
1225 call setline(1, range(1, 100))
1226 call cursor(1, 1)
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001227 call assert_equal(1, line('w0'))
1228 call assert_equal(10, line('w$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001229 set mouse=a
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001230 " One scroll event moves three lines.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001231 call feedkeys("A\<ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001232 call assert_equal(4, line('w0'))
1233 call assert_equal(13, line('w$'))
1234 " This should move by one page down.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001235 call feedkeys("A\<S-ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001236 call assert_equal(14, line('w0'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001237 set nostartofline
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001238 " Another page down.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001239 call feedkeys("A\<C-ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001240 call assert_equal(24, line('w0'))
1241
1242 call assert_equal([0, 24, 2, 0], getpos('.'))
1243 call test_setmouse(4, 3)
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001244 call feedkeys("A\<LeftMouse>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001245 call assert_equal([0, 27, 2, 0], getpos('.'))
Bram Moolenaarb3707712022-05-08 22:49:43 +01001246 set mousemodel=extend
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001247 call test_setmouse(5, 3)
1248 call feedkeys("A\<RightMouse>\<esc>\<esc>", 'tnix')
1249 call assert_equal([0, 28, 2, 0], getpos('.'))
Bram Moolenaarb3707712022-05-08 22:49:43 +01001250 set mousemodel&
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001251 call cursor(1, 100)
1252 norm! zt
1253 " this should move by a screen up, but when the test
1254 " is run, it moves up to the top of the buffer...
1255 call feedkeys("A\<ScrollWheelUp>\<esc>", 'tnix')
1256 call assert_equal([0, 1, 1, 0], getpos('.'))
1257 call cursor(1, 30)
1258 norm! zt
1259 call feedkeys("A\<S-ScrollWheelUp>\<esc>", 'tnix')
1260 call assert_equal([0, 1, 1, 0], getpos('.'))
1261 call cursor(1, 30)
1262 norm! zt
1263 call feedkeys("A\<C-ScrollWheelUp>\<esc>", 'tnix')
1264 call assert_equal([0, 1, 1, 0], getpos('.'))
1265 %d
1266 call setline(1, repeat(["12345678901234567890"], 100))
1267 call cursor(2, 1)
1268 call feedkeys("A\<ScrollWheelRight>\<esc>", 'tnix')
1269 call assert_equal([0, 2, 20, 0], getpos('.'))
1270 call feedkeys("A\<ScrollWheelLeft>\<esc>", 'tnix')
1271 call assert_equal([0, 2, 20, 0], getpos('.'))
1272 call feedkeys("A\<S-ScrollWheelRight>\<esc>", 'tnix')
1273 call assert_equal([0, 2, 20, 0], getpos('.'))
1274 call feedkeys("A\<S-ScrollWheelLeft>\<esc>", 'tnix')
1275 call assert_equal([0, 2, 20, 0], getpos('.'))
1276 call feedkeys("A\<C-ScrollWheelRight>\<esc>", 'tnix')
1277 call assert_equal([0, 2, 20, 0], getpos('.'))
1278 call feedkeys("A\<C-ScrollWheelLeft>\<esc>", 'tnix')
1279 call assert_equal([0, 2, 20, 0], getpos('.'))
1280 set mouse& startofline
1281 bw!
1282endfunc
1283
Bram Moolenaar1e115362019-01-09 23:01:02 +01001284func Test_edit_PAGEUP_PAGEDOWN()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001285 10new
1286 call setline(1, repeat(['abc def ghi'], 30))
1287 call cursor(1, 1)
1288 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1289 call assert_equal([0, 9, 1, 0], getpos('.'))
1290 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1291 call assert_equal([0, 17, 1, 0], getpos('.'))
1292 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1293 call assert_equal([0, 25, 1, 0], getpos('.'))
1294 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1295 call assert_equal([0, 30, 1, 0], getpos('.'))
1296 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1297 call assert_equal([0, 30, 1, 0], getpos('.'))
1298 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1299 call assert_equal([0, 29, 1, 0], getpos('.'))
1300 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1301 call assert_equal([0, 21, 1, 0], getpos('.'))
1302 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1303 call assert_equal([0, 13, 1, 0], getpos('.'))
1304 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1305 call assert_equal([0, 5, 1, 0], getpos('.'))
1306 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1307 call assert_equal([0, 5, 11, 0], getpos('.'))
1308 " <S-Up> is the same as <PageUp>
1309 " <S-Down> is the same as <PageDown>
1310 call cursor(1, 1)
1311 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1312 call assert_equal([0, 9, 1, 0], getpos('.'))
1313 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1314 call assert_equal([0, 17, 1, 0], getpos('.'))
1315 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1316 call assert_equal([0, 25, 1, 0], getpos('.'))
1317 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1318 call assert_equal([0, 30, 1, 0], getpos('.'))
1319 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1320 call assert_equal([0, 30, 1, 0], getpos('.'))
1321 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1322 call assert_equal([0, 29, 1, 0], getpos('.'))
1323 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1324 call assert_equal([0, 21, 1, 0], getpos('.'))
1325 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1326 call assert_equal([0, 13, 1, 0], getpos('.'))
1327 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1328 call assert_equal([0, 5, 1, 0], getpos('.'))
1329 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1330 call assert_equal([0, 5, 11, 0], getpos('.'))
1331 set nostartofline
1332 call cursor(30, 11)
1333 norm! zt
1334 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1335 call assert_equal([0, 29, 11, 0], getpos('.'))
1336 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1337 call assert_equal([0, 21, 11, 0], getpos('.'))
1338 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1339 call assert_equal([0, 13, 11, 0], getpos('.'))
1340 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1341 call assert_equal([0, 5, 11, 0], getpos('.'))
1342 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1343 call assert_equal([0, 5, 11, 0], getpos('.'))
1344 call cursor(1, 1)
1345 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1346 call assert_equal([0, 9, 11, 0], getpos('.'))
1347 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1348 call assert_equal([0, 17, 11, 0], getpos('.'))
1349 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1350 call assert_equal([0, 25, 11, 0], getpos('.'))
1351 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1352 call assert_equal([0, 30, 11, 0], getpos('.'))
1353 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1354 call assert_equal([0, 30, 11, 0], getpos('.'))
1355 " <S-Up> is the same as <PageUp>
1356 " <S-Down> is the same as <PageDown>
1357 call cursor(30, 11)
1358 norm! zt
1359 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1360 call assert_equal([0, 29, 11, 0], getpos('.'))
1361 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1362 call assert_equal([0, 21, 11, 0], getpos('.'))
1363 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1364 call assert_equal([0, 13, 11, 0], getpos('.'))
1365 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1366 call assert_equal([0, 5, 11, 0], getpos('.'))
1367 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1368 call assert_equal([0, 5, 11, 0], getpos('.'))
1369 call cursor(1, 1)
1370 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1371 call assert_equal([0, 9, 11, 0], getpos('.'))
1372 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1373 call assert_equal([0, 17, 11, 0], getpos('.'))
1374 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1375 call assert_equal([0, 25, 11, 0], getpos('.'))
1376 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1377 call assert_equal([0, 30, 11, 0], getpos('.'))
1378 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1379 call assert_equal([0, 30, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001380 bw!
1381endfunc
1382
Bram Moolenaar1e115362019-01-09 23:01:02 +01001383func Test_edit_forbidden()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001384 new
1385 " 1) edit in the sandbox is not allowed
1386 call setline(1, 'a')
1387 com! Sandbox :sandbox call feedkeys("i\<del>\<esc>", 'tnix')
1388 call assert_fails(':Sandbox', 'E48:')
1389 com! Sandbox :sandbox exe "norm! i\<del>"
1390 call assert_fails(':Sandbox', 'E48:')
1391 delcom Sandbox
1392 call assert_equal(['a'], getline(1,'$'))
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001393
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001394 " 2) edit with textlock set
1395 fu! DoIt()
1396 call feedkeys("i\<del>\<esc>", 'tnix')
1397 endfu
1398 au InsertCharPre <buffer> :call DoIt()
1399 try
1400 call feedkeys("ix\<esc>", 'tnix')
1401 call assert_fails(1, 'textlock')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001402 catch /^Vim\%((\a\+)\)\=:E565/ " catch E565: not allowed here
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001403 endtry
1404 " TODO: Might be a bug: should x really be inserted here
1405 call assert_equal(['xa'], getline(1, '$'))
1406 delfu DoIt
1407 try
1408 call feedkeys("ix\<esc>", 'tnix')
1409 call assert_fails(1, 'unknown function')
1410 catch /^Vim\%((\a\+)\)\=:E117/ " catch E117: unknown function
1411 endtry
1412 au! InsertCharPre
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001413
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001414 " 3) edit when completion is shown
1415 fun! Complete(findstart, base)
1416 if a:findstart
1417 return col('.')
1418 else
1419 call feedkeys("i\<del>\<esc>", 'tnix')
1420 return []
1421 endif
1422 endfun
1423 set completefunc=Complete
1424 try
1425 call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
1426 call assert_fails(1, 'change in complete function')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001427 catch /^Vim\%((\a\+)\)\=:E565/ " catch E565
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001428 endtry
1429 delfu Complete
1430 set completefunc=
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001431
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001432 if has("rightleft") && exists("+fkmap")
1433 " 4) 'R' when 'fkmap' and 'revins' is set.
1434 set revins fkmap
1435 try
1436 normal Ri
1437 call assert_fails(1, "R with 'fkmap' and 'ri' set")
1438 catch
1439 finally
1440 set norevins nofkmap
1441 endtry
1442 endif
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001443 bw!
1444endfunc
1445
Bram Moolenaar1e115362019-01-09 23:01:02 +01001446func Test_edit_rightleft()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001447 " Cursor in rightleft mode moves differently
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001448 CheckFeature rightleft
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001449 call NewWindow(10, 20)
1450 call setline(1, ['abc', 'def', 'ghi'])
1451 call cursor(1, 2)
1452 set rightleft
1453 " Screen looks as expected
1454 let lines = ScreenLines([1, 4], winwidth(0))
1455 let expect = [
1456 \" cba",
1457 \" fed",
1458 \" ihg",
1459 \" ~"]
1460 call assert_equal(join(expect, "\n"), join(lines, "\n"))
1461 " 2) right moves to the left
1462 call feedkeys("i\<right>\<esc>x", 'txin')
1463 call assert_equal(['bc', 'def', 'ghi'], getline(1,'$'))
1464 call cursor(1, 2)
1465 call feedkeys("i\<s-right>\<esc>", 'txin')
1466 call cursor(1, 2)
1467 call feedkeys("i\<c-right>\<esc>", 'txin')
1468 " Screen looks as expected
1469 let lines = ScreenLines([1, 4], winwidth(0))
1470 let expect = [
1471 \" cb",
1472 \" fed",
1473 \" ihg",
1474 \" ~"]
1475 call assert_equal(join(expect, "\n"), join(lines, "\n"))
1476 " 2) left moves to the right
1477 call setline(1, ['abc', 'def', 'ghi'])
1478 call cursor(1, 2)
1479 call feedkeys("i\<left>\<esc>x", 'txin')
1480 call assert_equal(['ac', 'def', 'ghi'], getline(1,'$'))
1481 call cursor(1, 2)
1482 call feedkeys("i\<s-left>\<esc>", 'txin')
1483 call cursor(1, 2)
1484 call feedkeys("i\<c-left>\<esc>", 'txin')
1485 " Screen looks as expected
1486 let lines = ScreenLines([1, 4], winwidth(0))
1487 let expect = [
1488 \" ca",
1489 \" fed",
1490 \" ihg",
1491 \" ~"]
1492 call assert_equal(join(expect, "\n"), join(lines, "\n"))
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001493 %d _
1494 call test_override('redraw_flag', 1)
1495 call test_override('char_avail', 1)
1496 call feedkeys("a\<C-V>x41", "xt")
1497 redraw!
1498 call assert_equal(repeat(' ', 19) .. 'A', Screenline(1))
1499 call test_override('ALL', 0)
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001500 set norightleft
1501 bw!
1502endfunc
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001503
1504func Test_edit_complete_very_long_name()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001505 " Long directory names only work on Unix.
1506 CheckUnix
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001507
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01001508 let dirname = getcwd() . "/Xlongdir"
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001509 let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
1510 try
Bram Moolenaar14f91762022-09-21 15:13:52 +01001511 call mkdir(longdirname, 'pR')
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001512 catch /E739:/
1513 " Long directory name probably not supported.
1514 call delete(dirname, 'rf')
1515 return
1516 endtry
1517
Bram Moolenaarf8191c52019-05-18 17:22:54 +02001518 " Try to get the Vim window position before setting 'columns', so that we can
1519 " move the window back to where it was.
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001520 let winposx = getwinposx()
1521 let winposy = getwinposy()
Bram Moolenaarf8191c52019-05-18 17:22:54 +02001522
1523 if winposx >= 0 && winposy >= 0 && !has('gui_running')
1524 " We did get the window position, but xterm may report the wrong numbers.
1525 " Move the window to the reported position and compute any offset.
1526 exe 'winpos ' . winposx . ' ' . winposy
1527 sleep 100m
1528 let x = getwinposx()
1529 if x >= 0
1530 let winposx += winposx - x
1531 endif
1532 let y = getwinposy()
1533 if y >= 0
1534 let winposy += winposy - y
1535 endif
1536 endif
1537
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001538 let save_columns = &columns
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001539 " Need at least about 1100 columns to reproduce the problem.
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001540 set columns=2000
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001541 set noswapfile
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001542
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001543 let longfilename = longdirname . '/' . repeat('a', 255)
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001544 call writefile(['Totum', 'Table'], longfilename)
1545 new
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001546 exe "next Xnofile " . longfilename
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001547 exe "normal iT\<C-N>"
1548
1549 bwipe!
1550 exe 'bwipe! ' . longfilename
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001551 let &columns = save_columns
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001552 if winposx >= 0 && winposy >= 0
1553 exe 'winpos ' . winposx . ' ' . winposy
1554 endif
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001555 set swapfile&
1556endfunc
Bram Moolenaarff930ca2017-10-19 17:12:10 +02001557
Bram Moolenaar2c8c6812018-07-28 17:07:52 +02001558func Test_edit_backtick()
1559 next a\`b c
1560 call assert_equal('a`b', expand('%'))
1561 next
1562 call assert_equal('c', expand('%'))
1563 call assert_equal('a\`b c', expand('##'))
1564endfunc
1565
Bram Moolenaarff930ca2017-10-19 17:12:10 +02001566func Test_edit_quit()
1567 edit foo.txt
1568 split
1569 new
1570 call setline(1, 'hello')
1571 3wincmd w
1572 redraw!
1573 call assert_fails('1q', 'E37:')
1574 bwipe! foo.txt
1575 only
1576endfunc
1577
Bram Moolenaaradb8fbe2018-06-04 20:34:23 +02001578func Test_edit_alt()
1579 " Keeping the cursor line didn't happen when the first line has indent.
1580 new
1581 call setline(1, [' one', 'two', 'three'])
1582 w XAltFile
1583 $
1584 call assert_equal(3, line('.'))
1585 e Xother
1586 e #
1587 call assert_equal(3, line('.'))
1588
1589 bwipe XAltFile
1590 call delete('XAltFile')
1591endfunc
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001592
Bram Moolenaardb934952020-04-27 20:18:31 +02001593func Test_edit_InsertLeave()
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001594 new
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001595 au InsertLeavePre * let g:did_au_pre = 1
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001596 au InsertLeave * let g:did_au = 1
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001597 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001598 let g:did_au = 0
1599 call feedkeys("afoo\<Esc>", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001600 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001601 call assert_equal(1, g:did_au)
1602 call assert_equal('foo', getline(1))
1603
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001604 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001605 let g:did_au = 0
1606 call feedkeys("Sbar\<C-C>", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001607 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001608 call assert_equal(0, g:did_au)
1609 call assert_equal('bar', getline(1))
1610
1611 inoremap x xx<Esc>
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001612 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001613 let g:did_au = 0
1614 call feedkeys("Saax", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001615 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001616 call assert_equal(1, g:did_au)
1617 call assert_equal('aaxx', getline(1))
1618
1619 inoremap x xx<C-C>
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001620 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001621 let g:did_au = 0
1622 call feedkeys("Sbbx", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001623 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001624 call assert_equal(0, g:did_au)
1625 call assert_equal('bbxx', getline(1))
1626
1627 bwipe!
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001628 au! InsertLeave InsertLeavePre
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001629 iunmap x
1630endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001631
Bram Moolenaardb934952020-04-27 20:18:31 +02001632func Test_edit_InsertLeave_undo()
1633 new XtestUndo
1634 set undofile
1635 au InsertLeave * wall
1636 exe "normal ofoo\<Esc>"
1637 call assert_equal(2, line('$'))
1638 normal u
1639 call assert_equal(1, line('$'))
1640
1641 bwipe!
1642 au! InsertLeave
1643 call delete('XtestUndo')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001644 call delete(undofile('XtestUndo'))
Bram Moolenaardb934952020-04-27 20:18:31 +02001645 set undofile&
1646endfunc
1647
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001648" Test for inserting characters using CTRL-V followed by a number.
1649func Test_edit_special_chars()
1650 new
1651
Bram Moolenaar424bcae2022-01-31 14:59:41 +00001652 let t = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>"
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001653
1654 exe "normal " . t
1655 call assert_equal("ABC !a\<C-O>g\<C-G>8", getline(2))
1656
1657 close!
1658endfunc
Bram Moolenaar8d3b5102019-09-05 21:29:01 +02001659
1660func Test_edit_startinsert()
1661 new
1662 set backspace+=start
1663 call setline(1, 'foobar')
1664 call feedkeys("A\<C-U>\<Esc>", 'xt')
1665 call assert_equal('', getline(1))
1666
1667 call setline(1, 'foobar')
1668 call feedkeys(":startinsert!\<CR>\<C-U>\<Esc>", 'xt')
1669 call assert_equal('', getline(1))
1670
1671 set backspace&
1672 bwipe!
1673endfunc
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001674
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001675" Test for :startreplace and :startgreplace
1676func Test_edit_startreplace()
1677 new
1678 call setline(1, 'abc')
1679 call feedkeys("l:startreplace\<CR>xyz\e", 'xt')
1680 call assert_equal('axyz', getline(1))
1681 call feedkeys("0:startreplace!\<CR>abc\e", 'xt')
1682 call assert_equal('axyzabc', getline(1))
1683 call setline(1, "a\tb")
1684 call feedkeys("0l:startgreplace\<CR>xyz\e", 'xt')
1685 call assert_equal("axyz\tb", getline(1))
1686 call feedkeys("0i\<C-R>=execute('startreplace')\<CR>12\e", 'xt')
1687 call assert_equal("12axyz\tb", getline(1))
1688 close!
1689endfunc
1690
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001691func Test_edit_noesckeys()
Bram Moolenaar215ba3b2019-11-06 15:07:07 +01001692 CheckNotGui
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001693 new
1694
1695 " <Left> moves cursor when 'esckeys' is set
1696 exe "set t_kl=\<Esc>OD"
1697 set esckeys
1698 call feedkeys("axyz\<Esc>ODX", "xt")
1699 call assert_equal("xyXz", getline(1))
1700
1701 " <Left> exits Insert mode when 'esckeys' is off
1702 set noesckeys
1703 call setline(1, '')
1704 call feedkeys("axyz\<Esc>ODX", "xt")
1705 call assert_equal(["DX", "xyz"], getline(1, 2))
1706
1707 bwipe!
1708 set esckeys
1709endfunc
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001710
Bram Moolenaar1671f442020-03-10 07:48:13 +01001711" Test for running an invalid ex command in insert mode using CTRL-O
Bram Moolenaar1671f442020-03-10 07:48:13 +01001712func Test_edit_ctrl_o_invalid_cmd()
1713 new
1714 set showmode showcmd
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001715 " Avoid a sleep of 3 seconds. Zero might have side effects.
1716 call test_override('ui_delay', 50)
Bram Moolenaar1671f442020-03-10 07:48:13 +01001717 let caught_e492 = 0
1718 try
1719 call feedkeys("i\<C-O>:invalid\<CR>abc\<Esc>", "xt")
1720 catch /E492:/
1721 let caught_e492 = 1
1722 endtry
1723 call assert_equal(1, caught_e492)
1724 call assert_equal('abc', getline(1))
1725 set showmode& showcmd&
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001726 call test_override('ui_delay', 0)
Bram Moolenaar1671f442020-03-10 07:48:13 +01001727 close!
1728endfunc
1729
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001730" Test for editing a file with a very long name
1731func Test_edit_illegal_filename()
1732 CheckEnglish
1733 new
1734 redir => msg
1735 exe 'edit ' . repeat('f', 5000)
1736 redir END
1737 call assert_match("Illegal file name$", split(msg, "\n")[0])
1738 close!
1739endfunc
1740
Bram Moolenaarc8fe6452020-10-03 17:04:37 +02001741" Test for editing a directory
1742func Test_edit_is_a_directory()
1743 CheckEnglish
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01001744 let dirname = getcwd() . "/Xeditdir"
Bram Moolenaarc8fe6452020-10-03 17:04:37 +02001745 call mkdir(dirname, 'p')
1746
1747 new
1748 redir => msg
1749 exe 'edit' dirname
1750 redir END
1751 call assert_match("is a directory$", split(msg, "\n")[0])
1752 bwipe!
1753
1754 let dirname .= '/'
1755
1756 new
1757 redir => msg
1758 exe 'edit' dirname
1759 redir END
1760 call assert_match("is a directory$", split(msg, "\n")[0])
1761 bwipe!
1762
1763 call delete(dirname, 'rf')
1764endfunc
1765
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001766" Test for editing a file using invalid file encoding
1767func Test_edit_invalid_encoding()
1768 CheckEnglish
Bram Moolenaar14f91762022-09-21 15:13:52 +01001769 call writefile([], 'Xinvfile', 'D')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001770 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001771 new ++enc=axbyc Xinvfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001772 redir END
1773 call assert_match('\[NOT converted\]', msg)
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001774 close!
1775endfunc
1776
1777" Test for the "charconvert" option
1778func Test_edit_charconvert()
1779 CheckEnglish
Bram Moolenaar14f91762022-09-21 15:13:52 +01001780 call writefile(['one', 'two'], 'Xccfile', 'D')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001781
1782 " set 'charconvert' to a non-existing function
1783 set charconvert=NonExitingFunc()
1784 new
1785 let caught_e117 = v:false
1786 try
1787 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001788 edit ++enc=axbyc Xccfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001789 catch /E117:/
1790 let caught_e117 = v:true
1791 finally
1792 redir END
1793 endtry
1794 call assert_true(caught_e117)
1795 call assert_equal(['one', 'two'], getline(1, '$'))
1796 call assert_match("Conversion with 'charconvert' failed", msg)
1797 close!
1798 set charconvert&
1799
Christian Brabandtee17b6f2023-09-09 11:23:50 +02001800 " 'charconvert' function doesn't create an output file
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001801 func Cconv1()
1802 endfunc
1803 set charconvert=Cconv1()
1804 new
1805 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001806 edit ++enc=axbyc Xccfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001807 redir END
1808 call assert_equal(['one', 'two'], getline(1, '$'))
1809 call assert_match("can't read output of 'charconvert'", msg)
1810 close!
1811 delfunc Cconv1
1812 set charconvert&
1813
1814 " 'charconvert' function to convert to upper case
1815 func Cconv2()
1816 let data = readfile(v:fname_in)
1817 call map(data, 'toupper(v:val)')
1818 call writefile(data, v:fname_out)
1819 endfunc
1820 set charconvert=Cconv2()
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001821 new Xccfile
1822 write ++enc=ucase Xccfile1
1823 call assert_equal(['ONE', 'TWO'], readfile('Xccfile1'))
1824 call delete('Xccfile1')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001825 close!
1826 delfunc Cconv2
1827 set charconvert&
1828
1829 " 'charconvert' function removes the input file
1830 func Cconv3()
1831 call delete(v:fname_in)
1832 endfunc
1833 set charconvert=Cconv3()
1834 new
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001835 call assert_fails('edit ++enc=lcase Xccfile', 'E202:')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001836 call assert_equal([''], getline(1, '$'))
1837 close!
1838 delfunc Cconv3
1839 set charconvert&
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001840endfunc
1841
1842" Test for editing a file without read permission
1843func Test_edit_file_no_read_perm()
1844 CheckUnix
Bram Moolenaar17709e22021-03-19 14:38:12 +01001845 CheckNotRoot
1846
Bram Moolenaar14f91762022-09-21 15:13:52 +01001847 call writefile(['one', 'two'], 'Xnrpfile', 'D')
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001848 call setfperm('Xnrpfile', '-w-------')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001849 new
1850 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001851 edit Xnrpfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001852 redir END
1853 call assert_equal(1, &readonly)
1854 call assert_equal([''], getline(1, '$'))
1855 call assert_match('\[Permission Denied\]', msg)
1856 close!
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001857endfunc
1858
zeertzjq3a56b6d2022-04-08 11:56:14 +01001859" Using :edit without leaving 'insertmode' should not cause Insert mode to be
1860" re-entered immediately after <C-L>
1861func Test_edit_insertmode_ex_edit()
1862 CheckRunVimInTerminal
1863
1864 let lines =<< trim END
1865 set insertmode noruler
1866 inoremap <C-B> <Cmd>edit Xfoo<CR>
1867 END
Bram Moolenaar14f91762022-09-21 15:13:52 +01001868 call writefile(lines, 'Xtest_edit_insertmode_ex_edit', 'D')
zeertzjq3a56b6d2022-04-08 11:56:14 +01001869
Bram Moolenaar14f91762022-09-21 15:13:52 +01001870 let buf = RunVimInTerminal('-S Xtest_edit_insertmode_ex_edit', #{rows: 6, wait_for_ruler: 0})
1871 " Somehow when using valgrind "INSERT" does not show up unless we send
1872 " something to the terminal.
1873 for i in range(30)
1874 if term_getline(buf, 6) =~ 'INSERT'
1875 break
1876 endif
1877 call term_sendkeys(buf, "-")
1878 sleep 100m
1879 endfor
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001880 call WaitForAssert({-> assert_match('^-- INSERT --\s*$', term_getline(buf, 6))})
zeertzjq3a56b6d2022-04-08 11:56:14 +01001881 call term_sendkeys(buf, "\<C-B>\<C-L>")
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001882 call WaitForAssert({-> assert_notmatch('^-- INSERT --\s*$', term_getline(buf, 6))})
zeertzjq3a56b6d2022-04-08 11:56:14 +01001883
1884 " clean up
1885 call StopVimInTerminal(buf)
zeertzjq3a56b6d2022-04-08 11:56:14 +01001886endfunc
1887
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001888" Pressing escape in 'insertmode' should beep
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001889" FIXME: Execute this later, when using valgrind it makes the next test
1890" Test_edit_insertmode_ex_edit() fail.
1891func Test_z_edit_insertmode_esc_beeps()
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001892 new
1893 set insertmode
1894 call assert_beeps("call feedkeys(\"one\<Esc>\", 'xt')")
1895 set insertmode&
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001896 " unsupported "CTRL-G l" command should beep in insert mode.
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001897 call assert_beeps("normal i\<C-G>l")
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001898 bwipe!
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001899endfunc
1900
1901" Test for 'hkmap' and 'hkmapp'
1902func Test_edit_hkmap()
1903 CheckFeature rightleft
1904 if has('win32') && !has('gui')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001905 throw 'Skipped: fails on the MS-Windows terminal version'
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001906 endif
1907 new
1908
1909 set revins hkmap
1910 let str = 'abcdefghijklmnopqrstuvwxyz'
1911 let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1912 let str ..= '`/'',.;'
1913 call feedkeys('i' .. str, 'xt')
1914 let expected = "óõú,.;"
1915 let expected ..= "ZYXWVUTSRQPONMLKJIHGFEDCBA"
1916 let expected ..= "æèñ'äåàãø/ôíîöêìçïéòë÷âáðù"
1917 call assert_equal(expected, getline(1))
1918
1919 %d
1920 set revins hkmap hkmapp
1921 let str = 'abcdefghijklmnopqrstuvwxyz'
1922 let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1923 call feedkeys('i' .. str, 'xt')
1924 let expected = "õYXWVUTSRQóOïíLKJIHGFEDêBA"
1925 let expected ..= "öòXùåèúæø'ôñðîì÷çéäâóǟãëáà"
1926 call assert_equal(expected, getline(1))
1927
1928 set revins& hkmap& hkmapp&
1929 close!
1930endfunc
1931
1932" Test for 'allowrevins' and using CTRL-_ in insert mode
1933func Test_edit_allowrevins()
1934 CheckFeature rightleft
1935 new
1936 set allowrevins
1937 call feedkeys("iABC\<C-_>DEF\<C-_>GHI", 'xt')
1938 call assert_equal('ABCFEDGHI', getline(1))
1939 set allowrevins&
1940 close!
1941endfunc
1942
1943" Test for inserting a register in insert mode using CTRL-R
1944func Test_edit_insert_reg()
1945 new
1946 let g:Line = ''
1947 func SaveFirstLine()
1948 let g:Line = Screenline(1)
1949 return 'r'
1950 endfunc
1951 inoremap <expr> <buffer> <F2> SaveFirstLine()
1952 call test_override('redraw_flag', 1)
1953 call test_override('char_avail', 1)
1954 let @r = 'sample'
1955 call feedkeys("a\<C-R>=SaveFirstLine()\<CR>", "xt")
1956 call assert_equal('"', g:Line)
1957 call test_override('ALL', 0)
1958 close!
1959endfunc
1960
Bram Moolenaarc174c2e2023-03-25 20:06:49 +00001961" Test for positioning cursor after CTRL-R expression failed
1962func Test_edit_ctrl_r_failed()
1963 CheckRunVimInTerminal
1964
1965 let buf = RunVimInTerminal('', #{rows: 6, cols: 60})
1966
1967 " trying to insert a dictionary produces an error
1968 call term_sendkeys(buf, "i\<C-R>={}\<CR>")
1969
1970 " ending Insert mode should put the cursor back on the ':'
1971 call term_sendkeys(buf, ":\<Esc>")
1972 call VerifyScreenDump(buf, 'Test_edit_ctlr_r_failed_1', {})
1973
1974 call StopVimInTerminal(buf)
1975endfunc
1976
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001977" When a character is inserted at the last position of the last line in a
1978" window, the window contents should be scrolled one line up. If the top line
1979" is part of a fold, then the entire fold should be scrolled up.
1980func Test_edit_lastline_scroll()
1981 new
1982 let h = winheight(0)
1983 let lines = ['one', 'two', 'three']
1984 let lines += repeat(['vim'], h - 4)
1985 call setline(1, lines)
1986 call setline(h, repeat('x', winwidth(0) - 1))
1987 call feedkeys("GAx", 'xt')
1988 redraw!
1989 call assert_equal(h - 1, winline())
1990 call assert_equal(2, line('w0'))
1991
1992 " scroll with a fold
1993 1,2fold
1994 normal gg
1995 call setline(h + 1, repeat('x', winwidth(0) - 1))
1996 call feedkeys("GAx", 'xt')
1997 redraw!
1998 call assert_equal(h - 1, winline())
1999 call assert_equal(3, line('w0'))
2000
2001 close!
2002endfunc
2003
Bram Moolenaar21cbe172020-10-13 19:08:24 +02002004func Test_edit_browse()
2005 " in the GUI this opens a file picker, we only test the terminal behavior
2006 CheckNotGui
2007
2008 " ":browse xxx" checks for the FileExplorer augroup and assumes editing "."
2009 " works then.
2010 augroup FileExplorer
2011 au!
2012 augroup END
2013
2014 " When the USE_FNAME_CASE is defined this used to cause a crash.
2015 browse enew
2016 bwipe!
2017
2018 browse split
2019 bwipe!
2020endfunc
2021
Bram Moolenaarcaf73dc2020-10-26 21:39:13 +01002022func Test_read_invalid()
2023 set encoding=latin1
2024 " This was not properly checking for going past the end.
2025 call assert_fails('r`=', 'E484')
2026 set encoding=utf-8
2027endfunc
2028
Yegappan Lakshmanan59585492021-06-12 13:46:41 +02002029" Test for the 'revins' option
2030func Test_edit_revins()
2031 CheckFeature rightleft
2032 new
2033 set revins
2034 exe "normal! ione\ttwo three"
2035 call assert_equal("eerht owt\teno", getline(1))
2036 call setline(1, "one\ttwo three")
2037 normal! gg$bi a
2038 call assert_equal("one\ttwo a three", getline(1))
2039 exe "normal! $bi\<BS>\<BS>"
2040 call assert_equal("one\ttwo a ree", getline(1))
2041 exe "normal! 0wi\<C-W>"
2042 call assert_equal("one\t a ree", getline(1))
2043 exe "normal! 0wi\<C-U>"
2044 call assert_equal("one\t ", getline(1))
2045 " newline in insert mode starts at the end of the line
2046 call setline(1, 'one two three')
2047 exe "normal! wi\nfour"
2048 call assert_equal(['one two three', 'ruof'], getline(1, '$'))
2049 set revins&
2050 bw!
2051endfunc
2052
Bram Moolenaar35a9a002021-09-11 21:14:20 +02002053" Test for getting the character of the line below after "p"
2054func Test_edit_put_CTRL_E()
2055 set encoding=latin1
2056 new
2057 let @" = ''
2058 sil! norm orggRx
2059 sil! norm pr
2060 call assert_equal(['r', 'r'], getline(1, 2))
2061 bwipe!
2062 set encoding=utf-8
2063endfunc
2064
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002065" Test toggling of input method. See :help i_CTRL-^
2066func Test_edit_CTRL_hat()
2067 CheckFeature xim
Dominique Pelle8753c1d2021-10-31 20:19:17 +00002068
Bram Moolenaar0b962e52022-04-03 18:02:37 +01002069 " FIXME: test fails with Motif GUI.
Dominique Pelle8753c1d2021-10-31 20:19:17 +00002070 " test also fails when running in the GUI.
2071 CheckFeature gui_gtk
2072 CheckNotGui
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002073
2074 new
2075
2076 call assert_equal(0, &iminsert)
2077 call feedkeys("i\<C-^>", 'xt')
2078 call assert_equal(2, &iminsert)
2079 call feedkeys("i\<C-^>", 'xt')
2080 call assert_equal(0, &iminsert)
2081
2082 bwipe!
2083endfunc
2084
Bram Moolenaarde05bb22022-01-13 13:08:14 +00002085" Weird long file name was going over the end of NameBuff
2086func Test_edit_overlong_file_name()
2087 CheckUnix
2088
2089 file 0000000000000000000000000000
2090 file %%%%%%%%%%%%%%%%%%%%%%%%%%
2091 file %%%%%%
2092 set readonly
Bram Moolenaar94722c52023-01-28 19:19:03 +00002093 set ls=2
Bram Moolenaarde05bb22022-01-13 13:08:14 +00002094
2095 redraw!
2096 set noreadonly ls&
2097 bwipe!
2098endfunc
2099
Christian Brabandtdfbdadc2022-05-05 20:46:47 +01002100func Test_edit_shift_bs()
2101 CheckMSWindows
2102
2103 " FIXME: this works interactively, but the test fails
2104 throw 'Skipped: Shift-Backspace Test not working correctly :('
2105
2106 " Need to run this in Win32 Terminal, do not use CheckRunVimInTerminal
2107 if !has("terminal")
2108 return
2109 endif
2110
2111 " Shift Backspace should work like Backspace in insert mode
2112 let lines =<< trim END
2113 call setline(1, ['abc'])
2114 END
Bram Moolenaar14f91762022-09-21 15:13:52 +01002115 call writefile(lines, 'Xtest_edit_shift_bs', 'D')
Christian Brabandtdfbdadc2022-05-05 20:46:47 +01002116
2117 let buf = RunVimInTerminal('-S Xtest_edit_shift_bs', #{rows: 3})
2118 call term_sendkeys(buf, "A\<S-BS>-\<esc>")
2119 call TermWait(buf, 50)
2120 call assert_equal('ab-', term_getline(buf, 1))
2121
2122 " clean up
2123 call StopVimInTerminal(buf)
Christian Brabandtdfbdadc2022-05-05 20:46:47 +01002124endfunc
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002125
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002126" vim: shiftwidth=2 sts=2 expandtab