blob: 401a3504ae0473bad6bdc64addc1c8dd8c42ff77 [file] [log] [blame]
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +01001" Tests for various Visual modes.
Bram Moolenaarc3c766e2017-03-08 22:55:19 +01002
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02003source shared.vim
Bram Moolenaar7d7bcc62021-06-28 21:54:27 +02004source check.vim
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02005source screendump.vim
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02006
Bram Moolenaar019b9c62016-03-05 17:26:00 +01007func Test_block_shift_multibyte()
Bram Moolenaarf8eb9c52017-01-02 17:31:24 +01008 " Uses double-wide character.
Bram Moolenaar019b9c62016-03-05 17:26:00 +01009 split
10 call setline(1, ['xヹxxx', 'ヹxxx'])
11 exe "normal 1G0l\<C-V>jl>"
12 call assert_equal('x ヹxxx', getline(1))
13 call assert_equal(' ヹxxx', getline(2))
14 q!
15endfunc
Bram Moolenaarf8eb9c52017-01-02 17:31:24 +010016
Bram Moolenaarbae5a172017-08-06 15:42:06 +020017func Test_block_shift_overflow()
18 " This used to cause a multiplication overflow followed by a crash.
19 new
20 normal ii
21 exe "normal \<C-V>876543210>"
22 q!
23endfunc
24
Bram Moolenaarf8eb9c52017-01-02 17:31:24 +010025func Test_dotregister_paste()
26 new
27 exe "norm! ihello world\<esc>"
28 norm! 0ve".p
29 call assert_equal('hello world world', getline(1))
30 q!
31endfunc
Bram Moolenaar23fa81d2017-02-01 21:50:21 +010032
33func Test_Visual_ctrl_o()
34 new
35 call setline(1, ['one', 'two', 'three'])
36 call cursor(1,2)
37 set noshowmode
38 set tw=0
39 call feedkeys("\<c-v>jjlIa\<c-\>\<c-o>:set tw=88\<cr>\<esc>", 'tx')
40 call assert_equal(['oane', 'tawo', 'tahree'], getline(1, 3))
41 call assert_equal(88, &tw)
42 set tw&
43 bw!
44endfu
Bram Moolenaar84b2a382017-02-17 11:40:00 +010045
46func Test_Visual_vapo()
47 new
48 normal oxx
49 normal vapo
50 bwipe!
51endfunc
Bram Moolenaar46522af2017-02-18 23:12:01 +010052
53func Test_Visual_inner_quote()
54 new
55 normal oxX
56 normal vki'
57 bwipe!
58endfunc
Bram Moolenaar75373f32017-08-07 22:02:30 +020059
60" Test for Visual mode not being reset causing E315 error.
61func TriggerTheProblem()
62 " At this point there is no visual selection because :call reset it.
63 " Let's restore the selection:
64 normal gv
65 '<,'>del _
66 try
67 exe "normal \<Esc>"
68 catch /^Vim\%((\a\+)\)\=:E315/
69 echom 'Snap! E315 error!'
Bram Moolenaar63e82db2018-03-06 12:10:48 +010070 let g:msg = 'Snap! E315 error!'
Bram Moolenaar75373f32017-08-07 22:02:30 +020071 endtry
72endfunc
73
74func Test_visual_mode_reset()
Bram Moolenaar75373f32017-08-07 22:02:30 +020075 enew
Bram Moolenaar63e82db2018-03-06 12:10:48 +010076 let g:msg = "Everything's fine."
Bram Moolenaar75373f32017-08-07 22:02:30 +020077 enew
78 setl buftype=nofile
79 call append(line('$'), 'Delete this line.')
80
81 " NOTE: this has to be done by a call to a function because executing :del
82 " the ex-way will require the colon operator which resets the visual mode
83 " thus preventing the problem:
84 exe "normal! GV:call TriggerTheProblem()\<CR>"
85 call assert_equal("Everything's fine.", g:msg)
Bram Moolenaar75373f32017-08-07 22:02:30 +020086endfunc
Bram Moolenaar67418d92017-10-15 22:07:39 +020087
Bram Moolenaar15993ce2017-10-26 20:21:44 +020088" Test for visual block shift and tab characters.
89func Test_block_shift_tab()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +020090 new
Bram Moolenaar15993ce2017-10-26 20:21:44 +020091 call append(0, repeat(['one two three'], 5))
92 call cursor(1,1)
93 exe "normal i\<C-G>u"
94 exe "normal fe\<C-V>4jR\<Esc>ugvr1"
95 call assert_equal('on1 two three', getline(1))
96 call assert_equal('on1 two three', getline(2))
97 call assert_equal('on1 two three', getline(5))
98
Bram Moolenaar3e72dca2021-05-29 16:30:12 +020099 %d _
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200100 call append(0, repeat(['abcdefghijklmnopqrstuvwxyz'], 5))
101 call cursor(1,1)
102 exe "normal \<C-V>4jI \<Esc>j<<11|D"
103 exe "normal j7|a\<Tab>\<Tab>"
104 exe "normal j7|a\<Tab>\<Tab> "
105 exe "normal j7|a\<Tab> \<Tab>\<Esc>4k13|\<C-V>4j<"
106 call assert_equal(' abcdefghijklmnopqrstuvwxyz', getline(1))
107 call assert_equal('abcdefghij', getline(2))
108 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(3))
109 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(4))
110 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(5))
111
112 %s/\s\+//g
113 call cursor(1,1)
114 exe "normal \<C-V>4jI \<Esc>j<<"
115 exe "normal j7|a\<Tab>\<Tab>"
116 exe "normal j7|a\<Tab>\<Tab>\<Tab>\<Tab>\<Tab>"
117 exe "normal j7|a\<Tab> \<Tab>\<Tab>\<Esc>4k13|\<C-V>4j3<"
118 call assert_equal(' abcdefghijklmnopqrstuvwxyz', getline(1))
119 call assert_equal('abcdefghij', getline(2))
120 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(3))
121 call assert_equal(" abc\<Tab>\<Tab>defghijklmnopqrstuvwxyz", getline(4))
122 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(5))
123
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200124 " Test for block shift with space characters at the beginning and with
125 " 'noexpandtab' and 'expandtab'
126 %d _
127 call setline(1, [" 1", " 2", " 3"])
128 setlocal shiftwidth=2 noexpandtab
129 exe "normal gg\<C-V>3j>"
130 call assert_equal(["\t1", "\t2", "\t3"], getline(1, '$'))
131 %d _
132 call setline(1, [" 1", " 2", " 3"])
133 setlocal shiftwidth=2 expandtab
134 exe "normal gg\<C-V>3j>"
135 call assert_equal([" 1", " 2", " 3"], getline(1, '$'))
136 setlocal shiftwidth&
137
138 bw!
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200139endfunc
140
141" Tests Blockwise Visual when there are TABs before the text.
142func Test_blockwise_visual()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200143 new
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200144 call append(0, ['123456',
145 \ '234567',
146 \ '345678',
147 \ '',
148 \ 'test text test tex start here',
149 \ "\t\tsome text",
150 \ "\t\ttest text",
151 \ 'test text'])
152 call cursor(1,1)
153 exe "normal /start here$\<CR>"
154 exe 'normal "by$' . "\<C-V>jjlld"
155 exe "normal /456$\<CR>"
156 exe "normal \<C-V>jj" . '"bP'
157 call assert_equal(['123start here56',
158 \ '234start here67',
159 \ '345start here78',
160 \ '',
161 \ 'test text test tex rt here',
162 \ "\t\tsomext",
163 \ "\t\ttesext"], getline(1, 7))
164
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200165 bw!
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200166endfunc
167
Bram Moolenaar2e949762018-05-20 14:06:38 +0200168" Test swapping corners in blockwise visual mode with o and O
169func Test_blockwise_visual_o_O()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200170 new
Bram Moolenaar2e949762018-05-20 14:06:38 +0200171
172 exe "norm! 10i.\<Esc>Y4P3lj\<C-V>4l2jr "
173 exe "norm! gvO\<Esc>ra"
174 exe "norm! gvO\<Esc>rb"
175 exe "norm! gvo\<C-c>rc"
176 exe "norm! gvO\<C-c>rd"
Bram Moolenaar1671f442020-03-10 07:48:13 +0100177 set selection=exclusive
178 exe "norm! gvOo\<C-c>re"
179 call assert_equal('...a be.', getline(4))
180 exe "norm! gvOO\<C-c>rf"
181 set selection&
Bram Moolenaar2e949762018-05-20 14:06:38 +0200182
183 call assert_equal(['..........',
184 \ '...c d..',
185 \ '... ..',
Bram Moolenaar1671f442020-03-10 07:48:13 +0100186 \ '...a bf.',
Bram Moolenaar2e949762018-05-20 14:06:38 +0200187 \ '..........'], getline(1, '$'))
188
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200189 bw!
Bram Moolenaar2e949762018-05-20 14:06:38 +0200190endfun
191
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200192" Test Virtual replace mode.
193func Test_virtual_replace()
Bram Moolenaardf0d24b2018-03-06 14:22:58 +0100194 if exists('&t_kD')
195 let save_t_kD = &t_kD
196 endif
197 if exists('&t_kb')
198 let save_t_kb = &t_kb
199 endif
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200200 exe "set t_kD=\<C-V>x7f t_kb=\<C-V>x08"
201 enew!
202 exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
203 call cursor(1,1)
204 set ai bs=2
205 exe "normal gR0\<C-D> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
206 call assert_equal([' 1',
207 \ ' A',
208 \ ' BCDEFGHIJ',
209 \ ' KL',
210 \ ' MNO',
211 \ ' PQR',
212 \ ], getline(1, 6))
213 normal G
214 mark a
215 exe "normal o0\<C-D>\nabcdefghi\njk\tlmn\n opq\trst\n\<C-D>uvwxyz\n"
216 exe "normal 'ajgR0\<C-D> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR" . repeat("\<BS>", 29)
217 call assert_equal([' 1',
218 \ 'abcdefghi',
219 \ 'jk lmn',
220 \ ' opq rst',
221 \ 'uvwxyz'], getline(7, 11))
222 normal G
223 exe "normal iab\tcdefghi\tjkl"
224 exe "normal 0gRAB......CDEFGHI.J\<Esc>o"
225 exe "normal iabcdefghijklmnopqrst\<Esc>0gRAB\tIJKLMNO\tQR"
226 call assert_equal(['AB......CDEFGHI.Jkl',
227 \ 'AB IJKLMNO QRst'], getline(12, 13))
Bram Moolenaar845e0ee2020-06-20 16:05:32 +0200228
229 " Test inserting Tab with 'noexpandtab' and 'softabstop' set to 4
230 %d
231 call setline(1, 'aaaaaaaaaaaaa')
232 set softtabstop=4
233 exe "normal gggR\<Tab>\<Tab>x"
234 call assert_equal("\txaaaa", getline(1))
235 set softtabstop&
236
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200237 enew!
Bram Moolenaare7808482018-03-06 13:17:23 +0100238 set noai bs&vim
Bram Moolenaardf0d24b2018-03-06 14:22:58 +0100239 if exists('save_t_kD')
240 let &t_kD = save_t_kD
241 endif
242 if exists('save_t_kb')
243 let &t_kb = save_t_kb
244 endif
Bram Moolenaar63e82db2018-03-06 12:10:48 +0100245endfunc
246
247" Test Virtual replace mode.
248func Test_virtual_replace2()
249 enew!
250 set bs=2
251 exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
252 call cursor(1,1)
253 " Test 1: Test that del deletes the newline
254 exe "normal gR0\<del> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
255 call assert_equal(['0 1',
256 \ 'A',
257 \ 'BCDEFGHIJ',
258 \ ' KL',
259 \ 'MNO',
260 \ 'PQR',
261 \ ], getline(1, 6))
262 " Test 2:
263 " a newline is not deleted, if no newline has been added in virtual replace mode
264 %d_
265 call setline(1, ['abcd', 'efgh', 'ijkl'])
266 call cursor(2,1)
267 exe "norm! gR1234\<cr>5\<bs>\<bs>\<bs>"
268 call assert_equal(['abcd',
269 \ '123h',
270 \ 'ijkl'], getline(1, '$'))
271 " Test 3:
272 " a newline is deleted, if a newline has been inserted before in virtual replace mode
273 %d_
274 call setline(1, ['abcd', 'efgh', 'ijkl'])
275 call cursor(2,1)
276 exe "norm! gR1234\<cr>\<cr>56\<bs>\<bs>\<bs>"
277 call assert_equal(['abcd',
278 \ '1234',
279 \ 'ijkl'], getline(1, '$'))
280 " Test 4:
281 " delete add a newline, delete it, add it again and check undo
282 %d_
283 call setline(1, ['abcd', 'efgh', 'ijkl'])
284 call cursor(2,1)
285 " break undo sequence explicitly
286 let &ul = &ul
287 exe "norm! gR1234\<cr>\<bs>\<del>56\<cr>"
288 let &ul = &ul
289 call assert_equal(['abcd',
290 \ '123456',
291 \ ''], getline(1, '$'))
292 norm! u
293 call assert_equal(['abcd',
294 \ 'efgh',
295 \ 'ijkl'], getline(1, '$'))
Bram Moolenaarca68ae12020-03-30 19:32:53 +0200296
297 " Test for truncating spaces in a newly added line using 'autoindent' if
298 " characters are not added to that line.
299 %d_
300 call setline(1, [' app', ' bee', ' cat'])
301 setlocal autoindent
302 exe "normal gg$gRt\n\nr"
303 call assert_equal([' apt', '', ' rat'], getline(1, '$'))
304
Bram Moolenaar63e82db2018-03-06 12:10:48 +0100305 " clean up
306 %d_
307 set bs&vim
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200308endfunc
Bram Moolenaar6d3a1942019-01-03 23:10:32 +0100309
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100310func Test_Visual_word_textobject()
311 new
312 call setline(1, ['First sentence. Second sentence.'])
313
314 " When start and end of visual area are identical, 'aw' or 'iw' select
315 " the whole word.
316 norm! 1go2fcvawy
317 call assert_equal('Second ', @")
318 norm! 1go2fcviwy
319 call assert_equal('Second', @")
320
321 " When start and end of visual area are not identical, 'aw' or 'iw'
322 " extend the word in direction of the end of the visual area.
323 norm! 1go2fcvlawy
324 call assert_equal('cond ', @")
325 norm! gv2awy
326 call assert_equal('cond sentence.', @")
327
328 norm! 1go2fcvliwy
329 call assert_equal('cond', @")
330 norm! gv2iwy
331 call assert_equal('cond sentence', @")
332
333 " Extend visual area in opposite direction.
334 norm! 1go2fcvhawy
335 call assert_equal(' Sec', @")
336 norm! gv2awy
337 call assert_equal(' sentence. Sec', @")
338
339 norm! 1go2fcvhiwy
340 call assert_equal('Sec', @")
341 norm! gv2iwy
342 call assert_equal('. Sec', @")
343
344 bwipe!
345endfunc
346
Bram Moolenaar6d3a1942019-01-03 23:10:32 +0100347func Test_Visual_sentence_textobject()
348 new
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100349 call setline(1, ['First sentence. Second sentence. Third', 'sentence. Fourth sentence'])
Bram Moolenaar6d3a1942019-01-03 23:10:32 +0100350
351 " When start and end of visual area are identical, 'as' or 'is' select
352 " the whole sentence.
353 norm! 1gofdvasy
354 call assert_equal('Second sentence. ', @")
355 norm! 1gofdvisy
356 call assert_equal('Second sentence.', @")
357
358 " When start and end of visual area are not identical, 'as' or 'is'
359 " extend the sentence in direction of the end of the visual area.
360 norm! 1gofdvlasy
361 call assert_equal('d sentence. ', @")
362 norm! gvasy
363 call assert_equal("d sentence. Third\nsentence. ", @")
364
365 norm! 1gofdvlisy
366 call assert_equal('d sentence.', @")
367 norm! gvisy
368 call assert_equal('d sentence. ', @")
369 norm! gvisy
370 call assert_equal("d sentence. Third\nsentence.", @")
371
372 " Extend visual area in opposite direction.
373 norm! 1gofdvhasy
374 call assert_equal(' Second', @")
375 norm! gvasy
376 call assert_equal("First sentence. Second", @")
377
378 norm! 1gofdvhisy
379 call assert_equal('Second', @")
380 norm! gvisy
381 call assert_equal(' Second', @")
382 norm! gvisy
383 call assert_equal('First sentence. Second', @")
384
385 bwipe!
386endfunc
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100387
388func Test_Visual_paragraph_textobject()
389 new
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200390 let lines =<< trim [END]
391 First line.
392
393 Second line.
394 Third line.
395 Fourth line.
396 Fifth line.
397
398 Sixth line.
399 [END]
400 call setline(1, lines)
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100401
402 " When start and end of visual area are identical, 'ap' or 'ip' select
403 " the whole paragraph.
404 norm! 4ggvapy
405 call assert_equal("Second line.\nThird line.\nFourth line.\nFifth line.\n\n", @")
406 norm! 4ggvipy
407 call assert_equal("Second line.\nThird line.\nFourth line.\nFifth line.\n", @")
408
409 " When start and end of visual area are not identical, 'ap' or 'ip'
410 " extend the sentence in direction of the end of the visual area.
411 " FIXME: actually, it is not sufficient to have different start and
412 " end of visual selection, the start line and end line have to differ,
413 " which is not consistent with the documentation.
414 norm! 4ggVjapy
415 call assert_equal("Third line.\nFourth line.\nFifth line.\n\n", @")
416 norm! gvapy
417 call assert_equal("Third line.\nFourth line.\nFifth line.\n\nSixth line.\n", @")
418 norm! 4ggVjipy
419 call assert_equal("Third line.\nFourth line.\nFifth line.\n", @")
420 norm! gvipy
421 call assert_equal("Third line.\nFourth line.\nFifth line.\n\n", @")
422 norm! gvipy
423 call assert_equal("Third line.\nFourth line.\nFifth line.\n\nSixth line.\n", @")
424
425 " Extend visual area in opposite direction.
426 norm! 5ggVkapy
427 call assert_equal("\nSecond line.\nThird line.\nFourth line.\n", @")
428 norm! gvapy
429 call assert_equal("First line.\n\nSecond line.\nThird line.\nFourth line.\n", @")
430 norm! 5ggVkipy
431 call assert_equal("Second line.\nThird line.\nFourth line.\n", @")
432 norma gvipy
433 call assert_equal("\nSecond line.\nThird line.\nFourth line.\n", @")
434 norm! gvipy
435 call assert_equal("First line.\n\nSecond line.\nThird line.\nFourth line.\n", @")
436
437 bwipe!
438endfunc
Bram Moolenaar19a66852019-03-07 11:25:32 +0100439
440func Test_curswant_not_changed()
441 new
442 call setline(1, ['one', 'two'])
443 au InsertLeave * call getcurpos()
444 call feedkeys("gg0\<C-V>jI123 \<Esc>j", 'xt')
445 call assert_equal([0, 2, 1, 0, 1], getcurpos())
446
447 bwipe!
448 au! InsertLeave
449endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +0200450
451" Tests for "vaBiB", end could be wrong.
452func Test_Visual_Block()
453 new
454 a
455- Bug in "vPPPP" on this text:
456 {
457 cmd;
458 {
459 cmd;\t/* <-- Start cursor here */
460 {
461 }
462 }
463 }
464.
465 normal gg
466 call search('Start cursor here')
467 normal vaBiBD
468 call assert_equal(['- Bug in "vPPPP" on this text:',
469 \ "\t{",
470 \ "\t}"], getline(1, '$'))
471
472 close!
473endfunc
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +0100474
475" Test for 'p'ut in visual block mode
476func Test_visual_block_put()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200477 new
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +0100478 call append(0, ['One', 'Two', 'Three'])
479 normal gg
480 yank
481 call feedkeys("jl\<C-V>ljp", 'xt')
482 call assert_equal(['One', 'T', 'Tee', 'One', ''], getline(1, '$'))
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200483 bw!
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +0100484endfunc
485
Bram Moolenaar36343ae2022-10-15 19:04:05 +0100486func Test_visual_block_put_invalid()
487 enew!
488 behave mswin
489 norm yy
490 norm v)Ps/^/
491 " this was causing the column to become negative
492 silent norm ggv)P
493
494 bwipe!
495 behave xterm
496endfunc
497
Bram Moolenaar309976e2019-12-05 18:16:33 +0100498" Visual modes (v V CTRL-V) followed by an operator; count; repeating
499func Test_visual_mode_op()
500 new
501 call append(0, '')
502
503 call setline(1, 'apple banana cherry')
504 call cursor(1, 1)
505 normal lvld.l3vd.
506 call assert_equal('a y', getline(1))
507
508 call setline(1, ['line 1 line 1', 'line 2 line 2', 'line 3 line 3',
509 \ 'line 4 line 4', 'line 5 line 5', 'line 6 line 6'])
510 call cursor(1, 1)
511 exe "normal Vcnewline\<Esc>j.j2Vd."
512 call assert_equal(['newline', 'newline'], getline(1, '$'))
513
514 call deletebufline('', 1, '$')
515 call setline(1, ['xxxxxxxxxxxxx', 'xxxxxxxxxxxxx', 'xxxxxxxxxxxxx',
516 \ 'xxxxxxxxxxxxx'])
517 exe "normal \<C-V>jlc \<Esc>l.l2\<C-V>c----\<Esc>l."
518 call assert_equal([' --------x',
519 \ ' --------x',
520 \ 'xxxx--------x',
521 \ 'xxxx--------x'], getline(1, '$'))
522
523 bwipe!
524endfunc
525
526" Visual mode maps (movement and text object)
527" Visual mode maps; count; repeating
528" - Simple
529" - With an Ex command (custom text object)
530func Test_visual_mode_maps()
531 new
532 call append(0, '')
533
534 func SelectInCaps()
535 let [line1, col1] = searchpos('\u', 'bcnW')
536 let [line2, col2] = searchpos('.\u', 'nW')
537 call setpos("'<", [0, line1, col1, 0])
538 call setpos("'>", [0, line2, col2, 0])
539 normal! gv
540 endfunction
541
542 vnoremap W /\u/s-1<CR>
543 vnoremap iW :<C-U>call SelectInCaps()<CR>
544
545 call setline(1, 'KiwiRaspberryDateWatermelonPeach')
546 call cursor(1, 1)
547 exe "normal vWcNo\<Esc>l.fD2vd."
548 call assert_equal('NoNoberryach', getline(1))
549
550 call setline(1, 'JambuRambutanBananaTangerineMango')
551 call cursor(1, 1)
552 exe "normal llviWc-\<Esc>l.l2vdl."
553 call assert_equal('--ago', getline(1))
554
555 vunmap W
556 vunmap iW
557 bwipe!
558 delfunc SelectInCaps
559endfunc
560
561" Operator-pending mode maps (movement and text object)
562" - Simple
563" - With Ex command moving the cursor
564" - With Ex command and Visual selection (custom text object)
565func Test_visual_oper_pending_mode_maps()
566 new
567 call append(0, '')
568
569 func MoveToCap()
570 call search('\u', 'W')
571 endfunction
572
573 func SelectInCaps()
574 let [line1, col1] = searchpos('\u', 'bcnW')
575 let [line2, col2] = searchpos('.\u', 'nW')
576 call setpos("'<", [0, line1, col1, 0])
577 call setpos("'>", [0, line2, col2, 0])
578 normal! gv
579 endfunction
580
581 onoremap W /\u/<CR>
582 onoremap <Leader>W :<C-U>call MoveToCap()<CR>
583 onoremap iW :<C-U>call SelectInCaps()<CR>
584
585 call setline(1, 'PineappleQuinceLoganberryOrangeGrapefruitKiwiZ')
586 call cursor(1, 1)
587 exe "normal cW-\<Esc>l.l2.l."
588 call assert_equal('----Z', getline(1))
589
590 call setline(1, 'JuniperDurianZ')
591 call cursor(1, 1)
592 exe "normal g?\WfD."
593 call assert_equal('WhavcreQhevnaZ', getline(1))
594
595 call setline(1, 'LemonNectarineZ')
596 call cursor(1, 1)
597 exe "normal yiWPlciWNew\<Esc>fr."
598 call assert_equal('LemonNewNewZ', getline(1))
599
600 ounmap W
601 ounmap <Leader>W
602 ounmap iW
603 bwipe!
604 delfunc MoveToCap
605 delfunc SelectInCaps
606endfunc
607
608" Patch 7.3.879: Properly abort Operator-pending mode for "dv:<Esc>" etc.
609func Test_op_pend_mode_abort()
610 new
611 call append(0, '')
612
613 call setline(1, ['zzzz', 'zzzz'])
614 call cursor(1, 1)
615
616 exe "normal dV:\<CR>dv:\<CR>"
617 call assert_equal(['zzz'], getline(1, 2))
618 set nomodifiable
619 call assert_fails('exe "normal d:\<CR>"', 'E21:')
620 set modifiable
621 call feedkeys("dv:\<Esc>dV:\<Esc>", 'xt')
622 call assert_equal(['zzz'], getline(1, 2))
623 set nomodifiable
624 let v:errmsg = ''
625 call feedkeys("d:\<Esc>", 'xt')
626 call assert_true(v:errmsg !~# '^E21:')
627 set modifiable
628
629 bwipe!
630endfunc
631
632func Test_characterwise_visual_mode()
633 new
634
635 " characterwise visual mode: replace last line
636 $put ='a'
637 let @" = 'x'
638 normal v$p
639 call assert_equal('x', getline('$'))
640
641 " characterwise visual mode: delete middle line
642 call deletebufline('', 1, '$')
643 call append('$', ['a', 'b', 'c'])
644 normal G
645 normal kkv$d
646 call assert_equal(['', 'b', 'c'], getline(1, '$'))
647
648 " characterwise visual mode: delete middle two lines
649 call deletebufline('', 1, '$')
650 call append('$', ['a', 'b', 'c'])
651 normal Gkkvj$d
652 call assert_equal(['', 'c'], getline(1, '$'))
653
654 " characterwise visual mode: delete last line
655 call deletebufline('', 1, '$')
656 call append('$', ['a', 'b', 'c'])
657 normal Gv$d
658 call assert_equal(['', 'a', 'b', ''], getline(1, '$'))
659
660 " characterwise visual mode: delete last two lines
661 call deletebufline('', 1, '$')
662 call append('$', ['a', 'b', 'c'])
663 normal Gkvj$d
664 call assert_equal(['', 'a', ''], getline(1, '$'))
665
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200666 " characterwise visual mode: use a count with the visual mode from the last
667 " line in the buffer
668 %d _
669 call setline(1, ['one', 'two', 'three', 'four'])
670 norm! vj$y
671 norm! G1vy
672 call assert_equal('four', @")
673
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200674 " characterwise visual mode: replace a single character line and the eol
675 %d _
676 call setline(1, "a")
677 normal v$rx
678 call assert_equal(['x'], getline(1, '$'))
679
Bram Moolenaar6ecf58b2021-12-16 10:05:41 +0000680 " replace a character with composing characters
681 call setline(1, "xã̳x")
682 normal gg0lvrb
683 call assert_equal("xbx", getline(1))
684
Bram Moolenaar309976e2019-12-05 18:16:33 +0100685 bwipe!
686endfunc
687
Bram Moolenaar309976e2019-12-05 18:16:33 +0100688func Test_visual_mode_put()
689 new
690
691 " v_p: replace last character with line register at middle line
692 call append('$', ['aaa', 'bbb', 'ccc'])
693 normal G
694 -2yank
695 normal k$vp
696 call assert_equal(['', 'aaa', 'bb', 'aaa', '', 'ccc'], getline(1, '$'))
697
698 " v_p: replace last character with line register at middle line selecting
699 " newline
700 call deletebufline('', 1, '$')
701 call append('$', ['aaa', 'bbb', 'ccc'])
702 normal G
703 -2yank
704 normal k$v$p
705 call assert_equal(['', 'aaa', 'bb', 'aaa', 'ccc'], getline(1, '$'))
706
707 " v_p: replace last character with line register at last line
708 call deletebufline('', 1, '$')
709 call append('$', ['aaa', 'bbb', 'ccc'])
710 normal G
711 -2yank
712 normal $vp
713 call assert_equal(['', 'aaa', 'bbb', 'cc', 'aaa', ''], getline(1, '$'))
714
715 " v_p: replace last character with line register at last line selecting
716 " newline
717 call deletebufline('', 1, '$')
718 call append('$', ['aaa', 'bbb', 'ccc'])
719 normal G
720 -2yank
721 normal $v$p
722 call assert_equal(['', 'aaa', 'bbb', 'cc', 'aaa', ''], getline(1, '$'))
723
724 bwipe!
725endfunc
726
Bram Moolenaar515545e2020-03-22 14:08:59 +0100727func Test_gv_with_exclusive_selection()
Bram Moolenaar309976e2019-12-05 18:16:33 +0100728 new
729
Bram Moolenaar515545e2020-03-22 14:08:59 +0100730 " gv with exclusive selection after an operation
Bram Moolenaar309976e2019-12-05 18:16:33 +0100731 call append('$', ['zzz ', 'äà '])
732 set selection=exclusive
733 normal Gkv3lyjv3lpgvcxxx
734 call assert_equal(['', 'zzz ', 'xxx '], getline(1, '$'))
735
Bram Moolenaar515545e2020-03-22 14:08:59 +0100736 " gv with exclusive selection without an operation
Bram Moolenaar309976e2019-12-05 18:16:33 +0100737 call deletebufline('', 1, '$')
738 call append('$', 'zzz ')
739 set selection=exclusive
740 exe "normal G0v3l\<Esc>gvcxxx"
741 call assert_equal(['', 'xxx '], getline(1, '$'))
742
743 set selection&vim
744 bwipe!
745endfunc
746
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100747" Tests for the visual block mode commands
748func Test_visual_block_mode()
749 new
750 call append(0, '')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100751 call setline(1, repeat(['abcdefghijklm'], 5))
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100752 call cursor(1, 1)
753
754 " Test shift-right of a block
755 exe "normal jllll\<C-V>jj>wll\<C-V>jlll>"
756 " Test shift-left of a block
757 exe "normal G$hhhh\<C-V>kk<"
758 " Test block-insert
759 exe "normal Gkl\<C-V>kkkIxyz"
760 " Test block-replace
761 exe "normal Gllll\<C-V>kkklllrq"
762 " Test block-change
763 exe "normal G$khhh\<C-V>hhkkcmno"
764 call assert_equal(['axyzbcdefghijklm',
765 \ 'axyzqqqq mno ghijklm',
766 \ 'axyzqqqqef mno ghijklm',
767 \ 'axyzqqqqefgmnoklm',
768 \ 'abcdqqqqijklm'], getline(1, 5))
769
Bram Moolenaar1671f442020-03-10 07:48:13 +0100770 " Test 'C' to change till the end of the line
771 call cursor(3, 4)
772 exe "normal! \<C-V>j3lCooo"
773 call assert_equal(['axyooo', 'axyooo'], getline(3, 4))
774
775 " Test 'D' to delete till the end of the line
776 call cursor(3, 3)
777 exe "normal! \<C-V>j2lD"
778 call assert_equal(['ax', 'ax'], getline(3, 4))
779
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200780 " Test block insert with a short line that ends before the block
781 %d _
782 call setline(1, [" one", "a", " two"])
783 exe "normal gg\<C-V>2jIx"
784 call assert_equal([" xone", "a", " xtwo"], getline(1, '$'))
785
786 " Test block append at EOL with '$' and without '$'
787 %d _
788 call setline(1, ["one", "a", "two"])
789 exe "normal gg$\<C-V>2jAx"
790 call assert_equal(["onex", "ax", "twox"], getline(1, '$'))
791 %d _
792 call setline(1, ["one", "a", "two"])
793 exe "normal gg3l\<C-V>2jAx"
794 call assert_equal(["onex", "a x", "twox"], getline(1, '$'))
795
796 " Test block replace with an empty line in the middle and use $ to jump to
797 " the end of the line.
798 %d _
799 call setline(1, ['one', '', 'two'])
800 exe "normal gg$\<C-V>2jrx"
801 call assert_equal(["onx", "", "twx"], getline(1, '$'))
802
803 " Test block replace with an empty line in the middle and move cursor to the
804 " end of the line
805 %d _
806 call setline(1, ['one', '', 'two'])
807 exe "normal gg2l\<C-V>2jrx"
808 call assert_equal(["onx", "", "twx"], getline(1, '$'))
809
810 " Replace odd number of characters with a multibyte character
811 %d _
812 call setline(1, ['abcd', 'efgh'])
813 exe "normal ggl\<C-V>2ljr\u1100"
814 call assert_equal(["a\u1100 ", "e\u1100 "], getline(1, '$'))
815
816 " During visual block append, if the cursor moved outside of the selected
817 " range, then the edit should not be applied to the block.
818 %d _
819 call setline(1, ['aaa', 'bbb', 'ccc'])
820 exe "normal 2G\<C-V>jAx\<Up>"
821 call assert_equal(['aaa', 'bxbb', 'ccc'], getline(1, '$'))
822
823 " During visual block append, if the cursor is moved before the start of the
824 " block, then the new text should be appended there.
825 %d _
826 call setline(1, ['aaa', 'bbb', 'ccc'])
827 exe "normal $\<C-V>2jA\<Left>x"
Bram Moolenaar4067bd32021-06-29 18:54:35 +0200828 call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$'))
Yegappan Lakshmanan59b26232021-06-05 20:59:22 +0200829 " Repeat the previous test but use 'l' to move the cursor instead of '$'
830 call setline(1, ['aaa', 'bbb', 'ccc'])
831 exe "normal! gg2l\<C-V>2jA\<Left>x"
832 call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$'))
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200833
834 " Change a characterwise motion to a blockwise motion using CTRL-V
835 %d _
836 call setline(1, ['123', '456', '789'])
837 exe "normal ld\<C-V>j"
838 call assert_equal(['13', '46', '789'], getline(1, '$'))
839
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +0200840 " Test from ':help v_b_I_example'
841 %d _
842 setlocal tabstop=8 shiftwidth=4
843 let lines =<< trim END
844 abcdefghijklmnopqrstuvwxyz
845 abc defghijklmnopqrstuvwxyz
846 abcdef ghi jklmnopqrstuvwxyz
847 abcdefghijklmnopqrstuvwxyz
848 END
849 call setline(1, lines)
850 exe "normal ggfo\<C-V>3jISTRING"
851 let expected =<< trim END
852 abcdefghijklmnSTRINGopqrstuvwxyz
853 abc STRING defghijklmnopqrstuvwxyz
854 abcdef ghi STRING jklmnopqrstuvwxyz
855 abcdefghijklmnSTRINGopqrstuvwxyz
856 END
857 call assert_equal(expected, getline(1, '$'))
858
859 " Test from ':help v_b_A_example'
860 %d _
861 let lines =<< trim END
862 abcdefghijklmnopqrstuvwxyz
863 abc defghijklmnopqrstuvwxyz
864 abcdef ghi jklmnopqrstuvwxyz
865 abcdefghijklmnopqrstuvwxyz
866 END
867 call setline(1, lines)
868 exe "normal ggfo\<C-V>3j$ASTRING"
869 let expected =<< trim END
870 abcdefghijklmnopqrstuvwxyzSTRING
871 abc defghijklmnopqrstuvwxyzSTRING
872 abcdef ghi jklmnopqrstuvwxyzSTRING
873 abcdefghijklmnopqrstuvwxyzSTRING
874 END
875 call assert_equal(expected, getline(1, '$'))
876
877 " Test from ':help v_b_<_example'
878 %d _
879 let lines =<< trim END
880 abcdefghijklmnopqrstuvwxyz
881 abc defghijklmnopqrstuvwxyz
882 abcdef ghi jklmnopqrstuvwxyz
883 abcdefghijklmnopqrstuvwxyz
884 END
885 call setline(1, lines)
886 exe "normal ggfo\<C-V>3j3l<.."
887 let expected =<< trim END
888 abcdefghijklmnopqrstuvwxyz
889 abc defghijklmnopqrstuvwxyz
890 abcdef ghi jklmnopqrstuvwxyz
891 abcdefghijklmnopqrstuvwxyz
892 END
893 call assert_equal(expected, getline(1, '$'))
894
895 " Test from ':help v_b_>_example'
896 %d _
897 let lines =<< trim END
898 abcdefghijklmnopqrstuvwxyz
899 abc defghijklmnopqrstuvwxyz
900 abcdef ghi jklmnopqrstuvwxyz
901 abcdefghijklmnopqrstuvwxyz
902 END
903 call setline(1, lines)
904 exe "normal ggfo\<C-V>3j>.."
905 let expected =<< trim END
906 abcdefghijklmn opqrstuvwxyz
907 abc defghijklmnopqrstuvwxyz
908 abcdef ghi jklmnopqrstuvwxyz
909 abcdefghijklmn opqrstuvwxyz
910 END
911 call assert_equal(expected, getline(1, '$'))
912
913 " Test from ':help v_b_r_example'
914 %d _
915 let lines =<< trim END
916 abcdefghijklmnopqrstuvwxyz
917 abc defghijklmnopqrstuvwxyz
918 abcdef ghi jklmnopqrstuvwxyz
919 abcdefghijklmnopqrstuvwxyz
920 END
921 call setline(1, lines)
922 exe "normal ggfo\<C-V>5l3jrX"
923 let expected =<< trim END
924 abcdefghijklmnXXXXXXuvwxyz
925 abc XXXXXXhijklmnopqrstuvwxyz
926 abcdef ghi XXXXXX jklmnopqrstuvwxyz
927 abcdefghijklmnXXXXXXuvwxyz
928 END
929 call assert_equal(expected, getline(1, '$'))
930
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100931 bwipe!
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +0200932 set tabstop& shiftwidth&
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100933endfunc
934
Bram Moolenaar21492742021-06-04 21:57:57 +0200935func Test_visual_force_motion_feedkeys()
936 onoremap <expr> i- execute('let g:mode = mode(1)')->slice(0, 0)
937 call feedkeys('dvi-', 'x')
938 call assert_equal('nov', g:mode)
939 call feedkeys('di-', 'x')
940 call assert_equal('no', g:mode)
941 ounmap i-
942endfunc
943
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100944" Test block-insert using cursor keys for movement
945func Test_visual_block_insert_cursor_keys()
946 new
947 call append(0, ['aaaaaa', 'bbbbbb', 'cccccc', 'dddddd'])
948 call cursor(1, 1)
949
950 exe "norm! l\<C-V>jjjlllI\<Right>\<Right> \<Esc>"
951 call assert_equal(['aaa aaa', 'bbb bbb', 'ccc ccc', 'ddd ddd'],
952 \ getline(1, 4))
953
954 call deletebufline('', 1, '$')
955 call setline(1, ['xaaa', 'bbbb', 'cccc', 'dddd'])
956 call cursor(1, 1)
957 exe "norm! \<C-V>jjjI<>\<Left>p\<Esc>"
958 call assert_equal(['<p>xaaa', '<p>bbbb', '<p>cccc', '<p>dddd'],
959 \ getline(1, 4))
960 bwipe!
961endfunc
962
963func Test_visual_block_create()
964 new
965 call append(0, '')
966 " Test for Visual block was created with the last <C-v>$
967 call setline(1, ['A23', '4567'])
968 call cursor(1, 1)
969 exe "norm! l\<C-V>j$Aab\<Esc>"
970 call assert_equal(['A23ab', '4567ab'], getline(1, 2))
971
972 " Test for Visual block was created with the middle <C-v>$ (1)
973 call deletebufline('', 1, '$')
974 call setline(1, ['B23', '4567'])
975 call cursor(1, 1)
976 exe "norm! l\<C-V>j$hAab\<Esc>"
977 call assert_equal(['B23 ab', '4567ab'], getline(1, 2))
978
979 " Test for Visual block was created with the middle <C-v>$ (2)
980 call deletebufline('', 1, '$')
981 call setline(1, ['C23', '4567'])
982 call cursor(1, 1)
983 exe "norm! l\<C-V>j$hhAab\<Esc>"
984 call assert_equal(['C23ab', '456ab7'], getline(1, 2))
985 bwipe!
986endfunc
987
988" Test for Visual block insert when virtualedit=all
989func Test_virtualedit_visual_block()
990 set ve=all
991 new
992 call append(0, ["\t\tline1", "\t\tline2", "\t\tline3"])
993 call cursor(1, 1)
994 exe "norm! 07l\<C-V>jjIx\<Esc>"
995 call assert_equal([" x \tline1",
996 \ " x \tline2",
997 \ " x \tline3"], getline(1, 3))
998
999 " Test for Visual block append when virtualedit=all
1000 exe "norm! 012l\<C-v>jjAx\<Esc>"
1001 call assert_equal([' x x line1',
1002 \ ' x x line2',
1003 \ ' x x line3'], getline(1, 3))
1004 set ve=
1005 bwipe!
1006endfunc
1007
1008" Test for changing case
1009func Test_visual_change_case()
1010 new
1011 " gUe must uppercase a whole word, also when ß changes to SS
1012 exe "normal Gothe youtußeuu end\<Esc>Ypk0wgUe\r"
1013 " gUfx must uppercase until x, inclusive.
1014 exe "normal O- youßtußexu -\<Esc>0fogUfx\r"
1015 " VU must uppercase a whole line
1016 exe "normal YpkVU\r"
1017 " same, when it's the last line in the buffer
1018 exe "normal YPGi111\<Esc>VUddP\r"
1019 " Uppercase two lines
1020 exe "normal Oblah di\rdoh dut\<Esc>VkUj\r"
1021 " Uppercase part of two lines
1022 exe "normal ddppi333\<Esc>k0i222\<Esc>fyllvjfuUk"
1023 call assert_equal(['the YOUTUSSEUU end', '- yOUSSTUSSEXu -',
1024 \ 'THE YOUTUSSEUU END', '111THE YOUTUSSEUU END', 'BLAH DI', 'DOH DUT',
1025 \ '222the yoUTUSSEUU END', '333THE YOUTUßeuu end'], getline(2, '$'))
1026 bwipe!
1027endfunc
1028
1029" Test for Visual replace using Enter or NL
1030func Test_visual_replace_crnl()
1031 new
1032 exe "normal G3o123456789\e2k05l\<C-V>2jr\r"
1033 exe "normal G3o98765\e2k02l\<C-V>2jr\<C-V>\r\n"
1034 exe "normal G3o123456789\e2k05l\<C-V>2jr\n"
1035 exe "normal G3o98765\e2k02l\<C-V>2jr\<C-V>\n"
1036 call assert_equal(['12345', '789', '12345', '789', '12345', '789', "98\r65",
1037 \ "98\r65", "98\r65", '12345', '789', '12345', '789', '12345', '789',
1038 \ "98\n65", "98\n65", "98\n65"], getline(2, '$'))
1039 bwipe!
1040endfunc
1041
1042func Test_ve_block_curpos()
1043 new
1044 " Test cursor position. When ve=block and Visual block mode and $gj
1045 call append(0, ['12345', '789'])
1046 call cursor(1, 3)
1047 set virtualedit=block
1048 exe "norm! \<C-V>$gj\<Esc>"
1049 call assert_equal([0, 2, 4, 0], getpos("'>"))
1050 set virtualedit=
1051 bwipe!
1052endfunc
1053
1054" Test for block_insert when replacing spaces in front of the a with tabs
1055func Test_block_insert_replace_tabs()
1056 new
1057 set ts=8 sts=4 sw=4
1058 call append(0, ["#define BO_ALL\t 0x0001",
1059 \ "#define BO_BS\t 0x0002",
1060 \ "#define BO_CRSR\t 0x0004"])
1061 call cursor(1, 1)
1062 exe "norm! f0\<C-V>2jI\<tab>\<esc>"
1063 call assert_equal([
1064 \ "#define BO_ALL\t\t0x0001",
1065 \ "#define BO_BS\t \t0x0002",
1066 \ "#define BO_CRSR\t \t0x0004", ''], getline(1, '$'))
1067 set ts& sts& sw&
1068 bwipe!
1069endfunc
1070
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001071" Test for * register in :
1072func Test_star_register()
1073 call assert_fails('*bfirst', 'E16:')
1074 new
1075 call setline(1, ['foo', 'bar', 'baz', 'qux'])
1076 exe "normal jVj\<ESC>"
1077 *yank r
1078 call assert_equal("bar\nbaz\n", @r)
1079
1080 delmarks < >
1081 call assert_fails('*yank', 'E20:')
1082 close!
1083endfunc
1084
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01001085" Test for changing text in visual mode with 'exclusive' selection
1086func Test_exclusive_selection()
1087 new
1088 call setline(1, ['one', 'two'])
1089 set selection=exclusive
1090 call feedkeys("vwcabc", 'xt')
1091 call assert_equal('abctwo', getline(1))
1092 call setline(1, ["\tone"])
1093 set virtualedit=all
1094 call feedkeys('0v2lcl', 'xt')
1095 call assert_equal('l one', getline(1))
1096 set virtualedit&
1097 set selection&
1098 close!
1099endfunc
1100
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001101" Test for starting linewise visual with a count.
1102" This test needs to be run without any previous visual mode. Otherwise the
1103" count will use the count from the previous visual mode.
1104func Test_linewise_visual_with_count()
1105 let after =<< trim [CODE]
1106 call setline(1, ['one', 'two', 'three', 'four'])
1107 norm! 3Vy
1108 call assert_equal("one\ntwo\nthree\n", @")
1109 call writefile(v:errors, 'Xtestout')
1110 qall!
1111 [CODE]
1112 if RunVim([], after, '')
1113 call assert_equal([], readfile('Xtestout'))
1114 call delete('Xtestout')
1115 endif
1116endfunc
1117
1118" Test for starting characterwise visual with a count.
1119" This test needs to be run without any previous visual mode. Otherwise the
1120" count will use the count from the previous visual mode.
1121func Test_characterwise_visual_with_count()
1122 let after =<< trim [CODE]
1123 call setline(1, ['one two', 'three'])
1124 norm! l5vy
1125 call assert_equal("ne tw", @")
1126 call writefile(v:errors, 'Xtestout')
1127 qall!
1128 [CODE]
1129 if RunVim([], after, '')
1130 call assert_equal([], readfile('Xtestout'))
1131 call delete('Xtestout')
1132 endif
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01001133endfunc
1134
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001135" Test for visually selecting an inner block (iB)
1136func Test_visual_inner_block()
1137 new
1138 call setline(1, ['one', '{', 'two', '{', 'three', '}', 'four', '}', 'five'])
1139 call cursor(5, 1)
1140 " visually select all the lines in the block and then execute iB
1141 call feedkeys("ViB\<C-C>", 'xt')
1142 call assert_equal([0, 5, 1, 0], getpos("'<"))
1143 call assert_equal([0, 5, 6, 0], getpos("'>"))
1144 " visually select two inner blocks
1145 call feedkeys("ViBiB\<C-C>", 'xt')
1146 call assert_equal([0, 3, 1, 0], getpos("'<"))
1147 call assert_equal([0, 7, 5, 0], getpos("'>"))
1148 " try to select non-existing inner block
1149 call cursor(5, 1)
1150 call assert_beeps('normal ViBiBiB')
1151 " try to select a unclosed inner block
1152 8,9d
1153 call cursor(5, 1)
1154 call assert_beeps('normal ViBiB')
1155 close!
1156endfunc
1157
Bram Moolenaarcd942772020-08-22 21:08:44 +02001158func Test_visual_put_in_block()
1159 new
1160 call setline(1, ['xxxx', 'yyy', 'zzzz'])
1161 normal 1G2yl
1162 exe "normal 1G2l\<C-V>jjlp"
1163 call assert_equal(['xxxx', 'yxx', 'zzxx'], getline(1, 3))
1164 bwipe!
1165endfunc
1166
Christian Brabandt2fa93842021-05-30 22:17:25 +02001167func Test_visual_put_in_block_using_zp()
1168 new
1169 " paste using zP
Bram Moolenaar94722c52023-01-28 19:19:03 +00001170 call setline(1, ['/path;text', '/path;text', '/path;text', '',
1171 \ '/subdir',
Christian Brabandt2fa93842021-05-30 22:17:25 +02001172 \ '/longsubdir',
1173 \ '/longlongsubdir'])
1174 exe "normal! 5G\<c-v>2j$y"
1175 norm! 1Gf;zP
1176 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1177 %d
1178 " paste using zP
Bram Moolenaar94722c52023-01-28 19:19:03 +00001179 call setline(1, ['/path;text', '/path;text', '/path;text', '',
1180 \ '/subdir',
Christian Brabandt2fa93842021-05-30 22:17:25 +02001181 \ '/longsubdir',
1182 \ '/longlongsubdir'])
1183 exe "normal! 5G\<c-v>2j$y"
1184 norm! 1Gf;hzp
1185 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1186 bwipe!
1187endfunc
1188
Christian Brabandt544a38e2021-06-10 19:39:11 +02001189func Test_visual_put_in_block_using_zy_and_zp()
1190 new
1191
1192 " Test 1) Paste using zp - after the cursor without trailing spaces
Bram Moolenaar94722c52023-01-28 19:19:03 +00001193 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001194 \ 'texttext /subdir columntext',
1195 \ 'texttext /longsubdir columntext',
1196 \ 'texttext /longlongsubdir columntext'])
1197 exe "normal! 5G0f/\<c-v>2jezy"
1198 norm! 1G0f;hzp
1199 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1200
1201 " Test 2) Paste using zP - in front of the cursor without trailing spaces
1202 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001203 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001204 \ 'texttext /subdir columntext',
1205 \ 'texttext /longsubdir columntext',
1206 \ 'texttext /longlongsubdir columntext'])
1207 exe "normal! 5G0f/\<c-v>2jezy"
1208 norm! 1G0f;zP
1209 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1210
1211 " Test 3) Paste using p - with trailing spaces
1212 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001213 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001214 \ 'texttext /subdir columntext',
1215 \ 'texttext /longsubdir columntext',
1216 \ 'texttext /longlongsubdir columntext'])
1217 exe "normal! 5G0f/\<c-v>2jezy"
1218 norm! 1G0f;hp
1219 call assert_equal(['/path/subdir ;text', '/path/longsubdir ;text', '/path/longlongsubdir;text'], getline(1, 3))
1220
1221 " Test 4) Paste using P - with trailing spaces
1222 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001223 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001224 \ 'texttext /subdir columntext',
1225 \ 'texttext /longsubdir columntext',
1226 \ 'texttext /longlongsubdir columntext'])
1227 exe "normal! 5G0f/\<c-v>2jezy"
1228 norm! 1G0f;P
1229 call assert_equal(['/path/subdir ;text', '/path/longsubdir ;text', '/path/longlongsubdir;text'], getline(1, 3))
1230
1231 " Test 5) Yank with spaces inside the block
1232 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001233 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001234 \ 'texttext /sub dir/ columntext',
1235 \ 'texttext /lon gsubdir/ columntext',
1236 \ 'texttext /lon glongsubdir/ columntext'])
1237 exe "normal! 5G0f/\<c-v>2jf/zy"
1238 norm! 1G0f;zP
1239 call assert_equal(['/path/sub dir/;text', '/path/lon gsubdir/;text', '/path/lon glongsubdir/;text'], getline(1, 3))
1240 bwipe!
1241endfunc
1242
Bram Moolenaar7d7bcc62021-06-28 21:54:27 +02001243func Test_visual_put_blockedit_zy_and_zp()
1244 new
1245
1246 call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
1247 exe "normal! gg0\<c-v>2j$zy"
1248 norm! 5gg0zP
1249 call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
1250 "
1251 " now with blockmode editing
1252 sil %d
1253 :set ve=block
1254 call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
1255 exe "normal! gg0\<c-v>2j$zy"
1256 norm! 5gg0zP
1257 call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
1258 set ve&vim
1259 bw!
1260endfunc
1261
Bram Moolenaar44db8212022-01-25 21:26:17 +00001262func Test_visual_block_yank_zy()
1263 new
1264 " this was reading before the start of the line
1265 exe "norm o\<C-T>\<Esc>\<C-V>zy"
1266 bwipe!
1267endfunc
1268
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001269func Test_visual_block_with_virtualedit()
1270 CheckScreendump
1271
1272 let lines =<< trim END
1273 call setline(1, ['aaaaaa', 'bbbb', 'cc'])
1274 set virtualedit=block
1275 normal G
1276 END
Bram Moolenaar5b148ef2022-10-15 21:35:56 +01001277 call writefile(lines, 'XTest_block', 'D')
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001278
1279 let buf = RunVimInTerminal('-S XTest_block', {'rows': 8, 'cols': 50})
1280 call term_sendkeys(buf, "\<C-V>gg$")
1281 call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit', {})
1282
Bram Moolenaarb17ab862021-07-03 22:15:17 +02001283 call term_sendkeys(buf, "\<Esc>gg\<C-V>G$")
1284 call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit2', {})
1285
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001286 " clean up
1287 call term_sendkeys(buf, "\<Esc>")
1288 call StopVimInTerminal(buf)
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001289endfunc
1290
Bram Moolenaar615ddd52021-11-17 18:00:31 +00001291func Test_visual_block_ctrl_w_f()
dundargocc57b5bc2022-11-02 13:30:51 +00001292 " Empty block selected in new buffer should not result in an error.
Bram Moolenaar615ddd52021-11-17 18:00:31 +00001293 au! BufNew foo sil norm f
1294 edit foo
1295
1296 au! BufNew
1297endfunc
1298
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001299func Test_visual_block_append_invalid_char()
1300 " this was going over the end of the line
Bram Moolenaar262898a2022-01-17 17:52:22 +00001301 set isprint=@,161-255
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001302 new
1303 call setline(1, [' let xxx', 'xxxxxˆ', 'xxxxxxxxxxx'])
1304 exe "normal 0\<C-V>jjA-\<Esc>"
1305 call assert_equal([' - let xxx', 'xxxxx ', 'xxxxxxxx-xxx'], getline(1, 3))
1306 bwipe!
Bram Moolenaar262898a2022-01-17 17:52:22 +00001307 set isprint&
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001308endfunc
1309
Bram Moolenaar7ce5b2b2022-05-16 19:40:59 +01001310func Test_visual_block_with_substitute()
1311 " this was reading beyond the end of the line
1312 new
1313 norm a0)
1314 sil! norm  O
1315 s/)
1316 sil! norm 
1317 bwipe!
1318endfunc
1319
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001320func Test_visual_reselect_with_count()
Bram Moolenaar8f531662023-02-01 17:33:18 +00001321 enew
1322 call setline(1, ['aaaaaa', ' bbbb', ' bbbb'])
1323 exe "normal! 2Gw\<C-V>jed"
1324 exe "normal! gg0lP"
1325 call assert_equal(['abbbbaaaaa', 'bbbb ', ' '], getline(1, '$'))
1326
1327 exe "normal! 1vr."
1328 call assert_equal(['a....aaaaa', '✗.... ', ' '], getline(1, '$'))
1329
1330 bwipe!
1331
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001332 " this was causing an illegal memory access
1333 let lines =<< trim END
1334
1335
1336
1337 :
1338 r<sfile>
1339 exe "%norm e3\<c-v>kr\t"
1340 :
1341
1342 :
1343 END
Bram Moolenaar5b148ef2022-10-15 21:35:56 +01001344 call writefile(lines, 'XvisualReselect', 'D')
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001345 source XvisualReselect
1346
1347 bwipe!
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001348endfunc
1349
Bram Moolenaar79c11e32023-01-10 17:29:29 +00001350func Test_visual_reselect_exclusive()
1351 new
1352 call setline(1, ['abcde', 'abcde'])
1353 set selection=exclusive
1354 normal 1G0viwd
1355 normal 2G01vd
1356 call assert_equal(['', ''], getline(1, 2))
1357
1358 set selection&
1359 bwipe!
1360endfunc
1361
Bram Moolenaar57df9e82022-01-20 12:10:48 +00001362func Test_visual_block_insert_round_off()
1363 new
1364 " The number of characters are tuned to fill a 4096 byte allocated block,
1365 " so that valgrind reports going over the end.
1366 call setline(1, ['xxxxx', repeat('0', 1350), "\t", repeat('x', 60)])
1367 exe "normal gg0\<C-V>GI" .. repeat('0', 1320) .. "\<Esc>"
1368 bwipe!
1369endfunc
1370
Bram Moolenaar05b27612022-01-20 13:32:50 +00001371" this was causing an ml_get error
1372func Test_visual_exchange_windows()
1373 enew!
1374 new
1375 call setline(1, ['foo', 'bar'])
1376 exe "normal G\<C-V>gg\<C-W>\<C-X>OO\<Esc>"
1377 bwipe!
1378 bwipe!
1379endfunc
1380
Bram Moolenaardc5490e2022-01-25 13:52:53 +00001381" this was leaving the end of the Visual area beyond the end of a line
1382func Test_visual_ex_copy_line()
1383 new
1384 call setline(1, ["aaa", "bbbbbbbbbxbb"])
1385 /x
1386 exe "normal ggvjfxO"
1387 t0
1388 normal gNU
1389 bwipe!
1390endfunc
1391
Bram Moolenaar8d02ce12022-01-25 18:24:00 +00001392" This was leaving the end of the Visual area beyond the end of a line.
1393" Set 'undolevels' to start a new undo block.
1394func Test_visual_undo_deletes_last_line()
1395 new
1396 call setline(1, ["aaa", "ccc", "dyd"])
1397 set undolevels=100
1398 exe "normal obbbbbbbbbxbb\<Esc>"
1399 set undolevels=100
1400 /y
1401 exe "normal ggvjfxO"
1402 undo
1403 normal gNU
Shougo Matsushitafb552072022-01-28 16:01:13 +00001404
Bram Moolenaar8d02ce12022-01-25 18:24:00 +00001405 bwipe!
1406endfunc
1407
Shougo Matsushitafb552072022-01-28 16:01:13 +00001408func Test_visual_paste()
1409 new
1410
1411 " v_p overwrites unnamed register.
1412 call setline(1, ['xxxx'])
1413 call setreg('"', 'foo')
1414 call setreg('-', 'bar')
zeertzjq6bf821e2022-02-07 10:33:20 +00001415 normal gg0vp
1416 call assert_equal('x', @")
1417 call assert_equal('x', @-)
1418 call assert_equal('fooxxx', getline(1))
1419 normal $vp
1420 call assert_equal('x', @")
1421 call assert_equal('x', @-)
1422 call assert_equal('fooxxx', getline(1))
1423 " Test with a different register as unnamed register.
1424 call setline(2, ['baz'])
1425 normal 2gg0"rD
1426 call assert_equal('baz', @")
1427 normal gg0vp
1428 call assert_equal('f', @")
1429 call assert_equal('f', @-)
1430 call assert_equal('bazooxxx', getline(1))
1431 normal $vp
1432 call assert_equal('x', @")
1433 call assert_equal('x', @-)
1434 call assert_equal('bazooxxf', getline(1))
Shougo Matsushitafb552072022-01-28 16:01:13 +00001435
Shougo Matsushita509142a2022-05-06 11:45:09 +01001436 bwipe!
1437endfunc
1438
1439func Test_visual_paste_clipboard()
1440 CheckFeature clipboard_working
1441
1442 if has('gui')
1443 " auto select feature breaks tests
1444 set guioptions-=a
1445 endif
1446
1447 " v_P does not overwrite unnamed register.
1448 call setline(1, ['xxxx'])
1449 call setreg('"', 'foo')
1450 call setreg('-', 'bar')
1451 normal gg0vP
1452 call assert_equal('foo', @")
1453 call assert_equal('bar', @-)
1454 call assert_equal('fooxxx', getline(1))
1455 normal $vP
1456 call assert_equal('foo', @")
1457 call assert_equal('bar', @-)
1458 call assert_equal('fooxxfoo', getline(1))
1459 " Test with a different register as unnamed register.
1460 call setline(2, ['baz'])
1461 normal 2gg0"rD
1462 call assert_equal('baz', @")
1463 normal gg0vP
1464 call assert_equal('baz', @")
1465 call assert_equal('bar', @-)
1466 call assert_equal('bazooxxfoo', getline(1))
1467 normal $vP
1468 call assert_equal('baz', @")
1469 call assert_equal('bar', @-)
1470 call assert_equal('bazooxxfobaz', getline(1))
1471
1472 " Test for unnamed clipboard
1473 set clipboard=unnamed
1474 call setline(1, ['xxxx'])
1475 call setreg('"', 'foo')
1476 call setreg('-', 'bar')
1477 call setreg('*', 'baz')
1478 normal gg0vP
1479 call assert_equal('foo', @")
1480 call assert_equal('bar', @-)
1481 call assert_equal('baz', @*)
1482 call assert_equal('bazxxx', getline(1))
1483
1484 " Test for unnamedplus clipboard
1485 if has('unnamedplus')
1486 set clipboard=unnamedplus
Shougo Matsushitafb552072022-01-28 16:01:13 +00001487 call setline(1, ['xxxx'])
1488 call setreg('"', 'foo')
1489 call setreg('-', 'bar')
Shougo Matsushita509142a2022-05-06 11:45:09 +01001490 call setreg('+', 'baz')
zeertzjq6bf821e2022-02-07 10:33:20 +00001491 normal gg0vP
1492 call assert_equal('foo', @")
Shougo Matsushita509142a2022-05-06 11:45:09 +01001493 call assert_equal('bar', @-)
1494 call assert_equal('baz', @+)
1495 call assert_equal('bazxxx', getline(1))
Shougo Matsushitafb552072022-01-28 16:01:13 +00001496 endif
1497
Shougo Matsushita509142a2022-05-06 11:45:09 +01001498 set clipboard&
1499 if has('gui')
1500 set guioptions&
1501 endif
Shougo Matsushitafb552072022-01-28 16:01:13 +00001502 bwipe!
1503endfunc
Christian Brabandt544a38e2021-06-10 19:39:11 +02001504
Bram Moolenaar3d51ce12022-07-01 15:26:15 +01001505func Test_visual_area_adjusted_when_hiding()
1506 " The Visual area ended after the end of the line after :hide
1507 call setline(1, 'xxx')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001508 vsplit Xvaafile
Bram Moolenaar3d51ce12022-07-01 15:26:15 +01001509 call setline(1, 'xxxxxxxx')
1510 norm! $o
1511 hid
1512 norm! zW
1513 bwipe!
1514 bwipe!
1515endfunc
1516
Bram Moolenaarcfeb8a52022-08-13 14:09:44 +01001517func Test_switch_buffer_ends_visual_mode()
1518 enew
1519 call setline(1, 'foo')
1520 set hidden
1521 set virtualedit=all
1522 let buf1 = bufnr()
1523 enew
1524 let buf2 = bufnr()
1525 call setline(1, ['', '', '', ''])
1526 call cursor(4, 5)
1527 call feedkeys("\<C-V>3k4h", 'xt')
1528 exe 'buffer' buf1
1529 call assert_equal('n', mode())
1530
1531 set nohidden
1532 set virtualedit=
1533 bwipe!
1534 exe 'bwipe!' buf2
1535endfunc
1536
Pavel Mayorove1121b12023-02-20 14:35:20 +00001537" Check fix for the heap-based buffer overflow bug found in the function
1538" utfc_ptr2len and reported at
1539" https://huntr.dev/bounties/ae933869-a1ec-402a-bbea-d51764c6618e
1540func Test_heap_buffer_overflow()
1541 enew
1542 set updatecount=0
1543
1544 norm R0
1545 split other
1546 norm R000
1547 exe "norm \<C-V>l"
1548 ball
1549 call assert_equal(getpos("."), getpos("v"))
1550 call assert_equal('n', mode())
1551 norm zW
1552
1553 %bwipe!
1554 set updatecount&
1555endfunc
1556
zeertzjq8fc6a1d2023-08-20 18:12:54 +02001557" Test Visual highlight with cursor at end of screen line and 'showbreak'
1558func Test_visual_hl_with_showbreak()
1559 CheckScreendump
1560
1561 let lines =<< trim END
1562 setlocal showbreak=+
1563 call setline(1, repeat('a', &columns + 10))
1564 normal g$v4lo
1565 END
1566 call writefile(lines, 'XTest_visual_sbr', 'D')
1567
1568 let buf = RunVimInTerminal('-S XTest_visual_sbr', {'rows': 6, 'cols': 50})
1569 call VerifyScreenDump(buf, 'Test_visual_hl_with_showbreak', {})
1570
1571 " clean up
1572 call term_sendkeys(buf, "\<Esc>")
1573 call StopVimInTerminal(buf)
1574endfunc
Pavel Mayorove1121b12023-02-20 14:35:20 +00001575
Christian Brabandt476733f2023-09-19 20:41:51 +02001576func Test_Visual_r_CTRL_C()
1577 new
1578 " visual r_cmd
1579 call setline(1, [' '])
1580 call feedkeys("\<c-v>$r\<c-c>", 'tx')
1581 call assert_equal([''], getline(1, 1))
1582
1583 " visual gr_cmd
1584 call setline(1, [' '])
1585 call feedkeys("\<c-v>$gr\<c-c>", 'tx')
1586 call assert_equal([''], getline(1, 1))
1587 bw!
zeertzjqec149242023-12-19 20:28:31 +01001588endfunc
1589
1590func Test_visual_drag_out_of_window()
1591 rightbelow vnew
1592 call setline(1, '123456789')
1593 set mouse=a
1594 func ClickExpr(off)
1595 call test_setmouse(1, getwininfo(win_getid())[0].wincol + a:off)
1596 return "\<LeftMouse>"
1597 endfunc
1598 func DragExpr(off)
1599 call test_setmouse(1, getwininfo(win_getid())[0].wincol + a:off)
1600 return "\<LeftDrag>"
1601 endfunc
1602
1603 nnoremap <expr> <F2> ClickExpr(5)
1604 nnoremap <expr> <F3> DragExpr(-1)
1605 redraw
1606 call feedkeys("\<F2>\<F3>\<LeftRelease>", 'tx')
1607 call assert_equal([1, 6], [col('.'), col('v')])
1608 call feedkeys("\<Esc>", 'tx')
1609
1610 nnoremap <expr> <F2> ClickExpr(6)
1611 nnoremap <expr> <F3> DragExpr(-2)
1612 redraw
1613 call feedkeys("\<F2>\<F3>\<LeftRelease>", 'tx')
1614 call assert_equal([1, 7], [col('.'), col('v')])
1615 call feedkeys("\<Esc>", 'tx')
1616
1617 nunmap <F2>
1618 nunmap <F3>
1619 delfunc ClickExpr
1620 delfunc DragExpr
1621 set mouse&
1622 bwipe!
1623endfunc
Christian Brabandt476733f2023-09-19 20:41:51 +02001624
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +01001625" vim: shiftwidth=2 sts=2 expandtab