blob: f8749f8814544c89ea5cbe103ca2552a390e63a0 [file] [log] [blame]
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001" Test for edit functions
Bram Moolenaar215ba3b2019-11-06 15:07:07 +01002
Bram Moolenaareb992cb2017-03-09 18:20:16 +01003if exists("+t_kD")
4 let &t_kD="[3;*~"
5endif
Bram Moolenaareb992cb2017-03-09 18:20:16 +01006
Bram Moolenaar215ba3b2019-11-06 15:07:07 +01007source check.vim
8
Bram Moolenaareb992cb2017-03-09 18:20:16 +01009" Needed for testing basic rightleft: Test_edit_rightleft
10source view_util.vim
11
12" Needs to come first until the bug in getchar() is
13" fixed: https://groups.google.com/d/msg/vim_dev/fXL9yme4H4c/bOR-U6_bAQAJ
Bram Moolenaar1e115362019-01-09 23:01:02 +010014func Test_edit_00b()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010015 new
16 call setline(1, ['abc '])
17 inoreabbr <buffer> h here some more
18 call cursor(1, 4)
19 " <c-l> expands the abbreviation and ends insertmode
20 call feedkeys(":set im\<cr> h\<c-l>:set noim\<cr>", 'tix')
21 call assert_equal(['abc here some more '], getline(1,'$'))
22 iunabbr <buffer> h
23 bw!
24endfunc
25
Bram Moolenaar1e115362019-01-09 23:01:02 +010026func Test_edit_01()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010027 " set for Travis CI?
28 " set nocp noesckeys
29 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +010030 " 1) empty buffer
31 call assert_equal([''], getline(1,'$'))
32 " 2) delete in an empty line
33 call feedkeys("i\<del>\<esc>", 'tnix')
34 call assert_equal([''], getline(1,'$'))
35 %d
36 " 3) delete one character
37 call setline(1, 'a')
38 call feedkeys("i\<del>\<esc>", 'tnix')
39 call assert_equal([''], getline(1,'$'))
40 %d
41 " 4) delete a multibyte character
Bram Moolenaar30276f22019-01-24 17:59:39 +010042 call setline(1, "\u0401")
43 call feedkeys("i\<del>\<esc>", 'tnix')
44 call assert_equal([''], getline(1,'$'))
45 %d
Bram Moolenaareb992cb2017-03-09 18:20:16 +010046 " 5.1) delete linebreak with 'bs' option containing eol
47 let _bs=&bs
48 set bs=eol
49 call setline(1, ["abc def", "ghi jkl"])
50 call cursor(1, 1)
51 call feedkeys("A\<del>\<esc>", 'tnix')
52 call assert_equal(['abc defghi jkl'], getline(1, 2))
53 %d
54 " 5.2) delete linebreak with backspace option w/out eol
55 set bs=
56 call setline(1, ["abc def", "ghi jkl"])
57 call cursor(1, 1)
58 call feedkeys("A\<del>\<esc>", 'tnix')
59 call assert_equal(["abc def", "ghi jkl"], getline(1, 2))
Bram Moolenaareb992cb2017-03-09 18:20:16 +010060 let &bs=_bs
61 bw!
62endfunc
63
Bram Moolenaar1e115362019-01-09 23:01:02 +010064func Test_edit_02()
Bram Moolenaareb992cb2017-03-09 18:20:16 +010065 " Change cursor position in InsertCharPre command
66 new
67 call setline(1, 'abc')
68 call cursor(1, 1)
69 fu! DoIt(...)
70 call cursor(1, 4)
71 if len(a:000)
72 let v:char=a:1
73 endif
74 endfu
75 au InsertCharPre <buffer> :call DoIt('y')
76 call feedkeys("ix\<esc>", 'tnix')
77 call assert_equal(['abcy'], getline(1, '$'))
78 " Setting <Enter> in InsertCharPre
79 au! InsertCharPre <buffer> :call DoIt("\n")
80 call setline(1, 'abc')
81 call cursor(1, 1)
82 call feedkeys("ix\<esc>", 'tnix')
83 call assert_equal(['abc', ''], getline(1, '$'))
84 %d
85 au! InsertCharPre
86 " Change cursor position in InsertEnter command
87 " 1) when setting v:char, keeps changed cursor position
88 au! InsertEnter <buffer> :call DoIt('y')
89 call setline(1, 'abc')
90 call cursor(1, 1)
91 call feedkeys("ix\<esc>", 'tnix')
92 call assert_equal(['abxc'], getline(1, '$'))
93 " 2) when not setting v:char, restores changed cursor position
94 au! InsertEnter <buffer> :call DoIt()
95 call setline(1, 'abc')
96 call cursor(1, 1)
97 call feedkeys("ix\<esc>", 'tnix')
98 call assert_equal(['xabc'], getline(1, '$'))
99 au! InsertEnter
100 delfu DoIt
101 bw!
102endfunc
103
Bram Moolenaar1e115362019-01-09 23:01:02 +0100104func Test_edit_03()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100105 " Change cursor after <c-o> command to end of line
106 new
107 call setline(1, 'abc')
108 call cursor(1, 1)
109 call feedkeys("i\<c-o>$y\<esc>", 'tnix')
110 call assert_equal(['abcy'], getline(1, '$'))
111 %d
112 call setline(1, 'abc')
113 call cursor(1, 1)
114 call feedkeys("i\<c-o>80|y\<esc>", 'tnix')
115 call assert_equal(['abcy'], getline(1, '$'))
116 %d
117 call setline(1, 'abc')
118 call feedkeys("Ad\<c-o>:s/$/efg/\<cr>hij", 'tnix')
119 call assert_equal(['hijabcdefg'], getline(1, '$'))
120 bw!
121endfunc
122
Bram Moolenaar1e115362019-01-09 23:01:02 +0100123func Test_edit_04()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100124 " test for :stopinsert
125 new
126 call setline(1, 'abc')
127 call cursor(1, 1)
128 call feedkeys("i\<c-o>:stopinsert\<cr>$", 'tnix')
129 call feedkeys("aX\<esc>", 'tnix')
130 call assert_equal(['abcX'], getline(1, '$'))
131 %d
132 bw!
133endfunc
134
Bram Moolenaar1e115362019-01-09 23:01:02 +0100135func Test_edit_05()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100136 " test for folds being opened
137 new
138 call setline(1, ['abcX', 'abcX', 'zzzZ'])
139 call cursor(1, 1)
140 set foldmethod=manual foldopen+=insert
141 " create fold for those two lines
142 norm! Vjzf
143 call feedkeys("$ay\<esc>", 'tnix')
144 call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
145 %d
146 call setline(1, ['abcX', 'abcX', 'zzzZ'])
147 call cursor(1, 1)
148 set foldmethod=manual foldopen-=insert
149 " create fold for those two lines
150 norm! Vjzf
151 call feedkeys("$ay\<esc>", 'tnix')
152 call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
153 %d
154 bw!
155endfunc
156
Bram Moolenaar1e115362019-01-09 23:01:02 +0100157func Test_edit_06()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100158 " Test in diff mode
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200159 CheckFeature diff
160 CheckExecutable diff
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100161 new
162 call setline(1, ['abc', 'xxx', 'yyy'])
163 vnew
164 call setline(1, ['abc', 'zzz', 'xxx', 'yyy'])
165 wincmd p
166 diffthis
167 wincmd p
168 diffthis
169 wincmd p
170 call cursor(2, 1)
171 norm! zt
172 call feedkeys("Ozzz\<esc>", 'tnix')
173 call assert_equal(['abc', 'zzz', 'xxx', 'yyy'], getline(1,'$'))
174 bw!
175 bw!
176endfunc
177
Bram Moolenaar1e115362019-01-09 23:01:02 +0100178func Test_edit_07()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100179 " 1) Test with completion <c-l> when popupmenu is visible
180 new
181 call setline(1, 'J')
182
183 func! ListMonths()
184 call complete(col('.')-1, ['January', 'February', 'March',
185 \ 'April', 'May', 'June', 'July', 'August', 'September',
186 \ 'October', 'November', 'December'])
187 return ''
188 endfunc
189 inoremap <buffer> <F5> <C-R>=ListMonths()<CR>
190
191 call feedkeys("A\<f5>\<c-p>". repeat("\<down>", 6)."\<c-l>\<down>\<c-l>\<cr>", 'tx')
192 call assert_equal(['July'], getline(1,'$'))
193 " 1) Test completion when InsertCharPre kicks in
194 %d
195 call setline(1, 'J')
196 fu! DoIt()
197 if v:char=='u'
198 let v:char='an'
199 endif
200 endfu
201 au InsertCharPre <buffer> :call DoIt()
202 call feedkeys("A\<f5>\<c-p>u\<cr>\<c-l>\<cr>", 'tx')
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200203 call assert_equal(["Jan\<c-l>",''], 1->getline('$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100204 %d
205 call setline(1, 'J')
206 call feedkeys("A\<f5>\<c-p>u\<down>\<c-l>\<cr>", 'tx')
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200207 call assert_equal(["January"], 1->getline('$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100208
209 delfu ListMonths
210 delfu DoIt
211 iunmap <buffer> <f5>
212 bw!
213endfunc
214
Bram Moolenaar1e115362019-01-09 23:01:02 +0100215func Test_edit_08()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100216 " reset insertmode from i_ctrl-r_=
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200217 let g:bufnr = bufnr('%')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100218 new
219 call setline(1, ['abc'])
220 call cursor(1, 4)
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200221 call feedkeys(":set im\<cr>ZZZ\<c-r>=setbufvar(g:bufnr,'&im', 0)\<cr>",'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100222 call assert_equal(['abZZZc'], getline(1,'$'))
223 call assert_equal([0, 1, 1, 0], getpos('.'))
224 call assert_false(0, '&im')
225 bw!
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200226 unlet g:bufnr
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100227endfunc
228
Bram Moolenaar1e115362019-01-09 23:01:02 +0100229func Test_edit_09()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100230 " test i_CTRL-\ combinations
231 new
232 call setline(1, ['abc', 'def', 'ghi'])
233 call cursor(1, 1)
234 " 1) CTRL-\ CTLR-N
235 call feedkeys(":set im\<cr>\<c-\>\<c-n>ccABC\<c-l>", 'txin')
236 call assert_equal(['ABC', 'def', 'ghi'], getline(1,'$'))
237 call setline(1, ['ABC', 'def', 'ghi'])
238 " 2) CTRL-\ CTLR-G
239 call feedkeys("j0\<c-\>\<c-g>ZZZ\<cr>\<c-l>", 'txin')
240 call assert_equal(['ABC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
241 call feedkeys("I\<c-\>\<c-g>YYY\<c-l>", 'txin')
242 call assert_equal(['ABC', 'ZZZ', 'YYYdef', 'ghi'], getline(1,'$'))
243 set noinsertmode
244 " 3) CTRL-\ CTRL-O
245 call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
246 call cursor(1, 1)
247 call feedkeys("A\<c-o>ix", 'txin')
248 call assert_equal(['ABxC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
249 call feedkeys("A\<c-\>\<c-o>ix", 'txin')
250 call assert_equal(['ABxCx', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
251 " 4) CTRL-\ a (should be inserted literally, not special after <c-\>
252 call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
253 call cursor(1, 1)
254 call feedkeys("A\<c-\>a", 'txin')
255 call assert_equal(["ABC\<c-\>a", 'ZZZ', 'def', 'ghi'], getline(1, '$'))
256 bw!
257endfunc
258
Bram Moolenaar1e115362019-01-09 23:01:02 +0100259func Test_edit_11()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100260 " Test that indenting kicks in
261 new
262 set cindent
263 call setline(1, ['{', '', ''])
264 call cursor(2, 1)
265 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
266 call cursor(3, 1)
Bram Moolenaar1671f442020-03-10 07:48:13 +0100267 call feedkeys("\<Insert>/* comment */", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100268 call assert_equal(['{', "\<tab>int c;", "/* comment */"], getline(1, '$'))
269 " added changed cindentkeys slightly
270 set cindent cinkeys+=*/
271 call setline(1, ['{', '', ''])
272 call cursor(2, 1)
273 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
274 call cursor(3, 1)
275 call feedkeys("i/* comment */", 'tnix')
276 call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */"], getline(1, '$'))
277 set cindent cinkeys+==end
278 call feedkeys("oend\<cr>\<esc>", 'tnix')
279 call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */", "\tend", ''], getline(1, '$'))
280 set cinkeys-==end
281 %d
282 " Use indentexpr instead of cindenting
283 func! Do_Indent()
284 if v:lnum == 3
285 return 3*shiftwidth()
286 else
287 return 2*shiftwidth()
288 endif
289 endfunc
290 setl indentexpr=Do_Indent() indentkeys+=*/
291 call setline(1, ['{', '', ''])
292 call cursor(2, 1)
293 call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
294 call cursor(3, 1)
295 call feedkeys("i/* comment */", 'tnix')
296 call assert_equal(['{', "\<tab>\<tab>int c;", "\<tab>\<tab>\<tab>/* comment */"], getline(1, '$'))
297 set cinkeys&vim indentkeys&vim
298 set nocindent indentexpr=
299 delfu Do_Indent
300 bw!
301endfunc
302
Bram Moolenaar1e115362019-01-09 23:01:02 +0100303func Test_edit_11_indentexpr()
Bram Moolenaar1b383442017-09-26 20:04:54 +0200304 " Test that indenting kicks in
305 new
306 " Use indentexpr instead of cindenting
307 func! Do_Indent()
308 let pline=prevnonblank(v:lnum)
309 if empty(getline(v:lnum))
310 if getline(pline) =~ 'if\|then'
311 return shiftwidth()
312 else
313 return 0
314 endif
315 else
316 return 0
317 endif
318 endfunc
319 setl indentexpr=Do_Indent() indentkeys+=0=then,0=fi
320 call setline(1, ['if [ $this ]'])
321 call cursor(1, 1)
322 call feedkeys("othen\<cr>that\<cr>fi", 'tnix')
323 call assert_equal(['if [ $this ]', "then", "\<tab>that", "fi"], getline(1, '$'))
324 set cinkeys&vim indentkeys&vim
325 set nocindent indentexpr=
326 delfu Do_Indent
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000327
328 " Using a script-local function
329 func s:NewIndentExpr()
330 endfunc
331 set indentexpr=s:NewIndentExpr()
332 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
333 set indentexpr=<SID>NewIndentExpr()
334 call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
335 set indentexpr&
336
Bram Moolenaar1b383442017-09-26 20:04:54 +0200337 bw!
338endfunc
339
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200340" Test changing indent in replace mode
Bram Moolenaar1e115362019-01-09 23:01:02 +0100341func Test_edit_12()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100342 new
343 call setline(1, ["\tabc", "\tdef"])
344 call cursor(2, 4)
345 call feedkeys("R^\<c-d>", 'tnix')
346 call assert_equal(["\tabc", "def"], getline(1, '$'))
Bram Moolenaar4c313b12019-08-24 22:58:31 +0200347 call assert_equal([0, 2, 2, 0], '.'->getpos())
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100348 %d
349 call setline(1, ["\tabc", "\t\tdef"])
350 call cursor(2, 2)
351 call feedkeys("R^\<c-d>", 'tnix')
352 call assert_equal(["\tabc", "def"], getline(1, '$'))
353 call assert_equal([0, 2, 1, 0], getpos('.'))
354 %d
355 call setline(1, ["\tabc", "\t\tdef"])
356 call cursor(2, 2)
357 call feedkeys("R\<c-t>", 'tnix')
358 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
359 call assert_equal([0, 2, 2, 0], getpos('.'))
360 bw!
361 10vnew
362 call setline(1, ["\tabc", "\t\tdef"])
363 call cursor(2, 2)
364 call feedkeys("R\<c-t>", 'tnix')
365 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
366 call assert_equal([0, 2, 2, 0], getpos('.'))
367 %d
368 set sw=4
369 call setline(1, ["\tabc", "\t\tdef"])
370 call cursor(2, 2)
371 call feedkeys("R\<c-t>\<c-t>", 'tnix')
372 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
373 call assert_equal([0, 2, 2, 0], getpos('.'))
374 %d
375 call setline(1, ["\tabc", "\t\tdef"])
376 call cursor(2, 2)
377 call feedkeys("R\<c-t>\<c-t>", 'tnix')
378 call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
379 call assert_equal([0, 2, 2, 0], getpos('.'))
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200380 set sw&
381
382 " In replace mode, after hitting enter in a line with tab characters,
383 " pressing backspace should restore the tab characters.
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100384 %d
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200385 setlocal autoindent backspace=2
386 call setline(1, "\tone\t\ttwo")
387 exe "normal ggRred\<CR>six" .. repeat("\<BS>", 8)
388 call assert_equal(["\tone\t\ttwo"], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100389 bw!
390endfunc
391
Bram Moolenaar1e115362019-01-09 23:01:02 +0100392func Test_edit_13()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100393 " Test smartindenting
Bram Moolenaar8e145b82022-05-21 20:17:31 +0100394 new
395 set smartindent autoindent
396 call setline(1, ["\tabc"])
397 call feedkeys("A {\<cr>more\<cr>}\<esc>", 'tnix')
398 call assert_equal(["\tabc {", "\t\tmore", "\t}"], getline(1, '$'))
399 set smartindent& autoindent&
400 bwipe!
Bram Moolenaar2ba42382019-03-16 18:11:07 +0100401
402 " Test autoindent removing indent of blank line.
403 new
404 call setline(1, ' foo bar baz')
405 set autoindent
406 exe "normal 0eea\<CR>\<CR>\<Esc>"
407 call assert_equal(" foo bar", getline(1))
408 call assert_equal("", getline(2))
409 call assert_equal(" baz", getline(3))
410 set autoindent&
Bram Moolenaar845e0ee2020-06-20 16:05:32 +0200411
412 " pressing <C-U> to erase line should keep the indent with 'autoindent'
413 set backspace=2 autoindent
414 %d
415 exe "normal i\tone\<CR>three\<C-U>two"
416 call assert_equal(["\tone", "\ttwo"], getline(1, '$'))
417 set backspace& autoindent&
418
Bram Moolenaar2ba42382019-03-16 18:11:07 +0100419 bwipe!
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100420endfunc
421
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100422" Test for autoindent removing indent when insert mode is stopped. Some parts
423" of the code is exercised only when interactive mode is used. So use Vim in a
424" terminal.
425func Test_autoindent_remove_indent()
426 CheckRunVimInTerminal
427 let buf = RunVimInTerminal('-N Xfile', {'rows': 6, 'cols' : 20})
428 call TermWait(buf)
429 call term_sendkeys(buf, ":set autoindent\n")
430 " leaving insert mode in a new line with indent added by autoindent, should
431 " remove the indent.
432 call term_sendkeys(buf, "i\<Tab>foo\<CR>\<Esc>")
Dominique Pelle923dce22021-11-21 11:36:04 +0000433 " Need to delay for some time, otherwise the code in getchar.c will not be
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100434 " exercised.
435 call TermWait(buf, 50)
436 " when a line is wrapped and the cursor is at the start of the second line,
437 " leaving insert mode, should move the cursor back to the first line.
438 call term_sendkeys(buf, "o" .. repeat('x', 20) .. "\<Esc>")
Dominique Pelle923dce22021-11-21 11:36:04 +0000439 " Need to delay for some time, otherwise the code in getchar.c will not be
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100440 " exercised.
441 call TermWait(buf, 50)
442 call term_sendkeys(buf, ":w\n")
443 call TermWait(buf)
444 call StopVimInTerminal(buf)
445 call assert_equal(["\tfoo", '', repeat('x', 20)], readfile('Xfile'))
446 call delete('Xfile')
447endfunc
448
Bram Moolenaar1e115362019-01-09 23:01:02 +0100449func Test_edit_CR()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100450 " Test for <CR> in insert mode
Dominique Pelle923dce22021-11-21 11:36:04 +0000451 " basically only in quickfix mode it's tested, the rest
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100452 " has been taken care of by other tests
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200453 CheckFeature quickfix
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100454 botright new
455 call writefile(range(1, 10), 'Xqflist.txt')
456 call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}])
457 copen
458 set modifiable
459 call feedkeys("A\<cr>", 'tnix')
460 call assert_equal('Xqflist.txt', bufname(''))
461 call assert_equal(2, line('.'))
462 cclose
463 botright new
464 call setloclist(0, [{'filename': 'Xqflist.txt', 'lnum': 10}])
465 lopen
466 set modifiable
467 call feedkeys("A\<cr>", 'tnix')
468 call assert_equal('Xqflist.txt', bufname(''))
469 call assert_equal(10, line('.'))
470 call feedkeys("A\<Enter>", 'tnix')
471 call feedkeys("A\<kEnter>", 'tnix')
472 call feedkeys("A\n", 'tnix')
473 call feedkeys("A\r", 'tnix')
474 call assert_equal(map(range(1, 10), 'string(v:val)') + ['', '', '', ''], getline(1, '$'))
475 bw!
476 lclose
477 call delete('Xqflist.txt')
478endfunc
479
Bram Moolenaar1e115362019-01-09 23:01:02 +0100480func Test_edit_CTRL_()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200481 CheckFeature rightleft
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100482 " disabled for Windows builds, why?
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200483 CheckNotMSWindows
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100484 let _encoding=&encoding
485 set encoding=utf-8
486 " Test for CTRL-_
487 new
488 call setline(1, ['abc'])
489 call cursor(1, 1)
490 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
491 call assert_equal(["\<C-_>xyzabc"], getline(1, '$'))
492 call assert_false(&revins)
493 set ari
494 call setline(1, ['abc'])
495 call cursor(1, 1)
496 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
497 call assert_equal(["æèñabc"], getline(1, '$'))
498 call assert_true(&revins)
499 call setline(1, ['abc'])
500 call cursor(1, 1)
501 call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
502 call assert_equal(["xyzabc"], getline(1, '$'))
503 call assert_false(&revins)
504 set noari
505 let &encoding=_encoding
506 bw!
507endfunc
508
509" needs to come first, to have the @. register empty
Bram Moolenaar1e115362019-01-09 23:01:02 +0100510func Test_edit_00a_CTRL_A()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100511 " Test pressing CTRL-A
512 new
513 call setline(1, repeat([''], 5))
514 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100515 try
516 call feedkeys("A\<NUL>", 'tnix')
517 catch /^Vim\%((\a\+)\)\=:E29/
518 call assert_true(1, 'E29 error caught')
519 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100520 call cursor(1, 1)
521 call feedkeys("Afoobar \<esc>", 'tnix')
522 call cursor(2, 1)
523 call feedkeys("A\<c-a>more\<esc>", 'tnix')
524 call cursor(3, 1)
525 call feedkeys("A\<NUL>and more\<esc>", 'tnix')
526 call assert_equal(['foobar ', 'foobar more', 'foobar morend more', '', ''], getline(1, '$'))
527 bw!
528endfunc
529
Bram Moolenaar1e115362019-01-09 23:01:02 +0100530func Test_edit_CTRL_EY()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100531 " Ctrl-E/ Ctrl-Y in insert mode completion to scroll
532 10new
533 call setline(1, range(1, 100))
534 call cursor(30, 1)
535 norm! z.
536 call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
537 call assert_equal(30, winsaveview()['topline'])
538 call assert_equal([0, 30, 2, 0], getpos('.'))
539 call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
540 call feedkeys("A\<c-x>".repeat("\<c-y>", 10), 'tnix')
541 call assert_equal(21, winsaveview()['topline'])
542 call assert_equal([0, 30, 2, 0], getpos('.'))
543 bw!
544endfunc
545
Bram Moolenaar1e115362019-01-09 23:01:02 +0100546func Test_edit_CTRL_G()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100547 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100548 call setline(1, ['foobar', 'foobar', 'foobar'])
549 call cursor(2, 4)
550 call feedkeys("ioooooooo\<c-g>k\<c-r>.\<esc>", 'tnix')
551 call assert_equal(['foooooooooobar', 'foooooooooobar', 'foobar'], getline(1, '$'))
552 call assert_equal([0, 1, 11, 0], getpos('.'))
553 call feedkeys("i\<c-g>k\<esc>", 'tnix')
554 call assert_equal([0, 1, 10, 0], getpos('.'))
555 call cursor(2, 4)
556 call feedkeys("i\<c-g>jzzzz\<esc>", 'tnix')
557 call assert_equal(['foooooooooobar', 'foooooooooobar', 'foozzzzbar'], getline(1, '$'))
558 call assert_equal([0, 3, 7, 0], getpos('.'))
559 call feedkeys("i\<c-g>j\<esc>", 'tnix')
560 call assert_equal([0, 3, 6, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100561 bw!
562endfunc
563
Bram Moolenaar1e115362019-01-09 23:01:02 +0100564func Test_edit_CTRL_I()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100565 " Tab in completion mode
566 let path=expand("%:p:h")
567 new
Bram Moolenaarca851592018-06-06 21:04:07 +0200568 call setline(1, [path. "/", ''])
Bram Moolenaarc5379472017-03-16 22:38:00 +0100569 call feedkeys("Arunt\<c-x>\<c-f>\<tab>\<cr>\<esc>", 'tnix')
570 call assert_match('runtest\.vim', getline(1))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100571 %d
572 call writefile(['one', 'two', 'three'], 'Xinclude.txt')
573 let include='#include Xinclude.txt'
574 call setline(1, [include, ''])
575 call cursor(2, 1)
576 call feedkeys("A\<c-x>\<tab>\<cr>\<esc>", 'tnix')
577 call assert_equal([include, 'one', ''], getline(1, '$'))
578 call feedkeys("2ggC\<c-x>\<tab>\<down>\<cr>\<esc>", 'tnix')
579 call assert_equal([include, 'two', ''], getline(1, '$'))
580 call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<cr>\<esc>", 'tnix')
581 call assert_equal([include, 'three', ''], getline(1, '$'))
582 call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
583 call assert_equal([include, '', ''], getline(1, '$'))
584 call delete("Xinclude.txt")
585 bw!
586endfunc
587
Bram Moolenaar1e115362019-01-09 23:01:02 +0100588func Test_edit_CTRL_K()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100589 " Test pressing CTRL-K (basically only dictionary completion and digraphs
590 " the rest is already covered
591 call writefile(['A', 'AA', 'AAA', 'AAAA'], 'Xdictionary.txt')
592 set dictionary=Xdictionary.txt
593 new
594 call setline(1, 'A')
595 call cursor(1, 1)
596 call feedkeys("A\<c-x>\<c-k>\<cr>\<esc>", 'tnix')
597 call assert_equal(['AA', ''], getline(1, '$'))
598 %d
599 call setline(1, 'A')
600 call cursor(1, 1)
601 call feedkeys("A\<c-x>\<c-k>\<down>\<cr>\<esc>", 'tnix')
602 call assert_equal(['AAA'], getline(1, '$'))
603 %d
604 call setline(1, 'A')
605 call cursor(1, 1)
606 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<cr>\<esc>", 'tnix')
607 call assert_equal(['AAAA'], getline(1, '$'))
608 %d
609 call setline(1, 'A')
610 call cursor(1, 1)
611 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
612 call assert_equal(['A'], getline(1, '$'))
613 %d
614 call setline(1, 'A')
615 call cursor(1, 1)
616 call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
617 call assert_equal(['AA'], getline(1, '$'))
618
Bram Moolenaar4b96df52020-01-26 22:00:26 +0100619 " press an unexpected key after dictionary completion
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100620 %d
621 call setline(1, 'A')
622 call cursor(1, 1)
623 call feedkeys("A\<c-x>\<c-k>\<c-]>\<cr>\<esc>", 'tnix')
624 call assert_equal(['AA', ''], getline(1, '$'))
625 %d
626 call setline(1, 'A')
627 call cursor(1, 1)
628 call feedkeys("A\<c-x>\<c-k>\<c-s>\<cr>\<esc>", 'tnix')
629 call assert_equal(["AA\<c-s>", ''], getline(1, '$'))
630 %d
631 call setline(1, 'A')
632 call cursor(1, 1)
633 call feedkeys("A\<c-x>\<c-k>\<c-f>\<cr>\<esc>", 'tnix')
634 call assert_equal(["AA\<c-f>", ''], getline(1, '$'))
635
636 set dictionary=
637 %d
638 call setline(1, 'A')
639 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100640 let v:testing = 1
641 try
642 call feedkeys("A\<c-x>\<c-k>\<esc>", 'tnix')
643 catch
644 " error sleeps 2 seconds, when v:testing is not set
645 let v:testing = 0
646 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100647 call delete('Xdictionary.txt')
648
Bram Moolenaar30276f22019-01-24 17:59:39 +0100649 call test_override("char_avail", 1)
650 set showcmd
651 %d
652 call feedkeys("A\<c-k>a:\<esc>", 'tnix')
653 call assert_equal(['ä'], getline(1, '$'))
654 call test_override("char_avail", 0)
655 set noshowcmd
656
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100657 bw!
658endfunc
659
Bram Moolenaar1e115362019-01-09 23:01:02 +0100660func Test_edit_CTRL_L()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100661 " Test Ctrl-X Ctrl-L (line completion)
662 new
663 set complete=.
664 call setline(1, ['one', 'two', 'three', '', '', '', ''])
665 call cursor(4, 1)
666 call feedkeys("A\<c-x>\<c-l>\<esc>", 'tnix')
667 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
668 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<esc>", 'tnix')
669 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
670 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100671 call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
Bram Moolenaar02ae9b42018-02-09 15:06:02 +0100672 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100673 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
Bram Moolenaar02ae9b42018-02-09 15:06:02 +0100674 call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
675 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100676 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<esc>", 'tnix')
677 call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
678 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<esc>", 'tnix')
679 call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
680 call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<c-p>\<esc>", 'tnix')
681 call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
682 set complete=
683 call cursor(5, 1)
684 call feedkeys("A\<c-x>\<c-l>\<c-p>\<c-n>\<esc>", 'tnix')
685 call assert_equal(['one', 'two', 'three', 'three', "\<c-l>\<c-p>\<c-n>", '', ''], getline(1, '$'))
686 set complete&
687 %d
688 if has("conceal") && has("syntax")
689 call setline(1, ['foo', 'bar', 'foobar'])
690 call test_override("char_avail", 1)
691 set conceallevel=2 concealcursor=n
692 syn on
693 syn match ErrorMsg "^bar"
694 call matchadd("Conceal", 'oo', 10, -1, {'conceal': 'X'})
695 func! DoIt()
696 let g:change=1
697 endfunc
698 au! TextChangedI <buffer> :call DoIt()
699
700 call cursor(2, 1)
701 call assert_false(exists("g:change"))
702 call feedkeys("A \<esc>", 'tnix')
703 call assert_equal(['foo', 'bar ', 'foobar'], getline(1, '$'))
704 call assert_equal(1, g:change)
705
706 call test_override("char_avail", 0)
707 call clearmatches()
708 syn off
709 au! TextChangedI
710 delfu DoIt
711 unlet! g:change
712 endif
713 bw!
714endfunc
715
Bram Moolenaar1e115362019-01-09 23:01:02 +0100716func Test_edit_CTRL_N()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100717 " Check keyword completion
Bram Moolenaara1070ea2021-02-20 19:21:36 +0100718 for e in ['latin1', 'utf-8']
719 exe 'set encoding=' .. e
720 new
721 set complete=.
722 call setline(1, ['INFER', 'loWER', '', '', ])
723 call cursor(3, 1)
724 call feedkeys("Ai\<c-n>\<cr>\<esc>", "tnix")
725 call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
726 call assert_equal(['INFER', 'loWER', 'i', 'LO', '', ''], getline(1, '$'), e)
727 %d
728 call setline(1, ['INFER', 'loWER', '', '', ])
729 call cursor(3, 1)
730 set ignorecase infercase
731 call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix")
732 call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
733 call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'), e)
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000734 set noignorecase noinfercase
735 %d
736 call setline(1, ['one word', 'two word'])
737 exe "normal! Goo\<C-P>\<C-X>\<C-P>"
738 call assert_equal('one word', getline(3))
739 %d
740 set complete&
Bram Moolenaara1070ea2021-02-20 19:21:36 +0100741 bw!
742 endfor
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100743endfunc
744
Bram Moolenaar1e115362019-01-09 23:01:02 +0100745func Test_edit_CTRL_O()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100746 " Check for CTRL-O in insert mode
747 new
748 inoreabbr <buffer> h here some more
749 call setline(1, ['abc', 'def'])
750 call cursor(1, 1)
751 " Ctrl-O after an abbreviation
752 exe "norm A h\<c-o>:set nu\<cr> text"
753 call assert_equal(['abc here some more text', 'def'], getline(1, '$'))
754 call assert_true(&nu)
755 set nonu
756 iunabbr <buffer> h
757 " Ctrl-O at end of line with 've'=onemore
758 call cursor(1, 1)
759 call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
760 call assert_equal([0, 1, 23, 0], g:a)
761 call cursor(1, 1)
762 set ve=onemore
763 call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
764 call assert_equal([0, 1, 24, 0], g:a)
765 set ve=
766 unlet! g:a
767 bw!
768endfunc
769
Bram Moolenaar1e115362019-01-09 23:01:02 +0100770func Test_edit_CTRL_R()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100771 " Insert Register
772 new
773 call test_override("ALL", 1)
774 set showcmd
775 call feedkeys("AFOOBAR eins zwei\<esc>", 'tnix')
776 call feedkeys("O\<c-r>.", 'tnix')
777 call feedkeys("O\<c-r>=10*500\<cr>\<esc>", 'tnix')
778 call feedkeys("O\<c-r>=getreg('=', 1)\<cr>\<esc>", 'tnix')
779 call assert_equal(["getreg('=', 1)", '5000', "FOOBAR eins zwei", "FOOBAR eins zwei"], getline(1, '$'))
780 call test_override("ALL", 0)
781 set noshowcmd
782 bw!
783endfunc
784
Bram Moolenaar1e115362019-01-09 23:01:02 +0100785func Test_edit_CTRL_S()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100786 " Test pressing CTRL-S (basically only spellfile completion)
787 " the rest is already covered
788 new
789 if !has("spell")
790 call setline(1, 'vim')
791 call feedkeys("A\<c-x>ss\<cr>\<esc>", 'tnix')
792 call assert_equal(['vims', ''], getline(1, '$'))
793 bw!
794 return
795 endif
796 call setline(1, 'vim')
797 " spell option not yet set
798 try
799 call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
800 catch /^Vim\%((\a\+)\)\=:E756/
801 call assert_true(1, 'error caught')
802 endtry
803 call assert_equal(['vim', ''], getline(1, '$'))
804 %d
805 setl spell spelllang=en
806 call setline(1, 'vim')
807 call cursor(1, 1)
808 call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
809 call assert_equal(['Vim', ''], getline(1, '$'))
810 %d
811 call setline(1, 'vim')
812 call cursor(1, 1)
813 call feedkeys("A\<c-x>\<c-s>\<down>\<cr>\<esc>", 'tnix')
814 call assert_equal(['Aim'], getline(1, '$'))
815 %d
816 call setline(1, 'vim')
817 call cursor(1, 1)
818 call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
819 call assert_equal(['vim', ''], getline(1, '$'))
820 %d
821 " empty buffer
822 call cursor(1, 1)
823 call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
824 call assert_equal(['', ''], getline(1, '$'))
825 setl nospell
826 bw!
827endfunc
828
Bram Moolenaar1e115362019-01-09 23:01:02 +0100829func Test_edit_CTRL_T()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100830 " Check for CTRL-T and CTRL-X CTRL-T in insert mode
831 " 1) increase indent
832 new
833 call setline(1, "abc")
834 call cursor(1, 1)
835 call feedkeys("A\<c-t>xyz", 'tnix')
836 call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
837 " 2) also when paste option is set
838 set paste
839 call setline(1, "abc")
840 call cursor(1, 1)
841 call feedkeys("A\<c-t>xyz", 'tnix')
842 call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
843 set nopaste
844 " CTRL-X CTRL-T (thesaurus complete)
845 call writefile(['angry furious mad enraged'], 'Xthesaurus')
846 set thesaurus=Xthesaurus
847 call setline(1, 'mad')
848 call cursor(1, 1)
849 call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
850 call assert_equal(['mad', ''], getline(1, '$'))
851 %d
852 call setline(1, 'mad')
853 call cursor(1, 1)
854 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
855 call assert_equal(['angry', ''], getline(1, '$'))
856 %d
857 call setline(1, 'mad')
858 call cursor(1, 1)
859 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
860 call assert_equal(['furious', ''], getline(1, '$'))
861 %d
862 call setline(1, 'mad')
863 call cursor(1, 1)
864 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
865 call assert_equal(['enraged', ''], getline(1, '$'))
866 %d
867 call setline(1, 'mad')
868 call cursor(1, 1)
869 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
870 call assert_equal(['mad', ''], getline(1, '$'))
871 %d
872 call setline(1, 'mad')
873 call cursor(1, 1)
874 call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
875 call assert_equal(['mad', ''], getline(1, '$'))
876 " Using <c-p> <c-n> when 'complete' is empty
877 set complete=
878 %d
879 call setline(1, 'mad')
880 call cursor(1, 1)
881 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
882 call assert_equal(['angry', ''], getline(1, '$'))
883 %d
884 call setline(1, 'mad')
885 call cursor(1, 1)
886 call feedkeys("A\<c-x>\<c-t>\<c-p>\<cr>\<esc>", 'tnix')
887 call assert_equal(['mad', ''], getline(1, '$'))
888 set complete&
889
890 set thesaurus=
891 %d
892 call setline(1, 'mad')
893 call cursor(1, 1)
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100894 let v:testing = 1
895 try
896 call feedkeys("A\<c-x>\<c-t>\<esc>", 'tnix')
897 catch
898 " error sleeps 2 seconds, when v:testing is not set
899 let v:testing = 0
900 endtry
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100901 call assert_equal(['mad'], getline(1, '$'))
902 call delete('Xthesaurus')
903 bw!
904endfunc
905
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000906" Test thesaurus completion with different encodings
907func Test_thesaurus_complete_with_encoding()
908 call writefile(['angry furious mad enraged'], 'Xthesaurus')
909 set thesaurus=Xthesaurus
910 for e in ['latin1', 'utf-8']
911 exe 'set encoding=' .. e
912 new
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 bw!
918 endfor
919 set thesaurus=
920 call delete('Xthesaurus')
921endfunc
922
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100923" Test 'thesaurusfunc'
924func MyThesaurus(findstart, base)
925 let mythesaurus = [
926 \ #{word: "happy",
927 \ synonyms: "cheerful,blissful,flying high,looking good,peppy"},
928 \ #{word: "kind",
929 \ synonyms: "amiable,bleeding-heart,heart in right place"}]
930 if a:findstart
931 " locate the start of the word
932 let line = getline('.')
933 let start = col('.') - 1
934 while start > 0 && line[start - 1] =~ '\a'
935 let start -= 1
936 endwhile
937 return start
938 else
939 " find strings matching with "a:base"
940 let res = []
941 for w in mythesaurus
942 if w.word =~ '^' . a:base
943 call add(res, w.word)
944 call extend(res, split(w.synonyms, ","))
945 endif
946 endfor
947 return res
948 endif
949endfunc
950
951func Test_thesaurus_func()
952 new
Bram Moolenaarf4d8b762021-10-17 14:13:09 +0100953 set thesaurus=notused
954 set thesaurusfunc=NotUsed
955 setlocal thesaurusfunc=MyThesaurus
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100956 call setline(1, "an ki")
957 call cursor(1, 1)
958 call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
959 call assert_equal(['an amiable', ''], getline(1, '$'))
Bram Moolenaarf4d8b762021-10-17 14:13:09 +0100960
961 setlocal thesaurusfunc=NonExistingFunc
962 call assert_fails("normal $a\<C-X>\<C-T>", 'E117:')
963
964 setlocal thesaurusfunc=
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100965 set thesaurusfunc=NonExistingFunc
966 call assert_fails("normal $a\<C-X>\<C-T>", 'E117:')
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100967 %bw!
Bram Moolenaarf4d8b762021-10-17 14:13:09 +0100968
969 set thesaurusfunc=
970 set thesaurus=
Yegappan Lakshmanan160e9942021-10-16 15:41:29 +0100971endfunc
972
Bram Moolenaar1e115362019-01-09 23:01:02 +0100973func Test_edit_CTRL_U()
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100974 " Test 'completefunc'
975 new
976 " -1, -2 and -3 are special return values
977 let g:special=0
978 fun! CompleteMonths(findstart, base)
979 if a:findstart
980 " locate the start of the word
981 return g:special
982 else
983 " find months matching with "a:base"
984 let res = []
985 for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
986 if m =~ '^\c'.a:base
987 call add(res, {'word': m, 'abbr': m.' Month', 'icase': 0})
988 endif
989 endfor
990 return {'words': res, 'refresh': 'always'}
991 endif
992 endfun
993 set completefunc=CompleteMonths
994 call setline(1, ['', ''])
995 call cursor(1, 1)
996 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
997 call assert_equal(['X', '', ''], getline(1, '$'))
998 %d
999 let g:special=-1
1000 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1001 call assert_equal(['XJan', ''], getline(1, '$'))
1002 %d
1003 let g:special=-2
1004 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1005 call assert_equal(['X', ''], getline(1, '$'))
1006 %d
1007 let g:special=-3
1008 call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1009 call assert_equal(['X', ''], getline(1, '$'))
1010 %d
1011 let g:special=0
1012 call feedkeys("AM\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
1013 call assert_equal(['Mar', ''], getline(1, '$'))
1014 %d
1015 call feedkeys("AM\<c-x>\<c-u>\<c-n>\<cr>\<esc>", 'tnix')
1016 call assert_equal(['May', ''], getline(1, '$'))
1017 %d
1018 call feedkeys("AM\<c-x>\<c-u>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
1019 call assert_equal(['M', ''], getline(1, '$'))
1020 delfu CompleteMonths
1021 %d
1022 try
1023 call feedkeys("A\<c-x>\<c-u>", 'tnix')
1024 call assert_fails(1, 'unknown completion function')
1025 catch /^Vim\%((\a\+)\)\=:E117/
1026 call assert_true(1, 'E117 error caught')
1027 endtry
1028 set completefunc=
1029 bw!
1030endfunc
1031
Bram Moolenaarff06f282020-04-21 22:01:14 +02001032func Test_edit_completefunc_delete()
1033 func CompleteFunc(findstart, base)
1034 if a:findstart == 1
1035 return col('.') - 1
1036 endif
1037 normal dd
1038 return ['a', 'b']
1039 endfunc
1040 new
1041 set completefunc=CompleteFunc
1042 call setline(1, ['', 'abcd', ''])
1043 2d
Bram Moolenaar6adb9ea2020-04-30 22:31:18 +02001044 call assert_fails("normal 2G$a\<C-X>\<C-U>", 'E578:')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001045 bwipe!
1046endfunc
1047
1048
Bram Moolenaar1e115362019-01-09 23:01:02 +01001049func Test_edit_CTRL_Z()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001050 " Ctrl-Z when insertmode is not set inserts it literally
1051 new
1052 call setline(1, 'abc')
1053 call feedkeys("A\<c-z>\<esc>", 'tnix')
1054 call assert_equal(["abc\<c-z>"], getline(1,'$'))
1055 bw!
1056 " TODO: How to Test Ctrl-Z in insert mode, e.g. suspend?
1057endfunc
1058
Bram Moolenaar1e115362019-01-09 23:01:02 +01001059func Test_edit_DROP()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001060 CheckFeature dnd
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001061 new
1062 call setline(1, ['abc def ghi'])
1063 call cursor(1, 1)
1064 try
1065 call feedkeys("i\<Drop>\<Esc>", 'tnix')
1066 call assert_fails(1, 'Invalid register name')
1067 catch /^Vim\%((\a\+)\)\=:E353/
1068 call assert_true(1, 'error caught')
1069 endtry
1070 bw!
1071endfunc
1072
Bram Moolenaar1e115362019-01-09 23:01:02 +01001073func Test_edit_CTRL_V()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001074 new
1075 call setline(1, ['abc'])
1076 call cursor(2, 1)
zeertzjq502d8ae2022-01-24 15:27:50 +00001077
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001078 " force some redraws
1079 set showmode showcmd
zeertzjq502d8ae2022-01-24 15:27:50 +00001080 call test_override('char_avail', 1)
1081
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001082 call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
1083 call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
1084
1085 if has("rightleft") && exists("+rl")
1086 set rl
1087 call setline(1, ['abc'])
1088 call cursor(2, 1)
1089 call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
1090 call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
1091 set norl
1092 endif
1093
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001094 set noshowmode showcmd
zeertzjq502d8ae2022-01-24 15:27:50 +00001095 call test_override('char_avail', 0)
1096
1097 " No modifiers should be applied to the char typed using i_CTRL-V_digit.
1098 call feedkeys(":append\<CR>\<C-V>76c\<C-V>76\<C-F2>\<C-V>u3c0j\<C-V>u3c0\<M-F3>\<CR>.\<CR>", 'tnix')
1099 call assert_equal('LcL<C-F2>πjπ<M-F3>', getline(2))
1100
1101 if has('osx')
1102 " A char with a modifier should not be a valid char for i_CTRL-V_digit.
1103 call feedkeys("o\<C-V>\<D-j>\<C-V>\<D-1>\<C-V>\<D-o>\<C-V>\<D-x>\<C-V>\<D-u>", 'tnix')
1104 call assert_equal('<D-j><D-1><D-o><D-x><D-u>', getline(3))
1105 endif
1106
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001107 bw!
1108endfunc
1109
Bram Moolenaar1e115362019-01-09 23:01:02 +01001110func Test_edit_F1()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001111 CheckFeature quickfix
1112
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001113 " Pressing <f1>
1114 new
1115 call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix')
1116 set noinsertmode
1117 call assert_equal('help', &buftype)
1118 bw
1119 bw
1120endfunc
1121
Bram Moolenaar1e115362019-01-09 23:01:02 +01001122func Test_edit_F21()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001123 " Pressing <f21>
1124 " sends a netbeans command
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001125 CheckFeature netbeans_intg
1126 new
1127 " I have no idea what this is supposed to do :)
1128 call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
1129 bw
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001130endfunc
1131
Bram Moolenaar1e115362019-01-09 23:01:02 +01001132func Test_edit_HOME_END()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001133 " Test Home/End Keys
1134 new
1135 set foldopen+=hor
1136 call setline(1, ['abc', 'def'])
1137 call cursor(1, 1)
1138 call feedkeys("AX\<Home>Y\<esc>", 'tnix')
1139 call cursor(2, 1)
1140 call feedkeys("iZ\<End>Y\<esc>", 'tnix')
1141 call assert_equal(['YabcX', 'ZdefY'], getline(1, '$'))
1142
1143 set foldopen-=hor
1144 bw!
1145endfunc
1146
Bram Moolenaar1e115362019-01-09 23:01:02 +01001147func Test_edit_INS()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001148 " Test for Pressing <Insert>
1149 new
1150 call setline(1, ['abc', 'def'])
1151 call cursor(1, 1)
1152 call feedkeys("i\<Insert>ZYX>", 'tnix')
1153 call assert_equal(['ZYX>', 'def'], getline(1, '$'))
1154 call setline(1, ['abc', 'def'])
1155 call cursor(1, 1)
1156 call feedkeys("i\<Insert>Z\<Insert>YX>", 'tnix')
1157 call assert_equal(['ZYX>bc', 'def'], getline(1, '$'))
1158 bw!
1159endfunc
1160
Bram Moolenaar1e115362019-01-09 23:01:02 +01001161func Test_edit_LEFT_RIGHT()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001162 " Left, Shift-Left, Right, Shift-Right
1163 new
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001164 call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX'])
1165 let _ww=&ww
1166 set ww=
1167 call cursor(2, 1)
1168 call feedkeys("i\<left>\<esc>", 'tnix')
1169 call assert_equal([0, 2, 1, 0], getpos('.'))
1170 " Is this a bug, <s-left> does not respect whichwrap option
1171 call feedkeys("i\<s-left>\<esc>", 'tnix')
1172 call assert_equal([0, 1, 8, 0], getpos('.'))
1173 call feedkeys("i". repeat("\<s-left>", 3). "\<esc>", 'tnix')
1174 call assert_equal([0, 1, 1, 0], getpos('.'))
1175 call feedkeys("i\<right>\<esc>", 'tnix')
1176 call assert_equal([0, 1, 1, 0], getpos('.'))
1177 call feedkeys("i\<right>\<right>\<esc>", 'tnix')
1178 call assert_equal([0, 1, 2, 0], getpos('.'))
1179 call feedkeys("A\<right>\<esc>", 'tnix')
1180 call assert_equal([0, 1, 11, 0], getpos('.'))
1181 call feedkeys("A\<s-right>\<esc>", 'tnix')
1182 call assert_equal([0, 2, 1, 0], getpos('.'))
1183 call feedkeys("i\<s-right>\<esc>", 'tnix')
1184 call assert_equal([0, 2, 4, 0], getpos('.'))
1185 call cursor(3, 11)
1186 call feedkeys("A\<right>\<esc>", 'tnix')
1187 call feedkeys("A\<s-right>\<esc>", 'tnix')
1188 call assert_equal([0, 3, 11, 0], getpos('.'))
1189 call cursor(2, 11)
1190 " <S-Right> does not respect 'whichwrap' option
1191 call feedkeys("A\<s-right>\<esc>", 'tnix')
1192 call assert_equal([0, 3, 1, 0], getpos('.'))
1193 " Check motion when 'whichwrap' contains cursor keys for insert mode
1194 set ww+=[,]
1195 call cursor(2, 1)
1196 call feedkeys("i\<left>\<esc>", 'tnix')
1197 call assert_equal([0, 1, 11, 0], getpos('.'))
1198 call cursor(2, 11)
1199 call feedkeys("A\<right>\<esc>", 'tnix')
1200 call assert_equal([0, 3, 1, 0], getpos('.'))
1201 call cursor(2, 11)
1202 call feedkeys("A\<s-right>\<esc>", 'tnix')
1203 call assert_equal([0, 3, 1, 0], getpos('.'))
1204 let &ww = _ww
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001205 bw!
1206endfunc
1207
Bram Moolenaar1e115362019-01-09 23:01:02 +01001208func Test_edit_MOUSE()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001209 " This is a simple test, since we not really using the mouse here
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001210 CheckFeature mouse
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001211 10new
1212 call setline(1, range(1, 100))
1213 call cursor(1, 1)
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001214 call assert_equal(1, line('w0'))
1215 call assert_equal(10, line('w$'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001216 set mouse=a
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001217 " One scroll event moves three lines.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001218 call feedkeys("A\<ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001219 call assert_equal(4, line('w0'))
1220 call assert_equal(13, line('w$'))
1221 " This should move by one page down.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001222 call feedkeys("A\<S-ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001223 call assert_equal(14, line('w0'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001224 set nostartofline
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001225 " Another page down.
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001226 call feedkeys("A\<C-ScrollWheelDown>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001227 call assert_equal(24, line('w0'))
1228
1229 call assert_equal([0, 24, 2, 0], getpos('.'))
1230 call test_setmouse(4, 3)
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001231 call feedkeys("A\<LeftMouse>\<esc>", 'tnix')
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001232 call assert_equal([0, 27, 2, 0], getpos('.'))
Bram Moolenaarb3707712022-05-08 22:49:43 +01001233 set mousemodel=extend
Bram Moolenaar8e8dc9b2022-05-08 20:38:06 +01001234 call test_setmouse(5, 3)
1235 call feedkeys("A\<RightMouse>\<esc>\<esc>", 'tnix')
1236 call assert_equal([0, 28, 2, 0], getpos('.'))
Bram Moolenaarb3707712022-05-08 22:49:43 +01001237 set mousemodel&
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001238 call cursor(1, 100)
1239 norm! zt
1240 " this should move by a screen up, but when the test
1241 " is run, it moves up to the top of the buffer...
1242 call feedkeys("A\<ScrollWheelUp>\<esc>", 'tnix')
1243 call assert_equal([0, 1, 1, 0], getpos('.'))
1244 call cursor(1, 30)
1245 norm! zt
1246 call feedkeys("A\<S-ScrollWheelUp>\<esc>", 'tnix')
1247 call assert_equal([0, 1, 1, 0], getpos('.'))
1248 call cursor(1, 30)
1249 norm! zt
1250 call feedkeys("A\<C-ScrollWheelUp>\<esc>", 'tnix')
1251 call assert_equal([0, 1, 1, 0], getpos('.'))
1252 %d
1253 call setline(1, repeat(["12345678901234567890"], 100))
1254 call cursor(2, 1)
1255 call feedkeys("A\<ScrollWheelRight>\<esc>", 'tnix')
1256 call assert_equal([0, 2, 20, 0], getpos('.'))
1257 call feedkeys("A\<ScrollWheelLeft>\<esc>", 'tnix')
1258 call assert_equal([0, 2, 20, 0], getpos('.'))
1259 call feedkeys("A\<S-ScrollWheelRight>\<esc>", 'tnix')
1260 call assert_equal([0, 2, 20, 0], getpos('.'))
1261 call feedkeys("A\<S-ScrollWheelLeft>\<esc>", 'tnix')
1262 call assert_equal([0, 2, 20, 0], getpos('.'))
1263 call feedkeys("A\<C-ScrollWheelRight>\<esc>", 'tnix')
1264 call assert_equal([0, 2, 20, 0], getpos('.'))
1265 call feedkeys("A\<C-ScrollWheelLeft>\<esc>", 'tnix')
1266 call assert_equal([0, 2, 20, 0], getpos('.'))
1267 set mouse& startofline
1268 bw!
1269endfunc
1270
Bram Moolenaar1e115362019-01-09 23:01:02 +01001271func Test_edit_PAGEUP_PAGEDOWN()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001272 10new
1273 call setline(1, repeat(['abc def ghi'], 30))
1274 call cursor(1, 1)
1275 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1276 call assert_equal([0, 9, 1, 0], getpos('.'))
1277 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1278 call assert_equal([0, 17, 1, 0], getpos('.'))
1279 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1280 call assert_equal([0, 25, 1, 0], getpos('.'))
1281 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1282 call assert_equal([0, 30, 1, 0], getpos('.'))
1283 call feedkeys("i\<PageDown>\<esc>", 'tnix')
1284 call assert_equal([0, 30, 1, 0], getpos('.'))
1285 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1286 call assert_equal([0, 29, 1, 0], getpos('.'))
1287 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1288 call assert_equal([0, 21, 1, 0], getpos('.'))
1289 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1290 call assert_equal([0, 13, 1, 0], getpos('.'))
1291 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1292 call assert_equal([0, 5, 1, 0], getpos('.'))
1293 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1294 call assert_equal([0, 5, 11, 0], getpos('.'))
1295 " <S-Up> is the same as <PageUp>
1296 " <S-Down> is the same as <PageDown>
1297 call cursor(1, 1)
1298 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1299 call assert_equal([0, 9, 1, 0], getpos('.'))
1300 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1301 call assert_equal([0, 17, 1, 0], getpos('.'))
1302 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1303 call assert_equal([0, 25, 1, 0], getpos('.'))
1304 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1305 call assert_equal([0, 30, 1, 0], getpos('.'))
1306 call feedkeys("i\<S-Down>\<esc>", 'tnix')
1307 call assert_equal([0, 30, 1, 0], getpos('.'))
1308 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1309 call assert_equal([0, 29, 1, 0], getpos('.'))
1310 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1311 call assert_equal([0, 21, 1, 0], getpos('.'))
1312 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1313 call assert_equal([0, 13, 1, 0], getpos('.'))
1314 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1315 call assert_equal([0, 5, 1, 0], getpos('.'))
1316 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1317 call assert_equal([0, 5, 11, 0], getpos('.'))
1318 set nostartofline
1319 call cursor(30, 11)
1320 norm! zt
1321 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1322 call assert_equal([0, 29, 11, 0], getpos('.'))
1323 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1324 call assert_equal([0, 21, 11, 0], getpos('.'))
1325 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1326 call assert_equal([0, 13, 11, 0], getpos('.'))
1327 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1328 call assert_equal([0, 5, 11, 0], getpos('.'))
1329 call feedkeys("A\<PageUp>\<esc>", 'tnix')
1330 call assert_equal([0, 5, 11, 0], getpos('.'))
1331 call cursor(1, 1)
1332 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1333 call assert_equal([0, 9, 11, 0], getpos('.'))
1334 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1335 call assert_equal([0, 17, 11, 0], getpos('.'))
1336 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1337 call assert_equal([0, 25, 11, 0], getpos('.'))
1338 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1339 call assert_equal([0, 30, 11, 0], getpos('.'))
1340 call feedkeys("A\<PageDown>\<esc>", 'tnix')
1341 call assert_equal([0, 30, 11, 0], getpos('.'))
1342 " <S-Up> is the same as <PageUp>
1343 " <S-Down> is the same as <PageDown>
1344 call cursor(30, 11)
1345 norm! zt
1346 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1347 call assert_equal([0, 29, 11, 0], getpos('.'))
1348 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1349 call assert_equal([0, 21, 11, 0], getpos('.'))
1350 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1351 call assert_equal([0, 13, 11, 0], getpos('.'))
1352 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1353 call assert_equal([0, 5, 11, 0], getpos('.'))
1354 call feedkeys("A\<S-Up>\<esc>", 'tnix')
1355 call assert_equal([0, 5, 11, 0], getpos('.'))
1356 call cursor(1, 1)
1357 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1358 call assert_equal([0, 9, 11, 0], getpos('.'))
1359 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1360 call assert_equal([0, 17, 11, 0], getpos('.'))
1361 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1362 call assert_equal([0, 25, 11, 0], getpos('.'))
1363 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1364 call assert_equal([0, 30, 11, 0], getpos('.'))
1365 call feedkeys("A\<S-Down>\<esc>", 'tnix')
1366 call assert_equal([0, 30, 11, 0], getpos('.'))
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001367 bw!
1368endfunc
1369
Bram Moolenaar1e115362019-01-09 23:01:02 +01001370func Test_edit_forbidden()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001371 new
1372 " 1) edit in the sandbox is not allowed
1373 call setline(1, 'a')
1374 com! Sandbox :sandbox call feedkeys("i\<del>\<esc>", 'tnix')
1375 call assert_fails(':Sandbox', 'E48:')
1376 com! Sandbox :sandbox exe "norm! i\<del>"
1377 call assert_fails(':Sandbox', 'E48:')
1378 delcom Sandbox
1379 call assert_equal(['a'], getline(1,'$'))
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001380
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001381 " 2) edit with textlock set
1382 fu! DoIt()
1383 call feedkeys("i\<del>\<esc>", 'tnix')
1384 endfu
1385 au InsertCharPre <buffer> :call DoIt()
1386 try
1387 call feedkeys("ix\<esc>", 'tnix')
1388 call assert_fails(1, 'textlock')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001389 catch /^Vim\%((\a\+)\)\=:E565/ " catch E565: not allowed here
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001390 endtry
1391 " TODO: Might be a bug: should x really be inserted here
1392 call assert_equal(['xa'], getline(1, '$'))
1393 delfu DoIt
1394 try
1395 call feedkeys("ix\<esc>", 'tnix')
1396 call assert_fails(1, 'unknown function')
1397 catch /^Vim\%((\a\+)\)\=:E117/ " catch E117: unknown function
1398 endtry
1399 au! InsertCharPre
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001400
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001401 " 3) edit when completion is shown
1402 fun! Complete(findstart, base)
1403 if a:findstart
1404 return col('.')
1405 else
1406 call feedkeys("i\<del>\<esc>", 'tnix')
1407 return []
1408 endif
1409 endfun
1410 set completefunc=Complete
1411 try
1412 call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
1413 call assert_fails(1, 'change in complete function')
Bram Moolenaarff06f282020-04-21 22:01:14 +02001414 catch /^Vim\%((\a\+)\)\=:E565/ " catch E565
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001415 endtry
1416 delfu Complete
1417 set completefunc=
Bram Moolenaar52797ba2021-12-16 14:45:13 +00001418
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001419 if has("rightleft") && exists("+fkmap")
1420 " 4) 'R' when 'fkmap' and 'revins' is set.
1421 set revins fkmap
1422 try
1423 normal Ri
1424 call assert_fails(1, "R with 'fkmap' and 'ri' set")
1425 catch
1426 finally
1427 set norevins nofkmap
1428 endtry
1429 endif
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001430 bw!
1431endfunc
1432
Bram Moolenaar1e115362019-01-09 23:01:02 +01001433func Test_edit_rightleft()
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001434 " Cursor in rightleft mode moves differently
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001435 CheckFeature rightleft
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001436 call NewWindow(10, 20)
1437 call setline(1, ['abc', 'def', 'ghi'])
1438 call cursor(1, 2)
1439 set rightleft
1440 " Screen looks as expected
1441 let lines = ScreenLines([1, 4], winwidth(0))
1442 let expect = [
1443 \" cba",
1444 \" fed",
1445 \" ihg",
1446 \" ~"]
1447 call assert_equal(join(expect, "\n"), join(lines, "\n"))
1448 " 2) right moves to the left
1449 call feedkeys("i\<right>\<esc>x", 'txin')
1450 call assert_equal(['bc', 'def', 'ghi'], getline(1,'$'))
1451 call cursor(1, 2)
1452 call feedkeys("i\<s-right>\<esc>", 'txin')
1453 call cursor(1, 2)
1454 call feedkeys("i\<c-right>\<esc>", 'txin')
1455 " Screen looks as expected
1456 let lines = ScreenLines([1, 4], winwidth(0))
1457 let expect = [
1458 \" cb",
1459 \" fed",
1460 \" ihg",
1461 \" ~"]
1462 call assert_equal(join(expect, "\n"), join(lines, "\n"))
1463 " 2) left moves to the right
1464 call setline(1, ['abc', 'def', 'ghi'])
1465 call cursor(1, 2)
1466 call feedkeys("i\<left>\<esc>x", 'txin')
1467 call assert_equal(['ac', 'def', 'ghi'], getline(1,'$'))
1468 call cursor(1, 2)
1469 call feedkeys("i\<s-left>\<esc>", 'txin')
1470 call cursor(1, 2)
1471 call feedkeys("i\<c-left>\<esc>", 'txin')
1472 " Screen looks as expected
1473 let lines = ScreenLines([1, 4], winwidth(0))
1474 let expect = [
1475 \" ca",
1476 \" fed",
1477 \" ihg",
1478 \" ~"]
1479 call assert_equal(join(expect, "\n"), join(lines, "\n"))
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001480 %d _
1481 call test_override('redraw_flag', 1)
1482 call test_override('char_avail', 1)
1483 call feedkeys("a\<C-V>x41", "xt")
1484 redraw!
1485 call assert_equal(repeat(' ', 19) .. 'A', Screenline(1))
1486 call test_override('ALL', 0)
Bram Moolenaareb992cb2017-03-09 18:20:16 +01001487 set norightleft
1488 bw!
1489endfunc
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001490
1491func Test_edit_complete_very_long_name()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001492 " Long directory names only work on Unix.
1493 CheckUnix
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001494
1495 let dirname = getcwd() . "/Xdir"
1496 let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
1497 try
1498 call mkdir(longdirname, 'p')
1499 catch /E739:/
1500 " Long directory name probably not supported.
1501 call delete(dirname, 'rf')
1502 return
1503 endtry
1504
Bram Moolenaarf8191c52019-05-18 17:22:54 +02001505 " Try to get the Vim window position before setting 'columns', so that we can
1506 " move the window back to where it was.
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001507 let winposx = getwinposx()
1508 let winposy = getwinposy()
Bram Moolenaarf8191c52019-05-18 17:22:54 +02001509
1510 if winposx >= 0 && winposy >= 0 && !has('gui_running')
1511 " We did get the window position, but xterm may report the wrong numbers.
1512 " Move the window to the reported position and compute any offset.
1513 exe 'winpos ' . winposx . ' ' . winposy
1514 sleep 100m
1515 let x = getwinposx()
1516 if x >= 0
1517 let winposx += winposx - x
1518 endif
1519 let y = getwinposy()
1520 if y >= 0
1521 let winposy += winposy - y
1522 endif
1523 endif
1524
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001525 let save_columns = &columns
Bram Moolenaar15ecbd62017-04-07 14:10:48 +02001526 " Need at least about 1100 columns to reproduce the problem.
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001527 set columns=2000
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001528 set noswapfile
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001529
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001530 let longfilename = longdirname . '/' . repeat('a', 255)
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001531 call writefile(['Totum', 'Table'], longfilename)
1532 new
1533 exe "next Xfile " . longfilename
1534 exe "normal iT\<C-N>"
1535
1536 bwipe!
1537 exe 'bwipe! ' . longfilename
1538 call delete(dirname, 'rf')
1539 let &columns = save_columns
Bram Moolenaarba6ec182017-04-04 22:41:10 +02001540 if winposx >= 0 && winposy >= 0
1541 exe 'winpos ' . winposx . ' ' . winposy
1542 endif
Bram Moolenaar658a3a22017-03-31 22:27:12 +02001543 set swapfile&
1544endfunc
Bram Moolenaarff930ca2017-10-19 17:12:10 +02001545
Bram Moolenaar2c8c6812018-07-28 17:07:52 +02001546func Test_edit_backtick()
1547 next a\`b c
1548 call assert_equal('a`b', expand('%'))
1549 next
1550 call assert_equal('c', expand('%'))
1551 call assert_equal('a\`b c', expand('##'))
1552endfunc
1553
Bram Moolenaarff930ca2017-10-19 17:12:10 +02001554func Test_edit_quit()
1555 edit foo.txt
1556 split
1557 new
1558 call setline(1, 'hello')
1559 3wincmd w
1560 redraw!
1561 call assert_fails('1q', 'E37:')
1562 bwipe! foo.txt
1563 only
1564endfunc
1565
Bram Moolenaaradb8fbe2018-06-04 20:34:23 +02001566func Test_edit_alt()
1567 " Keeping the cursor line didn't happen when the first line has indent.
1568 new
1569 call setline(1, [' one', 'two', 'three'])
1570 w XAltFile
1571 $
1572 call assert_equal(3, line('.'))
1573 e Xother
1574 e #
1575 call assert_equal(3, line('.'))
1576
1577 bwipe XAltFile
1578 call delete('XAltFile')
1579endfunc
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001580
Bram Moolenaardb934952020-04-27 20:18:31 +02001581func Test_edit_InsertLeave()
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001582 new
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001583 au InsertLeavePre * let g:did_au_pre = 1
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001584 au InsertLeave * let g:did_au = 1
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001585 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001586 let g:did_au = 0
1587 call feedkeys("afoo\<Esc>", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001588 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001589 call assert_equal(1, g:did_au)
1590 call assert_equal('foo', getline(1))
1591
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001592 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001593 let g:did_au = 0
1594 call feedkeys("Sbar\<C-C>", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001595 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001596 call assert_equal(0, g:did_au)
1597 call assert_equal('bar', getline(1))
1598
1599 inoremap x xx<Esc>
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001600 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001601 let g:did_au = 0
1602 call feedkeys("Saax", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001603 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001604 call assert_equal(1, g:did_au)
1605 call assert_equal('aaxx', getline(1))
1606
1607 inoremap x xx<C-C>
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001608 let g:did_au_pre = 0
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001609 let g:did_au = 0
1610 call feedkeys("Sbbx", 'tx')
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001611 call assert_equal(1, g:did_au_pre)
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001612 call assert_equal(0, g:did_au)
1613 call assert_equal('bbxx', getline(1))
1614
1615 bwipe!
Bram Moolenaarb53e13a2020-10-21 12:19:53 +02001616 au! InsertLeave InsertLeavePre
Bram Moolenaar4dbc2622018-11-02 11:59:15 +01001617 iunmap x
1618endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001619
Bram Moolenaardb934952020-04-27 20:18:31 +02001620func Test_edit_InsertLeave_undo()
1621 new XtestUndo
1622 set undofile
1623 au InsertLeave * wall
1624 exe "normal ofoo\<Esc>"
1625 call assert_equal(2, line('$'))
1626 normal u
1627 call assert_equal(1, line('$'))
1628
1629 bwipe!
1630 au! InsertLeave
1631 call delete('XtestUndo')
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001632 call delete(undofile('XtestUndo'))
Bram Moolenaardb934952020-04-27 20:18:31 +02001633 set undofile&
1634endfunc
1635
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001636" Test for inserting characters using CTRL-V followed by a number.
1637func Test_edit_special_chars()
1638 new
1639
Bram Moolenaar424bcae2022-01-31 14:59:41 +00001640 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 +02001641
1642 exe "normal " . t
1643 call assert_equal("ABC !a\<C-O>g\<C-G>8", getline(2))
1644
1645 close!
1646endfunc
Bram Moolenaar8d3b5102019-09-05 21:29:01 +02001647
1648func Test_edit_startinsert()
1649 new
1650 set backspace+=start
1651 call setline(1, 'foobar')
1652 call feedkeys("A\<C-U>\<Esc>", 'xt')
1653 call assert_equal('', getline(1))
1654
1655 call setline(1, 'foobar')
1656 call feedkeys(":startinsert!\<CR>\<C-U>\<Esc>", 'xt')
1657 call assert_equal('', getline(1))
1658
1659 set backspace&
1660 bwipe!
1661endfunc
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001662
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001663" Test for :startreplace and :startgreplace
1664func Test_edit_startreplace()
1665 new
1666 call setline(1, 'abc')
1667 call feedkeys("l:startreplace\<CR>xyz\e", 'xt')
1668 call assert_equal('axyz', getline(1))
1669 call feedkeys("0:startreplace!\<CR>abc\e", 'xt')
1670 call assert_equal('axyzabc', getline(1))
1671 call setline(1, "a\tb")
1672 call feedkeys("0l:startgreplace\<CR>xyz\e", 'xt')
1673 call assert_equal("axyz\tb", getline(1))
1674 call feedkeys("0i\<C-R>=execute('startreplace')\<CR>12\e", 'xt')
1675 call assert_equal("12axyz\tb", getline(1))
1676 close!
1677endfunc
1678
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001679func Test_edit_noesckeys()
Bram Moolenaar215ba3b2019-11-06 15:07:07 +01001680 CheckNotGui
Bram Moolenaar177c9f22019-11-06 13:59:16 +01001681 new
1682
1683 " <Left> moves cursor when 'esckeys' is set
1684 exe "set t_kl=\<Esc>OD"
1685 set esckeys
1686 call feedkeys("axyz\<Esc>ODX", "xt")
1687 call assert_equal("xyXz", getline(1))
1688
1689 " <Left> exits Insert mode when 'esckeys' is off
1690 set noesckeys
1691 call setline(1, '')
1692 call feedkeys("axyz\<Esc>ODX", "xt")
1693 call assert_equal(["DX", "xyz"], getline(1, 2))
1694
1695 bwipe!
1696 set esckeys
1697endfunc
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001698
Bram Moolenaar1671f442020-03-10 07:48:13 +01001699" Test for running an invalid ex command in insert mode using CTRL-O
Bram Moolenaar1671f442020-03-10 07:48:13 +01001700func Test_edit_ctrl_o_invalid_cmd()
1701 new
1702 set showmode showcmd
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001703 " Avoid a sleep of 3 seconds. Zero might have side effects.
1704 call test_override('ui_delay', 50)
Bram Moolenaar1671f442020-03-10 07:48:13 +01001705 let caught_e492 = 0
1706 try
1707 call feedkeys("i\<C-O>:invalid\<CR>abc\<Esc>", "xt")
1708 catch /E492:/
1709 let caught_e492 = 1
1710 endtry
1711 call assert_equal(1, caught_e492)
1712 call assert_equal('abc', getline(1))
1713 set showmode& showcmd&
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001714 call test_override('ui_delay', 0)
Bram Moolenaar1671f442020-03-10 07:48:13 +01001715 close!
1716endfunc
1717
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001718" Test for editing a file with a very long name
1719func Test_edit_illegal_filename()
1720 CheckEnglish
1721 new
1722 redir => msg
1723 exe 'edit ' . repeat('f', 5000)
1724 redir END
1725 call assert_match("Illegal file name$", split(msg, "\n")[0])
1726 close!
1727endfunc
1728
Bram Moolenaarc8fe6452020-10-03 17:04:37 +02001729" Test for editing a directory
1730func Test_edit_is_a_directory()
1731 CheckEnglish
1732 let dirname = getcwd() . "/Xdir"
1733 call mkdir(dirname, 'p')
1734
1735 new
1736 redir => msg
1737 exe 'edit' dirname
1738 redir END
1739 call assert_match("is a directory$", split(msg, "\n")[0])
1740 bwipe!
1741
1742 let dirname .= '/'
1743
1744 new
1745 redir => msg
1746 exe 'edit' dirname
1747 redir END
1748 call assert_match("is a directory$", split(msg, "\n")[0])
1749 bwipe!
1750
1751 call delete(dirname, 'rf')
1752endfunc
1753
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001754" Test for editing a file using invalid file encoding
1755func Test_edit_invalid_encoding()
1756 CheckEnglish
1757 call writefile([], 'Xfile')
1758 redir => msg
1759 new ++enc=axbyc Xfile
1760 redir END
1761 call assert_match('\[NOT converted\]', msg)
1762 call delete('Xfile')
1763 close!
1764endfunc
1765
1766" Test for the "charconvert" option
1767func Test_edit_charconvert()
1768 CheckEnglish
1769 call writefile(['one', 'two'], 'Xfile')
1770
1771 " set 'charconvert' to a non-existing function
1772 set charconvert=NonExitingFunc()
1773 new
1774 let caught_e117 = v:false
1775 try
1776 redir => msg
1777 edit ++enc=axbyc Xfile
1778 catch /E117:/
1779 let caught_e117 = v:true
1780 finally
1781 redir END
1782 endtry
1783 call assert_true(caught_e117)
1784 call assert_equal(['one', 'two'], getline(1, '$'))
1785 call assert_match("Conversion with 'charconvert' failed", msg)
1786 close!
1787 set charconvert&
1788
1789 " 'charconvert' function doesn't create a output file
1790 func Cconv1()
1791 endfunc
1792 set charconvert=Cconv1()
1793 new
1794 redir => msg
1795 edit ++enc=axbyc Xfile
1796 redir END
1797 call assert_equal(['one', 'two'], getline(1, '$'))
1798 call assert_match("can't read output of 'charconvert'", msg)
1799 close!
1800 delfunc Cconv1
1801 set charconvert&
1802
1803 " 'charconvert' function to convert to upper case
1804 func Cconv2()
1805 let data = readfile(v:fname_in)
1806 call map(data, 'toupper(v:val)')
1807 call writefile(data, v:fname_out)
1808 endfunc
1809 set charconvert=Cconv2()
1810 new Xfile
1811 write ++enc=ucase Xfile1
1812 call assert_equal(['ONE', 'TWO'], readfile('Xfile1'))
1813 call delete('Xfile1')
1814 close!
1815 delfunc Cconv2
1816 set charconvert&
1817
1818 " 'charconvert' function removes the input file
1819 func Cconv3()
1820 call delete(v:fname_in)
1821 endfunc
1822 set charconvert=Cconv3()
1823 new
1824 call assert_fails('edit ++enc=lcase Xfile', 'E202:')
1825 call assert_equal([''], getline(1, '$'))
1826 close!
1827 delfunc Cconv3
1828 set charconvert&
1829
1830 call delete('Xfile')
1831endfunc
1832
1833" Test for editing a file without read permission
1834func Test_edit_file_no_read_perm()
1835 CheckUnix
Bram Moolenaar17709e22021-03-19 14:38:12 +01001836 CheckNotRoot
1837
Bram Moolenaarb340bae2020-06-15 19:51:56 +02001838 call writefile(['one', 'two'], 'Xfile')
1839 call setfperm('Xfile', '-w-------')
1840 new
1841 redir => msg
1842 edit Xfile
1843 redir END
1844 call assert_equal(1, &readonly)
1845 call assert_equal([''], getline(1, '$'))
1846 call assert_match('\[Permission Denied\]', msg)
1847 close!
1848 call delete('Xfile')
1849endfunc
1850
zeertzjq3a56b6d2022-04-08 11:56:14 +01001851" Using :edit without leaving 'insertmode' should not cause Insert mode to be
1852" re-entered immediately after <C-L>
1853func Test_edit_insertmode_ex_edit()
1854 CheckRunVimInTerminal
1855
1856 let lines =<< trim END
1857 set insertmode noruler
1858 inoremap <C-B> <Cmd>edit Xfoo<CR>
1859 END
1860 call writefile(lines, 'Xtest_edit_insertmode_ex_edit')
1861
1862 let buf = RunVimInTerminal('-S Xtest_edit_insertmode_ex_edit', #{rows: 6})
1863 call TermWait(buf, 50)
1864 call assert_match('^-- INSERT --\s*$', term_getline(buf, 6))
1865 call term_sendkeys(buf, "\<C-B>\<C-L>")
1866 call TermWait(buf, 50)
1867 call assert_notmatch('^-- INSERT --\s*$', term_getline(buf, 6))
1868
1869 " clean up
1870 call StopVimInTerminal(buf)
1871 call delete('Xtest_edit_insertmode_ex_edit')
1872endfunc
1873
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001874" Pressing escape in 'insertmode' should beep
1875func Test_edit_insertmode_esc_beeps()
1876 new
1877 set insertmode
1878 call assert_beeps("call feedkeys(\"one\<Esc>\", 'xt')")
1879 set insertmode&
1880 " unsupported CTRL-G command should beep in insert mode.
1881 call assert_beeps("normal i\<C-G>l")
1882 close!
1883endfunc
1884
1885" Test for 'hkmap' and 'hkmapp'
1886func Test_edit_hkmap()
1887 CheckFeature rightleft
1888 if has('win32') && !has('gui')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001889 throw 'Skipped: fails on the MS-Windows terminal version'
Bram Moolenaar845e0ee2020-06-20 16:05:32 +02001890 endif
1891 new
1892
1893 set revins hkmap
1894 let str = 'abcdefghijklmnopqrstuvwxyz'
1895 let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1896 let str ..= '`/'',.;'
1897 call feedkeys('i' .. str, 'xt')
1898 let expected = "óõú,.;"
1899 let expected ..= "ZYXWVUTSRQPONMLKJIHGFEDCBA"
1900 let expected ..= "æèñ'äåàãø/ôíîöêìçïéòë÷âáðù"
1901 call assert_equal(expected, getline(1))
1902
1903 %d
1904 set revins hkmap hkmapp
1905 let str = 'abcdefghijklmnopqrstuvwxyz'
1906 let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1907 call feedkeys('i' .. str, 'xt')
1908 let expected = "õYXWVUTSRQóOïíLKJIHGFEDêBA"
1909 let expected ..= "öòXùåèúæø'ôñðîì÷çéäâóǟãëáà"
1910 call assert_equal(expected, getline(1))
1911
1912 set revins& hkmap& hkmapp&
1913 close!
1914endfunc
1915
1916" Test for 'allowrevins' and using CTRL-_ in insert mode
1917func Test_edit_allowrevins()
1918 CheckFeature rightleft
1919 new
1920 set allowrevins
1921 call feedkeys("iABC\<C-_>DEF\<C-_>GHI", 'xt')
1922 call assert_equal('ABCFEDGHI', getline(1))
1923 set allowrevins&
1924 close!
1925endfunc
1926
1927" Test for inserting a register in insert mode using CTRL-R
1928func Test_edit_insert_reg()
1929 new
1930 let g:Line = ''
1931 func SaveFirstLine()
1932 let g:Line = Screenline(1)
1933 return 'r'
1934 endfunc
1935 inoremap <expr> <buffer> <F2> SaveFirstLine()
1936 call test_override('redraw_flag', 1)
1937 call test_override('char_avail', 1)
1938 let @r = 'sample'
1939 call feedkeys("a\<C-R>=SaveFirstLine()\<CR>", "xt")
1940 call assert_equal('"', g:Line)
1941 call test_override('ALL', 0)
1942 close!
1943endfunc
1944
1945" When a character is inserted at the last position of the last line in a
1946" window, the window contents should be scrolled one line up. If the top line
1947" is part of a fold, then the entire fold should be scrolled up.
1948func Test_edit_lastline_scroll()
1949 new
1950 let h = winheight(0)
1951 let lines = ['one', 'two', 'three']
1952 let lines += repeat(['vim'], h - 4)
1953 call setline(1, lines)
1954 call setline(h, repeat('x', winwidth(0) - 1))
1955 call feedkeys("GAx", 'xt')
1956 redraw!
1957 call assert_equal(h - 1, winline())
1958 call assert_equal(2, line('w0'))
1959
1960 " scroll with a fold
1961 1,2fold
1962 normal gg
1963 call setline(h + 1, repeat('x', winwidth(0) - 1))
1964 call feedkeys("GAx", 'xt')
1965 redraw!
1966 call assert_equal(h - 1, winline())
1967 call assert_equal(3, line('w0'))
1968
1969 close!
1970endfunc
1971
Bram Moolenaar21cbe172020-10-13 19:08:24 +02001972func Test_edit_browse()
1973 " in the GUI this opens a file picker, we only test the terminal behavior
1974 CheckNotGui
1975
1976 " ":browse xxx" checks for the FileExplorer augroup and assumes editing "."
1977 " works then.
1978 augroup FileExplorer
1979 au!
1980 augroup END
1981
1982 " When the USE_FNAME_CASE is defined this used to cause a crash.
1983 browse enew
1984 bwipe!
1985
1986 browse split
1987 bwipe!
1988endfunc
1989
Bram Moolenaarcaf73dc2020-10-26 21:39:13 +01001990func Test_read_invalid()
1991 set encoding=latin1
1992 " This was not properly checking for going past the end.
1993 call assert_fails('r`=', 'E484')
1994 set encoding=utf-8
1995endfunc
1996
Yegappan Lakshmanan59585492021-06-12 13:46:41 +02001997" Test for the 'revins' option
1998func Test_edit_revins()
1999 CheckFeature rightleft
2000 new
2001 set revins
2002 exe "normal! ione\ttwo three"
2003 call assert_equal("eerht owt\teno", getline(1))
2004 call setline(1, "one\ttwo three")
2005 normal! gg$bi a
2006 call assert_equal("one\ttwo a three", getline(1))
2007 exe "normal! $bi\<BS>\<BS>"
2008 call assert_equal("one\ttwo a ree", getline(1))
2009 exe "normal! 0wi\<C-W>"
2010 call assert_equal("one\t a ree", getline(1))
2011 exe "normal! 0wi\<C-U>"
2012 call assert_equal("one\t ", getline(1))
2013 " newline in insert mode starts at the end of the line
2014 call setline(1, 'one two three')
2015 exe "normal! wi\nfour"
2016 call assert_equal(['one two three', 'ruof'], getline(1, '$'))
2017 set revins&
2018 bw!
2019endfunc
2020
Bram Moolenaar35a9a002021-09-11 21:14:20 +02002021" Test for getting the character of the line below after "p"
2022func Test_edit_put_CTRL_E()
2023 set encoding=latin1
2024 new
2025 let @" = ''
2026 sil! norm orggRx
2027 sil! norm pr
2028 call assert_equal(['r', 'r'], getline(1, 2))
2029 bwipe!
2030 set encoding=utf-8
2031endfunc
2032
=?UTF-8?q?Magnus=20Gro=C3=9F?=f1e88762021-09-12 13:39:55 +02002033" Test for ModeChanged pattern
2034func Test_mode_changes()
=?UTF-8?q?Magnus=20Gro=C3=9F?=f1e88762021-09-12 13:39:55 +02002035 let g:index = 0
=?UTF-8?q?Magnus=20Gro=C3=9F?=25def2c2021-10-22 18:56:39 +01002036 let g:mode_seq = ['n', 'i', 'n', 'v', 'V', 'i', 'ix', 'i', 'ic', 'i', 'n', 'no', 'n', 'V', 'v', 's', 'n']
=?UTF-8?q?Magnus=20Gro=C3=9F?=f1e88762021-09-12 13:39:55 +02002037 func! TestMode()
2038 call assert_equal(g:mode_seq[g:index], get(v:event, "old_mode"))
2039 call assert_equal(g:mode_seq[g:index + 1], get(v:event, "new_mode"))
Bram Moolenaard85931e2021-10-02 16:55:39 +01002040 call assert_equal(mode(1), get(v:event, "new_mode"))
=?UTF-8?q?Magnus=20Gro=C3=9F?=f1e88762021-09-12 13:39:55 +02002041 let g:index += 1
2042 endfunc
2043
2044 au ModeChanged * :call TestMode()
=?UTF-8?q?Magnus=20Gro=C3=9F?=25def2c2021-10-22 18:56:39 +01002045 let g:n_to_any = 0
2046 au ModeChanged n:* let g:n_to_any += 1
2047 call feedkeys("i\<esc>vVca\<CR>\<C-X>\<C-L>\<esc>ggdG", 'tnix')
=?UTF-8?q?Magnus=20Gro=C3=9F?=f1e88762021-09-12 13:39:55 +02002048
=?UTF-8?q?Magnus=20Gro=C3=9F?=25def2c2021-10-22 18:56:39 +01002049 let g:V_to_v = 0
2050 au ModeChanged V:v let g:V_to_v += 1
2051 call feedkeys("Vv\<C-G>\<esc>", 'tnix')
2052 call assert_equal(len(filter(g:mode_seq[1:], {idx, val -> val == 'n'})), g:n_to_any)
2053 call assert_equal(1, g:V_to_v)
Bram Moolenaard85931e2021-10-02 16:55:39 +01002054 call assert_equal(len(g:mode_seq) - 1, g:index)
=?UTF-8?q?Magnus=20Gro=C3=9F?=f1e88762021-09-12 13:39:55 +02002055
Bram Moolenaar72d2fa62021-10-02 21:48:15 +01002056 let g:n_to_i = 0
2057 au ModeChanged n:i let g:n_to_i += 1
2058 let g:n_to_niI = 0
2059 au ModeChanged i:niI let g:n_to_niI += 1
2060 let g:niI_to_i = 0
2061 au ModeChanged niI:i let g:niI_to_i += 1
2062 let g:nany_to_i = 0
2063 au ModeChanged n*:i let g:nany_to_i += 1
2064 let g:i_to_n = 0
2065 au ModeChanged i:n let g:i_to_n += 1
2066 let g:nori_to_any = 0
2067 au ModeChanged [ni]:* let g:nori_to_any += 1
2068 let g:i_to_any = 0
2069 au ModeChanged i:* let g:i_to_any += 1
Bram Moolenaard85931e2021-10-02 16:55:39 +01002070 let g:index = 0
2071 let g:mode_seq = ['n', 'i', 'niI', 'i', 'n']
2072 call feedkeys("a\<C-O>l\<esc>", 'tnix')
=?UTF-8?q?Magnus=20Gro=C3=9F?=f1e88762021-09-12 13:39:55 +02002073 call assert_equal(len(g:mode_seq) - 1, g:index)
Bram Moolenaar72d2fa62021-10-02 21:48:15 +01002074 call assert_equal(1, g:n_to_i)
2075 call assert_equal(1, g:n_to_niI)
2076 call assert_equal(1, g:niI_to_i)
2077 call assert_equal(2, g:nany_to_i)
2078 call assert_equal(1, g:i_to_n)
2079 call assert_equal(2, g:i_to_any)
2080 call assert_equal(3, g:nori_to_any)
=?UTF-8?q?Magnus=20Gro=C3=9F?=f1e88762021-09-12 13:39:55 +02002081
=?UTF-8?q?Magnus=20Gro=C3=9F?=25def2c2021-10-22 18:56:39 +01002082 if has('terminal')
2083 let g:mode_seq += ['c', 'n', 't', 'nt', 'c', 'nt', 'n']
2084 call feedkeys(":term\<CR>\<C-W>N:bd!\<CR>", 'tnix')
2085 call assert_equal(len(g:mode_seq) - 1, g:index)
2086 call assert_equal(1, g:n_to_i)
2087 call assert_equal(1, g:n_to_niI)
2088 call assert_equal(1, g:niI_to_i)
2089 call assert_equal(2, g:nany_to_i)
2090 call assert_equal(1, g:i_to_n)
2091 call assert_equal(2, g:i_to_any)
2092 call assert_equal(5, g:nori_to_any)
2093 endif
2094
=?UTF-8?q?Magnus=20Gro=C3=9F?=f1e88762021-09-12 13:39:55 +02002095 au! ModeChanged
2096 delfunc TestMode
2097 unlet! g:mode_seq
2098 unlet! g:index
=?UTF-8?q?Magnus=20Gro=C3=9F?=25def2c2021-10-22 18:56:39 +01002099 unlet! g:n_to_any
2100 unlet! g:V_to_v
2101 unlet! g:n_to_i
2102 unlet! g:n_to_niI
2103 unlet! g:niI_to_i
2104 unlet! g:nany_to_i
2105 unlet! g:i_to_n
2106 unlet! g:nori_to_any
2107 unlet! g:i_to_any
=?UTF-8?q?Magnus=20Gro=C3=9F?=f1e88762021-09-12 13:39:55 +02002108endfunc
2109
Bram Moolenaar3075a452021-11-17 15:51:52 +00002110func Test_recursive_ModeChanged()
2111 au! ModeChanged * norm 0u
2112 sil! norm 
Bram Moolenaara0620062021-11-17 16:52:40 +00002113 au! ModeChanged
2114endfunc
2115
2116func Test_ModeChanged_starts_visual()
2117 " This was triggering ModeChanged before setting VIsual, causing a crash.
2118 au! ModeChanged * norm 0u
2119 sil! norm 
2120
2121 au! ModeChanged
Bram Moolenaar3075a452021-11-17 15:51:52 +00002122endfunc
2123
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002124" Test toggling of input method. See :help i_CTRL-^
2125func Test_edit_CTRL_hat()
2126 CheckFeature xim
Dominique Pelle8753c1d2021-10-31 20:19:17 +00002127
Bram Moolenaar0b962e52022-04-03 18:02:37 +01002128 " FIXME: test fails with Motif GUI.
Dominique Pelle8753c1d2021-10-31 20:19:17 +00002129 " test also fails when running in the GUI.
2130 CheckFeature gui_gtk
2131 CheckNotGui
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002132
2133 new
2134
2135 call assert_equal(0, &iminsert)
2136 call feedkeys("i\<C-^>", 'xt')
2137 call assert_equal(2, &iminsert)
2138 call feedkeys("i\<C-^>", 'xt')
2139 call assert_equal(0, &iminsert)
2140
2141 bwipe!
2142endfunc
2143
Bram Moolenaarde05bb22022-01-13 13:08:14 +00002144" Weird long file name was going over the end of NameBuff
2145func Test_edit_overlong_file_name()
2146 CheckUnix
2147
2148 file 0000000000000000000000000000
2149 file %%%%%%%%%%%%%%%%%%%%%%%%%%
2150 file %%%%%%
2151 set readonly
2152 set ls=2
2153
2154 redraw!
2155 set noreadonly ls&
2156 bwipe!
2157endfunc
2158
Christian Brabandtdfbdadc2022-05-05 20:46:47 +01002159func Test_edit_shift_bs()
2160 CheckMSWindows
2161
2162 " FIXME: this works interactively, but the test fails
2163 throw 'Skipped: Shift-Backspace Test not working correctly :('
2164
2165 " Need to run this in Win32 Terminal, do not use CheckRunVimInTerminal
2166 if !has("terminal")
2167 return
2168 endif
2169
2170 " Shift Backspace should work like Backspace in insert mode
2171 let lines =<< trim END
2172 call setline(1, ['abc'])
2173 END
2174 call writefile(lines, 'Xtest_edit_shift_bs')
2175
2176 let buf = RunVimInTerminal('-S Xtest_edit_shift_bs', #{rows: 3})
2177 call term_sendkeys(buf, "A\<S-BS>-\<esc>")
2178 call TermWait(buf, 50)
2179 call assert_equal('ab-', term_getline(buf, 1))
2180
2181 " clean up
2182 call StopVimInTerminal(buf)
2183 call delete('Xtest_edit_shift_bs')
2184endfunc
Dominique Pelle9cd063e2021-10-28 21:06:05 +01002185
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002186" vim: shiftwidth=2 sts=2 expandtab