blob: c951f3a7b8e858a28162a01848a93b8859843afe [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
Christian Brabandteb380b92025-07-07 20:53:55 +02007source util/screendump.vim
Bram Moolenaareb992cb2017-03-09 18:20:16 +01008
9" Needs to come first until the bug in getchar() is
10" fixed: https://groups.google.com/d/msg/vim_dev/fXL9yme4H4c/bOR-U6_bAQAJ
Bram Moolenaar1e115362019-01-09 23:01:02 +010011func Test_edit_00b()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010012 new
13 call setline(1, ['abc '])
14 inoreabbr <buffer> h here some more
15 call cursor(1, 4)
16 " <c-l> expands the abbreviation and ends insertmode
17 call feedkeys(":set im\<cr> h\<c-l>:set noim\<cr>", 'tix')
18 call assert_equal(['abc here some more '], getline(1,'$'))
19 iunabbr <buffer> h
20 bw!
21endfunc
22
Bram Moolenaar1e115362019-01-09 23:01:02 +010023func Test_edit_01()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010024 " set for Travis CI?
25 " set nocp noesckeys
26 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +010027 " 1) empty buffer
28 call assert_equal([''], getline(1,'$'))
29 " 2) delete in an empty line
30 call feedkeys("i\<del>\<esc>", 'tnix')
31 call assert_equal([''], getline(1,'$'))
32 %d
33 " 3) delete one character
34 call setline(1, 'a')
35 call feedkeys("i\<del>\<esc>", 'tnix')
36 call assert_equal([''], getline(1,'$'))
37 %d
38 " 4) delete a multibyte character
Bram Moolenaar30276f22019-01-24 17:59:39 +010039 call setline(1, "\u0401")
40 call feedkeys("i\<del>\<esc>", 'tnix')
41 call assert_equal([''], getline(1,'$'))
42 %d
Bram Moolenaareb992cb2017-03-09 18:20:16 +010043 " 5.1) delete linebreak with 'bs' option containing eol
44 let _bs=&bs
45 set bs=eol
46 call setline(1, ["abc def", "ghi jkl"])
47 call cursor(1, 1)
48 call feedkeys("A\<del>\<esc>", 'tnix')
49 call assert_equal(['abc defghi jkl'], getline(1, 2))
50 %d
51 " 5.2) delete linebreak with backspace option w/out eol
52 set bs=
53 call setline(1, ["abc def", "ghi jkl"])
54 call cursor(1, 1)
55 call feedkeys("A\<del>\<esc>", 'tnix')
56 call assert_equal(["abc def", "ghi jkl"], getline(1, 2))
Bram Moolenaareb992cb2017-03-09 18:20:16 +010057 let &bs=_bs
58 bw!
59endfunc
60
Bram Moolenaar1e115362019-01-09 23:01:02 +010061func Test_edit_02()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010062 " Change cursor position in InsertCharPre command
63 new
64 call setline(1, 'abc')
65 call cursor(1, 1)
66 fu! DoIt(...)
67 call cursor(1, 4)
68 if len(a:000)
69 let v:char=a:1
70 endif
71 endfu
72 au InsertCharPre <buffer> :call DoIt('y')
73 call feedkeys("ix\<esc>", 'tnix')
74 call assert_equal(['abcy'], getline(1, '$'))
75 " Setting <Enter> in InsertCharPre
76 au! InsertCharPre <buffer> :call DoIt("\n")
77 call setline(1, 'abc')
78 call cursor(1, 1)
79 call feedkeys("ix\<esc>", 'tnix')
80 call assert_equal(['abc', ''], getline(1, '$'))
81 %d
82 au! InsertCharPre
83 " Change cursor position in InsertEnter command
84 " 1) when setting v:char, keeps changed cursor position
85 au! InsertEnter <buffer> :call DoIt('y')
86 call setline(1, 'abc')
87 call cursor(1, 1)
88 call feedkeys("ix\<esc>", 'tnix')
89 call assert_equal(['abxc'], getline(1, '$'))
90 " 2) when not setting v:char, restores changed cursor position
91 au! InsertEnter <buffer> :call DoIt()
92 call setline(1, 'abc')
93 call cursor(1, 1)
94 call feedkeys("ix\<esc>", 'tnix')
95 call assert_equal(['xabc'], getline(1, '$'))
96 au! InsertEnter
97 delfu DoIt
98 bw!
99endfunc
100
Bram Moolenaar1e115362019-01-09 23:01:02 +0100101func Test_edit_03()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100102 " Change cursor after <c-o> command to end of line
103 new
104 call setline(1, 'abc')
105 call cursor(1, 1)
106 call feedkeys("i\<c-o>$y\<esc>", 'tnix')
107 call assert_equal(['abcy'], getline(1, '$'))
108 %d
109 call setline(1, 'abc')
110 call cursor(1, 1)
111 call feedkeys("i\<c-o>80|y\<esc>", 'tnix')
112 call assert_equal(['abcy'], getline(1, '$'))
113 %d
114 call setline(1, 'abc')
115 call feedkeys("Ad\<c-o>:s/$/efg/\<cr>hij", 'tnix')
116 call assert_equal(['hijabcdefg'], getline(1, '$'))
117 bw!
118endfunc
119
Bram Moolenaar1e115362019-01-09 23:01:02 +0100120func Test_edit_04()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100121 " test for :stopinsert
122 new
123 call setline(1, 'abc')
124 call cursor(1, 1)
125 call feedkeys("i\<c-o>:stopinsert\<cr>$", 'tnix')
126 call feedkeys("aX\<esc>", 'tnix')
127 call assert_equal(['abcX'], getline(1, '$'))
128 %d
129 bw!
130endfunc
131
Bram Moolenaar1e115362019-01-09 23:01:02 +0100132func Test_edit_05()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100133 " test for folds being opened
134 new
135 call setline(1, ['abcX', 'abcX', 'zzzZ'])
136 call cursor(1, 1)
137 set foldmethod=manual foldopen+=insert
138 " create fold for those two lines
139 norm! Vjzf
140 call feedkeys("$ay\<esc>", 'tnix')
141 call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
142 %d
143 call setline(1, ['abcX', 'abcX', 'zzzZ'])
144 call cursor(1, 1)
145 set foldmethod=manual foldopen-=insert
146 " create fold for those two lines
147 norm! Vjzf
148 call feedkeys("$ay\<esc>", 'tnix')
149 call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
150 %d
151 bw!
152endfunc
153
Bram Moolenaar1e115362019-01-09 23:01:02 +0100154func Test_edit_06()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100155 " Test in diff mode
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200156 CheckFeature diff
157 CheckExecutable diff
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100158 new
159 call setline(1, ['abc', 'xxx', 'yyy'])
160 vnew
161 call setline(1, ['abc', 'zzz', 'xxx', 'yyy'])
162 wincmd p
163 diffthis
164 wincmd p
165 diffthis
166 wincmd p
167 call cursor(2, 1)
168 norm! zt
169 call feedkeys("Ozzz\<esc>", 'tnix')
170 call assert_equal(['abc', 'zzz', 'xxx', 'yyy'], getline(1,'$'))
171 bw!
172 bw!
173endfunc
174
Bram Moolenaar1e115362019-01-09 23:01:02 +0100175func Test_edit_07()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100176 " 1) Test with completion <c-l> when popupmenu is visible
177 new
178 call setline(1, 'J')
179
180 func! ListMonths()
181 call complete(col('.')-1, ['January', 'February', 'March',
182 \ 'April', 'May', 'June', 'July', 'August', 'September',
183 \ 'October', 'November', 'December'])
184 return ''
185 endfunc
186 inoremap <buffer> <F5> <C-R>=ListMonths()<CR>
187
188 call feedkeys("A\<f5>\<c-p>". repeat("\<down>", 6)."\<c-l>\<down>\<c-l>\<cr>", 'tx')
189 call assert_equal(['July'], getline(1,'$'))
190 " 1) Test completion when InsertCharPre kicks in
191 %d
192 call setline(1, 'J')
193 fu! DoIt()
194 if v:char=='u'
195 let v:char='an'
196 endif
197 endfu
198 au InsertCharPre <buffer> :call DoIt()
glepnir07f0dbe2025-02-18 20:27:30 +0100199 call feedkeys("A\<f5>\<c-p>u\<C-Y>\<c-l>\<cr>", 'tx')
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200200 call assert_equal(["Jan\<c-l>",''], 1->getline('$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100201 %d
202 call setline(1, 'J')
203 call feedkeys("A\<f5>\<c-p>u\<down>\<c-l>\<cr>", 'tx')
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200204 call assert_equal(["January"], 1->getline('$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100205
206 delfu ListMonths
207 delfu DoIt
208 iunmap <buffer> <f5>
209 bw!
210endfunc
211
Bram Moolenaar1e115362019-01-09 23:01:02 +0100212func Test_edit_08()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100213 " reset insertmode from i_ctrl-r_=
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200214 let g:bufnr = bufnr('%')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100215 new
216 call setline(1, ['abc'])
217 call cursor(1, 4)
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200218 call feedkeys(":set im\<cr>ZZZ\<c-r>=setbufvar(g:bufnr,'&im', 0)\<cr>",'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100219 call assert_equal(['abZZZc'], getline(1,'$'))
220 call assert_equal([0, 1, 1, 0], getpos('.'))
221 call assert_false(0, '&im')
222 bw!
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200223 unlet g:bufnr
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100224endfunc
225
Bram Moolenaar1e115362019-01-09 23:01:02 +0100226func Test_edit_09()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100227 " test i_CTRL-\ combinations
228 new
229 call setline(1, ['abc', 'def', 'ghi'])
230 call cursor(1, 1)
231 " 1) CTRL-\ CTLR-N
232 call feedkeys(":set im\<cr>\<c-\>\<c-n>ccABC\<c-l>", 'txin')
233 call assert_equal(['ABC', 'def', 'ghi'], getline(1,'$'))
234 call setline(1, ['ABC', 'def', 'ghi'])
235 " 2) CTRL-\ CTLR-G
236 call feedkeys("j0\<c-\>\<c-g>ZZZ\<cr>\<c-l>", 'txin')
237 call assert_equal(['ABC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
238 call feedkeys("I\<c-\>\<c-g>YYY\<c-l>", 'txin')
239 call assert_equal(['ABC', 'ZZZ', 'YYYdef', 'ghi'], getline(1,'$'))
240 set noinsertmode
241 " 3) CTRL-\ CTRL-O
242 call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
243 call cursor(1, 1)
244 call feedkeys("A\<c-o>ix", 'txin')
245 call assert_equal(['ABxC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
246 call feedkeys("A\<c-\>\<c-o>ix", 'txin')
247 call assert_equal(['ABxCx', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
248 " 4) CTRL-\ a (should be inserted literally, not special after <c-\>
249 call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
250 call cursor(1, 1)
251 call feedkeys("A\<c-\>a", 'txin')
252 call assert_equal(["ABC\<c-\>a", 'ZZZ', 'def', 'ghi'], getline(1, '$'))
253 bw!
254endfunc
255
Bram Moolenaar1e115362019-01-09 23:01:02 +0100256func Test_edit_11()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100257 " Test that indenting kicks in
258 new
259 set cindent
260 call setline(1, ['{', '', ''])
261 call cursor(2, 1)
262 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
263 call cursor(3, 1)
Bram Moolenaar1671f442020-03-10 07:48:13 +0100264 call feedkeys("\<Insert>/* comment */", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100265 call assert_equal(['{', "\<tab>int c;", "/* comment */"], getline(1, '$'))
266 " added changed cindentkeys slightly
267 set cindent cinkeys+=*/
268 call setline(1, ['{', '', ''])
269 call cursor(2, 1)
270 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
271 call cursor(3, 1)
272 call feedkeys("i/* comment */", 'tnix')
273 call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */"], getline(1, '$'))
274 set cindent cinkeys+==end
275 call feedkeys("oend\<cr>\<esc>", 'tnix')
276 call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */", "\tend", ''], getline(1, '$'))
277 set cinkeys-==end
278 %d
279 " Use indentexpr instead of cindenting
280 func! Do_Indent()
281 if v:lnum == 3
282 return 3*shiftwidth()
283 else
284 return 2*shiftwidth()
285 endif
286 endfunc
287 setl indentexpr=Do_Indent() indentkeys+=*/
288 call setline(1, ['{', '', ''])
289 call cursor(2, 1)
290 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
291 call cursor(3, 1)
292 call feedkeys("i/* comment */", 'tnix')
293 call assert_equal(['{', "\<tab>\<tab>int c;", "\<tab>\<tab>\<tab>/* comment */"], getline(1, '$'))
294 set cinkeys&vim indentkeys&vim
295 set nocindent indentexpr=
296 delfu Do_Indent
297 bw!
298endfunc
299
Bram Moolenaar1e115362019-01-09 23:01:02 +0100300func Test_edit_11_indentexpr()
Bram Moolenaar1b383442017-09-26 20:04:54 +0200301 " Test that indenting kicks in
302 new
303 " Use indentexpr instead of cindenting
304 func! Do_Indent()
305 let pline=prevnonblank(v:lnum)
306 if empty(getline(v:lnum))
307 if getline(pline) =~ 'if\|then'
308 return shiftwidth()
309 else
310 return 0
311 endif
312 else
313 return 0
314 endif
315 endfunc
316 setl indentexpr=Do_Indent() indentkeys+=0=then,0=fi
317 call setline(1, ['if [ $this ]'])
318 call cursor(1, 1)
319 call feedkeys("othen\<cr>that\<cr>fi", 'tnix')
320 call assert_equal(['if [ $this ]', "then", "\<tab>that", "fi"], getline(1, '$'))
321 set cinkeys&vim indentkeys&vim
322 set nocindent indentexpr=
323 delfu Do_Indent
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000324
325 " Using a script-local function
326 func s:NewIndentExpr()
327 endfunc
328 set indentexpr=s:NewIndentExpr()
329 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000330 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000331 set indentexpr=<SID>NewIndentExpr()
332 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000333 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
334 setlocal indentexpr=
335 setglobal indentexpr=s:NewIndentExpr()
336 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
337 call assert_equal('', &indentexpr)
338 new
339 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
340 bw!
341 setglobal indentexpr=<SID>NewIndentExpr()
342 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &g:indentexpr)
343 call assert_equal('', &indentexpr)
344 new
345 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
346 bw!
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000347 set indentexpr&
348
Bram Moolenaar1b383442017-09-26 20:04:54 +0200349 bw!
350endfunc
351
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200352" Test changing indent in replace mode
Bram Moolenaar1e115362019-01-09 23:01:02 +0100353func Test_edit_12()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100354 new
355 call setline(1, ["\tabc", "\tdef"])
356 call cursor(2, 4)
357 call feedkeys("R^\<c-d>", 'tnix')
358 call assert_equal(["\tabc", "def"], getline(1, '$'))
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200359 call assert_equal([0, 2, 2, 0], '.'->getpos())
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100360 %d
361 call setline(1, ["\tabc", "\t\tdef"])
362 call cursor(2, 2)
363 call feedkeys("R^\<c-d>", 'tnix')
364 call assert_equal(["\tabc", "def"], getline(1, '$'))
365 call assert_equal([0, 2, 1, 0], getpos('.'))
366 %d
367 call setline(1, ["\tabc", "\t\tdef"])
368 call cursor(2, 2)
369 call feedkeys("R\<c-t>", 'tnix')
370 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
371 call assert_equal([0, 2, 2, 0], getpos('.'))
372 bw!
373 10vnew
374 call setline(1, ["\tabc", "\t\tdef"])
375 call cursor(2, 2)
376 call feedkeys("R\<c-t>", 'tnix')
377 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
378 call assert_equal([0, 2, 2, 0], getpos('.'))
379 %d
380 set sw=4
381 call setline(1, ["\tabc", "\t\tdef"])
382 call cursor(2, 2)
383 call feedkeys("R\<c-t>\<c-t>", 'tnix')
384 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
385 call assert_equal([0, 2, 2, 0], getpos('.'))
386 %d
387 call setline(1, ["\tabc", "\t\tdef"])
388 call cursor(2, 2)
389 call feedkeys("R\<c-t>\<c-t>", 'tnix')
390 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
391 call assert_equal([0, 2, 2, 0], getpos('.'))
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200392 set sw&
393
394 " In replace mode, after hitting enter in a line with tab characters,
395 " pressing backspace should restore the tab characters.
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100396 %d
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200397 setlocal autoindent backspace=2
398 call setline(1, "\tone\t\ttwo")
399 exe "normal ggRred\<CR>six" .. repeat("\<BS>", 8)
400 call assert_equal(["\tone\t\ttwo"], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100401 bw!
402endfunc
403
Bram Moolenaar1e115362019-01-09 23:01:02 +0100404func Test_edit_13()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100405 " Test smartindenting
Bram Moolenaar8e145b82022-05-21 20:17:31 +0100406 new
407 set smartindent autoindent
408 call setline(1, ["\tabc"])
409 call feedkeys("A {\<cr>more\<cr>}\<esc>", 'tnix')
410 call assert_equal(["\tabc {", "\t\tmore", "\t}"], getline(1, '$'))
411 set smartindent& autoindent&
412 bwipe!
Bram Moolenaar2ba42382019-03-16 18:11:07 +0100413
414 " Test autoindent removing indent of blank line.
415 new
416 call setline(1, ' foo bar baz')
417 set autoindent
418 exe "normal 0eea\<CR>\<CR>\<Esc>"
419 call assert_equal(" foo bar", getline(1))
420 call assert_equal("", getline(2))
421 call assert_equal(" baz", getline(3))
422 set autoindent&
Bram Moolenaar845e0ee2020-06-20 16:05:32 +0200423
424 " pressing <C-U> to erase line should keep the indent with 'autoindent'
425 set backspace=2 autoindent
426 %d
427 exe "normal i\tone\<CR>three\<C-U>two"
428 call assert_equal(["\tone", "\ttwo"], getline(1, '$'))
429 set backspace& autoindent&
430
Bram Moolenaar2ba42382019-03-16 18:11:07 +0100431 bwipe!
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100432endfunc
433
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100434" Test for autoindent removing indent when insert mode is stopped. Some parts
435" of the code is exercised only when interactive mode is used. So use Vim in a
436" terminal.
437func Test_autoindent_remove_indent()
438 CheckRunVimInTerminal
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100439 let buf = RunVimInTerminal('-N Xarifile', {'rows': 6, 'cols' : 20})
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100440 call TermWait(buf)
441 call term_sendkeys(buf, ":set autoindent\n")
442 " leaving insert mode in a new line with indent added by autoindent, should
443 " remove the indent.
444 call term_sendkeys(buf, "i\<Tab>foo\<CR>\<Esc>")
Dominique Pelle923dce22021-11-21 11:36:04 +0000445 " Need to delay for some time, otherwise the code in getchar.c will not be
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100446 " exercised.
447 call TermWait(buf, 50)
448 " when a line is wrapped and the cursor is at the start of the second line,
449 " leaving insert mode, should move the cursor back to the first line.
450 call term_sendkeys(buf, "o" .. repeat('x', 20) .. "\<Esc>")
Dominique Pelle923dce22021-11-21 11:36:04 +0000451 " Need to delay for some time, otherwise the code in getchar.c will not be
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100452 " exercised.
453 call TermWait(buf, 50)
454 call term_sendkeys(buf, ":w\n")
455 call TermWait(buf)
456 call StopVimInTerminal(buf)
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100457 call assert_equal(["\tfoo", '', repeat('x', 20)], readfile('Xarifile'))
458 call delete('Xarifile')
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100459endfunc
460
zeertzjqa3a7d102025-03-18 20:41:24 +0100461func Test_edit_esc_after_CR_autoindent()
462 new
463 setlocal autoindent
464 autocmd InsertLeavePre * let g:prev_cursor = getpos('.')
465
466 call setline(1, 'foobar')
467 exe "normal! $hi\<CR>\<Esc>"
468 call assert_equal(['foob', 'ar'], getline(1, '$'))
469 call assert_equal([0, 2, 1, 0], getpos('.'))
470 call assert_equal([0, 2, 1, 0], getpos("'^"))
471 call assert_equal([0, 2, 1, 0], g:prev_cursor)
472 %d
473
474 call setline(1, 'foobar')
475 exe "normal! $i\<CR>\<Esc>"
476 call assert_equal(['fooba', 'r'], getline(1, '$'))
477 call assert_equal([0, 2, 1, 0], getpos('.'))
478 call assert_equal([0, 2, 1, 0], getpos("'^"))
479 call assert_equal([0, 2, 1, 0], g:prev_cursor)
480 %d
481
482 call setline(1, 'foobar')
483 exe "normal! A\<CR>\<Esc>"
484 call assert_equal(['foobar', ''], getline(1, '$'))
485 call assert_equal([0, 2, 1, 0], getpos('.'))
486 call assert_equal([0, 2, 1, 0], getpos("'^"))
487 call assert_equal([0, 2, 1, 0], g:prev_cursor)
488 %d
489
490 call setline(1, ' foobar')
491 exe "normal! $hi\<CR>\<Esc>"
492 call assert_equal([' foob', ' ar'], getline(1, '$'))
493 call assert_equal([0, 2, 2, 0], getpos('.'))
494 call assert_equal([0, 2, 3, 0], getpos("'^"))
495 call assert_equal([0, 2, 3, 0], g:prev_cursor)
496 %d
497
498 call setline(1, ' foobar')
499 exe "normal! $i\<CR>\<Esc>"
500 call assert_equal([' fooba', ' r'], getline(1, '$'))
501 call assert_equal([0, 2, 2, 0], getpos('.'))
502 call assert_equal([0, 2, 3, 0], getpos("'^"))
503 call assert_equal([0, 2, 3, 0], g:prev_cursor)
504 %d
505
506 call setline(1, ' foobar')
507 exe "normal! A\<CR>\<Esc>"
508 call assert_equal([' foobar', ''], getline(1, '$'))
509 call assert_equal([0, 2, 1, 0], getpos('.'))
510 call assert_equal([0, 2, 1, 0], getpos("'^"))
511 call assert_equal([0, 2, 1, 0], g:prev_cursor)
512 %d
513
514 autocmd! InsertLeavePre
515 unlet g:prev_cursor
516 bwipe!
517endfunc
518
Bram Moolenaar1e115362019-01-09 23:01:02 +0100519func Test_edit_CR()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100520 " Test for <CR> in insert mode
Dominique Pelle923dce22021-11-21 11:36:04 +0000521 " basically only in quickfix mode it's tested, the rest
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100522 " has been taken care of by other tests
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200523 CheckFeature quickfix
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100524 botright new
Bram Moolenaar14f91762022-09-21 15:13:52 +0100525 call writefile(range(1, 10), 'Xqflist.txt', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100526 call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}])
527 copen
528 set modifiable
529 call feedkeys("A\<cr>", 'tnix')
530 call assert_equal('Xqflist.txt', bufname(''))
531 call assert_equal(2, line('.'))
532 cclose
533 botright new
534 call setloclist(0, [{'filename': 'Xqflist.txt', 'lnum': 10}])
535 lopen
536 set modifiable
537 call feedkeys("A\<cr>", 'tnix')
538 call assert_equal('Xqflist.txt', bufname(''))
539 call assert_equal(10, line('.'))
540 call feedkeys("A\<Enter>", 'tnix')
541 call feedkeys("A\<kEnter>", 'tnix')
542 call feedkeys("A\n", 'tnix')
543 call feedkeys("A\r", 'tnix')
544 call assert_equal(map(range(1, 10), 'string(v:val)') + ['', '', '', ''], getline(1, '$'))
Bram Moolenaar14f91762022-09-21 15:13:52 +0100545
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100546 bw!
547 lclose
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100548endfunc
549
Bram Moolenaar1e115362019-01-09 23:01:02 +0100550func Test_edit_CTRL_()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200551 CheckFeature rightleft
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100552 " disabled for Windows builds, why?
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200553 CheckNotMSWindows
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100554 let _encoding=&encoding
555 set encoding=utf-8
556 " Test for CTRL-_
557 new
558 call setline(1, ['abc'])
559 call cursor(1, 1)
560 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
561 call assert_equal(["\<C-_>xyzabc"], getline(1, '$'))
562 call assert_false(&revins)
563 set ari
564 call setline(1, ['abc'])
565 call cursor(1, 1)
566 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
567 call assert_equal(["æèñabc"], getline(1, '$'))
568 call assert_true(&revins)
569 call setline(1, ['abc'])
570 call cursor(1, 1)
571 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
572 call assert_equal(["xyzabc"], getline(1, '$'))
573 call assert_false(&revins)
574 set noari
575 let &encoding=_encoding
576 bw!
577endfunc
578
579" needs to come first, to have the @. register empty
Bram Moolenaar1e115362019-01-09 23:01:02 +0100580func Test_edit_00a_CTRL_A()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100581 " Test pressing CTRL-A
582 new
583 call setline(1, repeat([''], 5))
584 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100585 try
586 call feedkeys("A\<NUL>", 'tnix')
587 catch /^Vim\%((\a\+)\)\=:E29/
588 call assert_true(1, 'E29 error caught')
589 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100590 call cursor(1, 1)
591 call feedkeys("Afoobar \<esc>", 'tnix')
592 call cursor(2, 1)
593 call feedkeys("A\<c-a>more\<esc>", 'tnix')
594 call cursor(3, 1)
595 call feedkeys("A\<NUL>and more\<esc>", 'tnix')
596 call assert_equal(['foobar ', 'foobar more', 'foobar morend more', '', ''], getline(1, '$'))
597 bw!
598endfunc
599
Bram Moolenaar1e115362019-01-09 23:01:02 +0100600func Test_edit_CTRL_EY()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100601 " Ctrl-E/ Ctrl-Y in insert mode completion to scroll
602 10new
603 call setline(1, range(1, 100))
604 call cursor(30, 1)
605 norm! z.
606 call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
607 call assert_equal(30, winsaveview()['topline'])
608 call assert_equal([0, 30, 2, 0], getpos('.'))
609 call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
610 call feedkeys("A\<c-x>".repeat("\<c-y>", 10), 'tnix')
611 call assert_equal(21, winsaveview()['topline'])
612 call assert_equal([0, 30, 2, 0], getpos('.'))
613 bw!
614endfunc
615
Bram Moolenaar1e115362019-01-09 23:01:02 +0100616func Test_edit_CTRL_G()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100617 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100618 call setline(1, ['foobar', 'foobar', 'foobar'])
619 call cursor(2, 4)
620 call feedkeys("ioooooooo\<c-g>k\<c-r>.\<esc>", 'tnix')
621 call assert_equal(['foooooooooobar', 'foooooooooobar', 'foobar'], getline(1, '$'))
622 call assert_equal([0, 1, 11, 0], getpos('.'))
623 call feedkeys("i\<c-g>k\<esc>", 'tnix')
624 call assert_equal([0, 1, 10, 0], getpos('.'))
625 call cursor(2, 4)
626 call feedkeys("i\<c-g>jzzzz\<esc>", 'tnix')
627 call assert_equal(['foooooooooobar', 'foooooooooobar', 'foozzzzbar'], getline(1, '$'))
628 call assert_equal([0, 3, 7, 0], getpos('.'))
629 call feedkeys("i\<c-g>j\<esc>", 'tnix')
630 call assert_equal([0, 3, 6, 0], getpos('.'))
zeertzjq4f026ea2023-02-26 14:47:24 +0000631 call assert_nobeep("normal! i\<c-g>\<esc>")
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100632 bw!
633endfunc
634
Bram Moolenaar1e115362019-01-09 23:01:02 +0100635func Test_edit_CTRL_I()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100636 " Tab in completion mode
637 let path=expand("%:p:h")
638 new
Bram Moolenaarca851592018-06-06 21:04:07 +0200639 call setline(1, [path. "/", ''])
Bram Moolenaarc5379472017-03-16 22:38:00 +0100640 call feedkeys("Arunt\<c-x>\<c-f>\<tab>\<cr>\<esc>", 'tnix')
641 call assert_match('runtest\.vim', getline(1))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100642 %d
Bram Moolenaar14f91762022-09-21 15:13:52 +0100643 call writefile(['one', 'two', 'three'], 'Xinclude.txt', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100644 let include='#include Xinclude.txt'
645 call setline(1, [include, ''])
646 call cursor(2, 1)
647 call feedkeys("A\<c-x>\<tab>\<cr>\<esc>", 'tnix')
648 call assert_equal([include, 'one', ''], getline(1, '$'))
649 call feedkeys("2ggC\<c-x>\<tab>\<down>\<cr>\<esc>", 'tnix')
650 call assert_equal([include, 'two', ''], getline(1, '$'))
651 call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<cr>\<esc>", 'tnix')
652 call assert_equal([include, 'three', ''], getline(1, '$'))
glepnir44180412025-02-20 22:09:48 +0100653 call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100654 call assert_equal([include, '', ''], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100655 bw!
656endfunc
657
Bram Moolenaar1e115362019-01-09 23:01:02 +0100658func Test_edit_CTRL_K()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100659 " Test pressing CTRL-K (basically only dictionary completion and digraphs
660 " the rest is already covered
Bram Moolenaar14f91762022-09-21 15:13:52 +0100661 call writefile(['A', 'AA', 'AAA', 'AAAA'], 'Xdictionary.txt', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100662 set dictionary=Xdictionary.txt
663 new
664 call setline(1, 'A')
665 call cursor(1, 1)
666 call feedkeys("A\<c-x>\<c-k>\<cr>\<esc>", 'tnix')
667 call assert_equal(['AA', ''], getline(1, '$'))
668 %d
669 call setline(1, 'A')
670 call cursor(1, 1)
671 call feedkeys("A\<c-x>\<c-k>\<down>\<cr>\<esc>", 'tnix')
672 call assert_equal(['AAA'], getline(1, '$'))
673 %d
674 call setline(1, 'A')
675 call cursor(1, 1)
676 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<cr>\<esc>", 'tnix')
677 call assert_equal(['AAAA'], getline(1, '$'))
678 %d
679 call setline(1, 'A')
680 call cursor(1, 1)
glepnir44180412025-02-20 22:09:48 +0100681 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100682 call assert_equal(['A'], getline(1, '$'))
683 %d
684 call setline(1, 'A')
685 call cursor(1, 1)
686 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
687 call assert_equal(['AA'], getline(1, '$'))
688
Bram Moolenaar4b96df52020-01-26 22:00:26 +0100689 " press an unexpected key after dictionary completion
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100690 %d
691 call setline(1, 'A')
692 call cursor(1, 1)
693 call feedkeys("A\<c-x>\<c-k>\<c-]>\<cr>\<esc>", 'tnix')
694 call assert_equal(['AA', ''], getline(1, '$'))
695 %d
696 call setline(1, 'A')
697 call cursor(1, 1)
698 call feedkeys("A\<c-x>\<c-k>\<c-s>\<cr>\<esc>", 'tnix')
699 call assert_equal(["AA\<c-s>", ''], getline(1, '$'))
700 %d
701 call setline(1, 'A')
702 call cursor(1, 1)
703 call feedkeys("A\<c-x>\<c-k>\<c-f>\<cr>\<esc>", 'tnix')
704 call assert_equal(["AA\<c-f>", ''], getline(1, '$'))
705
706 set dictionary=
707 %d
708 call setline(1, 'A')
709 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100710 try
711 call feedkeys("A\<c-x>\<c-k>\<esc>", 'tnix')
712 catch
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100713 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100714
Bram Moolenaar30276f22019-01-24 17:59:39 +0100715 call test_override("char_avail", 1)
716 set showcmd
717 %d
718 call feedkeys("A\<c-k>a:\<esc>", 'tnix')
719 call assert_equal(['ä'], getline(1, '$'))
720 call test_override("char_avail", 0)
721 set noshowcmd
722
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100723 bw!
724endfunc
725
Bram Moolenaar1e115362019-01-09 23:01:02 +0100726func Test_edit_CTRL_L()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100727 " Test Ctrl-X Ctrl-L (line completion)
728 new
729 set complete=.
730 call setline(1, ['one', 'two', 'three', '', '', '', ''])
731 call cursor(4, 1)
732 call feedkeys("A\<c-x>\<c-l>\<esc>", 'tnix')
733 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
734 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<esc>", 'tnix')
735 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
736 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100737 call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
Bram Moolenaar02ae9b42018-02-09 15:06:02 +0100738 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100739 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
Bram Moolenaar02ae9b42018-02-09 15:06:02 +0100740 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
741 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100742 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<esc>", 'tnix')
743 call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
744 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<esc>", 'tnix')
745 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
746 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<c-p>\<esc>", 'tnix')
747 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
748 set complete=
749 call cursor(5, 1)
750 call feedkeys("A\<c-x>\<c-l>\<c-p>\<c-n>\<esc>", 'tnix')
751 call assert_equal(['one', 'two', 'three', 'three', "\<c-l>\<c-p>\<c-n>", '', ''], getline(1, '$'))
752 set complete&
753 %d
754 if has("conceal") && has("syntax")
755 call setline(1, ['foo', 'bar', 'foobar'])
756 call test_override("char_avail", 1)
757 set conceallevel=2 concealcursor=n
758 syn on
759 syn match ErrorMsg "^bar"
760 call matchadd("Conceal", 'oo', 10, -1, {'conceal': 'X'})
761 func! DoIt()
762 let g:change=1
763 endfunc
764 au! TextChangedI <buffer> :call DoIt()
765
766 call cursor(2, 1)
767 call assert_false(exists("g:change"))
768 call feedkeys("A \<esc>", 'tnix')
769 call assert_equal(['foo', 'bar ', 'foobar'], getline(1, '$'))
770 call assert_equal(1, g:change)
771
772 call test_override("char_avail", 0)
773 call clearmatches()
774 syn off
775 au! TextChangedI
776 delfu DoIt
777 unlet! g:change
778 endif
779 bw!
780endfunc
781
Bram Moolenaar1e115362019-01-09 23:01:02 +0100782func Test_edit_CTRL_N()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100783 " Check keyword completion
Bram Moolenaara1070ea2021-02-20 19:21:36 +0100784 for e in ['latin1', 'utf-8']
785 exe 'set encoding=' .. e
786 new
787 set complete=.
788 call setline(1, ['INFER', 'loWER', '', '', ])
789 call cursor(3, 1)
790 call feedkeys("Ai\<c-n>\<cr>\<esc>", "tnix")
791 call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
792 call assert_equal(['INFER', 'loWER', 'i', 'LO', '', ''], getline(1, '$'), e)
793 %d
794 call setline(1, ['INFER', 'loWER', '', '', ])
795 call cursor(3, 1)
796 set ignorecase infercase
797 call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix")
798 call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
799 call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'), e)
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000800 set noignorecase noinfercase
801 %d
802 call setline(1, ['one word', 'two word'])
803 exe "normal! Goo\<C-P>\<C-X>\<C-P>"
804 call assert_equal('one word', getline(3))
805 %d
806 set complete&
Bram Moolenaara1070ea2021-02-20 19:21:36 +0100807 bw!
808 endfor
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100809endfunc
810
Bram Moolenaar1e115362019-01-09 23:01:02 +0100811func Test_edit_CTRL_O()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100812 " Check for CTRL-O in insert mode
813 new
814 inoreabbr <buffer> h here some more
815 call setline(1, ['abc', 'def'])
816 call cursor(1, 1)
817 " Ctrl-O after an abbreviation
818 exe "norm A h\<c-o>:set nu\<cr> text"
819 call assert_equal(['abc here some more text', 'def'], getline(1, '$'))
820 call assert_true(&nu)
821 set nonu
822 iunabbr <buffer> h
823 " Ctrl-O at end of line with 've'=onemore
824 call cursor(1, 1)
825 call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
826 call assert_equal([0, 1, 23, 0], g:a)
827 call cursor(1, 1)
828 set ve=onemore
829 call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
830 call assert_equal([0, 1, 24, 0], g:a)
831 set ve=
832 unlet! g:a
833 bw!
834endfunc
835
Bram Moolenaar1e115362019-01-09 23:01:02 +0100836func Test_edit_CTRL_R()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100837 " Insert Register
838 new
839 call test_override("ALL", 1)
840 set showcmd
841 call feedkeys("AFOOBAR eins zwei\<esc>", 'tnix')
842 call feedkeys("O\<c-r>.", 'tnix')
843 call feedkeys("O\<c-r>=10*500\<cr>\<esc>", 'tnix')
844 call feedkeys("O\<c-r>=getreg('=', 1)\<cr>\<esc>", 'tnix')
845 call assert_equal(["getreg('=', 1)", '5000', "FOOBAR eins zwei", "FOOBAR eins zwei"], getline(1, '$'))
846 call test_override("ALL", 0)
847 set noshowcmd
848 bw!
849endfunc
850
Bram Moolenaar1e115362019-01-09 23:01:02 +0100851func Test_edit_CTRL_S()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100852 " Test pressing CTRL-S (basically only spellfile completion)
853 " the rest is already covered
854 new
855 if !has("spell")
856 call setline(1, 'vim')
857 call feedkeys("A\<c-x>ss\<cr>\<esc>", 'tnix')
858 call assert_equal(['vims', ''], getline(1, '$'))
859 bw!
860 return
861 endif
862 call setline(1, 'vim')
863 " spell option not yet set
864 try
865 call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
866 catch /^Vim\%((\a\+)\)\=:E756/
867 call assert_true(1, 'error caught')
868 endtry
869 call assert_equal(['vim', ''], getline(1, '$'))
870 %d
871 setl spell spelllang=en
872 call setline(1, 'vim')
873 call cursor(1, 1)
874 call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
875 call assert_equal(['Vim', ''], getline(1, '$'))
876 %d
877 call setline(1, 'vim')
878 call cursor(1, 1)
879 call feedkeys("A\<c-x>\<c-s>\<down>\<cr>\<esc>", 'tnix')
880 call assert_equal(['Aim'], getline(1, '$'))
881 %d
882 call setline(1, 'vim')
883 call cursor(1, 1)
884 call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
885 call assert_equal(['vim', ''], getline(1, '$'))
886 %d
887 " empty buffer
888 call cursor(1, 1)
889 call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
890 call assert_equal(['', ''], getline(1, '$'))
891 setl nospell
892 bw!
893endfunc
894
Bram Moolenaar1e115362019-01-09 23:01:02 +0100895func Test_edit_CTRL_T()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100896 " Check for CTRL-T and CTRL-X CTRL-T in insert mode
897 " 1) increase indent
898 new
899 call setline(1, "abc")
900 call cursor(1, 1)
901 call feedkeys("A\<c-t>xyz", 'tnix')
902 call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
903 " 2) also when paste option is set
904 set paste
905 call setline(1, "abc")
906 call cursor(1, 1)
907 call feedkeys("A\<c-t>xyz", 'tnix')
908 call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
909 set nopaste
910 " CTRL-X CTRL-T (thesaurus complete)
Bram Moolenaar14f91762022-09-21 15:13:52 +0100911 call writefile(['angry furious mad enraged'], 'Xthesaurus', 'D')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100912 set thesaurus=Xthesaurus
913 call setline(1, 'mad')
914 call cursor(1, 1)
915 call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
916 call assert_equal(['mad', ''], getline(1, '$'))
917 %d
918 call setline(1, 'mad')
919 call cursor(1, 1)
920 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
921 call assert_equal(['angry', ''], getline(1, '$'))
922 %d
923 call setline(1, 'mad')
924 call cursor(1, 1)
925 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
926 call assert_equal(['furious', ''], 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>\<c-n>\<cr>\<esc>", 'tnix')
931 call assert_equal(['enraged', ''], 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>\<c-n>\<cr>\<esc>", 'tnix')
936 call assert_equal(['mad', ''], 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>\<c-n>\<cr>\<esc>", 'tnix')
941 call assert_equal(['mad', ''], getline(1, '$'))
942 " Using <c-p> <c-n> when 'complete' is empty
943 set complete=
944 %d
945 call setline(1, 'mad')
946 call cursor(1, 1)
947 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
948 call assert_equal(['angry', ''], getline(1, '$'))
949 %d
950 call setline(1, 'mad')
951 call cursor(1, 1)
952 call feedkeys("A\<c-x>\<c-t>\<c-p>\<cr>\<esc>", 'tnix')
953 call assert_equal(['mad', ''], getline(1, '$'))
954 set complete&
955
956 set thesaurus=
957 %d
958 call setline(1, 'mad')
959 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100960 try
961 call feedkeys("A\<c-x>\<c-t>\<esc>", 'tnix')
962 catch
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100963 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100964 call assert_equal(['mad'], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100965 bw!
966endfunc
967
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000968" Test thesaurus completion with different encodings
969func Test_thesaurus_complete_with_encoding()
Bram Moolenaar14f91762022-09-21 15:13:52 +0100970 call writefile(['angry furious mad enraged'], 'Xthesaurus', 'D')
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000971 set thesaurus=Xthesaurus
972 for e in ['latin1', 'utf-8']
973 exe 'set encoding=' .. e
974 new
975 call setline(1, 'mad')
976 call cursor(1, 1)
977 call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
978 call assert_equal(['mad', ''], getline(1, '$'))
979 bw!
980 endfor
981 set thesaurus=
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000982endfunc
983
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100984" Test 'thesaurusfunc'
985func MyThesaurus(findstart, base)
986 let mythesaurus = [
987 \ #{word: "happy",
988 \ synonyms: "cheerful,blissful,flying high,looking good,peppy"},
989 \ #{word: "kind",
990 \ synonyms: "amiable,bleeding-heart,heart in right place"}]
991 if a:findstart
992 " locate the start of the word
993 let line = getline('.')
994 let start = col('.') - 1
995 while start > 0 && line[start - 1] =~ '\a'
996 let start -= 1
997 endwhile
998 return start
999 else
1000 " find strings matching with "a:base"
1001 let res = []
1002 for w in mythesaurus
1003 if w.word =~ '^' . a:base
1004 call add(res, w.word)
1005 call extend(res, split(w.synonyms, ","))
1006 endif
1007 endfor
1008 return res
1009 endif
1010endfunc
1011
1012func Test_thesaurus_func()
1013 new
Bram Moolenaarf4d8b762021-10-17 14:13:09 +01001014 set thesaurus=notused
1015 set thesaurusfunc=NotUsed
1016 setlocal thesaurusfunc=MyThesaurus
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +01001017 call setline(1, "an ki")
1018 call cursor(1, 1)
1019 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
1020 call assert_equal(['an amiable', ''], getline(1, '$'))
Bram Moolenaarf4d8b762021-10-17 14:13:09 +01001021
1022 setlocal thesaurusfunc=NonExistingFunc
1023 call assert_fails("normal $a\<C-X>\<C-T>", 'E117:')
1024
1025 setlocal thesaurusfunc=
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +01001026 set thesaurusfunc=NonExistingFunc
1027 call assert_fails("normal $a\<C-X>\<C-T>", 'E117:')
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +01001028 %bw!
Bram Moolenaarf4d8b762021-10-17 14:13:09 +01001029
1030 set thesaurusfunc=
1031 set thesaurus=
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +01001032endfunc
1033
Bram Moolenaar1e115362019-01-09 23:01:02 +01001034func Test_edit_CTRL_U()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001035 " Test 'completefunc'
1036 new
1037 " -1, -2 and -3 are special return values
1038 let g:special=0
1039 fun! CompleteMonths(findstart, base)
1040 if a:findstart
1041 " locate the start of the word
1042 return g:special
1043 else
1044 " find months matching with "a:base"
1045 let res = []
1046 for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
1047 if m =~ '^\c'.a:base
1048 call add(res, {'word': m, 'abbr': m.' Month', 'icase': 0})
1049 endif
1050 endfor
1051 return {'words': res, 'refresh': 'always'}
1052 endif
1053 endfun
1054 set completefunc=CompleteMonths
1055 call setline(1, ['', ''])
1056 call cursor(1, 1)
1057 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1058 call assert_equal(['X', '', ''], getline(1, '$'))
1059 %d
1060 let g:special=-1
1061 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1062 call assert_equal(['XJan', ''], getline(1, '$'))
1063 %d
1064 let g:special=-2
1065 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1066 call assert_equal(['X', ''], getline(1, '$'))
1067 %d
1068 let g:special=-3
1069 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1070 call assert_equal(['X', ''], getline(1, '$'))
1071 %d
1072 let g:special=0
1073 call feedkeys("AM\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1074 call assert_equal(['Mar', ''], getline(1, '$'))
1075 %d
1076 call feedkeys("AM\<c-x>\<c-u>\<c-n>\<cr>\<esc>", 'tnix')
1077 call assert_equal(['May', ''], getline(1, '$'))
1078 %d
1079 call feedkeys("AM\<c-x>\<c-u>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
1080 call assert_equal(['M', ''], getline(1, '$'))
1081 delfu CompleteMonths
1082 %d
1083 try
1084 call feedkeys("A\<c-x>\<c-u>", 'tnix')
1085 call assert_fails(1, 'unknown completion function')
1086 catch /^Vim\%((\a\+)\)\=:E117/
1087 call assert_true(1, 'E117 error caught')
1088 endtry
1089 set completefunc=
1090 bw!
1091endfunc
1092
Bram Moolenaarff06f282020-04-21 22:01:14 +02001093func Test_edit_completefunc_delete()
1094 func CompleteFunc(findstart, base)
1095 if a:findstart == 1
1096 return col('.') - 1
1097 endif
1098 normal dd
1099 return ['a', 'b']
1100 endfunc
1101 new
1102 set completefunc=CompleteFunc
1103 call setline(1, ['', 'abcd', ''])
1104 2d
zeertzjqcfe45652022-05-27 17:26:55 +01001105 call assert_fails("normal 2G$a\<C-X>\<C-U>", 'E565:')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001106 bwipe!
1107endfunc
1108
1109
Bram Moolenaar1e115362019-01-09 23:01:02 +01001110func Test_edit_CTRL_Z()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001111 " Ctrl-Z when insertmode is not set inserts it literally
1112 new
1113 call setline(1, 'abc')
1114 call feedkeys("A\<c-z>\<esc>", 'tnix')
1115 call assert_equal(["abc\<c-z>"], getline(1,'$'))
1116 bw!
1117 " TODO: How to Test Ctrl-Z in insert mode, e.g. suspend?
1118endfunc
1119
Bram Moolenaar1e115362019-01-09 23:01:02 +01001120func Test_edit_DROP()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001121 CheckFeature dnd
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001122 new
1123 call setline(1, ['abc def ghi'])
1124 call cursor(1, 1)
1125 try
1126 call feedkeys("i\<Drop>\<Esc>", 'tnix')
1127 call assert_fails(1, 'Invalid register name')
1128 catch /^Vim\%((\a\+)\)\=:E353/
1129 call assert_true(1, 'error caught')
1130 endtry
1131 bw!
1132endfunc
1133
Bram Moolenaar1e115362019-01-09 23:01:02 +01001134func Test_edit_CTRL_V()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001135 new
1136 call setline(1, ['abc'])
1137 call cursor(2, 1)
zeertzjq502d8ae2022-01-24 15:27:50 +00001138
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001139 " force some redraws
1140 set showmode showcmd
zeertzjq502d8ae2022-01-24 15:27:50 +00001141 call test_override('char_avail', 1)
1142
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001143 call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
1144 call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
1145
1146 if has("rightleft") && exists("+rl")
1147 set rl
1148 call setline(1, ['abc'])
1149 call cursor(2, 1)
1150 call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
1151 call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
1152 set norl
1153 endif
1154
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001155 set noshowmode showcmd
zeertzjq502d8ae2022-01-24 15:27:50 +00001156 call test_override('char_avail', 0)
1157
1158 " No modifiers should be applied to the char typed using i_CTRL-V_digit.
1159 call feedkeys(":append\<CR>\<C-V>76c\<C-V>76\<C-F2>\<C-V>u3c0j\<C-V>u3c0\<M-F3>\<CR>.\<CR>", 'tnix')
1160 call assert_equal('LcL<C-F2>πjπ<M-F3>', getline(2))
1161
1162 if has('osx')
1163 " A char with a modifier should not be a valid char for i_CTRL-V_digit.
1164 call feedkeys("o\<C-V>\<D-j>\<C-V>\<D-1>\<C-V>\<D-o>\<C-V>\<D-x>\<C-V>\<D-u>", 'tnix')
1165 call assert_equal('<D-j><D-1><D-o><D-x><D-u>', getline(3))
1166 endif
1167
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001168 bw!
1169endfunc
1170
Bram Moolenaar1e115362019-01-09 23:01:02 +01001171func Test_edit_F1()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001172 CheckFeature quickfix
1173
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001174 " Pressing <f1>
1175 new
1176 call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix')
1177 set noinsertmode
1178 call assert_equal('help', &buftype)
1179 bw
1180 bw
1181endfunc
1182
Bram Moolenaar1e115362019-01-09 23:01:02 +01001183func Test_edit_F21()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001184 " Pressing <f21>
1185 " sends a netbeans command
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001186 CheckFeature netbeans_intg
1187 new
1188 " I have no idea what this is supposed to do :)
1189 call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
1190 bw
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001191endfunc
1192
Bram Moolenaar1e115362019-01-09 23:01:02 +01001193func Test_edit_HOME_END()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001194 " Test Home/End Keys
1195 new
1196 set foldopen+=hor
1197 call setline(1, ['abc', 'def'])
1198 call cursor(1, 1)
1199 call feedkeys("AX\<Home>Y\<esc>", 'tnix')
1200 call cursor(2, 1)
1201 call feedkeys("iZ\<End>Y\<esc>", 'tnix')
1202 call assert_equal(['YabcX', 'ZdefY'], getline(1, '$'))
1203
1204 set foldopen-=hor
1205 bw!
1206endfunc
1207
Bram Moolenaar1e115362019-01-09 23:01:02 +01001208func Test_edit_INS()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001209 " Test for Pressing <Insert>
1210 new
1211 call setline(1, ['abc', 'def'])
1212 call cursor(1, 1)
1213 call feedkeys("i\<Insert>ZYX>", 'tnix')
1214 call assert_equal(['ZYX>', 'def'], getline(1, '$'))
1215 call setline(1, ['abc', 'def'])
1216 call cursor(1, 1)
1217 call feedkeys("i\<Insert>Z\<Insert>YX>", 'tnix')
1218 call assert_equal(['ZYX>bc', 'def'], getline(1, '$'))
1219 bw!
1220endfunc
1221
Bram Moolenaar1e115362019-01-09 23:01:02 +01001222func Test_edit_LEFT_RIGHT()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001223 " Left, Shift-Left, Right, Shift-Right
1224 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001225 call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX'])
1226 let _ww=&ww
1227 set ww=
1228 call cursor(2, 1)
1229 call feedkeys("i\<left>\<esc>", 'tnix')
1230 call assert_equal([0, 2, 1, 0], getpos('.'))
1231 " Is this a bug, <s-left> does not respect whichwrap option
1232 call feedkeys("i\<s-left>\<esc>", 'tnix')
1233 call assert_equal([0, 1, 8, 0], getpos('.'))
1234 call feedkeys("i". repeat("\<s-left>", 3). "\<esc>", 'tnix')
1235 call assert_equal([0, 1, 1, 0], getpos('.'))
1236 call feedkeys("i\<right>\<esc>", 'tnix')
1237 call assert_equal([0, 1, 1, 0], getpos('.'))
1238 call feedkeys("i\<right>\<right>\<esc>", 'tnix')
1239 call assert_equal([0, 1, 2, 0], getpos('.'))
1240 call feedkeys("A\<right>\<esc>", 'tnix')
1241 call assert_equal([0, 1, 11, 0], getpos('.'))
1242 call feedkeys("A\<s-right>\<esc>", 'tnix')
1243 call assert_equal([0, 2, 1, 0], getpos('.'))
1244 call feedkeys("i\<s-right>\<esc>", 'tnix')
1245 call assert_equal([0, 2, 4, 0], getpos('.'))
1246 call cursor(3, 11)
1247 call feedkeys("A\<right>\<esc>", 'tnix')
1248 call feedkeys("A\<s-right>\<esc>", 'tnix')
1249 call assert_equal([0, 3, 11, 0], getpos('.'))
1250 call cursor(2, 11)
1251 " <S-Right> does not respect 'whichwrap' option
1252 call feedkeys("A\<s-right>\<esc>", 'tnix')
1253 call assert_equal([0, 3, 1, 0], getpos('.'))
1254 " Check motion when 'whichwrap' contains cursor keys for insert mode
1255 set ww+=[,]
1256 call cursor(2, 1)
1257 call feedkeys("i\<left>\<esc>", 'tnix')
1258 call assert_equal([0, 1, 11, 0], getpos('.'))
1259 call cursor(2, 11)
1260 call feedkeys("A\<right>\<esc>", 'tnix')
1261 call assert_equal([0, 3, 1, 0], getpos('.'))
1262 call cursor(2, 11)
1263 call feedkeys("A\<s-right>\<esc>", 'tnix')
1264 call assert_equal([0, 3, 1, 0], getpos('.'))
1265 let &ww = _ww
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001266 bw!
1267endfunc
1268
Bram Moolenaar1e115362019-01-09 23:01:02 +01001269func Test_edit_MOUSE()
Christian Brabandtee17b6f2023-09-09 11:23:50 +02001270 " This is a simple test, since we're not really using the mouse here
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001271 CheckFeature mouse
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001272 10new
1273 call setline(1, range(1, 100))
1274 call cursor(1, 1)
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001275 call assert_equal(1, line('w0'))
1276 call assert_equal(10, line('w$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001277 set mouse=a
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001278 " One scroll event moves three lines.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001279 call feedkeys("A\<ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001280 call assert_equal(4, line('w0'))
1281 call assert_equal(13, line('w$'))
1282 " This should move by one page down.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001283 call feedkeys("A\<S-ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001284 call assert_equal(14, line('w0'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001285 set nostartofline
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001286 " Another page down.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001287 call feedkeys("A\<C-ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001288 call assert_equal(24, line('w0'))
1289
1290 call assert_equal([0, 24, 2, 0], getpos('.'))
1291 call test_setmouse(4, 3)
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001292 call feedkeys("A\<LeftMouse>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001293 call assert_equal([0, 27, 2, 0], getpos('.'))
Bram Moolenaarb3707712022-05-08 22:49:43 +01001294 set mousemodel=extend
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001295 call test_setmouse(5, 3)
1296 call feedkeys("A\<RightMouse>\<esc>\<esc>", 'tnix')
1297 call assert_equal([0, 28, 2, 0], getpos('.'))
Bram Moolenaarb3707712022-05-08 22:49:43 +01001298 set mousemodel&
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001299 call cursor(1, 100)
1300 norm! zt
1301 " this should move by a screen up, but when the test
1302 " is run, it moves up to the top of the buffer...
1303 call feedkeys("A\<ScrollWheelUp>\<esc>", 'tnix')
1304 call assert_equal([0, 1, 1, 0], getpos('.'))
1305 call cursor(1, 30)
1306 norm! zt
1307 call feedkeys("A\<S-ScrollWheelUp>\<esc>", 'tnix')
1308 call assert_equal([0, 1, 1, 0], getpos('.'))
1309 call cursor(1, 30)
1310 norm! zt
1311 call feedkeys("A\<C-ScrollWheelUp>\<esc>", 'tnix')
1312 call assert_equal([0, 1, 1, 0], getpos('.'))
1313 %d
1314 call setline(1, repeat(["12345678901234567890"], 100))
1315 call cursor(2, 1)
1316 call feedkeys("A\<ScrollWheelRight>\<esc>", 'tnix')
1317 call assert_equal([0, 2, 20, 0], getpos('.'))
1318 call feedkeys("A\<ScrollWheelLeft>\<esc>", 'tnix')
1319 call assert_equal([0, 2, 20, 0], getpos('.'))
1320 call feedkeys("A\<S-ScrollWheelRight>\<esc>", 'tnix')
1321 call assert_equal([0, 2, 20, 0], getpos('.'))
1322 call feedkeys("A\<S-ScrollWheelLeft>\<esc>", 'tnix')
1323 call assert_equal([0, 2, 20, 0], getpos('.'))
1324 call feedkeys("A\<C-ScrollWheelRight>\<esc>", 'tnix')
1325 call assert_equal([0, 2, 20, 0], getpos('.'))
1326 call feedkeys("A\<C-ScrollWheelLeft>\<esc>", 'tnix')
1327 call assert_equal([0, 2, 20, 0], getpos('.'))
1328 set mouse& startofline
1329 bw!
1330endfunc
1331
Bram Moolenaar1e115362019-01-09 23:01:02 +01001332func Test_edit_PAGEUP_PAGEDOWN()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001333 10new
1334 call setline(1, repeat(['abc def ghi'], 30))
1335 call cursor(1, 1)
1336 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1337 call assert_equal([0, 9, 1, 0], getpos('.'))
1338 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1339 call assert_equal([0, 17, 1, 0], getpos('.'))
1340 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1341 call assert_equal([0, 25, 1, 0], getpos('.'))
1342 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1343 call assert_equal([0, 30, 1, 0], getpos('.'))
1344 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1345 call assert_equal([0, 30, 1, 0], getpos('.'))
1346 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001347 call assert_equal([0, 29, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001348 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001349 call assert_equal([0, 21, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001350 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001351 call assert_equal([0, 13, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001352 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001353 call assert_equal([0, 10, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001354 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baalcb204e62024-04-02 20:49:45 +02001355 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001356 " <S-Up> is the same as <PageUp>
1357 " <S-Down> is the same as <PageDown>
1358 call cursor(1, 1)
1359 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1360 call assert_equal([0, 9, 1, 0], getpos('.'))
1361 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1362 call assert_equal([0, 17, 1, 0], getpos('.'))
1363 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1364 call assert_equal([0, 25, 1, 0], getpos('.'))
1365 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1366 call assert_equal([0, 30, 1, 0], getpos('.'))
1367 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1368 call assert_equal([0, 30, 1, 0], getpos('.'))
1369 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001370 call assert_equal([0, 29, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001371 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001372 call assert_equal([0, 21, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001373 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001374 call assert_equal([0, 13, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001375 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001376 call assert_equal([0, 10, 1, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001377 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baalcb204e62024-04-02 20:49:45 +02001378 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001379 set nostartofline
1380 call cursor(30, 11)
1381 norm! zt
1382 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001383 call assert_equal([0, 29, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001384 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001385 call assert_equal([0, 21, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001386 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001387 call assert_equal([0, 13, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001388 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001389 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001390 call feedkeys("A\<PageUp>\<esc>", 'tnix')
Luuk van Baalcb204e62024-04-02 20:49:45 +02001391 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001392 call cursor(1, 1)
1393 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1394 call assert_equal([0, 9, 11, 0], getpos('.'))
1395 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1396 call assert_equal([0, 17, 11, 0], getpos('.'))
1397 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1398 call assert_equal([0, 25, 11, 0], getpos('.'))
1399 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1400 call assert_equal([0, 30, 11, 0], getpos('.'))
1401 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1402 call assert_equal([0, 30, 11, 0], getpos('.'))
1403 " <S-Up> is the same as <PageUp>
1404 " <S-Down> is the same as <PageDown>
1405 call cursor(30, 11)
1406 norm! zt
1407 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001408 call assert_equal([0, 29, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001409 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001410 call assert_equal([0, 21, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001411 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001412 call assert_equal([0, 13, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001413 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001414 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001415 call feedkeys("A\<S-Up>\<esc>", 'tnix')
Luuk van Baalcb204e62024-04-02 20:49:45 +02001416 call assert_equal([0, 10, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001417 call cursor(1, 1)
1418 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1419 call assert_equal([0, 9, 11, 0], getpos('.'))
1420 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1421 call assert_equal([0, 17, 11, 0], getpos('.'))
1422 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1423 call assert_equal([0, 25, 11, 0], getpos('.'))
1424 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1425 call assert_equal([0, 30, 11, 0], getpos('.'))
1426 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1427 call assert_equal([0, 30, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001428 bw!
1429endfunc
1430
Bram Moolenaar1e115362019-01-09 23:01:02 +01001431func Test_edit_forbidden()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001432 new
1433 " 1) edit in the sandbox is not allowed
1434 call setline(1, 'a')
1435 com! Sandbox :sandbox call feedkeys("i\<del>\<esc>", 'tnix')
1436 call assert_fails(':Sandbox', 'E48:')
1437 com! Sandbox :sandbox exe "norm! i\<del>"
1438 call assert_fails(':Sandbox', 'E48:')
1439 delcom Sandbox
1440 call assert_equal(['a'], getline(1,'$'))
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001441
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001442 " 2) edit with textlock set
1443 fu! DoIt()
1444 call feedkeys("i\<del>\<esc>", 'tnix')
1445 endfu
1446 au InsertCharPre <buffer> :call DoIt()
1447 try
1448 call feedkeys("ix\<esc>", 'tnix')
1449 call assert_fails(1, 'textlock')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001450 catch /^Vim\%((\a\+)\)\=:E565/ " catch E565: not allowed here
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001451 endtry
1452 " TODO: Might be a bug: should x really be inserted here
1453 call assert_equal(['xa'], getline(1, '$'))
1454 delfu DoIt
1455 try
1456 call feedkeys("ix\<esc>", 'tnix')
1457 call assert_fails(1, 'unknown function')
1458 catch /^Vim\%((\a\+)\)\=:E117/ " catch E117: unknown function
1459 endtry
1460 au! InsertCharPre
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001461
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001462 " 3) edit when completion is shown
1463 fun! Complete(findstart, base)
1464 if a:findstart
1465 return col('.')
1466 else
1467 call feedkeys("i\<del>\<esc>", 'tnix')
1468 return []
1469 endif
1470 endfun
1471 set completefunc=Complete
1472 try
1473 call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
1474 call assert_fails(1, 'change in complete function')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001475 catch /^Vim\%((\a\+)\)\=:E565/ " catch E565
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001476 endtry
1477 delfu Complete
1478 set completefunc=
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001479
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001480 if has("rightleft") && exists("+fkmap")
1481 " 4) 'R' when 'fkmap' and 'revins' is set.
1482 set revins fkmap
1483 try
1484 normal Ri
1485 call assert_fails(1, "R with 'fkmap' and 'ri' set")
1486 catch
1487 finally
1488 set norevins nofkmap
1489 endtry
1490 endif
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001491 bw!
1492endfunc
1493
Bram Moolenaar1e115362019-01-09 23:01:02 +01001494func Test_edit_rightleft()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001495 " Cursor in rightleft mode moves differently
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001496 CheckFeature rightleft
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001497 call NewWindow(10, 20)
1498 call setline(1, ['abc', 'def', 'ghi'])
1499 call cursor(1, 2)
1500 set rightleft
1501 " Screen looks as expected
1502 let lines = ScreenLines([1, 4], winwidth(0))
1503 let expect = [
1504 \" cba",
1505 \" fed",
1506 \" ihg",
1507 \" ~"]
1508 call assert_equal(join(expect, "\n"), join(lines, "\n"))
1509 " 2) right moves to the left
1510 call feedkeys("i\<right>\<esc>x", 'txin')
1511 call assert_equal(['bc', 'def', 'ghi'], getline(1,'$'))
1512 call cursor(1, 2)
1513 call feedkeys("i\<s-right>\<esc>", 'txin')
1514 call cursor(1, 2)
1515 call feedkeys("i\<c-right>\<esc>", 'txin')
1516 " Screen looks as expected
1517 let lines = ScreenLines([1, 4], winwidth(0))
1518 let expect = [
1519 \" cb",
1520 \" fed",
1521 \" ihg",
1522 \" ~"]
1523 call assert_equal(join(expect, "\n"), join(lines, "\n"))
1524 " 2) left moves to the right
1525 call setline(1, ['abc', 'def', 'ghi'])
1526 call cursor(1, 2)
1527 call feedkeys("i\<left>\<esc>x", 'txin')
1528 call assert_equal(['ac', 'def', 'ghi'], getline(1,'$'))
1529 call cursor(1, 2)
1530 call feedkeys("i\<s-left>\<esc>", 'txin')
1531 call cursor(1, 2)
1532 call feedkeys("i\<c-left>\<esc>", 'txin')
1533 " Screen looks as expected
1534 let lines = ScreenLines([1, 4], winwidth(0))
1535 let expect = [
1536 \" ca",
1537 \" fed",
1538 \" ihg",
1539 \" ~"]
1540 call assert_equal(join(expect, "\n"), join(lines, "\n"))
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001541 %d _
1542 call test_override('redraw_flag', 1)
1543 call test_override('char_avail', 1)
1544 call feedkeys("a\<C-V>x41", "xt")
1545 redraw!
1546 call assert_equal(repeat(' ', 19) .. 'A', Screenline(1))
1547 call test_override('ALL', 0)
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001548 set norightleft
1549 bw!
1550endfunc
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001551
1552func Test_edit_complete_very_long_name()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001553 " Long directory names only work on Unix.
1554 CheckUnix
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001555
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01001556 let dirname = getcwd() . "/Xlongdir"
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001557 let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
1558 try
Bram Moolenaar14f91762022-09-21 15:13:52 +01001559 call mkdir(longdirname, 'pR')
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001560 catch /E739:/
1561 " Long directory name probably not supported.
1562 call delete(dirname, 'rf')
1563 return
1564 endtry
1565
Bram Moolenaarf8191c52019-05-18 17:22:54 +02001566 " Try to get the Vim window position before setting 'columns', so that we can
1567 " move the window back to where it was.
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001568 let winposx = getwinposx()
1569 let winposy = getwinposy()
Bram Moolenaarf8191c52019-05-18 17:22:54 +02001570
1571 if winposx >= 0 && winposy >= 0 && !has('gui_running')
1572 " We did get the window position, but xterm may report the wrong numbers.
1573 " Move the window to the reported position and compute any offset.
1574 exe 'winpos ' . winposx . ' ' . winposy
1575 sleep 100m
1576 let x = getwinposx()
1577 if x >= 0
1578 let winposx += winposx - x
1579 endif
1580 let y = getwinposy()
1581 if y >= 0
1582 let winposy += winposy - y
1583 endif
1584 endif
1585
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001586 let save_columns = &columns
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001587 " Need at least about 1100 columns to reproduce the problem.
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001588 set columns=2000
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001589 set noswapfile
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001590
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001591 let longfilename = longdirname . '/' . repeat('a', 255)
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001592 call writefile(['Totum', 'Table'], longfilename)
1593 new
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001594 exe "next Xnofile " . longfilename
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001595 exe "normal iT\<C-N>"
1596
1597 bwipe!
1598 exe 'bwipe! ' . longfilename
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001599 let &columns = save_columns
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001600 if winposx >= 0 && winposy >= 0
1601 exe 'winpos ' . winposx . ' ' . winposy
1602 endif
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001603 set swapfile&
1604endfunc
Bram Moolenaarff930ca2017-10-19 17:12:10 +02001605
Bram Moolenaar2c8c6812018-07-28 17:07:52 +02001606func Test_edit_backtick()
1607 next a\`b c
1608 call assert_equal('a`b', expand('%'))
1609 next
1610 call assert_equal('c', expand('%'))
1611 call assert_equal('a\`b c', expand('##'))
1612endfunc
1613
Bram Moolenaarff930ca2017-10-19 17:12:10 +02001614func Test_edit_quit()
1615 edit foo.txt
1616 split
1617 new
1618 call setline(1, 'hello')
1619 3wincmd w
1620 redraw!
1621 call assert_fails('1q', 'E37:')
1622 bwipe! foo.txt
1623 only
1624endfunc
1625
Bram Moolenaaradb8fbe2018-06-04 20:34:23 +02001626func Test_edit_alt()
1627 " Keeping the cursor line didn't happen when the first line has indent.
1628 new
1629 call setline(1, [' one', 'two', 'three'])
1630 w XAltFile
1631 $
1632 call assert_equal(3, line('.'))
1633 e Xother
1634 e #
1635 call assert_equal(3, line('.'))
1636
1637 bwipe XAltFile
1638 call delete('XAltFile')
1639endfunc
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001640
Bram Moolenaardb934952020-04-27 20:18:31 +02001641func Test_edit_InsertLeave()
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001642 new
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001643 au InsertLeavePre * let g:did_au_pre = 1
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001644 au InsertLeave * let g:did_au = 1
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001645 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001646 let g:did_au = 0
1647 call feedkeys("afoo\<Esc>", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001648 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001649 call assert_equal(1, g:did_au)
1650 call assert_equal('foo', getline(1))
1651
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001652 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001653 let g:did_au = 0
1654 call feedkeys("Sbar\<C-C>", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001655 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001656 call assert_equal(0, g:did_au)
1657 call assert_equal('bar', getline(1))
1658
1659 inoremap x xx<Esc>
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("Saax", '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(1, g:did_au)
1665 call assert_equal('aaxx', getline(1))
1666
1667 inoremap x xx<C-C>
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("Sbbx", '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(0, g:did_au)
1673 call assert_equal('bbxx', getline(1))
1674
1675 bwipe!
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001676 au! InsertLeave InsertLeavePre
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001677 iunmap x
1678endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001679
Bram Moolenaardb934952020-04-27 20:18:31 +02001680func Test_edit_InsertLeave_undo()
1681 new XtestUndo
1682 set undofile
1683 au InsertLeave * wall
1684 exe "normal ofoo\<Esc>"
1685 call assert_equal(2, line('$'))
1686 normal u
1687 call assert_equal(1, line('$'))
1688
1689 bwipe!
1690 au! InsertLeave
1691 call delete('XtestUndo')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001692 call delete(undofile('XtestUndo'))
Bram Moolenaardb934952020-04-27 20:18:31 +02001693 set undofile&
1694endfunc
1695
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001696" Test for inserting characters using CTRL-V followed by a number.
1697func Test_edit_special_chars()
1698 new
1699
Bram Moolenaar424bcae2022-01-31 14:59:41 +00001700 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 +02001701
1702 exe "normal " . t
1703 call assert_equal("ABC !a\<C-O>g\<C-G>8", getline(2))
1704
1705 close!
1706endfunc
Bram Moolenaar8d3b5102019-09-05 21:29:01 +02001707
1708func Test_edit_startinsert()
1709 new
1710 set backspace+=start
1711 call setline(1, 'foobar')
1712 call feedkeys("A\<C-U>\<Esc>", 'xt')
1713 call assert_equal('', getline(1))
1714
1715 call setline(1, 'foobar')
1716 call feedkeys(":startinsert!\<CR>\<C-U>\<Esc>", 'xt')
1717 call assert_equal('', getline(1))
1718
1719 set backspace&
1720 bwipe!
1721endfunc
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001722
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001723" Test for :startreplace and :startgreplace
1724func Test_edit_startreplace()
1725 new
1726 call setline(1, 'abc')
1727 call feedkeys("l:startreplace\<CR>xyz\e", 'xt')
1728 call assert_equal('axyz', getline(1))
1729 call feedkeys("0:startreplace!\<CR>abc\e", 'xt')
1730 call assert_equal('axyzabc', getline(1))
1731 call setline(1, "a\tb")
1732 call feedkeys("0l:startgreplace\<CR>xyz\e", 'xt')
1733 call assert_equal("axyz\tb", getline(1))
1734 call feedkeys("0i\<C-R>=execute('startreplace')\<CR>12\e", 'xt')
1735 call assert_equal("12axyz\tb", getline(1))
1736 close!
1737endfunc
1738
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001739func Test_edit_noesckeys()
Bram Moolenaar215ba3b2019-11-06 15:07:07 +01001740 CheckNotGui
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001741 new
1742
1743 " <Left> moves cursor when 'esckeys' is set
1744 exe "set t_kl=\<Esc>OD"
1745 set esckeys
1746 call feedkeys("axyz\<Esc>ODX", "xt")
1747 call assert_equal("xyXz", getline(1))
1748
1749 " <Left> exits Insert mode when 'esckeys' is off
1750 set noesckeys
1751 call setline(1, '')
1752 call feedkeys("axyz\<Esc>ODX", "xt")
1753 call assert_equal(["DX", "xyz"], getline(1, 2))
1754
1755 bwipe!
1756 set esckeys
1757endfunc
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001758
Bram Moolenaar1671f442020-03-10 07:48:13 +01001759" Test for running an invalid ex command in insert mode using CTRL-O
Bram Moolenaar1671f442020-03-10 07:48:13 +01001760func Test_edit_ctrl_o_invalid_cmd()
1761 new
1762 set showmode showcmd
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001763 " Avoid a sleep of 3 seconds. Zero might have side effects.
1764 call test_override('ui_delay', 50)
Bram Moolenaar1671f442020-03-10 07:48:13 +01001765 let caught_e492 = 0
1766 try
1767 call feedkeys("i\<C-O>:invalid\<CR>abc\<Esc>", "xt")
1768 catch /E492:/
1769 let caught_e492 = 1
1770 endtry
1771 call assert_equal(1, caught_e492)
1772 call assert_equal('abc', getline(1))
1773 set showmode& showcmd&
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001774 call test_override('ui_delay', 0)
Bram Moolenaar1671f442020-03-10 07:48:13 +01001775 close!
1776endfunc
1777
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001778" Test for editing a file with a very long name
1779func Test_edit_illegal_filename()
1780 CheckEnglish
1781 new
1782 redir => msg
1783 exe 'edit ' . repeat('f', 5000)
1784 redir END
1785 call assert_match("Illegal file name$", split(msg, "\n")[0])
1786 close!
1787endfunc
1788
Bram Moolenaarc8fe6452020-10-03 17:04:37 +02001789" Test for editing a directory
1790func Test_edit_is_a_directory()
1791 CheckEnglish
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01001792 let dirname = getcwd() . "/Xeditdir"
Bram Moolenaarc8fe6452020-10-03 17:04:37 +02001793 call mkdir(dirname, 'p')
1794
1795 new
1796 redir => msg
1797 exe 'edit' dirname
1798 redir END
1799 call assert_match("is a directory$", split(msg, "\n")[0])
1800 bwipe!
1801
1802 let dirname .= '/'
1803
1804 new
1805 redir => msg
1806 exe 'edit' dirname
1807 redir END
1808 call assert_match("is a directory$", split(msg, "\n")[0])
1809 bwipe!
1810
1811 call delete(dirname, 'rf')
1812endfunc
1813
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001814" Test for editing a file using invalid file encoding
1815func Test_edit_invalid_encoding()
1816 CheckEnglish
Bram Moolenaar14f91762022-09-21 15:13:52 +01001817 call writefile([], 'Xinvfile', 'D')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001818 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001819 new ++enc=axbyc Xinvfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001820 redir END
1821 call assert_match('\[NOT converted\]', msg)
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001822 close!
1823endfunc
1824
1825" Test for the "charconvert" option
1826func Test_edit_charconvert()
1827 CheckEnglish
Bram Moolenaar14f91762022-09-21 15:13:52 +01001828 call writefile(['one', 'two'], 'Xccfile', 'D')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001829
1830 " set 'charconvert' to a non-existing function
1831 set charconvert=NonExitingFunc()
1832 new
1833 let caught_e117 = v:false
1834 try
1835 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001836 edit ++enc=axbyc Xccfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001837 catch /E117:/
1838 let caught_e117 = v:true
1839 finally
1840 redir END
1841 endtry
1842 call assert_true(caught_e117)
1843 call assert_equal(['one', 'two'], getline(1, '$'))
1844 call assert_match("Conversion with 'charconvert' failed", msg)
1845 close!
1846 set charconvert&
1847
Christian Brabandtee17b6f2023-09-09 11:23:50 +02001848 " 'charconvert' function doesn't create an output file
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001849 func Cconv1()
1850 endfunc
1851 set charconvert=Cconv1()
1852 new
1853 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001854 edit ++enc=axbyc Xccfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001855 redir END
1856 call assert_equal(['one', 'two'], getline(1, '$'))
1857 call assert_match("can't read output of 'charconvert'", msg)
1858 close!
1859 delfunc Cconv1
1860 set charconvert&
1861
1862 " 'charconvert' function to convert to upper case
1863 func Cconv2()
1864 let data = readfile(v:fname_in)
1865 call map(data, 'toupper(v:val)')
1866 call writefile(data, v:fname_out)
1867 endfunc
1868 set charconvert=Cconv2()
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001869 new Xccfile
1870 write ++enc=ucase Xccfile1
1871 call assert_equal(['ONE', 'TWO'], readfile('Xccfile1'))
1872 call delete('Xccfile1')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001873 close!
1874 delfunc Cconv2
1875 set charconvert&
1876
1877 " 'charconvert' function removes the input file
1878 func Cconv3()
1879 call delete(v:fname_in)
1880 endfunc
1881 set charconvert=Cconv3()
1882 new
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001883 call assert_fails('edit ++enc=lcase Xccfile', 'E202:')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001884 call assert_equal([''], getline(1, '$'))
1885 close!
1886 delfunc Cconv3
1887 set charconvert&
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001888endfunc
1889
1890" Test for editing a file without read permission
1891func Test_edit_file_no_read_perm()
1892 CheckUnix
Bram Moolenaar17709e22021-03-19 14:38:12 +01001893 CheckNotRoot
1894
Bram Moolenaar14f91762022-09-21 15:13:52 +01001895 call writefile(['one', 'two'], 'Xnrpfile', 'D')
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001896 call setfperm('Xnrpfile', '-w-------')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001897 new
1898 redir => msg
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001899 edit Xnrpfile
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001900 redir END
1901 call assert_equal(1, &readonly)
1902 call assert_equal([''], getline(1, '$'))
1903 call assert_match('\[Permission Denied\]', msg)
1904 close!
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001905endfunc
1906
zeertzjq3a56b6d2022-04-08 11:56:14 +01001907" Using :edit without leaving 'insertmode' should not cause Insert mode to be
1908" re-entered immediately after <C-L>
1909func Test_edit_insertmode_ex_edit()
1910 CheckRunVimInTerminal
1911
1912 let lines =<< trim END
1913 set insertmode noruler
1914 inoremap <C-B> <Cmd>edit Xfoo<CR>
1915 END
Bram Moolenaar14f91762022-09-21 15:13:52 +01001916 call writefile(lines, 'Xtest_edit_insertmode_ex_edit', 'D')
zeertzjq3a56b6d2022-04-08 11:56:14 +01001917
Bram Moolenaar14f91762022-09-21 15:13:52 +01001918 let buf = RunVimInTerminal('-S Xtest_edit_insertmode_ex_edit', #{rows: 6, wait_for_ruler: 0})
1919 " Somehow when using valgrind "INSERT" does not show up unless we send
1920 " something to the terminal.
1921 for i in range(30)
1922 if term_getline(buf, 6) =~ 'INSERT'
1923 break
1924 endif
1925 call term_sendkeys(buf, "-")
1926 sleep 100m
1927 endfor
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001928 call WaitForAssert({-> assert_match('^-- INSERT --\s*$', term_getline(buf, 6))})
zeertzjq3a56b6d2022-04-08 11:56:14 +01001929 call term_sendkeys(buf, "\<C-B>\<C-L>")
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001930 call WaitForAssert({-> assert_notmatch('^-- INSERT --\s*$', term_getline(buf, 6))})
zeertzjq3a56b6d2022-04-08 11:56:14 +01001931
1932 " clean up
1933 call StopVimInTerminal(buf)
zeertzjq3a56b6d2022-04-08 11:56:14 +01001934endfunc
1935
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001936" Pressing escape in 'insertmode' should beep
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001937" FIXME: Execute this later, when using valgrind it makes the next test
1938" Test_edit_insertmode_ex_edit() fail.
1939func Test_z_edit_insertmode_esc_beeps()
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001940 new
1941 set insertmode
1942 call assert_beeps("call feedkeys(\"one\<Esc>\", 'xt')")
1943 set insertmode&
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001944 " unsupported "CTRL-G l" command should beep in insert mode.
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001945 call assert_beeps("normal i\<C-G>l")
Bram Moolenaarc5382b62022-06-19 15:22:36 +01001946 bwipe!
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001947endfunc
1948
1949" Test for 'hkmap' and 'hkmapp'
1950func Test_edit_hkmap()
1951 CheckFeature rightleft
1952 if has('win32') && !has('gui')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001953 throw 'Skipped: fails on the MS-Windows terminal version'
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001954 endif
1955 new
1956
1957 set revins hkmap
1958 let str = 'abcdefghijklmnopqrstuvwxyz'
1959 let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1960 let str ..= '`/'',.;'
1961 call feedkeys('i' .. str, 'xt')
1962 let expected = "óõú,.;"
1963 let expected ..= "ZYXWVUTSRQPONMLKJIHGFEDCBA"
1964 let expected ..= "æèñ'äåàãø/ôíîöêìçïéòë÷âáðù"
1965 call assert_equal(expected, getline(1))
1966
1967 %d
1968 set revins hkmap hkmapp
1969 let str = 'abcdefghijklmnopqrstuvwxyz'
1970 let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1971 call feedkeys('i' .. str, 'xt')
1972 let expected = "õYXWVUTSRQóOïíLKJIHGFEDêBA"
1973 let expected ..= "öòXùåèúæø'ôñðîì÷çéäâóǟãëáà"
1974 call assert_equal(expected, getline(1))
1975
1976 set revins& hkmap& hkmapp&
1977 close!
1978endfunc
1979
1980" Test for 'allowrevins' and using CTRL-_ in insert mode
1981func Test_edit_allowrevins()
1982 CheckFeature rightleft
1983 new
1984 set allowrevins
1985 call feedkeys("iABC\<C-_>DEF\<C-_>GHI", 'xt')
1986 call assert_equal('ABCFEDGHI', getline(1))
1987 set allowrevins&
1988 close!
1989endfunc
1990
1991" Test for inserting a register in insert mode using CTRL-R
1992func Test_edit_insert_reg()
1993 new
1994 let g:Line = ''
1995 func SaveFirstLine()
1996 let g:Line = Screenline(1)
1997 return 'r'
1998 endfunc
1999 inoremap <expr> <buffer> <F2> SaveFirstLine()
2000 call test_override('redraw_flag', 1)
2001 call test_override('char_avail', 1)
2002 let @r = 'sample'
2003 call feedkeys("a\<C-R>=SaveFirstLine()\<CR>", "xt")
2004 call assert_equal('"', g:Line)
Yegappan Lakshmananfe424d12024-05-17 18:20:43 +02002005
2006 " Test for inserting an null and an empty list
2007 call feedkeys("a\<C-R>=test_null_list()\<CR>", "xt")
2008 call feedkeys("a\<C-R>=[]\<CR>", "xt")
2009 call assert_equal(['r'], getbufline('', 1, '$'))
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02002010 call test_override('ALL', 0)
2011 close!
2012endfunc
2013
Bram Moolenaarc174c2e2023-03-25 20:06:49 +00002014" Test for positioning cursor after CTRL-R expression failed
2015func Test_edit_ctrl_r_failed()
Drew Vogelea67ba72025-05-07 22:05:17 +02002016 CheckScreendump
Bram Moolenaarc174c2e2023-03-25 20:06:49 +00002017 CheckRunVimInTerminal
2018
2019 let buf = RunVimInTerminal('', #{rows: 6, cols: 60})
2020
Yegappan Lakshmananf01493c2024-04-14 23:21:02 +02002021 " trying to insert a blob produces an error
2022 call term_sendkeys(buf, "i\<C-R>=0z\<CR>")
Bram Moolenaarc174c2e2023-03-25 20:06:49 +00002023
2024 " ending Insert mode should put the cursor back on the ':'
2025 call term_sendkeys(buf, ":\<Esc>")
2026 call VerifyScreenDump(buf, 'Test_edit_ctlr_r_failed_1', {})
2027
2028 call StopVimInTerminal(buf)
2029endfunc
2030
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02002031" When a character is inserted at the last position of the last line in a
2032" window, the window contents should be scrolled one line up. If the top line
2033" is part of a fold, then the entire fold should be scrolled up.
2034func Test_edit_lastline_scroll()
2035 new
2036 let h = winheight(0)
2037 let lines = ['one', 'two', 'three']
2038 let lines += repeat(['vim'], h - 4)
2039 call setline(1, lines)
2040 call setline(h, repeat('x', winwidth(0) - 1))
2041 call feedkeys("GAx", 'xt')
2042 redraw!
2043 call assert_equal(h - 1, winline())
2044 call assert_equal(2, line('w0'))
2045
2046 " scroll with a fold
2047 1,2fold
2048 normal gg
2049 call setline(h + 1, repeat('x', winwidth(0) - 1))
2050 call feedkeys("GAx", 'xt')
2051 redraw!
2052 call assert_equal(h - 1, winline())
2053 call assert_equal(3, line('w0'))
2054
2055 close!
2056endfunc
2057
Bram Moolenaar21cbe172020-10-13 19:08:24 +02002058func Test_edit_browse()
2059 " in the GUI this opens a file picker, we only test the terminal behavior
2060 CheckNotGui
2061
2062 " ":browse xxx" checks for the FileExplorer augroup and assumes editing "."
2063 " works then.
2064 augroup FileExplorer
2065 au!
2066 augroup END
2067
2068 " When the USE_FNAME_CASE is defined this used to cause a crash.
2069 browse enew
2070 bwipe!
2071
2072 browse split
2073 bwipe!
2074endfunc
2075
Bram Moolenaarcaf73dc2020-10-26 21:39:13 +01002076func Test_read_invalid()
2077 set encoding=latin1
2078 " This was not properly checking for going past the end.
zeertzjq67fe77d2025-04-20 10:21:18 +02002079 call assert_fails('r`=', 'E484:')
Bram Moolenaarcaf73dc2020-10-26 21:39:13 +01002080 set encoding=utf-8
2081endfunc
2082
Yegappan Lakshmanan59585492021-06-12 13:46:41 +02002083" Test for the 'revins' option
2084func Test_edit_revins()
2085 CheckFeature rightleft
2086 new
2087 set revins
2088 exe "normal! ione\ttwo three"
2089 call assert_equal("eerht owt\teno", getline(1))
2090 call setline(1, "one\ttwo three")
2091 normal! gg$bi a
2092 call assert_equal("one\ttwo a three", getline(1))
2093 exe "normal! $bi\<BS>\<BS>"
2094 call assert_equal("one\ttwo a ree", getline(1))
2095 exe "normal! 0wi\<C-W>"
2096 call assert_equal("one\t a ree", getline(1))
2097 exe "normal! 0wi\<C-U>"
2098 call assert_equal("one\t ", getline(1))
2099 " newline in insert mode starts at the end of the line
2100 call setline(1, 'one two three')
2101 exe "normal! wi\nfour"
2102 call assert_equal(['one two three', 'ruof'], getline(1, '$'))
zeertzjq8ede7a02024-03-28 10:30:08 +01002103 set backspace=indent,eol,start
2104 exe "normal! ggA\<BS>:"
2105 call assert_equal(['one two three:ruof'], getline(1, '$'))
2106 set revins& backspace&
Yegappan Lakshmanan59585492021-06-12 13:46:41 +02002107 bw!
2108endfunc
2109
Bram Moolenaar35a9a002021-09-11 21:14:20 +02002110" Test for getting the character of the line below after "p"
2111func Test_edit_put_CTRL_E()
2112 set encoding=latin1
2113 new
2114 let @" = ''
2115 sil! norm orggRx
2116 sil! norm pr
2117 call assert_equal(['r', 'r'], getline(1, 2))
2118 bwipe!
2119 set encoding=utf-8
2120endfunc
2121
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002122" Test toggling of input method. See :help i_CTRL-^
2123func Test_edit_CTRL_hat()
2124 CheckFeature xim
Dominique Pelle8753c1d2021-10-31 20:19:17 +00002125
Bram Moolenaar0b962e52022-04-03 18:02:37 +01002126 " FIXME: test fails with Motif GUI.
Dominique Pelle8753c1d2021-10-31 20:19:17 +00002127 " test also fails when running in the GUI.
2128 CheckFeature gui_gtk
2129 CheckNotGui
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002130
2131 new
2132
2133 call assert_equal(0, &iminsert)
2134 call feedkeys("i\<C-^>", 'xt')
2135 call assert_equal(2, &iminsert)
2136 call feedkeys("i\<C-^>", 'xt')
2137 call assert_equal(0, &iminsert)
2138
2139 bwipe!
2140endfunc
2141
Bram Moolenaarde05bb22022-01-13 13:08:14 +00002142" Weird long file name was going over the end of NameBuff
2143func Test_edit_overlong_file_name()
2144 CheckUnix
2145
2146 file 0000000000000000000000000000
2147 file %%%%%%%%%%%%%%%%%%%%%%%%%%
2148 file %%%%%%
2149 set readonly
Bram Moolenaar94722c52023-01-28 19:19:03 +00002150 set ls=2
Bram Moolenaarde05bb22022-01-13 13:08:14 +00002151
2152 redraw!
2153 set noreadonly ls&
2154 bwipe!
2155endfunc
2156
Christian Brabandtdfbdadc2022-05-05 20:46:47 +01002157func Test_edit_shift_bs()
2158 CheckMSWindows
2159
2160 " FIXME: this works interactively, but the test fails
2161 throw 'Skipped: Shift-Backspace Test not working correctly :('
2162
2163 " Need to run this in Win32 Terminal, do not use CheckRunVimInTerminal
2164 if !has("terminal")
2165 return
2166 endif
2167
2168 " Shift Backspace should work like Backspace in insert mode
2169 let lines =<< trim END
2170 call setline(1, ['abc'])
2171 END
Bram Moolenaar14f91762022-09-21 15:13:52 +01002172 call writefile(lines, 'Xtest_edit_shift_bs', 'D')
Christian Brabandtdfbdadc2022-05-05 20:46:47 +01002173
2174 let buf = RunVimInTerminal('-S Xtest_edit_shift_bs', #{rows: 3})
2175 call term_sendkeys(buf, "A\<S-BS>-\<esc>")
2176 call TermWait(buf, 50)
2177 call assert_equal('ab-', term_getline(buf, 1))
2178
2179 " clean up
2180 call StopVimInTerminal(buf)
Christian Brabandtdfbdadc2022-05-05 20:46:47 +01002181endfunc
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002182
altermo7d711fe2024-01-16 17:25:17 +01002183func Test_edit_Ctrl_RSB()
2184 new
2185 let g:triggered = []
2186 autocmd InsertCharPre <buffer> let g:triggered += [v:char]
2187
2188 " i_CTRL-] should not trigger InsertCharPre
2189 exe "normal! A\<C-]>"
2190 call assert_equal([], g:triggered)
2191
2192 " i_CTRL-] should expand abbreviations but not trigger InsertCharPre
2193 inoreabbr <buffer> f foo
2194 exe "normal! Af\<C-]>a"
2195 call assert_equal(['f', 'f', 'o', 'o', 'a'], g:triggered)
2196 call assert_equal('fooa', getline(1))
2197
2198 " CTRL-] followed by i_CTRL-V should not expand abbreviations
2199 " i_CTRL-V doesn't trigger InsertCharPre
2200 call setline(1, '')
2201 exe "normal! Af\<C-V>\<C-]>"
2202 call assert_equal("f\<C-]>", getline(1))
2203
2204 let g:triggered = []
2205 call setline(1, '')
2206
2207 " Also test assigning to v:char
2208 autocmd InsertCharPre <buffer> let v:char = 'f'
2209 exe "normal! Ag\<C-]>h"
2210 call assert_equal(['g', 'f', 'o', 'o', 'h'], g:triggered)
2211 call assert_equal('ffff', getline(1))
2212
2213 autocmd! InsertCharPre
2214 unlet g:triggered
2215 bwipe!
2216endfunc
2217
zeertzjq0185c772024-03-25 16:34:51 +01002218func s:check_backspace(expected)
2219 let g:actual = []
2220 inoremap <buffer> <F2> <Cmd>let g:actual += [getline('.')]<CR>
2221 set backspace=indent,eol,start
2222
zeertzjq8ede7a02024-03-28 10:30:08 +01002223 exe "normal i" .. repeat("\<BS>\<F2>", len(a:expected))
zeertzjq0185c772024-03-25 16:34:51 +01002224 call assert_equal(a:expected, g:actual)
2225
2226 set backspace&
2227 iunmap <buffer> <F2>
2228 unlet g:actual
2229endfunc
2230
2231" Test that backspace works with 'smarttab' and mixed Tabs and spaces.
2232func Test_edit_backspace_smarttab_mixed()
zeertzjq8ede7a02024-03-28 10:30:08 +01002233 set smarttab
zeertzjq0185c772024-03-25 16:34:51 +01002234 call NewWindow(1, 30)
zeertzjq8ede7a02024-03-28 10:30:08 +01002235 setlocal tabstop=4 shiftwidth=4
2236
zeertzjq0185c772024-03-25 16:34:51 +01002237 call setline(1, "\t \t \t a")
zeertzjq8ede7a02024-03-28 10:30:08 +01002238 normal! $
zeertzjq0185c772024-03-25 16:34:51 +01002239 call s:check_backspace([
2240 \ "\t \t \ta",
2241 \ "\t \t a",
2242 \ "\t \t a",
2243 \ "\t \ta",
2244 \ "\t a",
2245 \ "\ta",
2246 \ "a",
2247 \ ])
2248
2249 call CloseWindow()
zeertzjq8ede7a02024-03-28 10:30:08 +01002250 set smarttab&
zeertzjq0185c772024-03-25 16:34:51 +01002251endfunc
2252
2253" Test that backspace works with 'smarttab' and 'varsofttabstop'.
2254func Test_edit_backspace_smarttab_varsofttabstop()
2255 CheckFeature vartabs
2256
zeertzjq8ede7a02024-03-28 10:30:08 +01002257 set smarttab
zeertzjq0185c772024-03-25 16:34:51 +01002258 call NewWindow(1, 30)
zeertzjq8ede7a02024-03-28 10:30:08 +01002259 setlocal tabstop=8 varsofttabstop=6,2,5,3
2260
zeertzjq0185c772024-03-25 16:34:51 +01002261 call setline(1, "a\t \t a")
zeertzjq8ede7a02024-03-28 10:30:08 +01002262 normal! $
zeertzjq0185c772024-03-25 16:34:51 +01002263 call s:check_backspace([
2264 \ "a\t \ta",
2265 \ "a\t a",
2266 \ "a\ta",
2267 \ "a a",
2268 \ "aa",
2269 \ "a",
2270 \ ])
2271
2272 call CloseWindow()
zeertzjq8ede7a02024-03-28 10:30:08 +01002273 set smarttab&
zeertzjq0185c772024-03-25 16:34:51 +01002274endfunc
2275
2276" Test that backspace works with 'smarttab' when a Tab is shown as "^I".
2277func Test_edit_backspace_smarttab_list()
zeertzjq8ede7a02024-03-28 10:30:08 +01002278 set smarttab
zeertzjq0185c772024-03-25 16:34:51 +01002279 call NewWindow(1, 30)
zeertzjq8ede7a02024-03-28 10:30:08 +01002280 setlocal tabstop=4 shiftwidth=4 list listchars=
2281
zeertzjq0185c772024-03-25 16:34:51 +01002282 call setline(1, "\t \t \t a")
zeertzjq8ede7a02024-03-28 10:30:08 +01002283 normal! $
zeertzjq0185c772024-03-25 16:34:51 +01002284 call s:check_backspace([
2285 \ "\t \t a",
2286 \ "\t \t a",
2287 \ "\t \ta",
2288 \ "\t a",
2289 \ "a",
2290 \ ])
2291
2292 call CloseWindow()
zeertzjq8ede7a02024-03-28 10:30:08 +01002293 set smarttab&
zeertzjq0185c772024-03-25 16:34:51 +01002294endfunc
2295
2296" Test that backspace works with 'smarttab' and 'breakindent'.
2297func Test_edit_backspace_smarttab_breakindent()
2298 CheckFeature linebreak
2299
zeertzjq8ede7a02024-03-28 10:30:08 +01002300 set smarttab
zeertzjq0185c772024-03-25 16:34:51 +01002301 call NewWindow(3, 17)
zeertzjq8ede7a02024-03-28 10:30:08 +01002302 setlocal tabstop=4 shiftwidth=4 breakindent breakindentopt=min:5
2303
zeertzjq0185c772024-03-25 16:34:51 +01002304 call setline(1, "\t \t \t a")
zeertzjq8ede7a02024-03-28 10:30:08 +01002305 normal! $
zeertzjq0185c772024-03-25 16:34:51 +01002306 call s:check_backspace([
2307 \ "\t \t \ta",
2308 \ "\t \t a",
2309 \ "\t \t a",
2310 \ "\t \ta",
2311 \ "\t a",
2312 \ "\ta",
2313 \ "a",
2314 \ ])
2315
2316 call CloseWindow()
zeertzjq8ede7a02024-03-28 10:30:08 +01002317 set smarttab&
zeertzjq0185c772024-03-25 16:34:51 +01002318endfunc
2319
2320" Test that backspace works with 'smarttab' and virtual text.
2321func Test_edit_backspace_smarttab_virtual_text()
2322 CheckFeature textprop
2323
zeertzjq8ede7a02024-03-28 10:30:08 +01002324 set smarttab
zeertzjq0185c772024-03-25 16:34:51 +01002325 call NewWindow(1, 50)
zeertzjq8ede7a02024-03-28 10:30:08 +01002326 setlocal tabstop=4 shiftwidth=4
2327
zeertzjq0185c772024-03-25 16:34:51 +01002328 call setline(1, "\t \t \t a")
2329 call prop_type_add('theprop', {})
2330 call prop_add(1, 3, {'type': 'theprop', 'text': 'text'})
zeertzjq8ede7a02024-03-28 10:30:08 +01002331 normal! $
zeertzjq0185c772024-03-25 16:34:51 +01002332 call s:check_backspace([
2333 \ "\t \t \ta",
2334 \ "\t \t a",
2335 \ "\t \t a",
2336 \ "\t \ta",
2337 \ "\t a",
2338 \ "\ta",
2339 \ "a",
2340 \ ])
2341
2342 call CloseWindow()
2343 call prop_type_delete('theprop')
zeertzjq8ede7a02024-03-28 10:30:08 +01002344 set smarttab&
zeertzjq0185c772024-03-25 16:34:51 +01002345endfunc
2346
glepnir07f0dbe2025-02-18 20:27:30 +01002347func Test_edit_CAR()
2348 set cot=menu,menuone,noselect
2349 new
2350
2351 call feedkeys("Shello hero\<CR>h\<C-x>\<C-N>e\<CR>", 'tx')
2352 call assert_equal(['hello hero', 'he', ''], getline(1, '$'))
2353
2354 bw!
2355 set cot&
2356endfunc
2357
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002358" vim: shiftwidth=2 sts=2 expandtab