blob: b925b23211156b6aa3f96a858281bbece9ba5dc2 [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 Moolenaareb992cb2017-03-09 18:20:16 +01009source view_util.vim
10
11" Needs to come first until the bug in getchar() is
12" fixed: https://groups.google.com/d/msg/vim_dev/fXL9yme4H4c/bOR-U6_bAQAJ
Bram Moolenaar1e115362019-01-09 23:01:02 +010013func Test_edit_00b()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010014 new
15 call setline(1, ['abc '])
16 inoreabbr <buffer> h here some more
17 call cursor(1, 4)
18 " <c-l> expands the abbreviation and ends insertmode
19 call feedkeys(":set im\<cr> h\<c-l>:set noim\<cr>", 'tix')
20 call assert_equal(['abc here some more '], getline(1,'$'))
21 iunabbr <buffer> h
22 bw!
23endfunc
24
Bram Moolenaar1e115362019-01-09 23:01:02 +010025func Test_edit_01()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010026 " set for Travis CI?
27 " set nocp noesckeys
28 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +010029 " 1) empty buffer
30 call assert_equal([''], getline(1,'$'))
31 " 2) delete in an empty line
32 call feedkeys("i\<del>\<esc>", 'tnix')
33 call assert_equal([''], getline(1,'$'))
34 %d
35 " 3) delete one character
36 call setline(1, 'a')
37 call feedkeys("i\<del>\<esc>", 'tnix')
38 call assert_equal([''], getline(1,'$'))
39 %d
40 " 4) delete a multibyte character
Bram Moolenaar30276f22019-01-24 17:59:39 +010041 call setline(1, "\u0401")
42 call feedkeys("i\<del>\<esc>", 'tnix')
43 call assert_equal([''], getline(1,'$'))
44 %d
Bram Moolenaareb992cb2017-03-09 18:20:16 +010045 " 5.1) delete linebreak with 'bs' option containing eol
46 let _bs=&bs
47 set bs=eol
48 call setline(1, ["abc def", "ghi jkl"])
49 call cursor(1, 1)
50 call feedkeys("A\<del>\<esc>", 'tnix')
51 call assert_equal(['abc defghi jkl'], getline(1, 2))
52 %d
53 " 5.2) delete linebreak with backspace option w/out eol
54 set bs=
55 call setline(1, ["abc def", "ghi jkl"])
56 call cursor(1, 1)
57 call feedkeys("A\<del>\<esc>", 'tnix')
58 call assert_equal(["abc def", "ghi jkl"], getline(1, 2))
Bram Moolenaareb992cb2017-03-09 18:20:16 +010059 let &bs=_bs
60 bw!
61endfunc
62
Bram Moolenaar1e115362019-01-09 23:01:02 +010063func Test_edit_02()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010064 " Change cursor position in InsertCharPre command
65 new
66 call setline(1, 'abc')
67 call cursor(1, 1)
68 fu! DoIt(...)
69 call cursor(1, 4)
70 if len(a:000)
71 let v:char=a:1
72 endif
73 endfu
74 au InsertCharPre <buffer> :call DoIt('y')
75 call feedkeys("ix\<esc>", 'tnix')
76 call assert_equal(['abcy'], getline(1, '$'))
77 " Setting <Enter> in InsertCharPre
78 au! InsertCharPre <buffer> :call DoIt("\n")
79 call setline(1, 'abc')
80 call cursor(1, 1)
81 call feedkeys("ix\<esc>", 'tnix')
82 call assert_equal(['abc', ''], getline(1, '$'))
83 %d
84 au! InsertCharPre
85 " Change cursor position in InsertEnter command
86 " 1) when setting v:char, keeps changed cursor position
87 au! InsertEnter <buffer> :call DoIt('y')
88 call setline(1, 'abc')
89 call cursor(1, 1)
90 call feedkeys("ix\<esc>", 'tnix')
91 call assert_equal(['abxc'], getline(1, '$'))
92 " 2) when not setting v:char, restores changed cursor position
93 au! InsertEnter <buffer> :call DoIt()
94 call setline(1, 'abc')
95 call cursor(1, 1)
96 call feedkeys("ix\<esc>", 'tnix')
97 call assert_equal(['xabc'], getline(1, '$'))
98 au! InsertEnter
99 delfu DoIt
100 bw!
101endfunc
102
Bram Moolenaar1e115362019-01-09 23:01:02 +0100103func Test_edit_03()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100104 " Change cursor after <c-o> command to end of line
105 new
106 call setline(1, 'abc')
107 call cursor(1, 1)
108 call feedkeys("i\<c-o>$y\<esc>", 'tnix')
109 call assert_equal(['abcy'], getline(1, '$'))
110 %d
111 call setline(1, 'abc')
112 call cursor(1, 1)
113 call feedkeys("i\<c-o>80|y\<esc>", 'tnix')
114 call assert_equal(['abcy'], getline(1, '$'))
115 %d
116 call setline(1, 'abc')
117 call feedkeys("Ad\<c-o>:s/$/efg/\<cr>hij", 'tnix')
118 call assert_equal(['hijabcdefg'], getline(1, '$'))
119 bw!
120endfunc
121
Bram Moolenaar1e115362019-01-09 23:01:02 +0100122func Test_edit_04()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100123 " test for :stopinsert
124 new
125 call setline(1, 'abc')
126 call cursor(1, 1)
127 call feedkeys("i\<c-o>:stopinsert\<cr>$", 'tnix')
128 call feedkeys("aX\<esc>", 'tnix')
129 call assert_equal(['abcX'], getline(1, '$'))
130 %d
131 bw!
132endfunc
133
Bram Moolenaar1e115362019-01-09 23:01:02 +0100134func Test_edit_05()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100135 " test for folds being opened
136 new
137 call setline(1, ['abcX', 'abcX', 'zzzZ'])
138 call cursor(1, 1)
139 set foldmethod=manual foldopen+=insert
140 " create fold for those two lines
141 norm! Vjzf
142 call feedkeys("$ay\<esc>", 'tnix')
143 call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
144 %d
145 call setline(1, ['abcX', 'abcX', 'zzzZ'])
146 call cursor(1, 1)
147 set foldmethod=manual foldopen-=insert
148 " create fold for those two lines
149 norm! Vjzf
150 call feedkeys("$ay\<esc>", 'tnix')
151 call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
152 %d
153 bw!
154endfunc
155
Bram Moolenaar1e115362019-01-09 23:01:02 +0100156func Test_edit_06()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100157 " Test in diff mode
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200158 CheckFeature diff
159 CheckExecutable diff
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100160 new
161 call setline(1, ['abc', 'xxx', 'yyy'])
162 vnew
163 call setline(1, ['abc', 'zzz', 'xxx', 'yyy'])
164 wincmd p
165 diffthis
166 wincmd p
167 diffthis
168 wincmd p
169 call cursor(2, 1)
170 norm! zt
171 call feedkeys("Ozzz\<esc>", 'tnix')
172 call assert_equal(['abc', 'zzz', 'xxx', 'yyy'], getline(1,'$'))
173 bw!
174 bw!
175endfunc
176
Bram Moolenaar1e115362019-01-09 23:01:02 +0100177func Test_edit_07()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100178 " 1) Test with completion <c-l> when popupmenu is visible
179 new
180 call setline(1, 'J')
181
182 func! ListMonths()
183 call complete(col('.')-1, ['January', 'February', 'March',
184 \ 'April', 'May', 'June', 'July', 'August', 'September',
185 \ 'October', 'November', 'December'])
186 return ''
187 endfunc
188 inoremap <buffer> <F5> <C-R>=ListMonths()<CR>
189
190 call feedkeys("A\<f5>\<c-p>". repeat("\<down>", 6)."\<c-l>\<down>\<c-l>\<cr>", 'tx')
191 call assert_equal(['July'], getline(1,'$'))
192 " 1) Test completion when InsertCharPre kicks in
193 %d
194 call setline(1, 'J')
195 fu! DoIt()
196 if v:char=='u'
197 let v:char='an'
198 endif
199 endfu
200 au InsertCharPre <buffer> :call DoIt()
glepnir07f0dbe2025-02-18 20:27:30 +0100201 call feedkeys("A\<f5>\<c-p>u\<C-Y>\<c-l>\<cr>", 'tx')
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200202 call assert_equal(["Jan\<c-l>",''], 1->getline('$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100203 %d
204 call setline(1, 'J')
205 call feedkeys("A\<f5>\<c-p>u\<down>\<c-l>\<cr>", 'tx')
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200206 call assert_equal(["January"], 1->getline('$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100207
208 delfu ListMonths
209 delfu DoIt
210 iunmap <buffer> <f5>
211 bw!
212endfunc
213
Bram Moolenaar1e115362019-01-09 23:01:02 +0100214func Test_edit_08()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100215 " reset insertmode from i_ctrl-r_=
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200216 let g:bufnr = bufnr('%')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100217 new
218 call setline(1, ['abc'])
219 call cursor(1, 4)
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200220 call feedkeys(":set im\<cr>ZZZ\<c-r>=setbufvar(g:bufnr,'&im', 0)\<cr>",'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100221 call assert_equal(['abZZZc'], getline(1,'$'))
222 call assert_equal([0, 1, 1, 0], getpos('.'))
223 call assert_false(0, '&im')
224 bw!
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200225 unlet g:bufnr
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100226endfunc
227
Bram Moolenaar1e115362019-01-09 23:01:02 +0100228func Test_edit_09()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100229 " test i_CTRL-\ combinations
230 new
231 call setline(1, ['abc', 'def', 'ghi'])
232 call cursor(1, 1)
233 " 1) CTRL-\ CTLR-N
234 call feedkeys(":set im\<cr>\<c-\>\<c-n>ccABC\<c-l>", 'txin')
235 call assert_equal(['ABC', 'def', 'ghi'], getline(1,'$'))
236 call setline(1, ['ABC', 'def', 'ghi'])
237 " 2) CTRL-\ CTLR-G
238 call feedkeys("j0\<c-\>\<c-g>ZZZ\<cr>\<c-l>", 'txin')
239 call assert_equal(['ABC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
240 call feedkeys("I\<c-\>\<c-g>YYY\<c-l>", 'txin')
241 call assert_equal(['ABC', 'ZZZ', 'YYYdef', 'ghi'], getline(1,'$'))
242 set noinsertmode
243 " 3) CTRL-\ CTRL-O
244 call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
245 call cursor(1, 1)
246 call feedkeys("A\<c-o>ix", 'txin')
247 call assert_equal(['ABxC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
248 call feedkeys("A\<c-\>\<c-o>ix", 'txin')
249 call assert_equal(['ABxCx', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
250 " 4) CTRL-\ a (should be inserted literally, not special after <c-\>
251 call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
252 call cursor(1, 1)
253 call feedkeys("A\<c-\>a", 'txin')
254 call assert_equal(["ABC\<c-\>a", 'ZZZ', 'def', 'ghi'], getline(1, '$'))
255 bw!
256endfunc
257
Bram Moolenaar1e115362019-01-09 23:01:02 +0100258func Test_edit_11()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100259 " Test that indenting kicks in
260 new
261 set cindent
262 call setline(1, ['{', '', ''])
263 call cursor(2, 1)
264 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
265 call cursor(3, 1)
Bram Moolenaar1671f442020-03-10 07:48:13 +0100266 call feedkeys("\<Insert>/* comment */", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100267 call assert_equal(['{', "\<tab>int c;", "/* comment */"], getline(1, '$'))
268 " added changed cindentkeys slightly
269 set cindent cinkeys+=*/
270 call setline(1, ['{', '', ''])
271 call cursor(2, 1)
272 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
273 call cursor(3, 1)
274 call feedkeys("i/* comment */", 'tnix')
275 call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */"], getline(1, '$'))
276 set cindent cinkeys+==end
277 call feedkeys("oend\<cr>\<esc>", 'tnix')
278 call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */", "\tend", ''], getline(1, '$'))
279 set cinkeys-==end
280 %d
281 " Use indentexpr instead of cindenting
282 func! Do_Indent()
283 if v:lnum == 3
284 return 3*shiftwidth()
285 else
286 return 2*shiftwidth()
287 endif
288 endfunc
289 setl indentexpr=Do_Indent() indentkeys+=*/
290 call setline(1, ['{', '', ''])
291 call cursor(2, 1)
292 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
293 call cursor(3, 1)
294 call feedkeys("i/* comment */", 'tnix')
295 call assert_equal(['{', "\<tab>\<tab>int c;", "\<tab>\<tab>\<tab>/* comment */"], getline(1, '$'))
296 set cinkeys&vim indentkeys&vim
297 set nocindent indentexpr=
298 delfu Do_Indent
299 bw!
300endfunc
301
Bram Moolenaar1e115362019-01-09 23:01:02 +0100302func Test_edit_11_indentexpr()
Bram Moolenaar1b383442017-09-26 20:04:54 +0200303 " Test that indenting kicks in
304 new
305 " Use indentexpr instead of cindenting
306 func! Do_Indent()
307 let pline=prevnonblank(v:lnum)
308 if empty(getline(v:lnum))
309 if getline(pline) =~ 'if\|then'
310 return shiftwidth()
311 else
312 return 0
313 endif
314 else
315 return 0
316 endif
317 endfunc
318 setl indentexpr=Do_Indent() indentkeys+=0=then,0=fi
319 call setline(1, ['if [ $this ]'])
320 call cursor(1, 1)
321 call feedkeys("othen\<cr>that\<cr>fi", 'tnix')
322 call assert_equal(['if [ $this ]', "then", "\<tab>that", "fi"], getline(1, '$'))
323 set cinkeys&vim indentkeys&vim
324 set nocindent indentexpr=
325 delfu Do_Indent
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000326
327 " Using a script-local function
328 func s:NewIndentExpr()
329 endfunc
330 set indentexpr=s:NewIndentExpr()
331 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000332 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000333 set indentexpr=<SID>NewIndentExpr()
334 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000335 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
336 setlocal indentexpr=
337 setglobal indentexpr=s:NewIndentExpr()
338 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
339 call assert_equal('', &indentexpr)
340 new
341 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
342 bw!
343 setglobal indentexpr=<SID>NewIndentExpr()
344 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
345 call assert_equal('', &indentexpr)
346 new
347 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
348 bw!
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000349 set indentexpr&
350
Bram Moolenaar1b383442017-09-26 20:04:54 +0200351 bw!
352endfunc
353
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200354" Test changing indent in replace mode
Bram Moolenaar1e115362019-01-09 23:01:02 +0100355func Test_edit_12()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100356 new
357 call setline(1, ["\tabc", "\tdef"])
358 call cursor(2, 4)
359 call feedkeys("R^\<c-d>", 'tnix')
360 call assert_equal(["\tabc", "def"], getline(1, '$'))
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200361 call assert_equal([0, 2, 2, 0], '.'->getpos())
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100362 %d
363 call setline(1, ["\tabc", "\t\tdef"])
364 call cursor(2, 2)
365 call feedkeys("R^\<c-d>", 'tnix')
366 call assert_equal(["\tabc", "def"], getline(1, '$'))
367 call assert_equal([0, 2, 1, 0], getpos('.'))
368 %d
369 call setline(1, ["\tabc", "\t\tdef"])
370 call cursor(2, 2)
371 call feedkeys("R\<c-t>", 'tnix')
372 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
373 call assert_equal([0, 2, 2, 0], getpos('.'))
374 bw!
375 10vnew
376 call setline(1, ["\tabc", "\t\tdef"])
377 call cursor(2, 2)
378 call feedkeys("R\<c-t>", 'tnix')
379 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
380 call assert_equal([0, 2, 2, 0], getpos('.'))
381 %d
382 set sw=4
383 call setline(1, ["\tabc", "\t\tdef"])
384 call cursor(2, 2)
385 call feedkeys("R\<c-t>\<c-t>", 'tnix')
386 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
387 call assert_equal([0, 2, 2, 0], getpos('.'))
388 %d
389 call setline(1, ["\tabc", "\t\tdef"])
390 call cursor(2, 2)
391 call feedkeys("R\<c-t>\<c-t>", 'tnix')
392 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
393 call assert_equal([0, 2, 2, 0], getpos('.'))
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200394 set sw&
395
396 " In replace mode, after hitting enter in a line with tab characters,
397 " pressing backspace should restore the tab characters.
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100398 %d
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200399 setlocal autoindent backspace=2
400 call setline(1, "\tone\t\ttwo")
401 exe "normal ggRred\<CR>six" .. repeat("\<BS>", 8)
402 call assert_equal(["\tone\t\ttwo"], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100403 bw!
404endfunc
405
Bram Moolenaar1e115362019-01-09 23:01:02 +0100406func Test_edit_13()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100407 " Test smartindenting
Bram Moolenaar8e145b82022-05-21 20:17:31 +0100408 new
409 set smartindent autoindent
410 call setline(1, ["\tabc"])
411 call feedkeys("A {\<cr>more\<cr>}\<esc>", 'tnix')
412 call assert_equal(["\tabc {", "\t\tmore", "\t}"], getline(1, '$'))
413 set smartindent& autoindent&
414 bwipe!
Bram Moolenaar2ba42382019-03-16 18:11:07 +0100415
416 " Test autoindent removing indent of blank line.
417 new
418 call setline(1, ' foo bar baz')
419 set autoindent
420 exe "normal 0eea\<CR>\<CR>\<Esc>"
421 call assert_equal(" foo bar", getline(1))
422 call assert_equal("", getline(2))
423 call assert_equal(" baz", getline(3))
424 set autoindent&
Bram Moolenaar845e0ee2020-06-20 16:05:32 +0200425
426 " pressing <C-U> to erase line should keep the indent with 'autoindent'
427 set backspace=2 autoindent
428 %d
429 exe "normal i\tone\<CR>three\<C-U>two"
430 call assert_equal(["\tone", "\ttwo"], getline(1, '$'))
431 set backspace& autoindent&
432
Bram Moolenaar2ba42382019-03-16 18:11:07 +0100433 bwipe!
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100434endfunc
435
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100436" Test for autoindent removing indent when insert mode is stopped. Some parts
437" of the code is exercised only when interactive mode is used. So use Vim in a
438" terminal.
439func Test_autoindent_remove_indent()
440 CheckRunVimInTerminal
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100441 let buf = RunVimInTerminal('-N Xarifile', {'rows': 6, 'cols' : 20})
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100442 call TermWait(buf)
443 call term_sendkeys(buf, ":set autoindent\n")
444 " leaving insert mode in a new line with indent added by autoindent, should
445 " remove the indent.
446 call term_sendkeys(buf, "i\<Tab>foo\<CR>\<Esc>")
Dominique Pelle923dce22021-11-21 11:36:04 +0000447 " Need to delay for some time, otherwise the code in getchar.c will not be
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100448 " exercised.
449 call TermWait(buf, 50)
450 " when a line is wrapped and the cursor is at the start of the second line,
451 " leaving insert mode, should move the cursor back to the first line.
452 call term_sendkeys(buf, "o" .. repeat('x', 20) .. "\<Esc>")
Dominique Pelle923dce22021-11-21 11:36:04 +0000453 " Need to delay for some time, otherwise the code in getchar.c will not be
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100454 " exercised.
455 call TermWait(buf, 50)
456 call term_sendkeys(buf, ":w\n")
457 call TermWait(buf)
458 call StopVimInTerminal(buf)
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100459 call assert_equal(["\tfoo", '', repeat('x', 20)], readfile('Xarifile'))
460 call delete('Xarifile')
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100461endfunc
462
zeertzjqa3a7d102025-03-18 20:41:24 +0100463func Test_edit_esc_after_CR_autoindent()
464 new
465 setlocal autoindent
466 autocmd InsertLeavePre * let g:prev_cursor = getpos('.')
467
468 call setline(1, 'foobar')
469 exe "normal! $hi\<CR>\<Esc>"
470 call assert_equal(['foob', 'ar'], getline(1, '$'))
471 call assert_equal([0, 2, 1, 0], getpos('.'))
472 call assert_equal([0, 2, 1, 0], getpos("'^"))
473 call assert_equal([0, 2, 1, 0], g:prev_cursor)
474 %d
475
476 call setline(1, 'foobar')
477 exe "normal! $i\<CR>\<Esc>"
478 call assert_equal(['fooba', 'r'], getline(1, '$'))
479 call assert_equal([0, 2, 1, 0], getpos('.'))
480 call assert_equal([0, 2, 1, 0], getpos("'^"))
481 call assert_equal([0, 2, 1, 0], g:prev_cursor)
482 %d
483
484 call setline(1, 'foobar')
485 exe "normal! A\<CR>\<Esc>"
486 call assert_equal(['foobar', ''], getline(1, '$'))
487 call assert_equal([0, 2, 1, 0], getpos('.'))
488 call assert_equal([0, 2, 1, 0], getpos("'^"))
489 call assert_equal([0, 2, 1, 0], g:prev_cursor)
490 %d
491
492 call setline(1, ' foobar')
493 exe "normal! $hi\<CR>\<Esc>"
494 call assert_equal([' foob', ' ar'], getline(1, '$'))
495 call assert_equal([0, 2, 2, 0], getpos('.'))
496 call assert_equal([0, 2, 3, 0], getpos("'^"))
497 call assert_equal([0, 2, 3, 0], g:prev_cursor)
498 %d
499
500 call setline(1, ' foobar')
501 exe "normal! $i\<CR>\<Esc>"
502 call assert_equal([' fooba', ' r'], getline(1, '$'))
503 call assert_equal([0, 2, 2, 0], getpos('.'))
504 call assert_equal([0, 2, 3, 0], getpos("'^"))
505 call assert_equal([0, 2, 3, 0], g:prev_cursor)
506 %d
507
508 call setline(1, ' foobar')
509 exe "normal! A\<CR>\<Esc>"
510 call assert_equal([' foobar', ''], getline(1, '$'))
511 call assert_equal([0, 2, 1, 0], getpos('.'))
512 call assert_equal([0, 2, 1, 0], getpos("'^"))
513 call assert_equal([0, 2, 1, 0], g:prev_cursor)
514 %d
515
516 autocmd! InsertLeavePre
517 unlet g:prev_cursor
518 bwipe!
519endfunc
520
Bram Moolenaar1e115362019-01-09 23:01:02 +0100521func Test_edit_CR()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100522 " Test for <CR> in insert mode
Dominique Pelle923dce22021-11-21 11:36:04 +0000523 " basically only in quickfix mode it's tested, the rest
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100524 " has been taken care of by other tests
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200525 CheckFeature quickfix
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100526 botright new
Bram Moolenaar14f91762022-09-21 15:13:52 +0100527 call writefile(range(1, 10), 'Xqflist.txt', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100528 call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}])
529 copen
530 set modifiable
531 call feedkeys("A\<cr>", 'tnix')
532 call assert_equal('Xqflist.txt', bufname(''))
533 call assert_equal(2, line('.'))
534 cclose
535 botright new
536 call setloclist(0, [{'filename': 'Xqflist.txt', 'lnum': 10}])
537 lopen
538 set modifiable
539 call feedkeys("A\<cr>", 'tnix')
540 call assert_equal('Xqflist.txt', bufname(''))
541 call assert_equal(10, line('.'))
542 call feedkeys("A\<Enter>", 'tnix')
543 call feedkeys("A\<kEnter>", 'tnix')
544 call feedkeys("A\n", 'tnix')
545 call feedkeys("A\r", 'tnix')
546 call assert_equal(map(range(1, 10), 'string(v:val)') + ['', '', '', ''], getline(1, '$'))
Bram Moolenaar14f91762022-09-21 15:13:52 +0100547
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100548 bw!
549 lclose
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100550endfunc
551
Bram Moolenaar1e115362019-01-09 23:01:02 +0100552func Test_edit_CTRL_()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200553 CheckFeature rightleft
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100554 " disabled for Windows builds, why?
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200555 CheckNotMSWindows
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100556 let _encoding=&encoding
557 set encoding=utf-8
558 " Test for CTRL-_
559 new
560 call setline(1, ['abc'])
561 call cursor(1, 1)
562 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
563 call assert_equal(["\<C-_>xyzabc"], getline(1, '$'))
564 call assert_false(&revins)
565 set ari
566 call setline(1, ['abc'])
567 call cursor(1, 1)
568 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
569 call assert_equal(["æèñabc"], getline(1, '$'))
570 call assert_true(&revins)
571 call setline(1, ['abc'])
572 call cursor(1, 1)
573 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
574 call assert_equal(["xyzabc"], getline(1, '$'))
575 call assert_false(&revins)
576 set noari
577 let &encoding=_encoding
578 bw!
579endfunc
580
581" needs to come first, to have the @. register empty
Bram Moolenaar1e115362019-01-09 23:01:02 +0100582func Test_edit_00a_CTRL_A()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100583 " Test pressing CTRL-A
584 new
585 call setline(1, repeat([''], 5))
586 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100587 try
588 call feedkeys("A\<NUL>", 'tnix')
589 catch /^Vim\%((\a\+)\)\=:E29/
590 call assert_true(1, 'E29 error caught')
591 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100592 call cursor(1, 1)
593 call feedkeys("Afoobar \<esc>", 'tnix')
594 call cursor(2, 1)
595 call feedkeys("A\<c-a>more\<esc>", 'tnix')
596 call cursor(3, 1)
597 call feedkeys("A\<NUL>and more\<esc>", 'tnix')
598 call assert_equal(['foobar ', 'foobar more', 'foobar morend more', '', ''], getline(1, '$'))
599 bw!
600endfunc
601
Bram Moolenaar1e115362019-01-09 23:01:02 +0100602func Test_edit_CTRL_EY()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100603 " Ctrl-E/ Ctrl-Y in insert mode completion to scroll
604 10new
605 call setline(1, range(1, 100))
606 call cursor(30, 1)
607 norm! z.
608 call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
609 call assert_equal(30, winsaveview()['topline'])
610 call assert_equal([0, 30, 2, 0], getpos('.'))
611 call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
612 call feedkeys("A\<c-x>".repeat("\<c-y>", 10), 'tnix')
613 call assert_equal(21, winsaveview()['topline'])
614 call assert_equal([0, 30, 2, 0], getpos('.'))
615 bw!
616endfunc
617
Bram Moolenaar1e115362019-01-09 23:01:02 +0100618func Test_edit_CTRL_G()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100619 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100620 call setline(1, ['foobar', 'foobar', 'foobar'])
621 call cursor(2, 4)
622 call feedkeys("ioooooooo\<c-g>k\<c-r>.\<esc>", 'tnix')
623 call assert_equal(['foooooooooobar', 'foooooooooobar', 'foobar'], getline(1, '$'))
624 call assert_equal([0, 1, 11, 0], getpos('.'))
625 call feedkeys("i\<c-g>k\<esc>", 'tnix')
626 call assert_equal([0, 1, 10, 0], getpos('.'))
627 call cursor(2, 4)
628 call feedkeys("i\<c-g>jzzzz\<esc>", 'tnix')
629 call assert_equal(['foooooooooobar', 'foooooooooobar', 'foozzzzbar'], getline(1, '$'))
630 call assert_equal([0, 3, 7, 0], getpos('.'))
631 call feedkeys("i\<c-g>j\<esc>", 'tnix')
632 call assert_equal([0, 3, 6, 0], getpos('.'))
zeertzjq4f026ea2023-02-26 14:47:24 +0000633 call assert_nobeep("normal! i\<c-g>\<esc>")
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100634 bw!
635endfunc
636
Bram Moolenaar1e115362019-01-09 23:01:02 +0100637func Test_edit_CTRL_I()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100638 " Tab in completion mode
639 let path=expand("%:p:h")
640 new
Bram Moolenaarca851592018-06-06 21:04:07 +0200641 call setline(1, [path. "/", ''])
Bram Moolenaarc5379472017-03-16 22:38:00 +0100642 call feedkeys("Arunt\<c-x>\<c-f>\<tab>\<cr>\<esc>", 'tnix')
643 call assert_match('runtest\.vim', getline(1))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100644 %d
Bram Moolenaar14f91762022-09-21 15:13:52 +0100645 call writefile(['one', 'two', 'three'], 'Xinclude.txt', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100646 let include='#include Xinclude.txt'
647 call setline(1, [include, ''])
648 call cursor(2, 1)
649 call feedkeys("A\<c-x>\<tab>\<cr>\<esc>", 'tnix')
650 call assert_equal([include, 'one', ''], getline(1, '$'))
651 call feedkeys("2ggC\<c-x>\<tab>\<down>\<cr>\<esc>", 'tnix')
652 call assert_equal([include, 'two', ''], getline(1, '$'))
653 call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<cr>\<esc>", 'tnix')
654 call assert_equal([include, 'three', ''], getline(1, '$'))
glepnir44180412025-02-20 22:09:48 +0100655 call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100656 call assert_equal([include, '', ''], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100657 bw!
658endfunc
659
Bram Moolenaar1e115362019-01-09 23:01:02 +0100660func Test_edit_CTRL_K()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100661 " Test pressing CTRL-K (basically only dictionary completion and digraphs
662 " the rest is already covered
Bram Moolenaar14f91762022-09-21 15:13:52 +0100663 call writefile(['A', 'AA', 'AAA', 'AAAA'], 'Xdictionary.txt', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100664 set dictionary=Xdictionary.txt
665 new
666 call setline(1, 'A')
667 call cursor(1, 1)
668 call feedkeys("A\<c-x>\<c-k>\<cr>\<esc>", 'tnix')
669 call assert_equal(['AA', ''], getline(1, '$'))
670 %d
671 call setline(1, 'A')
672 call cursor(1, 1)
673 call feedkeys("A\<c-x>\<c-k>\<down>\<cr>\<esc>", 'tnix')
674 call assert_equal(['AAA'], getline(1, '$'))
675 %d
676 call setline(1, 'A')
677 call cursor(1, 1)
678 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<cr>\<esc>", 'tnix')
679 call assert_equal(['AAAA'], getline(1, '$'))
680 %d
681 call setline(1, 'A')
682 call cursor(1, 1)
glepnir44180412025-02-20 22:09:48 +0100683 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100684 call assert_equal(['A'], getline(1, '$'))
685 %d
686 call setline(1, 'A')
687 call cursor(1, 1)
688 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
689 call assert_equal(['AA'], getline(1, '$'))
690
Bram Moolenaar4b96df52020-01-26 22:00:26 +0100691 " press an unexpected key after dictionary completion
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100692 %d
693 call setline(1, 'A')
694 call cursor(1, 1)
695 call feedkeys("A\<c-x>\<c-k>\<c-]>\<cr>\<esc>", 'tnix')
696 call assert_equal(['AA', ''], getline(1, '$'))
697 %d
698 call setline(1, 'A')
699 call cursor(1, 1)
700 call feedkeys("A\<c-x>\<c-k>\<c-s>\<cr>\<esc>", 'tnix')
701 call assert_equal(["AA\<c-s>", ''], getline(1, '$'))
702 %d
703 call setline(1, 'A')
704 call cursor(1, 1)
705 call feedkeys("A\<c-x>\<c-k>\<c-f>\<cr>\<esc>", 'tnix')
706 call assert_equal(["AA\<c-f>", ''], getline(1, '$'))
707
708 set dictionary=
709 %d
710 call setline(1, 'A')
711 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100712 let v:testing = 1
713 try
714 call feedkeys("A\<c-x>\<c-k>\<esc>", 'tnix')
715 catch
716 " error sleeps 2 seconds, when v:testing is not set
717 let v:testing = 0
718 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100719
Bram Moolenaar30276f22019-01-24 17:59:39 +0100720 call test_override("char_avail", 1)
721 set showcmd
722 %d
723 call feedkeys("A\<c-k>a:\<esc>", 'tnix')
724 call assert_equal(['ä'], getline(1, '$'))
725 call test_override("char_avail", 0)
726 set noshowcmd
727
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100728 bw!
729endfunc
730
Bram Moolenaar1e115362019-01-09 23:01:02 +0100731func Test_edit_CTRL_L()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100732 " Test Ctrl-X Ctrl-L (line completion)
733 new
734 set complete=.
735 call setline(1, ['one', 'two', 'three', '', '', '', ''])
736 call cursor(4, 1)
737 call feedkeys("A\<c-x>\<c-l>\<esc>", 'tnix')
738 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
739 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<esc>", 'tnix')
740 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
741 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100742 call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
Bram Moolenaar02ae9b42018-02-09 15:06:02 +0100743 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100744 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
Bram Moolenaar02ae9b42018-02-09 15:06:02 +0100745 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
746 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100747 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<esc>", 'tnix')
748 call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
749 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<esc>", 'tnix')
750 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
751 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<c-p>\<esc>", 'tnix')
752 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
753 set complete=
754 call cursor(5, 1)
755 call feedkeys("A\<c-x>\<c-l>\<c-p>\<c-n>\<esc>", 'tnix')
756 call assert_equal(['one', 'two', 'three', 'three', "\<c-l>\<c-p>\<c-n>", '', ''], getline(1, '$'))
757 set complete&
758 %d
759 if has("conceal") && has("syntax")
760 call setline(1, ['foo', 'bar', 'foobar'])
761 call test_override("char_avail", 1)
762 set conceallevel=2 concealcursor=n
763 syn on
764 syn match ErrorMsg "^bar"
765 call matchadd("Conceal", 'oo', 10, -1, {'conceal': 'X'})
766 func! DoIt()
767 let g:change=1
768 endfunc
769 au! TextChangedI <buffer> :call DoIt()
770
771 call cursor(2, 1)
772 call assert_false(exists("g:change"))
773 call feedkeys("A \<esc>", 'tnix')
774 call assert_equal(['foo', 'bar ', 'foobar'], getline(1, '$'))
775 call assert_equal(1, g:change)
776
777 call test_override("char_avail", 0)
778 call clearmatches()
779 syn off
780 au! TextChangedI
781 delfu DoIt
782 unlet! g:change
783 endif
784 bw!
785endfunc
786
Bram Moolenaar1e115362019-01-09 23:01:02 +0100787func Test_edit_CTRL_N()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100788 " Check keyword completion
Bram Moolenaara1070ea2021-02-20 19:21:36 +0100789 for e in ['latin1', 'utf-8']
790 exe 'set encoding=' .. e
791 new
792 set complete=.
793 call setline(1, ['INFER', 'loWER', '', '', ])
794 call cursor(3, 1)
795 call feedkeys("Ai\<c-n>\<cr>\<esc>", "tnix")
796 call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
797 call assert_equal(['INFER', 'loWER', 'i', 'LO', '', ''], getline(1, '$'), e)
798 %d
799 call setline(1, ['INFER', 'loWER', '', '', ])
800 call cursor(3, 1)
801 set ignorecase infercase
802 call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix")
803 call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
804 call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'), e)
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000805 set noignorecase noinfercase
806 %d
807 call setline(1, ['one word', 'two word'])
808 exe "normal! Goo\<C-P>\<C-X>\<C-P>"
809 call assert_equal('one word', getline(3))
810 %d
811 set complete&
Bram Moolenaara1070ea2021-02-20 19:21:36 +0100812 bw!
813 endfor
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100814endfunc
815
Bram Moolenaar1e115362019-01-09 23:01:02 +0100816func Test_edit_CTRL_O()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100817 " Check for CTRL-O in insert mode
818 new
819 inoreabbr <buffer> h here some more
820 call setline(1, ['abc', 'def'])
821 call cursor(1, 1)
822 " Ctrl-O after an abbreviation
823 exe "norm A h\<c-o>:set nu\<cr> text"
824 call assert_equal(['abc here some more text', 'def'], getline(1, '$'))
825 call assert_true(&nu)
826 set nonu
827 iunabbr <buffer> h
828 " Ctrl-O at end of line with 've'=onemore
829 call cursor(1, 1)
830 call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
831 call assert_equal([0, 1, 23, 0], g:a)
832 call cursor(1, 1)
833 set ve=onemore
834 call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
835 call assert_equal([0, 1, 24, 0], g:a)
836 set ve=
837 unlet! g:a
838 bw!
839endfunc
840
Bram Moolenaar1e115362019-01-09 23:01:02 +0100841func Test_edit_CTRL_R()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100842 " Insert Register
843 new
844 call test_override("ALL", 1)
845 set showcmd
846 call feedkeys("AFOOBAR eins zwei\<esc>", 'tnix')
847 call feedkeys("O\<c-r>.", 'tnix')
848 call feedkeys("O\<c-r>=10*500\<cr>\<esc>", 'tnix')
849 call feedkeys("O\<c-r>=getreg('=', 1)\<cr>\<esc>", 'tnix')
850 call assert_equal(["getreg('=', 1)", '5000', "FOOBAR eins zwei", "FOOBAR eins zwei"], getline(1, '$'))
851 call test_override("ALL", 0)
852 set noshowcmd
853 bw!
854endfunc
855
Bram Moolenaar1e115362019-01-09 23:01:02 +0100856func Test_edit_CTRL_S()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100857 " Test pressing CTRL-S (basically only spellfile completion)
858 " the rest is already covered
859 new
860 if !has("spell")
861 call setline(1, 'vim')
862 call feedkeys("A\<c-x>ss\<cr>\<esc>", 'tnix')
863 call assert_equal(['vims', ''], getline(1, '$'))
864 bw!
865 return
866 endif
867 call setline(1, 'vim')
868 " spell option not yet set
869 try
870 call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
871 catch /^Vim\%((\a\+)\)\=:E756/
872 call assert_true(1, 'error caught')
873 endtry
874 call assert_equal(['vim', ''], getline(1, '$'))
875 %d
876 setl spell spelllang=en
877 call setline(1, 'vim')
878 call cursor(1, 1)
879 call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
880 call assert_equal(['Vim', ''], getline(1, '$'))
881 %d
882 call setline(1, 'vim')
883 call cursor(1, 1)
884 call feedkeys("A\<c-x>\<c-s>\<down>\<cr>\<esc>", 'tnix')
885 call assert_equal(['Aim'], getline(1, '$'))
886 %d
887 call setline(1, 'vim')
888 call cursor(1, 1)
889 call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
890 call assert_equal(['vim', ''], getline(1, '$'))
891 %d
892 " empty buffer
893 call cursor(1, 1)
894 call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
895 call assert_equal(['', ''], getline(1, '$'))
896 setl nospell
897 bw!
898endfunc
899
Bram Moolenaar1e115362019-01-09 23:01:02 +0100900func Test_edit_CTRL_T()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100901 " Check for CTRL-T and CTRL-X CTRL-T in insert mode
902 " 1) increase indent
903 new
904 call setline(1, "abc")
905 call cursor(1, 1)
906 call feedkeys("A\<c-t>xyz", 'tnix')
907 call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
908 " 2) also when paste option is set
909 set paste
910 call setline(1, "abc")
911 call cursor(1, 1)
912 call feedkeys("A\<c-t>xyz", 'tnix')
913 call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
914 set nopaste
915 " CTRL-X CTRL-T (thesaurus complete)
Bram Moolenaar14f91762022-09-21 15:13:52 +0100916 call writefile(['angry furious mad enraged'], 'Xthesaurus', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100917 set thesaurus=Xthesaurus
918 call setline(1, 'mad')
919 call cursor(1, 1)
920 call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
921 call assert_equal(['mad', ''], getline(1, '$'))
922 %d
923 call setline(1, 'mad')
924 call cursor(1, 1)
925 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
926 call assert_equal(['angry', ''], getline(1, '$'))
927 %d
928 call setline(1, 'mad')
929 call cursor(1, 1)
930 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
931 call assert_equal(['furious', ''], getline(1, '$'))
932 %d
933 call setline(1, 'mad')
934 call cursor(1, 1)
935 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
936 call assert_equal(['enraged', ''], getline(1, '$'))
937 %d
938 call setline(1, 'mad')
939 call cursor(1, 1)
940 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
941 call assert_equal(['mad', ''], getline(1, '$'))
942 %d
943 call setline(1, 'mad')
944 call cursor(1, 1)
945 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
946 call assert_equal(['mad', ''], getline(1, '$'))
947 " Using <c-p> <c-n> when 'complete' is empty
948 set complete=
949 %d
950 call setline(1, 'mad')
951 call cursor(1, 1)
952 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
953 call assert_equal(['angry', ''], getline(1, '$'))
954 %d
955 call setline(1, 'mad')
956 call cursor(1, 1)
957 call feedkeys("A\<c-x>\<c-t>\<c-p>\<cr>\<esc>", 'tnix')
958 call assert_equal(['mad', ''], getline(1, '$'))
959 set complete&
960
961 set thesaurus=
962 %d
963 call setline(1, 'mad')
964 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100965 let v:testing = 1
966 try
967 call feedkeys("A\<c-x>\<c-t>\<esc>", 'tnix')
968 catch
969 " error sleeps 2 seconds, when v:testing is not set
970 let v:testing = 0
971 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100972 call assert_equal(['mad'], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100973 bw!
974endfunc
975
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000976" Test thesaurus completion with different encodings
977func Test_thesaurus_complete_with_encoding()
Bram Moolenaar14f91762022-09-21 15:13:52 +0100978 call writefile(['angry furious mad enraged'], 'Xthesaurus', 'D')
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000979 set thesaurus=Xthesaurus
980 for e in ['latin1', 'utf-8']
981 exe 'set encoding=' .. e
982 new
983 call setline(1, 'mad')
984 call cursor(1, 1)
985 call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
986 call assert_equal(['mad', ''], getline(1, '$'))
987 bw!
988 endfor
989 set thesaurus=
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000990endfunc
991
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100992" Test 'thesaurusfunc'
993func MyThesaurus(findstart, base)
994 let mythesaurus = [
995 \ #{word: "happy",
996 \ synonyms: "cheerful,blissful,flying high,looking good,peppy"},
997 \ #{word: "kind",
998 \ synonyms: "amiable,bleeding-heart,heart in right place"}]
999 if a:findstart
1000 " locate the start of the word
1001 let line = getline('.')
1002 let start = col('.') - 1
1003 while start > 0 && line[start - 1] =~ '\a'
1004 let start -= 1
1005 endwhile
1006 return start
1007 else
1008 " find strings matching with "a:base"
1009 let res = []
1010 for w in mythesaurus
1011 if w.word =~ '^' . a:base
1012 call add(res, w.word)
1013 call extend(res, split(w.synonyms, ","))
1014 endif
1015 endfor
1016 return res
1017 endif
1018endfunc
1019
1020func Test_thesaurus_func()
1021 new
Bram Moolenaarf4d8b762021-10-17 14:13:09 +01001022 set thesaurus=notused
1023 set thesaurusfunc=NotUsed
1024 setlocal thesaurusfunc=MyThesaurus
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +01001025 call setline(1, "an ki")
1026 call cursor(1, 1)
1027 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
1028 call assert_equal(['an amiable', ''], getline(1, '$'))
Bram Moolenaarf4d8b762021-10-17 14:13:09 +01001029
1030 setlocal thesaurusfunc=NonExistingFunc
1031 call assert_fails("normal $a\<C-X>\<C-T>", 'E117:')
1032
1033 setlocal thesaurusfunc=
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +01001034 set thesaurusfunc=NonExistingFunc
1035 call assert_fails("normal $a\<C-X>\<C-T>", 'E117:')
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +01001036 %bw!
Bram Moolenaarf4d8b762021-10-17 14:13:09 +01001037
1038 set thesaurusfunc=
1039 set thesaurus=
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +01001040endfunc
1041
Bram Moolenaar1e115362019-01-09 23:01:02 +01001042func Test_edit_CTRL_U()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001043 " Test 'completefunc'
1044 new
1045 " -1, -2 and -3 are special return values
1046 let g:special=0
1047 fun! CompleteMonths(findstart, base)
1048 if a:findstart
1049 " locate the start of the word
1050 return g:special
1051 else
1052 " find months matching with "a:base"
1053 let res = []
1054 for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
1055 if m =~ '^\c'.a:base
1056 call add(res, {'word': m, 'abbr': m.' Month', 'icase': 0})
1057 endif
1058 endfor
1059 return {'words': res, 'refresh': 'always'}
1060 endif
1061 endfun
1062 set completefunc=CompleteMonths
1063 call setline(1, ['', ''])
1064 call cursor(1, 1)
1065 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1066 call assert_equal(['X', '', ''], getline(1, '$'))
1067 %d
1068 let g:special=-1
1069 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1070 call assert_equal(['XJan', ''], getline(1, '$'))
1071 %d
1072 let g:special=-2
1073 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1074 call assert_equal(['X', ''], getline(1, '$'))
1075 %d
1076 let g:special=-3
1077 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1078 call assert_equal(['X', ''], getline(1, '$'))
1079 %d
1080 let g:special=0
1081 call feedkeys("AM\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1082 call assert_equal(['Mar', ''], getline(1, '$'))
1083 %d
1084 call feedkeys("AM\<c-x>\<c-u>\<c-n>\<cr>\<esc>", 'tnix')
1085 call assert_equal(['May', ''], getline(1, '$'))
1086 %d
1087 call feedkeys("AM\<c-x>\<c-u>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
1088 call assert_equal(['M', ''], getline(1, '$'))
1089 delfu CompleteMonths
1090 %d
1091 try
1092 call feedkeys("A\<c-x>\<c-u>", 'tnix')
1093 call assert_fails(1, 'unknown completion function')
1094 catch /^Vim\%((\a\+)\)\=:E117/
1095 call assert_true(1, 'E117 error caught')
1096 endtry
1097 set completefunc=
1098 bw!
1099endfunc
1100
Bram Moolenaarff06f282020-04-21 22:01:14 +02001101func Test_edit_completefunc_delete()
1102 func CompleteFunc(findstart, base)
1103 if a:findstart == 1
1104 return col('.') - 1
1105 endif
1106 normal dd
1107 return ['a', 'b']
1108 endfunc
1109 new
1110 set completefunc=CompleteFunc
1111 call setline(1, ['', 'abcd', ''])
1112 2d
zeertzjqcfe45652022-05-27 17:26:55 +01001113 call assert_fails("normal 2G$a\<C-X>\<C-U>", 'E565:')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001114 bwipe!
1115endfunc
1116
1117
Bram Moolenaar1e115362019-01-09 23:01:02 +01001118func Test_edit_CTRL_Z()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001119 " Ctrl-Z when insertmode is not set inserts it literally
1120 new
1121 call setline(1, 'abc')
1122 call feedkeys("A\<c-z>\<esc>", 'tnix')
1123 call assert_equal(["abc\<c-z>"], getline(1,'$'))
1124 bw!
1125 " TODO: How to Test Ctrl-Z in insert mode, e.g. suspend?
1126endfunc
1127
Bram Moolenaar1e115362019-01-09 23:01:02 +01001128func Test_edit_DROP()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001129 CheckFeature dnd
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001130 new
1131 call setline(1, ['abc def ghi'])
1132 call cursor(1, 1)
1133 try
1134 call feedkeys("i\<Drop>\<Esc>", 'tnix')
1135 call assert_fails(1, 'Invalid register name')
1136 catch /^Vim\%((\a\+)\)\=:E353/
1137 call assert_true(1, 'error caught')
1138 endtry
1139 bw!
1140endfunc
1141
Bram Moolenaar1e115362019-01-09 23:01:02 +01001142func Test_edit_CTRL_V()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001143 new
1144 call setline(1, ['abc'])
1145 call cursor(2, 1)
zeertzjq502d8ae2022-01-24 15:27:50 +00001146
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001147 " force some redraws
1148 set showmode showcmd
zeertzjq502d8ae2022-01-24 15:27:50 +00001149 call test_override('char_avail', 1)
1150
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001151 call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
1152 call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
1153
1154 if has("rightleft") && exists("+rl")
1155 set rl
1156 call setline(1, ['abc'])
1157 call cursor(2, 1)
1158 call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
1159 call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
1160 set norl
1161 endif
1162
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001163 set noshowmode showcmd
zeertzjq502d8ae2022-01-24 15:27:50 +00001164 call test_override('char_avail', 0)
1165
1166 " No modifiers should be applied to the char typed using i_CTRL-V_digit.
1167 call feedkeys(":append\<CR>\<C-V>76c\<C-V>76\<C-F2>\<C-V>u3c0j\<C-V>u3c0\<M-F3>\<CR>.\<CR>", 'tnix')
1168 call assert_equal('LcL<C-F2>πjπ<M-F3>', getline(2))
1169
1170 if has('osx')
1171 " A char with a modifier should not be a valid char for i_CTRL-V_digit.
1172 call feedkeys("o\<C-V>\<D-j>\<C-V>\<D-1>\<C-V>\<D-o>\<C-V>\<D-x>\<C-V>\<D-u>", 'tnix')
1173 call assert_equal('<D-j><D-1><D-o><D-x><D-u>', getline(3))
1174 endif
1175
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001176 bw!
1177endfunc
1178
Bram Moolenaar1e115362019-01-09 23:01:02 +01001179func Test_edit_F1()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001180 CheckFeature quickfix
1181
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001182 " Pressing <f1>
1183 new
1184 call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix')
1185 set noinsertmode
1186 call assert_equal('help', &buftype)
1187 bw
1188 bw
1189endfunc
1190
Bram Moolenaar1e115362019-01-09 23:01:02 +01001191func Test_edit_F21()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001192 " Pressing <f21>
1193 " sends a netbeans command
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001194 CheckFeature netbeans_intg
1195 new
1196 " I have no idea what this is supposed to do :)
1197 call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
1198 bw
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001199endfunc
1200
Bram Moolenaar1e115362019-01-09 23:01:02 +01001201func Test_edit_HOME_END()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001202 " Test Home/End Keys
1203 new
1204 set foldopen+=hor
1205 call setline(1, ['abc', 'def'])
1206 call cursor(1, 1)
1207 call feedkeys("AX\<Home>Y\<esc>", 'tnix')
1208 call cursor(2, 1)
1209 call feedkeys("iZ\<End>Y\<esc>", 'tnix')
1210 call assert_equal(['YabcX', 'ZdefY'], getline(1, '$'))
1211
1212 set foldopen-=hor
1213 bw!
1214endfunc
1215
Bram Moolenaar1e115362019-01-09 23:01:02 +01001216func Test_edit_INS()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001217 " Test for Pressing <Insert>
1218 new
1219 call setline(1, ['abc', 'def'])
1220 call cursor(1, 1)
1221 call feedkeys("i\<Insert>ZYX>", 'tnix')
1222 call assert_equal(['ZYX>', 'def'], getline(1, '$'))
1223 call setline(1, ['abc', 'def'])
1224 call cursor(1, 1)
1225 call feedkeys("i\<Insert>Z\<Insert>YX>", 'tnix')
1226 call assert_equal(['ZYX>bc', 'def'], getline(1, '$'))
1227 bw!
1228endfunc
1229
Bram Moolenaar1e115362019-01-09 23:01:02 +01001230func Test_edit_LEFT_RIGHT()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001231 " Left, Shift-Left, Right, Shift-Right
1232 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001233 call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX'])
1234 let _ww=&ww
1235 set ww=
1236 call cursor(2, 1)
1237 call feedkeys("i\<left>\<esc>", 'tnix')
1238 call assert_equal([0, 2, 1, 0], getpos('.'))
1239 " Is this a bug, <s-left> does not respect whichwrap option
1240 call feedkeys("i\<s-left>\<esc>", 'tnix')
1241 call assert_equal([0, 1, 8, 0], getpos('.'))
1242 call feedkeys("i". repeat("\<s-left>", 3). "\<esc>", 'tnix')
1243 call assert_equal([0, 1, 1, 0], getpos('.'))
1244 call feedkeys("i\<right>\<esc>", 'tnix')
1245 call assert_equal([0, 1, 1, 0], getpos('.'))
1246 call feedkeys("i\<right>\<right>\<esc>", 'tnix')
1247 call assert_equal([0, 1, 2, 0], getpos('.'))
1248 call feedkeys("A\<right>\<esc>", 'tnix')
1249 call assert_equal([0, 1, 11, 0], getpos('.'))
1250 call feedkeys("A\<s-right>\<esc>", 'tnix')
1251 call assert_equal([0, 2, 1, 0], getpos('.'))
1252 call feedkeys("i\<s-right>\<esc>", 'tnix')
1253 call assert_equal([0, 2, 4, 0], getpos('.'))
1254 call cursor(3, 11)
1255 call feedkeys("A\<right>\<esc>", 'tnix')
1256 call feedkeys("A\<s-right>\<esc>", 'tnix')
1257 call assert_equal([0, 3, 11, 0], getpos('.'))
1258 call cursor(2, 11)
1259 " <S-Right> does not respect 'whichwrap' option
1260 call feedkeys("A\<s-right>\<esc>", 'tnix')
1261 call assert_equal([0, 3, 1, 0], getpos('.'))
1262 " Check motion when 'whichwrap' contains cursor keys for insert mode
1263 set ww+=[,]
1264 call cursor(2, 1)
1265 call feedkeys("i\<left>\<esc>", 'tnix')
1266 call assert_equal([0, 1, 11, 0], getpos('.'))
1267 call cursor(2, 11)
1268 call feedkeys("A\<right>\<esc>", 'tnix')
1269 call assert_equal([0, 3, 1, 0], getpos('.'))
1270 call cursor(2, 11)
1271 call feedkeys("A\<s-right>\<esc>", 'tnix')
1272 call assert_equal([0, 3, 1, 0], getpos('.'))
1273 let &ww = _ww
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001274 bw!
1275endfunc
1276
Bram Moolenaar1e115362019-01-09 23:01:02 +01001277func Test_edit_MOUSE()
Christian Brabandtee17b6f2023-09-09 11:23:50 +02001278 " This is a simple test, since we're not really using the mouse here
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001279 CheckFeature mouse
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001280 10new
1281 call setline(1, range(1, 100))
1282 call cursor(1, 1)
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001283 call assert_equal(1, line('w0'))
1284 call assert_equal(10, line('w$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001285 set mouse=a
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001286 " One scroll event moves three lines.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001287 call feedkeys("A\<ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001288 call assert_equal(4, line('w0'))
1289 call assert_equal(13, line('w$'))
1290 " This should move by one page down.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001291 call feedkeys("A\<S-ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001292 call assert_equal(14, line('w0'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001293 set nostartofline
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001294 " Another page down.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001295 call feedkeys("A\<C-ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001296 call assert_equal(24, line('w0'))
1297
1298 call assert_equal([0, 24, 2, 0], getpos('.'))
1299 call test_setmouse(4, 3)
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001300 call feedkeys("A\<LeftMouse>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001301 call assert_equal([0, 27, 2, 0], getpos('.'))
Bram Moolenaarb3707712022-05-08 22:49:43 +01001302 set mousemodel=extend
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001303 call test_setmouse(5, 3)
1304 call feedkeys("A\<RightMouse>\<esc>\<esc>", 'tnix')
1305 call assert_equal([0, 28, 2, 0], getpos('.'))
Bram Moolenaarb3707712022-05-08 22:49:43 +01001306 set mousemodel&
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001307 call cursor(1, 100)
1308 norm! zt
1309 " this should move by a screen up, but when the test
1310 " is run, it moves up to the top of the buffer...
1311 call feedkeys("A\<ScrollWheelUp>\<esc>", 'tnix')
1312 call assert_equal([0, 1, 1, 0], getpos('.'))
1313 call cursor(1, 30)
1314 norm! zt
1315 call feedkeys("A\<S-ScrollWheelUp>\<esc>", 'tnix')
1316 call assert_equal([0, 1, 1, 0], getpos('.'))
1317 call cursor(1, 30)
1318 norm! zt
1319 call feedkeys("A\<C-ScrollWheelUp>\<esc>", 'tnix')
1320 call assert_equal([0, 1, 1, 0], getpos('.'))
1321 %d
1322 call setline(1, repeat(["12345678901234567890"], 100))
1323 call cursor(2, 1)
1324 call feedkeys("A\<ScrollWheelRight>\<esc>", 'tnix')
1325 call assert_equal([0, 2, 20, 0], getpos('.'))
1326 call feedkeys("A\<ScrollWheelLeft>\<esc>", 'tnix')
1327 call assert_equal([0, 2, 20, 0], getpos('.'))
1328 call feedkeys("A\<S-ScrollWheelRight>\<esc>", 'tnix')
1329 call assert_equal([0, 2, 20, 0], getpos('.'))
1330 call feedkeys("A\<S-ScrollWheelLeft>\<esc>", 'tnix')
1331 call assert_equal([0, 2, 20, 0], getpos('.'))
1332 call feedkeys("A\<C-ScrollWheelRight>\<esc>", 'tnix')
1333 call assert_equal([0, 2, 20, 0], getpos('.'))
1334 call feedkeys("A\<C-ScrollWheelLeft>\<esc>", 'tnix')
1335 call assert_equal([0, 2, 20, 0], getpos('.'))
1336 set mouse& startofline
1337 bw!
1338endfunc
1339
Bram Moolenaar1e115362019-01-09 23:01:02 +01001340func Test_edit_PAGEUP_PAGEDOWN()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001341 10new
1342 call setline(1, repeat(['abc def ghi'], 30))
1343 call cursor(1, 1)
1344 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1345 call assert_equal([0, 9, 1, 0], getpos('.'))
1346 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1347 call assert_equal([0, 17, 1, 0], getpos('.'))
1348 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1349 call assert_equal([0, 25, 1, 0], getpos('.'))
1350 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1351 call assert_equal([0, 30, 1, 0], getpos('.'))
1352 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1353 call assert_equal([0, 30, 1, 0], getpos('.'))
1354 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001355 call assert_equal([0, 29, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001356 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001357 call assert_equal([0, 21, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001358 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001359 call assert_equal([0, 13, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001360 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001361 call assert_equal([0, 10, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001362 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baalcb204e62024-04-02 20:49:45 +02001363 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001364 " <S-Up> is the same as <PageUp>
1365 " <S-Down> is the same as <PageDown>
1366 call cursor(1, 1)
1367 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1368 call assert_equal([0, 9, 1, 0], getpos('.'))
1369 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1370 call assert_equal([0, 17, 1, 0], getpos('.'))
1371 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1372 call assert_equal([0, 25, 1, 0], getpos('.'))
1373 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1374 call assert_equal([0, 30, 1, 0], getpos('.'))
1375 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1376 call assert_equal([0, 30, 1, 0], getpos('.'))
1377 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001378 call assert_equal([0, 29, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001379 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001380 call assert_equal([0, 21, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001381 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001382 call assert_equal([0, 13, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001383 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001384 call assert_equal([0, 10, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001385 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baalcb204e62024-04-02 20:49:45 +02001386 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001387 set nostartofline
1388 call cursor(30, 11)
1389 norm! zt
1390 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001391 call assert_equal([0, 29, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001392 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001393 call assert_equal([0, 21, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001394 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001395 call assert_equal([0, 13, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001396 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001397 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001398 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baalcb204e62024-04-02 20:49:45 +02001399 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001400 call cursor(1, 1)
1401 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1402 call assert_equal([0, 9, 11, 0], getpos('.'))
1403 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1404 call assert_equal([0, 17, 11, 0], getpos('.'))
1405 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1406 call assert_equal([0, 25, 11, 0], getpos('.'))
1407 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1408 call assert_equal([0, 30, 11, 0], getpos('.'))
1409 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1410 call assert_equal([0, 30, 11, 0], getpos('.'))
1411 " <S-Up> is the same as <PageUp>
1412 " <S-Down> is the same as <PageDown>
1413 call cursor(30, 11)
1414 norm! zt
1415 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001416 call assert_equal([0, 29, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001417 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001418 call assert_equal([0, 21, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001419 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001420 call assert_equal([0, 13, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001421 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001422 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001423 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baalcb204e62024-04-02 20:49:45 +02001424 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001425 call cursor(1, 1)
1426 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1427 call assert_equal([0, 9, 11, 0], getpos('.'))
1428 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1429 call assert_equal([0, 17, 11, 0], getpos('.'))
1430 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1431 call assert_equal([0, 25, 11, 0], getpos('.'))
1432 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1433 call assert_equal([0, 30, 11, 0], getpos('.'))
1434 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1435 call assert_equal([0, 30, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001436 bw!
1437endfunc
1438
Bram Moolenaar1e115362019-01-09 23:01:02 +01001439func Test_edit_forbidden()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001440 new
1441 " 1) edit in the sandbox is not allowed
1442 call setline(1, 'a')
1443 com! Sandbox :sandbox call feedkeys("i\<del>\<esc>", 'tnix')
1444 call assert_fails(':Sandbox', 'E48:')
1445 com! Sandbox :sandbox exe "norm! i\<del>"
1446 call assert_fails(':Sandbox', 'E48:')
1447 delcom Sandbox
1448 call assert_equal(['a'], getline(1,'$'))
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001449
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001450 " 2) edit with textlock set
1451 fu! DoIt()
1452 call feedkeys("i\<del>\<esc>", 'tnix')
1453 endfu
1454 au InsertCharPre <buffer> :call DoIt()
1455 try
1456 call feedkeys("ix\<esc>", 'tnix')
1457 call assert_fails(1, 'textlock')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001458 catch /^Vim\%((\a\+)\)\=:E565/ " catch E565: not allowed here
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001459 endtry
1460 " TODO: Might be a bug: should x really be inserted here
1461 call assert_equal(['xa'], getline(1, '$'))
1462 delfu DoIt
1463 try
1464 call feedkeys("ix\<esc>", 'tnix')
1465 call assert_fails(1, 'unknown function')
1466 catch /^Vim\%((\a\+)\)\=:E117/ " catch E117: unknown function
1467 endtry
1468 au! InsertCharPre
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001469
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001470 " 3) edit when completion is shown
1471 fun! Complete(findstart, base)
1472 if a:findstart
1473 return col('.')
1474 else
1475 call feedkeys("i\<del>\<esc>", 'tnix')
1476 return []
1477 endif
1478 endfun
1479 set completefunc=Complete
1480 try
1481 call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
1482 call assert_fails(1, 'change in complete function')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001483 catch /^Vim\%((\a\+)\)\=:E565/ " catch E565
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001484 endtry
1485 delfu Complete
1486 set completefunc=
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001487
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001488 if has("rightleft") && exists("+fkmap")
1489 " 4) 'R' when 'fkmap' and 'revins' is set.
1490 set revins fkmap
1491 try
1492 normal Ri
1493 call assert_fails(1, "R with 'fkmap' and 'ri' set")
1494 catch
1495 finally
1496 set norevins nofkmap
1497 endtry
1498 endif
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001499 bw!
1500endfunc
1501
Bram Moolenaar1e115362019-01-09 23:01:02 +01001502func Test_edit_rightleft()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001503 " Cursor in rightleft mode moves differently
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001504 CheckFeature rightleft
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001505 call NewWindow(10, 20)
1506 call setline(1, ['abc', 'def', 'ghi'])
1507 call cursor(1, 2)
1508 set rightleft
1509 " Screen looks as expected
1510 let lines = ScreenLines([1, 4], winwidth(0))
1511 let expect = [
1512 \" cba",
1513 \" fed",
1514 \" ihg",
1515 \" ~"]
1516 call assert_equal(join(expect, "\n"), join(lines, "\n"))
1517 " 2) right moves to the left
1518 call feedkeys("i\<right>\<esc>x", 'txin')
1519 call assert_equal(['bc', 'def', 'ghi'], getline(1,'$'))
1520 call cursor(1, 2)
1521 call feedkeys("i\<s-right>\<esc>", 'txin')
1522 call cursor(1, 2)
1523 call feedkeys("i\<c-right>\<esc>", 'txin')
1524 " Screen looks as expected
1525 let lines = ScreenLines([1, 4], winwidth(0))
1526 let expect = [
1527 \" cb",
1528 \" fed",
1529 \" ihg",
1530 \" ~"]
1531 call assert_equal(join(expect, "\n"), join(lines, "\n"))
1532 " 2) left moves to the right
1533 call setline(1, ['abc', 'def', 'ghi'])
1534 call cursor(1, 2)
1535 call feedkeys("i\<left>\<esc>x", 'txin')
1536 call assert_equal(['ac', 'def', 'ghi'], getline(1,'$'))
1537 call cursor(1, 2)
1538 call feedkeys("i\<s-left>\<esc>", 'txin')
1539 call cursor(1, 2)
1540 call feedkeys("i\<c-left>\<esc>", 'txin')
1541 " Screen looks as expected
1542 let lines = ScreenLines([1, 4], winwidth(0))
1543 let expect = [
1544 \" ca",
1545 \" fed",
1546 \" ihg",
1547 \" ~"]
1548 call assert_equal(join(expect, "\n"), join(lines, "\n"))
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001549 %d _
1550 call test_override('redraw_flag', 1)
1551 call test_override('char_avail', 1)
1552 call feedkeys("a\<C-V>x41", "xt")
1553 redraw!
1554 call assert_equal(repeat(' ', 19) .. 'A', Screenline(1))
1555 call test_override('ALL', 0)
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001556 set norightleft
1557 bw!
1558endfunc
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001559
1560func Test_edit_complete_very_long_name()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001561 " Long directory names only work on Unix.
1562 CheckUnix
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001563
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01001564 let dirname = getcwd() . "/Xlongdir"
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001565 let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
1566 try
Bram Moolenaar14f91762022-09-21 15:13:52 +01001567 call mkdir(longdirname, 'pR')
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001568 catch /E739:/
1569 " Long directory name probably not supported.
1570 call delete(dirname, 'rf')
1571 return
1572 endtry
1573
Bram Moolenaarf8191c52019-05-18 17:22:54 +02001574 " Try to get the Vim window position before setting 'columns', so that we can
1575 " move the window back to where it was.
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001576 let winposx = getwinposx()
1577 let winposy = getwinposy()
Bram Moolenaarf8191c52019-05-18 17:22:54 +02001578
1579 if winposx >= 0 && winposy >= 0 && !has('gui_running')
1580 " We did get the window position, but xterm may report the wrong numbers.
1581 " Move the window to the reported position and compute any offset.
1582 exe 'winpos ' . winposx . ' ' . winposy
1583 sleep 100m
1584 let x = getwinposx()
1585 if x >= 0
1586 let winposx += winposx - x
1587 endif
1588 let y = getwinposy()
1589 if y >= 0
1590 let winposy += winposy - y
1591 endif
1592 endif
1593
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001594 let save_columns = &columns
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001595 " Need at least about 1100 columns to reproduce the problem.
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001596 set columns=2000
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001597 set noswapfile
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001598
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001599 let longfilename = longdirname . '/' . repeat('a', 255)
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001600 call writefile(['Totum', 'Table'], longfilename)
1601 new
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001602 exe "next Xnofile " . longfilename
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001603 exe "normal iT\<C-N>"
1604
1605 bwipe!
1606 exe 'bwipe! ' . longfilename
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001607 let &columns = save_columns
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001608 if winposx >= 0 && winposy >= 0
1609 exe 'winpos ' . winposx . ' ' . winposy
1610 endif
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001611 set swapfile&
1612endfunc
Bram Moolenaarff930ca2017-10-19 17:12:10 +02001613
Bram Moolenaar2c8c6812018-07-28 17:07:52 +02001614func Test_edit_backtick()
1615 next a\`b c
1616 call assert_equal('a`b', expand('%'))
1617 next
1618 call assert_equal('c', expand('%'))
1619 call assert_equal('a\`b c', expand('##'))
1620endfunc
1621
Bram Moolenaarff930ca2017-10-19 17:12:10 +02001622func Test_edit_quit()
1623 edit foo.txt
1624 split
1625 new
1626 call setline(1, 'hello')
1627 3wincmd w
1628 redraw!
1629 call assert_fails('1q', 'E37:')
1630 bwipe! foo.txt
1631 only
1632endfunc
1633
Bram Moolenaaradb8fbe2018-06-04 20:34:23 +02001634func Test_edit_alt()
1635 " Keeping the cursor line didn't happen when the first line has indent.
1636 new
1637 call setline(1, [' one', 'two', 'three'])
1638 w XAltFile
1639 $
1640 call assert_equal(3, line('.'))
1641 e Xother
1642 e #
1643 call assert_equal(3, line('.'))
1644
1645 bwipe XAltFile
1646 call delete('XAltFile')
1647endfunc
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001648
Bram Moolenaardb934952020-04-27 20:18:31 +02001649func Test_edit_InsertLeave()
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001650 new
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001651 au InsertLeavePre * let g:did_au_pre = 1
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001652 au InsertLeave * let g:did_au = 1
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001653 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001654 let g:did_au = 0
1655 call feedkeys("afoo\<Esc>", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001656 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001657 call assert_equal(1, g:did_au)
1658 call assert_equal('foo', getline(1))
1659
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001660 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001661 let g:did_au = 0
1662 call feedkeys("Sbar\<C-C>", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001663 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001664 call assert_equal(0, g:did_au)
1665 call assert_equal('bar', getline(1))
1666
1667 inoremap x xx<Esc>
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001668 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001669 let g:did_au = 0
1670 call feedkeys("Saax", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001671 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001672 call assert_equal(1, g:did_au)
1673 call assert_equal('aaxx', getline(1))
1674
1675 inoremap x xx<C-C>
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001676 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001677 let g:did_au = 0
1678 call feedkeys("Sbbx", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001679 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001680 call assert_equal(0, g:did_au)
1681 call assert_equal('bbxx', getline(1))
1682
1683 bwipe!
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001684 au! InsertLeave InsertLeavePre
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001685 iunmap x
1686endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001687
Bram Moolenaardb934952020-04-27 20:18:31 +02001688func Test_edit_InsertLeave_undo()
1689 new XtestUndo
1690 set undofile
1691 au InsertLeave * wall
1692 exe "normal ofoo\<Esc>"
1693 call assert_equal(2, line('$'))
1694 normal u
1695 call assert_equal(1, line('$'))
1696
1697 bwipe!
1698 au! InsertLeave
1699 call delete('XtestUndo')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001700 call delete(undofile('XtestUndo'))
Bram Moolenaardb934952020-04-27 20:18:31 +02001701 set undofile&
1702endfunc
1703
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001704" Test for inserting characters using CTRL-V followed by a number.
1705func Test_edit_special_chars()
1706 new
1707
Bram Moolenaar424bcae2022-01-31 14:59:41 +00001708 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 +02001709
1710 exe "normal " . t
1711 call assert_equal("ABC !a\<C-O>g\<C-G>8", getline(2))
1712
1713 close!
1714endfunc
Bram Moolenaar8d3b5102019-09-05 21:29:01 +02001715
1716func Test_edit_startinsert()
1717 new
1718 set backspace+=start
1719 call setline(1, 'foobar')
1720 call feedkeys("A\<C-U>\<Esc>", 'xt')
1721 call assert_equal('', getline(1))
1722
1723 call setline(1, 'foobar')
1724 call feedkeys(":startinsert!\<CR>\<C-U>\<Esc>", 'xt')
1725 call assert_equal('', getline(1))
1726
1727 set backspace&
1728 bwipe!
1729endfunc
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001730
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001731" Test for :startreplace and :startgreplace
1732func Test_edit_startreplace()
1733 new
1734 call setline(1, 'abc')
1735 call feedkeys("l:startreplace\<CR>xyz\e", 'xt')
1736 call assert_equal('axyz', getline(1))
1737 call feedkeys("0:startreplace!\<CR>abc\e", 'xt')
1738 call assert_equal('axyzabc', getline(1))
1739 call setline(1, "a\tb")
1740 call feedkeys("0l:startgreplace\<CR>xyz\e", 'xt')
1741 call assert_equal("axyz\tb", getline(1))
1742 call feedkeys("0i\<C-R>=execute('startreplace')\<CR>12\e", 'xt')
1743 call assert_equal("12axyz\tb", getline(1))
1744 close!
1745endfunc
1746
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001747func Test_edit_noesckeys()
Bram Moolenaar215ba3b2019-11-06 15:07:07 +01001748 CheckNotGui
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001749 new
1750
1751 " <Left> moves cursor when 'esckeys' is set
1752 exe "set t_kl=\<Esc>OD"
1753 set esckeys
1754 call feedkeys("axyz\<Esc>ODX", "xt")
1755 call assert_equal("xyXz", getline(1))
1756
1757 " <Left> exits Insert mode when 'esckeys' is off
1758 set noesckeys
1759 call setline(1, '')
1760 call feedkeys("axyz\<Esc>ODX", "xt")
1761 call assert_equal(["DX", "xyz"], getline(1, 2))
1762
1763 bwipe!
1764 set esckeys
1765endfunc
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001766
Bram Moolenaar1671f442020-03-10 07:48:13 +01001767" Test for running an invalid ex command in insert mode using CTRL-O
Bram Moolenaar1671f442020-03-10 07:48:13 +01001768func Test_edit_ctrl_o_invalid_cmd()
1769 new
1770 set showmode showcmd
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001771 " Avoid a sleep of 3 seconds. Zero might have side effects.
1772 call test_override('ui_delay', 50)
Bram Moolenaar1671f442020-03-10 07:48:13 +01001773 let caught_e492 = 0
1774 try
1775 call feedkeys("i\<C-O>:invalid\<CR>abc\<Esc>", "xt")
1776 catch /E492:/
1777 let caught_e492 = 1
1778 endtry
1779 call assert_equal(1, caught_e492)
1780 call assert_equal('abc', getline(1))
1781 set showmode& showcmd&
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001782 call test_override('ui_delay', 0)
Bram Moolenaar1671f442020-03-10 07:48:13 +01001783 close!
1784endfunc
1785
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001786" Test for editing a file with a very long name
1787func Test_edit_illegal_filename()
1788 CheckEnglish
1789 new
1790 redir => msg
1791 exe 'edit ' . repeat('f', 5000)
1792 redir END
1793 call assert_match("Illegal file name$", split(msg, "\n")[0])
1794 close!
1795endfunc
1796
Bram Moolenaarc8fe6452020-10-03 17:04:37 +02001797" Test for editing a directory
1798func Test_edit_is_a_directory()
1799 CheckEnglish
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01001800 let dirname = getcwd() . "/Xeditdir"
Bram Moolenaarc8fe6452020-10-03 17:04:37 +02001801 call mkdir(dirname, 'p')
1802
1803 new
1804 redir => msg
1805 exe 'edit' dirname
1806 redir END
1807 call assert_match("is a directory$", split(msg, "\n")[0])
1808 bwipe!
1809
1810 let dirname .= '/'
1811
1812 new
1813 redir => msg
1814 exe 'edit' dirname
1815 redir END
1816 call assert_match("is a directory$", split(msg, "\n")[0])
1817 bwipe!
1818
1819 call delete(dirname, 'rf')
1820endfunc
1821
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001822" Test for editing a file using invalid file encoding
1823func Test_edit_invalid_encoding()
1824 CheckEnglish
Bram Moolenaar14f91762022-09-21 15:13:52 +01001825 call writefile([], 'Xinvfile', 'D')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001826 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001827 new ++enc=axbyc Xinvfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001828 redir END
1829 call assert_match('\[NOT converted\]', msg)
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001830 close!
1831endfunc
1832
1833" Test for the "charconvert" option
1834func Test_edit_charconvert()
1835 CheckEnglish
Bram Moolenaar14f91762022-09-21 15:13:52 +01001836 call writefile(['one', 'two'], 'Xccfile', 'D')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001837
1838 " set 'charconvert' to a non-existing function
1839 set charconvert=NonExitingFunc()
1840 new
1841 let caught_e117 = v:false
1842 try
1843 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001844 edit ++enc=axbyc Xccfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001845 catch /E117:/
1846 let caught_e117 = v:true
1847 finally
1848 redir END
1849 endtry
1850 call assert_true(caught_e117)
1851 call assert_equal(['one', 'two'], getline(1, '$'))
1852 call assert_match("Conversion with 'charconvert' failed", msg)
1853 close!
1854 set charconvert&
1855
Christian Brabandtee17b6f2023-09-09 11:23:50 +02001856 " 'charconvert' function doesn't create an output file
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001857 func Cconv1()
1858 endfunc
1859 set charconvert=Cconv1()
1860 new
1861 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001862 edit ++enc=axbyc Xccfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001863 redir END
1864 call assert_equal(['one', 'two'], getline(1, '$'))
1865 call assert_match("can't read output of 'charconvert'", msg)
1866 close!
1867 delfunc Cconv1
1868 set charconvert&
1869
1870 " 'charconvert' function to convert to upper case
1871 func Cconv2()
1872 let data = readfile(v:fname_in)
1873 call map(data, 'toupper(v:val)')
1874 call writefile(data, v:fname_out)
1875 endfunc
1876 set charconvert=Cconv2()
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001877 new Xccfile
1878 write ++enc=ucase Xccfile1
1879 call assert_equal(['ONE', 'TWO'], readfile('Xccfile1'))
1880 call delete('Xccfile1')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001881 close!
1882 delfunc Cconv2
1883 set charconvert&
1884
1885 " 'charconvert' function removes the input file
1886 func Cconv3()
1887 call delete(v:fname_in)
1888 endfunc
1889 set charconvert=Cconv3()
1890 new
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001891 call assert_fails('edit ++enc=lcase Xccfile', 'E202:')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001892 call assert_equal([''], getline(1, '$'))
1893 close!
1894 delfunc Cconv3
1895 set charconvert&
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001896endfunc
1897
1898" Test for editing a file without read permission
1899func Test_edit_file_no_read_perm()
1900 CheckUnix
Bram Moolenaar17709e22021-03-19 14:38:12 +01001901 CheckNotRoot
1902
Bram Moolenaar14f91762022-09-21 15:13:52 +01001903 call writefile(['one', 'two'], 'Xnrpfile', 'D')
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001904 call setfperm('Xnrpfile', '-w-------')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001905 new
1906 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001907 edit Xnrpfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001908 redir END
1909 call assert_equal(1, &readonly)
1910 call assert_equal([''], getline(1, '$'))
1911 call assert_match('\[Permission Denied\]', msg)
1912 close!
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001913endfunc
1914
zeertzjq3a56b6d2022-04-08 11:56:14 +01001915" Using :edit without leaving 'insertmode' should not cause Insert mode to be
1916" re-entered immediately after <C-L>
1917func Test_edit_insertmode_ex_edit()
1918 CheckRunVimInTerminal
1919
1920 let lines =<< trim END
1921 set insertmode noruler
1922 inoremap <C-B> <Cmd>edit Xfoo<CR>
1923 END
Bram Moolenaar14f91762022-09-21 15:13:52 +01001924 call writefile(lines, 'Xtest_edit_insertmode_ex_edit', 'D')
zeertzjq3a56b6d2022-04-08 11:56:14 +01001925
Bram Moolenaar14f91762022-09-21 15:13:52 +01001926 let buf = RunVimInTerminal('-S Xtest_edit_insertmode_ex_edit', #{rows: 6, wait_for_ruler: 0})
1927 " Somehow when using valgrind "INSERT" does not show up unless we send
1928 " something to the terminal.
1929 for i in range(30)
1930 if term_getline(buf, 6) =~ 'INSERT'
1931 break
1932 endif
1933 call term_sendkeys(buf, "-")
1934 sleep 100m
1935 endfor
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001936 call WaitForAssert({-> assert_match('^-- INSERT --\s*$', term_getline(buf, 6))})
zeertzjq3a56b6d2022-04-08 11:56:14 +01001937 call term_sendkeys(buf, "\<C-B>\<C-L>")
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001938 call WaitForAssert({-> assert_notmatch('^-- INSERT --\s*$', term_getline(buf, 6))})
zeertzjq3a56b6d2022-04-08 11:56:14 +01001939
1940 " clean up
1941 call StopVimInTerminal(buf)
zeertzjq3a56b6d2022-04-08 11:56:14 +01001942endfunc
1943
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001944" Pressing escape in 'insertmode' should beep
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001945" FIXME: Execute this later, when using valgrind it makes the next test
1946" Test_edit_insertmode_ex_edit() fail.
1947func Test_z_edit_insertmode_esc_beeps()
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001948 new
1949 set insertmode
1950 call assert_beeps("call feedkeys(\"one\<Esc>\", 'xt')")
1951 set insertmode&
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001952 " unsupported "CTRL-G l" command should beep in insert mode.
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001953 call assert_beeps("normal i\<C-G>l")
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001954 bwipe!
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001955endfunc
1956
1957" Test for 'hkmap' and 'hkmapp'
1958func Test_edit_hkmap()
1959 CheckFeature rightleft
1960 if has('win32') && !has('gui')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001961 throw 'Skipped: fails on the MS-Windows terminal version'
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001962 endif
1963 new
1964
1965 set revins hkmap
1966 let str = 'abcdefghijklmnopqrstuvwxyz'
1967 let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1968 let str ..= '`/'',.;'
1969 call feedkeys('i' .. str, 'xt')
1970 let expected = "óõú,.;"
1971 let expected ..= "ZYXWVUTSRQPONMLKJIHGFEDCBA"
1972 let expected ..= "æèñ'äåàãø/ôíîöêìçïéòë÷âáðù"
1973 call assert_equal(expected, getline(1))
1974
1975 %d
1976 set revins hkmap hkmapp
1977 let str = 'abcdefghijklmnopqrstuvwxyz'
1978 let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1979 call feedkeys('i' .. str, 'xt')
1980 let expected = "õYXWVUTSRQóOïíLKJIHGFEDêBA"
1981 let expected ..= "öòXùåèúæø'ôñðîì÷çéäâóǟãëáà"
1982 call assert_equal(expected, getline(1))
1983
1984 set revins& hkmap& hkmapp&
1985 close!
1986endfunc
1987
1988" Test for 'allowrevins' and using CTRL-_ in insert mode
1989func Test_edit_allowrevins()
1990 CheckFeature rightleft
1991 new
1992 set allowrevins
1993 call feedkeys("iABC\<C-_>DEF\<C-_>GHI", 'xt')
1994 call assert_equal('ABCFEDGHI', getline(1))
1995 set allowrevins&
1996 close!
1997endfunc
1998
1999" Test for inserting a register in insert mode using CTRL-R
2000func Test_edit_insert_reg()
2001 new
2002 let g:Line = ''
2003 func SaveFirstLine()
2004 let g:Line = Screenline(1)
2005 return 'r'
2006 endfunc
2007 inoremap <expr> <buffer> <F2> SaveFirstLine()
2008 call test_override('redraw_flag', 1)
2009 call test_override('char_avail', 1)
2010 let @r = 'sample'
2011 call feedkeys("a\<C-R>=SaveFirstLine()\<CR>", "xt")
2012 call assert_equal('"', g:Line)
Yegappan Lakshmananfe424d12024-05-17 18:20:43 +02002013
2014 " Test for inserting an null and an empty list
2015 call feedkeys("a\<C-R>=test_null_list()\<CR>", "xt")
2016 call feedkeys("a\<C-R>=[]\<CR>", "xt")
2017 call assert_equal(['r'], getbufline('', 1, '$'))
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02002018 call test_override('ALL', 0)
2019 close!
2020endfunc
2021
Bram Moolenaarc174c2e2023-03-25 20:06:49 +00002022" Test for positioning cursor after CTRL-R expression failed
2023func Test_edit_ctrl_r_failed()
2024 CheckRunVimInTerminal
2025
2026 let buf = RunVimInTerminal('', #{rows: 6, cols: 60})
2027
Yegappan Lakshmananf01493c2024-04-14 23:21:02 +02002028 " trying to insert a blob produces an error
2029 call term_sendkeys(buf, "i\<C-R>=0z\<CR>")
Bram Moolenaarc174c2e2023-03-25 20:06:49 +00002030
2031 " ending Insert mode should put the cursor back on the ':'
2032 call term_sendkeys(buf, ":\<Esc>")
2033 call VerifyScreenDump(buf, 'Test_edit_ctlr_r_failed_1', {})
2034
2035 call StopVimInTerminal(buf)
2036endfunc
2037
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02002038" When a character is inserted at the last position of the last line in a
2039" window, the window contents should be scrolled one line up. If the top line
2040" is part of a fold, then the entire fold should be scrolled up.
2041func Test_edit_lastline_scroll()
2042 new
2043 let h = winheight(0)
2044 let lines = ['one', 'two', 'three']
2045 let lines += repeat(['vim'], h - 4)
2046 call setline(1, lines)
2047 call setline(h, repeat('x', winwidth(0) - 1))
2048 call feedkeys("GAx", 'xt')
2049 redraw!
2050 call assert_equal(h - 1, winline())
2051 call assert_equal(2, line('w0'))
2052
2053 " scroll with a fold
2054 1,2fold
2055 normal gg
2056 call setline(h + 1, repeat('x', winwidth(0) - 1))
2057 call feedkeys("GAx", 'xt')
2058 redraw!
2059 call assert_equal(h - 1, winline())
2060 call assert_equal(3, line('w0'))
2061
2062 close!
2063endfunc
2064
Bram Moolenaar21cbe172020-10-13 19:08:24 +02002065func Test_edit_browse()
2066 " in the GUI this opens a file picker, we only test the terminal behavior
2067 CheckNotGui
2068
2069 " ":browse xxx" checks for the FileExplorer augroup and assumes editing "."
2070 " works then.
2071 augroup FileExplorer
2072 au!
2073 augroup END
2074
2075 " When the USE_FNAME_CASE is defined this used to cause a crash.
2076 browse enew
2077 bwipe!
2078
2079 browse split
2080 bwipe!
2081endfunc
2082
Bram Moolenaarcaf73dc2020-10-26 21:39:13 +01002083func Test_read_invalid()
2084 set encoding=latin1
2085 " This was not properly checking for going past the end.
zeertzjq67fe77d2025-04-20 10:21:18 +02002086 call assert_fails('r`=', 'E484:')
Bram Moolenaarcaf73dc2020-10-26 21:39:13 +01002087 set encoding=utf-8
2088endfunc
2089
Yegappan Lakshmanan59585492021-06-12 13:46:41 +02002090" Test for the 'revins' option
2091func Test_edit_revins()
2092 CheckFeature rightleft
2093 new
2094 set revins
2095 exe "normal! ione\ttwo three"
2096 call assert_equal("eerht owt\teno", getline(1))
2097 call setline(1, "one\ttwo three")
2098 normal! gg$bi a
2099 call assert_equal("one\ttwo a three", getline(1))
2100 exe "normal! $bi\<BS>\<BS>"
2101 call assert_equal("one\ttwo a ree", getline(1))
2102 exe "normal! 0wi\<C-W>"
2103 call assert_equal("one\t a ree", getline(1))
2104 exe "normal! 0wi\<C-U>"
2105 call assert_equal("one\t ", getline(1))
2106 " newline in insert mode starts at the end of the line
2107 call setline(1, 'one two three')
2108 exe "normal! wi\nfour"
2109 call assert_equal(['one two three', 'ruof'], getline(1, '$'))
zeertzjq8ede7a02024-03-28 10:30:08 +01002110 set backspace=indent,eol,start
2111 exe "normal! ggA\<BS>:"
2112 call assert_equal(['one two three:ruof'], getline(1, '$'))
2113 set revins& backspace&
Yegappan Lakshmanan59585492021-06-12 13:46:41 +02002114 bw!
2115endfunc
2116
Bram Moolenaar35a9a002021-09-11 21:14:20 +02002117" Test for getting the character of the line below after "p"
2118func Test_edit_put_CTRL_E()
2119 set encoding=latin1
2120 new
2121 let @" = ''
2122 sil! norm orggRx
2123 sil! norm pr
2124 call assert_equal(['r', 'r'], getline(1, 2))
2125 bwipe!
2126 set encoding=utf-8
2127endfunc
2128
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002129" Test toggling of input method. See :help i_CTRL-^
2130func Test_edit_CTRL_hat()
2131 CheckFeature xim
Dominique Pelle8753c1d2021-10-31 20:19:17 +00002132
Bram Moolenaar0b962e52022-04-03 18:02:37 +01002133 " FIXME: test fails with Motif GUI.
Dominique Pelle8753c1d2021-10-31 20:19:17 +00002134 " test also fails when running in the GUI.
2135 CheckFeature gui_gtk
2136 CheckNotGui
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002137
2138 new
2139
2140 call assert_equal(0, &iminsert)
2141 call feedkeys("i\<C-^>", 'xt')
2142 call assert_equal(2, &iminsert)
2143 call feedkeys("i\<C-^>", 'xt')
2144 call assert_equal(0, &iminsert)
2145
2146 bwipe!
2147endfunc
2148
Bram Moolenaarde05bb22022-01-13 13:08:14 +00002149" Weird long file name was going over the end of NameBuff
2150func Test_edit_overlong_file_name()
2151 CheckUnix
2152
2153 file 0000000000000000000000000000
2154 file %%%%%%%%%%%%%%%%%%%%%%%%%%
2155 file %%%%%%
2156 set readonly
Bram Moolenaar94722c52023-01-28 19:19:03 +00002157 set ls=2
Bram Moolenaarde05bb22022-01-13 13:08:14 +00002158
2159 redraw!
2160 set noreadonly ls&
2161 bwipe!
2162endfunc
2163
Christian Brabandtdfbdadc2022-05-05 20:46:47 +01002164func Test_edit_shift_bs()
2165 CheckMSWindows
2166
2167 " FIXME: this works interactively, but the test fails
2168 throw 'Skipped: Shift-Backspace Test not working correctly :('
2169
2170 " Need to run this in Win32 Terminal, do not use CheckRunVimInTerminal
2171 if !has("terminal")
2172 return
2173 endif
2174
2175 " Shift Backspace should work like Backspace in insert mode
2176 let lines =<< trim END
2177 call setline(1, ['abc'])
2178 END
Bram Moolenaar14f91762022-09-21 15:13:52 +01002179 call writefile(lines, 'Xtest_edit_shift_bs', 'D')
Christian Brabandtdfbdadc2022-05-05 20:46:47 +01002180
2181 let buf = RunVimInTerminal('-S Xtest_edit_shift_bs', #{rows: 3})
2182 call term_sendkeys(buf, "A\<S-BS>-\<esc>")
2183 call TermWait(buf, 50)
2184 call assert_equal('ab-', term_getline(buf, 1))
2185
2186 " clean up
2187 call StopVimInTerminal(buf)
Christian Brabandtdfbdadc2022-05-05 20:46:47 +01002188endfunc
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002189
altermo7d711fe2024-01-16 17:25:17 +01002190func Test_edit_Ctrl_RSB()
2191 new
2192 let g:triggered = []
2193 autocmd InsertCharPre <buffer> let g:triggered += [v:char]
2194
2195 " i_CTRL-] should not trigger InsertCharPre
2196 exe "normal! A\<C-]>"
2197 call assert_equal([], g:triggered)
2198
2199 " i_CTRL-] should expand abbreviations but not trigger InsertCharPre
2200 inoreabbr <buffer> f foo
2201 exe "normal! Af\<C-]>a"
2202 call assert_equal(['f', 'f', 'o', 'o', 'a'], g:triggered)
2203 call assert_equal('fooa', getline(1))
2204
2205 " CTRL-] followed by i_CTRL-V should not expand abbreviations
2206 " i_CTRL-V doesn't trigger InsertCharPre
2207 call setline(1, '')
2208 exe "normal! Af\<C-V>\<C-]>"
2209 call assert_equal("f\<C-]>", getline(1))
2210
2211 let g:triggered = []
2212 call setline(1, '')
2213
2214 " Also test assigning to v:char
2215 autocmd InsertCharPre <buffer> let v:char = 'f'
2216 exe "normal! Ag\<C-]>h"
2217 call assert_equal(['g', 'f', 'o', 'o', 'h'], g:triggered)
2218 call assert_equal('ffff', getline(1))
2219
2220 autocmd! InsertCharPre
2221 unlet g:triggered
2222 bwipe!
2223endfunc
2224
zeertzjq0185c772024-03-25 16:34:51 +01002225func s:check_backspace(expected)
2226 let g:actual = []
2227 inoremap <buffer> <F2> <Cmd>let g:actual += [getline('.')]<CR>
2228 set backspace=indent,eol,start
2229
zeertzjq8ede7a02024-03-28 10:30:08 +01002230 exe "normal i" .. repeat("\<BS>\<F2>", len(a:expected))
zeertzjq0185c772024-03-25 16:34:51 +01002231 call assert_equal(a:expected, g:actual)
2232
2233 set backspace&
2234 iunmap <buffer> <F2>
2235 unlet g:actual
2236endfunc
2237
2238" Test that backspace works with 'smarttab' and mixed Tabs and spaces.
2239func Test_edit_backspace_smarttab_mixed()
zeertzjq8ede7a02024-03-28 10:30:08 +01002240 set smarttab
zeertzjq0185c772024-03-25 16:34:51 +01002241 call NewWindow(1, 30)
zeertzjq8ede7a02024-03-28 10:30:08 +01002242 setlocal tabstop=4 shiftwidth=4
2243
zeertzjq0185c772024-03-25 16:34:51 +01002244 call setline(1, "\t \t \t a")
zeertzjq8ede7a02024-03-28 10:30:08 +01002245 normal! $
zeertzjq0185c772024-03-25 16:34:51 +01002246 call s:check_backspace([
2247 \ "\t \t \ta",
2248 \ "\t \t a",
2249 \ "\t \t a",
2250 \ "\t \ta",
2251 \ "\t a",
2252 \ "\ta",
2253 \ "a",
2254 \ ])
2255
2256 call CloseWindow()
zeertzjq8ede7a02024-03-28 10:30:08 +01002257 set smarttab&
zeertzjq0185c772024-03-25 16:34:51 +01002258endfunc
2259
2260" Test that backspace works with 'smarttab' and 'varsofttabstop'.
2261func Test_edit_backspace_smarttab_varsofttabstop()
2262 CheckFeature vartabs
2263
zeertzjq8ede7a02024-03-28 10:30:08 +01002264 set smarttab
zeertzjq0185c772024-03-25 16:34:51 +01002265 call NewWindow(1, 30)
zeertzjq8ede7a02024-03-28 10:30:08 +01002266 setlocal tabstop=8 varsofttabstop=6,2,5,3
2267
zeertzjq0185c772024-03-25 16:34:51 +01002268 call setline(1, "a\t \t a")
zeertzjq8ede7a02024-03-28 10:30:08 +01002269 normal! $
zeertzjq0185c772024-03-25 16:34:51 +01002270 call s:check_backspace([
2271 \ "a\t \ta",
2272 \ "a\t a",
2273 \ "a\ta",
2274 \ "a a",
2275 \ "aa",
2276 \ "a",
2277 \ ])
2278
2279 call CloseWindow()
zeertzjq8ede7a02024-03-28 10:30:08 +01002280 set smarttab&
zeertzjq0185c772024-03-25 16:34:51 +01002281endfunc
2282
2283" Test that backspace works with 'smarttab' when a Tab is shown as "^I".
2284func Test_edit_backspace_smarttab_list()
zeertzjq8ede7a02024-03-28 10:30:08 +01002285 set smarttab
zeertzjq0185c772024-03-25 16:34:51 +01002286 call NewWindow(1, 30)
zeertzjq8ede7a02024-03-28 10:30:08 +01002287 setlocal tabstop=4 shiftwidth=4 list listchars=
2288
zeertzjq0185c772024-03-25 16:34:51 +01002289 call setline(1, "\t \t \t a")
zeertzjq8ede7a02024-03-28 10:30:08 +01002290 normal! $
zeertzjq0185c772024-03-25 16:34:51 +01002291 call s:check_backspace([
2292 \ "\t \t a",
2293 \ "\t \t a",
2294 \ "\t \ta",
2295 \ "\t a",
2296 \ "a",
2297 \ ])
2298
2299 call CloseWindow()
zeertzjq8ede7a02024-03-28 10:30:08 +01002300 set smarttab&
zeertzjq0185c772024-03-25 16:34:51 +01002301endfunc
2302
2303" Test that backspace works with 'smarttab' and 'breakindent'.
2304func Test_edit_backspace_smarttab_breakindent()
2305 CheckFeature linebreak
2306
zeertzjq8ede7a02024-03-28 10:30:08 +01002307 set smarttab
zeertzjq0185c772024-03-25 16:34:51 +01002308 call NewWindow(3, 17)
zeertzjq8ede7a02024-03-28 10:30:08 +01002309 setlocal tabstop=4 shiftwidth=4 breakindent breakindentopt=min:5
2310
zeertzjq0185c772024-03-25 16:34:51 +01002311 call setline(1, "\t \t \t a")
zeertzjq8ede7a02024-03-28 10:30:08 +01002312 normal! $
zeertzjq0185c772024-03-25 16:34:51 +01002313 call s:check_backspace([
2314 \ "\t \t \ta",
2315 \ "\t \t a",
2316 \ "\t \t a",
2317 \ "\t \ta",
2318 \ "\t a",
2319 \ "\ta",
2320 \ "a",
2321 \ ])
2322
2323 call CloseWindow()
zeertzjq8ede7a02024-03-28 10:30:08 +01002324 set smarttab&
zeertzjq0185c772024-03-25 16:34:51 +01002325endfunc
2326
2327" Test that backspace works with 'smarttab' and virtual text.
2328func Test_edit_backspace_smarttab_virtual_text()
2329 CheckFeature textprop
2330
zeertzjq8ede7a02024-03-28 10:30:08 +01002331 set smarttab
zeertzjq0185c772024-03-25 16:34:51 +01002332 call NewWindow(1, 50)
zeertzjq8ede7a02024-03-28 10:30:08 +01002333 setlocal tabstop=4 shiftwidth=4
2334
zeertzjq0185c772024-03-25 16:34:51 +01002335 call setline(1, "\t \t \t a")
2336 call prop_type_add('theprop', {})
2337 call prop_add(1, 3, {'type': 'theprop', 'text': 'text'})
zeertzjq8ede7a02024-03-28 10:30:08 +01002338 normal! $
zeertzjq0185c772024-03-25 16:34:51 +01002339 call s:check_backspace([
2340 \ "\t \t \ta",
2341 \ "\t \t a",
2342 \ "\t \t a",
2343 \ "\t \ta",
2344 \ "\t a",
2345 \ "\ta",
2346 \ "a",
2347 \ ])
2348
2349 call CloseWindow()
2350 call prop_type_delete('theprop')
zeertzjq8ede7a02024-03-28 10:30:08 +01002351 set smarttab&
zeertzjq0185c772024-03-25 16:34:51 +01002352endfunc
2353
glepnir07f0dbe2025-02-18 20:27:30 +01002354func Test_edit_CAR()
2355 set cot=menu,menuone,noselect
2356 new
2357
2358 call feedkeys("Shello hero\<CR>h\<C-x>\<C-N>e\<CR>", 'tx')
2359 call assert_equal(['hello hero', 'he', ''], getline(1, '$'))
2360
2361 bw!
2362 set cot&
2363endfunc
2364
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002365" vim: shiftwidth=2 sts=2 expandtab