blob: 4fab9254637d818e0be6473118ee400716970680 [file] [log] [blame]
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +01001" Tests for various Visual modes.
Bram Moolenaarc3c766e2017-03-08 22:55:19 +01002
Christian Brabandteb380b92025-07-07 20:53:55 +02003source util/screendump.vim
4import './util/vim9.vim' as v9
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02005
Bram Moolenaar019b9c62016-03-05 17:26:00 +01006func Test_block_shift_multibyte()
Bram Moolenaarf8eb9c52017-01-02 17:31:24 +01007 " Uses double-wide character.
Bram Moolenaar019b9c62016-03-05 17:26:00 +01008 split
9 call setline(1, ['xヹxxx', 'ヹxxx'])
10 exe "normal 1G0l\<C-V>jl>"
11 call assert_equal('x ヹxxx', getline(1))
12 call assert_equal(' ヹxxx', getline(2))
13 q!
14endfunc
Bram Moolenaarf8eb9c52017-01-02 17:31:24 +010015
Bram Moolenaarbae5a172017-08-06 15:42:06 +020016func Test_block_shift_overflow()
17 " This used to cause a multiplication overflow followed by a crash.
18 new
19 normal ii
20 exe "normal \<C-V>876543210>"
21 q!
22endfunc
23
Bram Moolenaarf8eb9c52017-01-02 17:31:24 +010024func Test_dotregister_paste()
25 new
26 exe "norm! ihello world\<esc>"
27 norm! 0ve".p
28 call assert_equal('hello world world', getline(1))
29 q!
30endfunc
Bram Moolenaar23fa81d2017-02-01 21:50:21 +010031
32func Test_Visual_ctrl_o()
33 new
34 call setline(1, ['one', 'two', 'three'])
35 call cursor(1,2)
36 set noshowmode
37 set tw=0
38 call feedkeys("\<c-v>jjlIa\<c-\>\<c-o>:set tw=88\<cr>\<esc>", 'tx')
39 call assert_equal(['oane', 'tawo', 'tahree'], getline(1, 3))
40 call assert_equal(88, &tw)
41 set tw&
42 bw!
43endfu
Bram Moolenaar84b2a382017-02-17 11:40:00 +010044
45func Test_Visual_vapo()
46 new
47 normal oxx
48 normal vapo
49 bwipe!
50endfunc
Bram Moolenaar46522af2017-02-18 23:12:01 +010051
52func Test_Visual_inner_quote()
53 new
54 normal oxX
55 normal vki'
56 bwipe!
57endfunc
Bram Moolenaar75373f32017-08-07 22:02:30 +020058
59" Test for Visual mode not being reset causing E315 error.
60func TriggerTheProblem()
61 " At this point there is no visual selection because :call reset it.
62 " Let's restore the selection:
63 normal gv
64 '<,'>del _
65 try
66 exe "normal \<Esc>"
67 catch /^Vim\%((\a\+)\)\=:E315/
68 echom 'Snap! E315 error!'
Bram Moolenaar63e82db2018-03-06 12:10:48 +010069 let g:msg = 'Snap! E315 error!'
Bram Moolenaar75373f32017-08-07 22:02:30 +020070 endtry
71endfunc
72
73func Test_visual_mode_reset()
Bram Moolenaar75373f32017-08-07 22:02:30 +020074 enew
Bram Moolenaar63e82db2018-03-06 12:10:48 +010075 let g:msg = "Everything's fine."
Bram Moolenaar75373f32017-08-07 22:02:30 +020076 enew
77 setl buftype=nofile
78 call append(line('$'), 'Delete this line.')
79
80 " NOTE: this has to be done by a call to a function because executing :del
81 " the ex-way will require the colon operator which resets the visual mode
82 " thus preventing the problem:
83 exe "normal! GV:call TriggerTheProblem()\<CR>"
84 call assert_equal("Everything's fine.", g:msg)
Bram Moolenaar75373f32017-08-07 22:02:30 +020085endfunc
Bram Moolenaar67418d92017-10-15 22:07:39 +020086
Bram Moolenaar15993ce2017-10-26 20:21:44 +020087" Test for visual block shift and tab characters.
88func Test_block_shift_tab()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +020089 new
Bram Moolenaar15993ce2017-10-26 20:21:44 +020090 call append(0, repeat(['one two three'], 5))
91 call cursor(1,1)
92 exe "normal i\<C-G>u"
93 exe "normal fe\<C-V>4jR\<Esc>ugvr1"
94 call assert_equal('on1 two three', getline(1))
95 call assert_equal('on1 two three', getline(2))
96 call assert_equal('on1 two three', getline(5))
97
Bram Moolenaar3e72dca2021-05-29 16:30:12 +020098 %d _
Bram Moolenaar15993ce2017-10-26 20:21:44 +020099 call append(0, repeat(['abcdefghijklmnopqrstuvwxyz'], 5))
100 call cursor(1,1)
101 exe "normal \<C-V>4jI \<Esc>j<<11|D"
102 exe "normal j7|a\<Tab>\<Tab>"
103 exe "normal j7|a\<Tab>\<Tab> "
104 exe "normal j7|a\<Tab> \<Tab>\<Esc>4k13|\<C-V>4j<"
105 call assert_equal(' abcdefghijklmnopqrstuvwxyz', getline(1))
106 call assert_equal('abcdefghij', getline(2))
107 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(3))
108 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(4))
109 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(5))
110
111 %s/\s\+//g
112 call cursor(1,1)
113 exe "normal \<C-V>4jI \<Esc>j<<"
114 exe "normal j7|a\<Tab>\<Tab>"
115 exe "normal j7|a\<Tab>\<Tab>\<Tab>\<Tab>\<Tab>"
116 exe "normal j7|a\<Tab> \<Tab>\<Tab>\<Esc>4k13|\<C-V>4j3<"
117 call assert_equal(' abcdefghijklmnopqrstuvwxyz', getline(1))
118 call assert_equal('abcdefghij', getline(2))
119 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(3))
120 call assert_equal(" abc\<Tab>\<Tab>defghijklmnopqrstuvwxyz", getline(4))
121 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(5))
122
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200123 " Test for block shift with space characters at the beginning and with
124 " 'noexpandtab' and 'expandtab'
125 %d _
126 call setline(1, [" 1", " 2", " 3"])
127 setlocal shiftwidth=2 noexpandtab
128 exe "normal gg\<C-V>3j>"
129 call assert_equal(["\t1", "\t2", "\t3"], getline(1, '$'))
130 %d _
131 call setline(1, [" 1", " 2", " 3"])
132 setlocal shiftwidth=2 expandtab
133 exe "normal gg\<C-V>3j>"
134 call assert_equal([" 1", " 2", " 3"], getline(1, '$'))
135 setlocal shiftwidth&
136
137 bw!
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200138endfunc
139
140" Tests Blockwise Visual when there are TABs before the text.
141func Test_blockwise_visual()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200142 new
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200143 call append(0, ['123456',
144 \ '234567',
145 \ '345678',
146 \ '',
147 \ 'test text test tex start here',
148 \ "\t\tsome text",
149 \ "\t\ttest text",
150 \ 'test text'])
151 call cursor(1,1)
152 exe "normal /start here$\<CR>"
153 exe 'normal "by$' . "\<C-V>jjlld"
154 exe "normal /456$\<CR>"
155 exe "normal \<C-V>jj" . '"bP'
156 call assert_equal(['123start here56',
157 \ '234start here67',
158 \ '345start here78',
159 \ '',
160 \ 'test text test tex rt here',
161 \ "\t\tsomext",
162 \ "\t\ttesext"], getline(1, 7))
163
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200164 bw!
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200165endfunc
166
Bram Moolenaar2e949762018-05-20 14:06:38 +0200167" Test swapping corners in blockwise visual mode with o and O
168func Test_blockwise_visual_o_O()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200169 new
Bram Moolenaar2e949762018-05-20 14:06:38 +0200170
171 exe "norm! 10i.\<Esc>Y4P3lj\<C-V>4l2jr "
172 exe "norm! gvO\<Esc>ra"
173 exe "norm! gvO\<Esc>rb"
174 exe "norm! gvo\<C-c>rc"
175 exe "norm! gvO\<C-c>rd"
Bram Moolenaar1671f442020-03-10 07:48:13 +0100176 set selection=exclusive
177 exe "norm! gvOo\<C-c>re"
178 call assert_equal('...a be.', getline(4))
179 exe "norm! gvOO\<C-c>rf"
180 set selection&
Bram Moolenaar2e949762018-05-20 14:06:38 +0200181
182 call assert_equal(['..........',
183 \ '...c d..',
184 \ '... ..',
Bram Moolenaar1671f442020-03-10 07:48:13 +0100185 \ '...a bf.',
Bram Moolenaar2e949762018-05-20 14:06:38 +0200186 \ '..........'], getline(1, '$'))
187
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200188 bw!
Bram Moolenaar2e949762018-05-20 14:06:38 +0200189endfun
190
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200191" Test Virtual replace mode.
192func Test_virtual_replace()
Bram Moolenaardf0d24b2018-03-06 14:22:58 +0100193 if exists('&t_kD')
194 let save_t_kD = &t_kD
195 endif
196 if exists('&t_kb')
197 let save_t_kb = &t_kb
198 endif
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200199 exe "set t_kD=\<C-V>x7f t_kb=\<C-V>x08"
200 enew!
201 exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
202 call cursor(1,1)
203 set ai bs=2
204 exe "normal gR0\<C-D> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
205 call assert_equal([' 1',
206 \ ' A',
207 \ ' BCDEFGHIJ',
208 \ ' KL',
209 \ ' MNO',
210 \ ' PQR',
211 \ ], getline(1, 6))
212 normal G
213 mark a
214 exe "normal o0\<C-D>\nabcdefghi\njk\tlmn\n opq\trst\n\<C-D>uvwxyz\n"
215 exe "normal 'ajgR0\<C-D> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR" . repeat("\<BS>", 29)
216 call assert_equal([' 1',
217 \ 'abcdefghi',
218 \ 'jk lmn',
219 \ ' opq rst',
220 \ 'uvwxyz'], getline(7, 11))
221 normal G
222 exe "normal iab\tcdefghi\tjkl"
223 exe "normal 0gRAB......CDEFGHI.J\<Esc>o"
224 exe "normal iabcdefghijklmnopqrst\<Esc>0gRAB\tIJKLMNO\tQR"
225 call assert_equal(['AB......CDEFGHI.Jkl',
226 \ 'AB IJKLMNO QRst'], getline(12, 13))
Bram Moolenaar845e0ee2020-06-20 16:05:32 +0200227
228 " Test inserting Tab with 'noexpandtab' and 'softabstop' set to 4
229 %d
230 call setline(1, 'aaaaaaaaaaaaa')
231 set softtabstop=4
232 exe "normal gggR\<Tab>\<Tab>x"
233 call assert_equal("\txaaaa", getline(1))
234 set softtabstop&
235
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200236 enew!
Bram Moolenaare7808482018-03-06 13:17:23 +0100237 set noai bs&vim
Bram Moolenaardf0d24b2018-03-06 14:22:58 +0100238 if exists('save_t_kD')
239 let &t_kD = save_t_kD
240 endif
241 if exists('save_t_kb')
242 let &t_kb = save_t_kb
243 endif
Bram Moolenaar63e82db2018-03-06 12:10:48 +0100244endfunc
245
246" Test Virtual replace mode.
247func Test_virtual_replace2()
248 enew!
249 set bs=2
250 exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
251 call cursor(1,1)
252 " Test 1: Test that del deletes the newline
253 exe "normal gR0\<del> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
254 call assert_equal(['0 1',
255 \ 'A',
256 \ 'BCDEFGHIJ',
257 \ ' KL',
258 \ 'MNO',
259 \ 'PQR',
260 \ ], getline(1, 6))
261 " Test 2:
262 " a newline is not deleted, if no newline has been added in virtual replace mode
263 %d_
264 call setline(1, ['abcd', 'efgh', 'ijkl'])
265 call cursor(2,1)
266 exe "norm! gR1234\<cr>5\<bs>\<bs>\<bs>"
267 call assert_equal(['abcd',
268 \ '123h',
269 \ 'ijkl'], getline(1, '$'))
270 " Test 3:
271 " a newline is deleted, if a newline has been inserted before in virtual replace mode
272 %d_
273 call setline(1, ['abcd', 'efgh', 'ijkl'])
274 call cursor(2,1)
275 exe "norm! gR1234\<cr>\<cr>56\<bs>\<bs>\<bs>"
276 call assert_equal(['abcd',
277 \ '1234',
278 \ 'ijkl'], getline(1, '$'))
279 " Test 4:
280 " delete add a newline, delete it, add it again and check undo
281 %d_
282 call setline(1, ['abcd', 'efgh', 'ijkl'])
283 call cursor(2,1)
284 " break undo sequence explicitly
285 let &ul = &ul
286 exe "norm! gR1234\<cr>\<bs>\<del>56\<cr>"
287 let &ul = &ul
288 call assert_equal(['abcd',
289 \ '123456',
290 \ ''], getline(1, '$'))
291 norm! u
292 call assert_equal(['abcd',
293 \ 'efgh',
294 \ 'ijkl'], getline(1, '$'))
Bram Moolenaarca68ae12020-03-30 19:32:53 +0200295
296 " Test for truncating spaces in a newly added line using 'autoindent' if
297 " characters are not added to that line.
298 %d_
299 call setline(1, [' app', ' bee', ' cat'])
300 setlocal autoindent
301 exe "normal gg$gRt\n\nr"
302 call assert_equal([' apt', '', ' rat'], getline(1, '$'))
303
Bram Moolenaar63e82db2018-03-06 12:10:48 +0100304 " clean up
305 %d_
306 set bs&vim
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200307endfunc
Bram Moolenaar6d3a1942019-01-03 23:10:32 +0100308
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100309func Test_Visual_word_textobject()
310 new
311 call setline(1, ['First sentence. Second sentence.'])
312
313 " When start and end of visual area are identical, 'aw' or 'iw' select
314 " the whole word.
315 norm! 1go2fcvawy
316 call assert_equal('Second ', @")
317 norm! 1go2fcviwy
318 call assert_equal('Second', @")
319
320 " When start and end of visual area are not identical, 'aw' or 'iw'
321 " extend the word in direction of the end of the visual area.
322 norm! 1go2fcvlawy
323 call assert_equal('cond ', @")
324 norm! gv2awy
325 call assert_equal('cond sentence.', @")
326
327 norm! 1go2fcvliwy
328 call assert_equal('cond', @")
329 norm! gv2iwy
330 call assert_equal('cond sentence', @")
331
332 " Extend visual area in opposite direction.
333 norm! 1go2fcvhawy
334 call assert_equal(' Sec', @")
335 norm! gv2awy
336 call assert_equal(' sentence. Sec', @")
337
338 norm! 1go2fcvhiwy
339 call assert_equal('Sec', @")
340 norm! gv2iwy
341 call assert_equal('. Sec', @")
342
343 bwipe!
344endfunc
345
Bram Moolenaar6d3a1942019-01-03 23:10:32 +0100346func Test_Visual_sentence_textobject()
347 new
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100348 call setline(1, ['First sentence. Second sentence. Third', 'sentence. Fourth sentence'])
Bram Moolenaar6d3a1942019-01-03 23:10:32 +0100349
350 " When start and end of visual area are identical, 'as' or 'is' select
351 " the whole sentence.
352 norm! 1gofdvasy
353 call assert_equal('Second sentence. ', @")
354 norm! 1gofdvisy
355 call assert_equal('Second sentence.', @")
356
357 " When start and end of visual area are not identical, 'as' or 'is'
358 " extend the sentence in direction of the end of the visual area.
359 norm! 1gofdvlasy
360 call assert_equal('d sentence. ', @")
361 norm! gvasy
362 call assert_equal("d sentence. Third\nsentence. ", @")
363
364 norm! 1gofdvlisy
365 call assert_equal('d sentence.', @")
366 norm! gvisy
367 call assert_equal('d sentence. ', @")
368 norm! gvisy
369 call assert_equal("d sentence. Third\nsentence.", @")
370
371 " Extend visual area in opposite direction.
372 norm! 1gofdvhasy
373 call assert_equal(' Second', @")
374 norm! gvasy
375 call assert_equal("First sentence. Second", @")
376
377 norm! 1gofdvhisy
378 call assert_equal('Second', @")
379 norm! gvisy
380 call assert_equal(' Second', @")
381 norm! gvisy
382 call assert_equal('First sentence. Second', @")
383
384 bwipe!
385endfunc
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100386
387func Test_Visual_paragraph_textobject()
388 new
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200389 let lines =<< trim [END]
390 First line.
391
392 Second line.
393 Third line.
394 Fourth line.
395 Fifth line.
396
397 Sixth line.
398 [END]
399 call setline(1, lines)
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100400
401 " When start and end of visual area are identical, 'ap' or 'ip' select
402 " the whole paragraph.
403 norm! 4ggvapy
404 call assert_equal("Second line.\nThird line.\nFourth line.\nFifth line.\n\n", @")
405 norm! 4ggvipy
406 call assert_equal("Second line.\nThird line.\nFourth line.\nFifth line.\n", @")
407
408 " When start and end of visual area are not identical, 'ap' or 'ip'
409 " extend the sentence in direction of the end of the visual area.
410 " FIXME: actually, it is not sufficient to have different start and
411 " end of visual selection, the start line and end line have to differ,
412 " which is not consistent with the documentation.
413 norm! 4ggVjapy
414 call assert_equal("Third line.\nFourth line.\nFifth line.\n\n", @")
415 norm! gvapy
416 call assert_equal("Third line.\nFourth line.\nFifth line.\n\nSixth line.\n", @")
417 norm! 4ggVjipy
418 call assert_equal("Third line.\nFourth line.\nFifth line.\n", @")
419 norm! gvipy
420 call assert_equal("Third line.\nFourth line.\nFifth line.\n\n", @")
421 norm! gvipy
422 call assert_equal("Third line.\nFourth line.\nFifth line.\n\nSixth line.\n", @")
423
424 " Extend visual area in opposite direction.
425 norm! 5ggVkapy
426 call assert_equal("\nSecond line.\nThird line.\nFourth line.\n", @")
427 norm! gvapy
428 call assert_equal("First line.\n\nSecond line.\nThird line.\nFourth line.\n", @")
429 norm! 5ggVkipy
430 call assert_equal("Second line.\nThird line.\nFourth line.\n", @")
431 norma gvipy
432 call assert_equal("\nSecond line.\nThird line.\nFourth line.\n", @")
433 norm! gvipy
434 call assert_equal("First line.\n\nSecond line.\nThird line.\nFourth line.\n", @")
435
436 bwipe!
437endfunc
Bram Moolenaar19a66852019-03-07 11:25:32 +0100438
439func Test_curswant_not_changed()
440 new
441 call setline(1, ['one', 'two'])
442 au InsertLeave * call getcurpos()
443 call feedkeys("gg0\<C-V>jI123 \<Esc>j", 'xt')
444 call assert_equal([0, 2, 1, 0, 1], getcurpos())
445
446 bwipe!
447 au! InsertLeave
448endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +0200449
450" Tests for "vaBiB", end could be wrong.
451func Test_Visual_Block()
452 new
453 a
454- Bug in "vPPPP" on this text:
455 {
456 cmd;
457 {
458 cmd;\t/* <-- Start cursor here */
459 {
460 }
461 }
462 }
463.
464 normal gg
465 call search('Start cursor here')
466 normal vaBiBD
467 call assert_equal(['- Bug in "vPPPP" on this text:',
468 \ "\t{",
469 \ "\t}"], getline(1, '$'))
470
Christian Brabandtc9a1e252025-01-11 15:25:00 +0100471 bw!
Bram Moolenaarc6b37db2019-04-27 18:00:34 +0200472endfunc
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +0100473
474" Test for 'p'ut in visual block mode
475func Test_visual_block_put()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200476 new
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +0100477 call append(0, ['One', 'Two', 'Three'])
478 normal gg
479 yank
480 call feedkeys("jl\<C-V>ljp", 'xt')
481 call assert_equal(['One', 'T', 'Tee', 'One', ''], getline(1, '$'))
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200482 bw!
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +0100483endfunc
484
Bram Moolenaar36343ae2022-10-15 19:04:05 +0100485func Test_visual_block_put_invalid()
486 enew!
487 behave mswin
488 norm yy
489 norm v)Ps/^/
490 " this was causing the column to become negative
491 silent norm ggv)P
492
493 bwipe!
494 behave xterm
495endfunc
496
Bram Moolenaar309976e2019-12-05 18:16:33 +0100497" Visual modes (v V CTRL-V) followed by an operator; count; repeating
498func Test_visual_mode_op()
499 new
500 call append(0, '')
501
502 call setline(1, 'apple banana cherry')
503 call cursor(1, 1)
504 normal lvld.l3vd.
505 call assert_equal('a y', getline(1))
506
507 call setline(1, ['line 1 line 1', 'line 2 line 2', 'line 3 line 3',
508 \ 'line 4 line 4', 'line 5 line 5', 'line 6 line 6'])
509 call cursor(1, 1)
510 exe "normal Vcnewline\<Esc>j.j2Vd."
511 call assert_equal(['newline', 'newline'], getline(1, '$'))
512
513 call deletebufline('', 1, '$')
514 call setline(1, ['xxxxxxxxxxxxx', 'xxxxxxxxxxxxx', 'xxxxxxxxxxxxx',
515 \ 'xxxxxxxxxxxxx'])
516 exe "normal \<C-V>jlc \<Esc>l.l2\<C-V>c----\<Esc>l."
517 call assert_equal([' --------x',
518 \ ' --------x',
519 \ 'xxxx--------x',
520 \ 'xxxx--------x'], getline(1, '$'))
521
522 bwipe!
523endfunc
524
525" Visual mode maps (movement and text object)
526" Visual mode maps; count; repeating
527" - Simple
528" - With an Ex command (custom text object)
529func Test_visual_mode_maps()
530 new
531 call append(0, '')
532
533 func SelectInCaps()
534 let [line1, col1] = searchpos('\u', 'bcnW')
535 let [line2, col2] = searchpos('.\u', 'nW')
536 call setpos("'<", [0, line1, col1, 0])
537 call setpos("'>", [0, line2, col2, 0])
538 normal! gv
539 endfunction
540
541 vnoremap W /\u/s-1<CR>
542 vnoremap iW :<C-U>call SelectInCaps()<CR>
543
544 call setline(1, 'KiwiRaspberryDateWatermelonPeach')
545 call cursor(1, 1)
546 exe "normal vWcNo\<Esc>l.fD2vd."
547 call assert_equal('NoNoberryach', getline(1))
548
549 call setline(1, 'JambuRambutanBananaTangerineMango')
550 call cursor(1, 1)
551 exe "normal llviWc-\<Esc>l.l2vdl."
552 call assert_equal('--ago', getline(1))
553
554 vunmap W
555 vunmap iW
556 bwipe!
557 delfunc SelectInCaps
558endfunc
559
560" Operator-pending mode maps (movement and text object)
561" - Simple
562" - With Ex command moving the cursor
563" - With Ex command and Visual selection (custom text object)
564func Test_visual_oper_pending_mode_maps()
565 new
566 call append(0, '')
567
568 func MoveToCap()
569 call search('\u', 'W')
570 endfunction
571
572 func SelectInCaps()
573 let [line1, col1] = searchpos('\u', 'bcnW')
574 let [line2, col2] = searchpos('.\u', 'nW')
575 call setpos("'<", [0, line1, col1, 0])
576 call setpos("'>", [0, line2, col2, 0])
577 normal! gv
578 endfunction
579
580 onoremap W /\u/<CR>
581 onoremap <Leader>W :<C-U>call MoveToCap()<CR>
582 onoremap iW :<C-U>call SelectInCaps()<CR>
583
584 call setline(1, 'PineappleQuinceLoganberryOrangeGrapefruitKiwiZ')
585 call cursor(1, 1)
586 exe "normal cW-\<Esc>l.l2.l."
587 call assert_equal('----Z', getline(1))
588
589 call setline(1, 'JuniperDurianZ')
590 call cursor(1, 1)
591 exe "normal g?\WfD."
592 call assert_equal('WhavcreQhevnaZ', getline(1))
593
594 call setline(1, 'LemonNectarineZ')
595 call cursor(1, 1)
596 exe "normal yiWPlciWNew\<Esc>fr."
597 call assert_equal('LemonNewNewZ', getline(1))
598
599 ounmap W
600 ounmap <Leader>W
601 ounmap iW
602 bwipe!
603 delfunc MoveToCap
604 delfunc SelectInCaps
605endfunc
606
607" Patch 7.3.879: Properly abort Operator-pending mode for "dv:<Esc>" etc.
608func Test_op_pend_mode_abort()
609 new
610 call append(0, '')
611
612 call setline(1, ['zzzz', 'zzzz'])
613 call cursor(1, 1)
614
615 exe "normal dV:\<CR>dv:\<CR>"
616 call assert_equal(['zzz'], getline(1, 2))
617 set nomodifiable
618 call assert_fails('exe "normal d:\<CR>"', 'E21:')
619 set modifiable
620 call feedkeys("dv:\<Esc>dV:\<Esc>", 'xt')
621 call assert_equal(['zzz'], getline(1, 2))
622 set nomodifiable
623 let v:errmsg = ''
624 call feedkeys("d:\<Esc>", 'xt')
625 call assert_true(v:errmsg !~# '^E21:')
626 set modifiable
627
628 bwipe!
629endfunc
630
631func Test_characterwise_visual_mode()
632 new
633
634 " characterwise visual mode: replace last line
635 $put ='a'
636 let @" = 'x'
637 normal v$p
638 call assert_equal('x', getline('$'))
639
640 " characterwise visual mode: delete middle line
641 call deletebufline('', 1, '$')
642 call append('$', ['a', 'b', 'c'])
643 normal G
644 normal kkv$d
645 call assert_equal(['', 'b', 'c'], getline(1, '$'))
646
647 " characterwise visual mode: delete middle two lines
648 call deletebufline('', 1, '$')
649 call append('$', ['a', 'b', 'c'])
650 normal Gkkvj$d
651 call assert_equal(['', 'c'], getline(1, '$'))
652
653 " characterwise visual mode: delete last line
654 call deletebufline('', 1, '$')
655 call append('$', ['a', 'b', 'c'])
656 normal Gv$d
657 call assert_equal(['', 'a', 'b', ''], getline(1, '$'))
658
659 " characterwise visual mode: delete last two lines
660 call deletebufline('', 1, '$')
661 call append('$', ['a', 'b', 'c'])
662 normal Gkvj$d
663 call assert_equal(['', 'a', ''], getline(1, '$'))
664
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200665 " characterwise visual mode: use a count with the visual mode from the last
666 " line in the buffer
667 %d _
668 call setline(1, ['one', 'two', 'three', 'four'])
669 norm! vj$y
670 norm! G1vy
671 call assert_equal('four', @")
672
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200673 " characterwise visual mode: replace a single character line and the eol
674 %d _
675 call setline(1, "a")
676 normal v$rx
677 call assert_equal(['x'], getline(1, '$'))
678
Bram Moolenaar6ecf58b2021-12-16 10:05:41 +0000679 " replace a character with composing characters
680 call setline(1, "xã̳x")
681 normal gg0lvrb
682 call assert_equal("xbx", getline(1))
683
Bram Moolenaar309976e2019-12-05 18:16:33 +0100684 bwipe!
685endfunc
686
Bram Moolenaar309976e2019-12-05 18:16:33 +0100687func Test_visual_mode_put()
688 new
689
690 " v_p: replace last character with line register at middle line
691 call append('$', ['aaa', 'bbb', 'ccc'])
692 normal G
693 -2yank
694 normal k$vp
695 call assert_equal(['', 'aaa', 'bb', 'aaa', '', 'ccc'], getline(1, '$'))
696
697 " v_p: replace last character with line register at middle line selecting
698 " newline
699 call deletebufline('', 1, '$')
700 call append('$', ['aaa', 'bbb', 'ccc'])
701 normal G
702 -2yank
703 normal k$v$p
704 call assert_equal(['', 'aaa', 'bb', 'aaa', 'ccc'], getline(1, '$'))
705
706 " v_p: replace last character with line register at last line
707 call deletebufline('', 1, '$')
708 call append('$', ['aaa', 'bbb', 'ccc'])
709 normal G
710 -2yank
711 normal $vp
712 call assert_equal(['', 'aaa', 'bbb', 'cc', 'aaa', ''], getline(1, '$'))
713
714 " v_p: replace last character with line register at last line selecting
715 " newline
716 call deletebufline('', 1, '$')
717 call append('$', ['aaa', 'bbb', 'ccc'])
718 normal G
719 -2yank
720 normal $v$p
721 call assert_equal(['', 'aaa', 'bbb', 'cc', 'aaa', ''], getline(1, '$'))
722
723 bwipe!
724endfunc
725
Bram Moolenaar515545e2020-03-22 14:08:59 +0100726func Test_gv_with_exclusive_selection()
Bram Moolenaar309976e2019-12-05 18:16:33 +0100727 new
728
Bram Moolenaar515545e2020-03-22 14:08:59 +0100729 " gv with exclusive selection after an operation
Bram Moolenaar309976e2019-12-05 18:16:33 +0100730 call append('$', ['zzz ', 'äà '])
731 set selection=exclusive
732 normal Gkv3lyjv3lpgvcxxx
733 call assert_equal(['', 'zzz ', 'xxx '], getline(1, '$'))
734
Bram Moolenaar515545e2020-03-22 14:08:59 +0100735 " gv with exclusive selection without an operation
Bram Moolenaar309976e2019-12-05 18:16:33 +0100736 call deletebufline('', 1, '$')
737 call append('$', 'zzz ')
738 set selection=exclusive
739 exe "normal G0v3l\<Esc>gvcxxx"
740 call assert_equal(['', 'xxx '], getline(1, '$'))
741
742 set selection&vim
743 bwipe!
744endfunc
745
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100746" Tests for the visual block mode commands
747func Test_visual_block_mode()
748 new
749 call append(0, '')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100750 call setline(1, repeat(['abcdefghijklm'], 5))
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100751 call cursor(1, 1)
752
753 " Test shift-right of a block
754 exe "normal jllll\<C-V>jj>wll\<C-V>jlll>"
755 " Test shift-left of a block
756 exe "normal G$hhhh\<C-V>kk<"
757 " Test block-insert
758 exe "normal Gkl\<C-V>kkkIxyz"
759 " Test block-replace
760 exe "normal Gllll\<C-V>kkklllrq"
761 " Test block-change
762 exe "normal G$khhh\<C-V>hhkkcmno"
763 call assert_equal(['axyzbcdefghijklm',
764 \ 'axyzqqqq mno ghijklm',
765 \ 'axyzqqqqef mno ghijklm',
766 \ 'axyzqqqqefgmnoklm',
767 \ 'abcdqqqqijklm'], getline(1, 5))
768
Bram Moolenaar1671f442020-03-10 07:48:13 +0100769 " Test 'C' to change till the end of the line
770 call cursor(3, 4)
771 exe "normal! \<C-V>j3lCooo"
772 call assert_equal(['axyooo', 'axyooo'], getline(3, 4))
773
774 " Test 'D' to delete till the end of the line
775 call cursor(3, 3)
776 exe "normal! \<C-V>j2lD"
777 call assert_equal(['ax', 'ax'], getline(3, 4))
778
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200779 " Test block insert with a short line that ends before the block
780 %d _
781 call setline(1, [" one", "a", " two"])
782 exe "normal gg\<C-V>2jIx"
783 call assert_equal([" xone", "a", " xtwo"], getline(1, '$'))
784
785 " Test block append at EOL with '$' and without '$'
786 %d _
787 call setline(1, ["one", "a", "two"])
788 exe "normal gg$\<C-V>2jAx"
789 call assert_equal(["onex", "ax", "twox"], getline(1, '$'))
790 %d _
791 call setline(1, ["one", "a", "two"])
792 exe "normal gg3l\<C-V>2jAx"
793 call assert_equal(["onex", "a x", "twox"], getline(1, '$'))
794
795 " Test block replace with an empty line in the middle and use $ to jump to
796 " the end of the line.
797 %d _
798 call setline(1, ['one', '', 'two'])
799 exe "normal gg$\<C-V>2jrx"
800 call assert_equal(["onx", "", "twx"], getline(1, '$'))
801
802 " Test block replace with an empty line in the middle and move cursor to the
803 " end of the line
804 %d _
805 call setline(1, ['one', '', 'two'])
806 exe "normal gg2l\<C-V>2jrx"
807 call assert_equal(["onx", "", "twx"], getline(1, '$'))
808
809 " Replace odd number of characters with a multibyte character
810 %d _
811 call setline(1, ['abcd', 'efgh'])
812 exe "normal ggl\<C-V>2ljr\u1100"
813 call assert_equal(["a\u1100 ", "e\u1100 "], getline(1, '$'))
814
815 " During visual block append, if the cursor moved outside of the selected
816 " range, then the edit should not be applied to the block.
817 %d _
818 call setline(1, ['aaa', 'bbb', 'ccc'])
819 exe "normal 2G\<C-V>jAx\<Up>"
820 call assert_equal(['aaa', 'bxbb', 'ccc'], getline(1, '$'))
821
822 " During visual block append, if the cursor is moved before the start of the
823 " block, then the new text should be appended there.
824 %d _
825 call setline(1, ['aaa', 'bbb', 'ccc'])
826 exe "normal $\<C-V>2jA\<Left>x"
Bram Moolenaar4067bd32021-06-29 18:54:35 +0200827 call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$'))
Yegappan Lakshmanan59b26232021-06-05 20:59:22 +0200828 " Repeat the previous test but use 'l' to move the cursor instead of '$'
829 call setline(1, ['aaa', 'bbb', 'ccc'])
830 exe "normal! gg2l\<C-V>2jA\<Left>x"
831 call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$'))
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200832
833 " Change a characterwise motion to a blockwise motion using CTRL-V
834 %d _
835 call setline(1, ['123', '456', '789'])
836 exe "normal ld\<C-V>j"
837 call assert_equal(['13', '46', '789'], getline(1, '$'))
838
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +0200839 " Test from ':help v_b_I_example'
840 %d _
841 setlocal tabstop=8 shiftwidth=4
842 let lines =<< trim END
843 abcdefghijklmnopqrstuvwxyz
844 abc defghijklmnopqrstuvwxyz
845 abcdef ghi jklmnopqrstuvwxyz
846 abcdefghijklmnopqrstuvwxyz
847 END
848 call setline(1, lines)
849 exe "normal ggfo\<C-V>3jISTRING"
850 let expected =<< trim END
851 abcdefghijklmnSTRINGopqrstuvwxyz
852 abc STRING defghijklmnopqrstuvwxyz
853 abcdef ghi STRING jklmnopqrstuvwxyz
854 abcdefghijklmnSTRINGopqrstuvwxyz
855 END
856 call assert_equal(expected, getline(1, '$'))
857
858 " Test from ':help v_b_A_example'
859 %d _
860 let lines =<< trim END
861 abcdefghijklmnopqrstuvwxyz
862 abc defghijklmnopqrstuvwxyz
863 abcdef ghi jklmnopqrstuvwxyz
864 abcdefghijklmnopqrstuvwxyz
865 END
866 call setline(1, lines)
867 exe "normal ggfo\<C-V>3j$ASTRING"
868 let expected =<< trim END
869 abcdefghijklmnopqrstuvwxyzSTRING
870 abc defghijklmnopqrstuvwxyzSTRING
871 abcdef ghi jklmnopqrstuvwxyzSTRING
872 abcdefghijklmnopqrstuvwxyzSTRING
873 END
874 call assert_equal(expected, getline(1, '$'))
875
876 " Test from ':help v_b_<_example'
877 %d _
878 let lines =<< trim END
879 abcdefghijklmnopqrstuvwxyz
880 abc defghijklmnopqrstuvwxyz
881 abcdef ghi jklmnopqrstuvwxyz
882 abcdefghijklmnopqrstuvwxyz
883 END
884 call setline(1, lines)
885 exe "normal ggfo\<C-V>3j3l<.."
886 let expected =<< trim END
887 abcdefghijklmnopqrstuvwxyz
888 abc defghijklmnopqrstuvwxyz
889 abcdef ghi jklmnopqrstuvwxyz
890 abcdefghijklmnopqrstuvwxyz
891 END
892 call assert_equal(expected, getline(1, '$'))
893
894 " Test from ':help v_b_>_example'
895 %d _
896 let lines =<< trim END
897 abcdefghijklmnopqrstuvwxyz
898 abc defghijklmnopqrstuvwxyz
899 abcdef ghi jklmnopqrstuvwxyz
900 abcdefghijklmnopqrstuvwxyz
901 END
902 call setline(1, lines)
903 exe "normal ggfo\<C-V>3j>.."
904 let expected =<< trim END
905 abcdefghijklmn opqrstuvwxyz
906 abc defghijklmnopqrstuvwxyz
907 abcdef ghi jklmnopqrstuvwxyz
908 abcdefghijklmn opqrstuvwxyz
909 END
910 call assert_equal(expected, getline(1, '$'))
911
912 " Test from ':help v_b_r_example'
913 %d _
914 let lines =<< trim END
915 abcdefghijklmnopqrstuvwxyz
916 abc defghijklmnopqrstuvwxyz
917 abcdef ghi jklmnopqrstuvwxyz
918 abcdefghijklmnopqrstuvwxyz
919 END
920 call setline(1, lines)
921 exe "normal ggfo\<C-V>5l3jrX"
922 let expected =<< trim END
923 abcdefghijklmnXXXXXXuvwxyz
924 abc XXXXXXhijklmnopqrstuvwxyz
925 abcdef ghi XXXXXX jklmnopqrstuvwxyz
926 abcdefghijklmnXXXXXXuvwxyz
927 END
928 call assert_equal(expected, getline(1, '$'))
929
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100930 bwipe!
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +0200931 set tabstop& shiftwidth&
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100932endfunc
933
Bram Moolenaar21492742021-06-04 21:57:57 +0200934func Test_visual_force_motion_feedkeys()
935 onoremap <expr> i- execute('let g:mode = mode(1)')->slice(0, 0)
936 call feedkeys('dvi-', 'x')
937 call assert_equal('nov', g:mode)
938 call feedkeys('di-', 'x')
939 call assert_equal('no', g:mode)
940 ounmap i-
941endfunc
942
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100943" Test block-insert using cursor keys for movement
944func Test_visual_block_insert_cursor_keys()
945 new
946 call append(0, ['aaaaaa', 'bbbbbb', 'cccccc', 'dddddd'])
947 call cursor(1, 1)
948
949 exe "norm! l\<C-V>jjjlllI\<Right>\<Right> \<Esc>"
950 call assert_equal(['aaa aaa', 'bbb bbb', 'ccc ccc', 'ddd ddd'],
951 \ getline(1, 4))
952
953 call deletebufline('', 1, '$')
954 call setline(1, ['xaaa', 'bbbb', 'cccc', 'dddd'])
955 call cursor(1, 1)
956 exe "norm! \<C-V>jjjI<>\<Left>p\<Esc>"
957 call assert_equal(['<p>xaaa', '<p>bbbb', '<p>cccc', '<p>dddd'],
958 \ getline(1, 4))
959 bwipe!
960endfunc
961
962func Test_visual_block_create()
963 new
964 call append(0, '')
965 " Test for Visual block was created with the last <C-v>$
966 call setline(1, ['A23', '4567'])
967 call cursor(1, 1)
968 exe "norm! l\<C-V>j$Aab\<Esc>"
969 call assert_equal(['A23ab', '4567ab'], getline(1, 2))
970
971 " Test for Visual block was created with the middle <C-v>$ (1)
972 call deletebufline('', 1, '$')
973 call setline(1, ['B23', '4567'])
974 call cursor(1, 1)
975 exe "norm! l\<C-V>j$hAab\<Esc>"
976 call assert_equal(['B23 ab', '4567ab'], getline(1, 2))
977
978 " Test for Visual block was created with the middle <C-v>$ (2)
979 call deletebufline('', 1, '$')
980 call setline(1, ['C23', '4567'])
981 call cursor(1, 1)
982 exe "norm! l\<C-V>j$hhAab\<Esc>"
983 call assert_equal(['C23ab', '456ab7'], getline(1, 2))
984 bwipe!
985endfunc
986
987" Test for Visual block insert when virtualedit=all
988func Test_virtualedit_visual_block()
989 set ve=all
990 new
991 call append(0, ["\t\tline1", "\t\tline2", "\t\tline3"])
992 call cursor(1, 1)
993 exe "norm! 07l\<C-V>jjIx\<Esc>"
994 call assert_equal([" x \tline1",
995 \ " x \tline2",
996 \ " x \tline3"], getline(1, 3))
997
998 " Test for Visual block append when virtualedit=all
999 exe "norm! 012l\<C-v>jjAx\<Esc>"
1000 call assert_equal([' x x line1',
1001 \ ' x x line2',
1002 \ ' x x line3'], getline(1, 3))
1003 set ve=
1004 bwipe!
1005endfunc
1006
1007" Test for changing case
1008func Test_visual_change_case()
1009 new
zeertzjqe7102202024-02-13 20:32:04 +01001010 " gUe must uppercase a whole word, also when ß changes to
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +01001011 exe "normal Gothe youtußeuu end\<Esc>Ypk0wgUe\r"
1012 " gUfx must uppercase until x, inclusive.
1013 exe "normal O- youßtußexu -\<Esc>0fogUfx\r"
1014 " VU must uppercase a whole line
1015 exe "normal YpkVU\r"
1016 " same, when it's the last line in the buffer
1017 exe "normal YPGi111\<Esc>VUddP\r"
1018 " Uppercase two lines
1019 exe "normal Oblah di\rdoh dut\<Esc>VkUj\r"
1020 " Uppercase part of two lines
1021 exe "normal ddppi333\<Esc>k0i222\<Esc>fyllvjfuUk"
glepnirbd1232a2024-02-12 22:14:53 +01001022 call assert_equal(['the YOUTUẞEUU end', '- yOUẞTUẞEXu -',
1023 \ 'THE YOUTUẞEUU END', '111THE YOUTUẞEUU END', 'BLAH DI', 'DOH DUT',
1024 \ '222the yoUTUẞEUU END', '333THE YOUTUßeuu end'], getline(2, '$'))
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +01001025 bwipe!
1026endfunc
1027
1028" Test for Visual replace using Enter or NL
1029func Test_visual_replace_crnl()
1030 new
1031 exe "normal G3o123456789\e2k05l\<C-V>2jr\r"
1032 exe "normal G3o98765\e2k02l\<C-V>2jr\<C-V>\r\n"
1033 exe "normal G3o123456789\e2k05l\<C-V>2jr\n"
1034 exe "normal G3o98765\e2k02l\<C-V>2jr\<C-V>\n"
1035 call assert_equal(['12345', '789', '12345', '789', '12345', '789', "98\r65",
1036 \ "98\r65", "98\r65", '12345', '789', '12345', '789', '12345', '789',
1037 \ "98\n65", "98\n65", "98\n65"], getline(2, '$'))
1038 bwipe!
1039endfunc
1040
1041func Test_ve_block_curpos()
1042 new
1043 " Test cursor position. When ve=block and Visual block mode and $gj
1044 call append(0, ['12345', '789'])
1045 call cursor(1, 3)
1046 set virtualedit=block
1047 exe "norm! \<C-V>$gj\<Esc>"
1048 call assert_equal([0, 2, 4, 0], getpos("'>"))
1049 set virtualedit=
1050 bwipe!
1051endfunc
1052
1053" Test for block_insert when replacing spaces in front of the a with tabs
1054func Test_block_insert_replace_tabs()
1055 new
1056 set ts=8 sts=4 sw=4
1057 call append(0, ["#define BO_ALL\t 0x0001",
1058 \ "#define BO_BS\t 0x0002",
1059 \ "#define BO_CRSR\t 0x0004"])
1060 call cursor(1, 1)
1061 exe "norm! f0\<C-V>2jI\<tab>\<esc>"
1062 call assert_equal([
1063 \ "#define BO_ALL\t\t0x0001",
1064 \ "#define BO_BS\t \t0x0002",
1065 \ "#define BO_CRSR\t \t0x0004", ''], getline(1, '$'))
1066 set ts& sts& sw&
1067 bwipe!
1068endfunc
1069
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001070" Test for * register in :
1071func Test_star_register()
1072 call assert_fails('*bfirst', 'E16:')
1073 new
1074 call setline(1, ['foo', 'bar', 'baz', 'qux'])
1075 exe "normal jVj\<ESC>"
1076 *yank r
1077 call assert_equal("bar\nbaz\n", @r)
1078
1079 delmarks < >
1080 call assert_fails('*yank', 'E20:')
Christian Brabandtc9a1e252025-01-11 15:25:00 +01001081 bw!
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001082endfunc
1083
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01001084" Test for changing text in visual mode with 'exclusive' selection
1085func Test_exclusive_selection()
1086 new
1087 call setline(1, ['one', 'two'])
1088 set selection=exclusive
1089 call feedkeys("vwcabc", 'xt')
1090 call assert_equal('abctwo', getline(1))
1091 call setline(1, ["\tone"])
1092 set virtualedit=all
1093 call feedkeys('0v2lcl', 'xt')
1094 call assert_equal('l one', getline(1))
1095 set virtualedit&
1096 set selection&
Christian Brabandtc9a1e252025-01-11 15:25:00 +01001097 bw!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01001098endfunc
1099
Jim Zhouc8cce712025-03-05 20:47:29 +01001100" Test for inclusive motion in visual mode with 'exclusive' selection
1101func Test_inclusive_motion_selection_exclusive()
1102 func s:compare_exclu_inclu(line, keys, expected_exclu)
1103 let msg = "data: '" . a:line . "' operation: '" . a:keys . "'"
1104 call setline(1, a:line)
1105 set selection=exclusive
1106 call feedkeys(a:keys, 'xt')
1107 call assert_equal(a:expected_exclu, getpos('.'), msg)
1108 let pos_ex = col('.')
1109 set selection=inclusive
1110 call feedkeys(a:keys, 'xt')
1111 let pos_in = col('.')
1112 call assert_equal(1, pos_ex - pos_in, msg)
1113 endfunc
1114
1115 new
1116 " Test 'e' motion
1117 set selection=exclusive
1118 call setline(1, 'eins zwei drei')
1119 norm! ggvey
1120 call assert_equal('eins', @")
1121 call setline(1, 'abc(abc)abc')
1122 norm! ggveeed
1123 call assert_equal(')abc', getline(1))
1124 call setline(1, 'abc(abc)abc')
1125 norm! gg3lvey
1126 call assert_equal('(abc', @")
1127 call s:compare_exclu_inclu('abc(abc)abc', 'ggveee', [0, 1, 8, 0])
1128 " Test 'f' motion
1129 call s:compare_exclu_inclu('geschwindigkeit', 'ggvfefe', [0, 1, 14, 0])
1130 call s:compare_exclu_inclu('loooooooooooong', 'ggv2fo2fo2fo', [0, 1, 8, 0])
1131 " Test 't' motion
1132 call s:compare_exclu_inclu('geschwindigkeit', 'ggv2te', [0, 1, 13, 0])
1133 call s:compare_exclu_inclu('loooooooooooong', 'gglv2to2to2to', [0, 1, 6, 0])
1134 " Test ';' motion
1135 call s:compare_exclu_inclu('geschwindigkeit', 'ggvfi;;', [0, 1, 15, 0])
1136 call s:compare_exclu_inclu('geschwindigkeit', 'ggvti;;', [0, 1, 14, 0])
1137 call s:compare_exclu_inclu('loooooooooooong', 'ggv2fo;;', [0, 1, 6, 0])
1138 call s:compare_exclu_inclu('loooooooooooong', 'ggvl2to;;', [0, 1, 6, 0])
1139 " Clean up
1140 set selection&
1141 bw!
1142endfunc
1143
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001144" Test for starting linewise visual with a count.
1145" This test needs to be run without any previous visual mode. Otherwise the
1146" count will use the count from the previous visual mode.
1147func Test_linewise_visual_with_count()
1148 let after =<< trim [CODE]
1149 call setline(1, ['one', 'two', 'three', 'four'])
1150 norm! 3Vy
1151 call assert_equal("one\ntwo\nthree\n", @")
1152 call writefile(v:errors, 'Xtestout')
1153 qall!
1154 [CODE]
1155 if RunVim([], after, '')
1156 call assert_equal([], readfile('Xtestout'))
1157 call delete('Xtestout')
1158 endif
1159endfunc
1160
1161" Test for starting characterwise visual with a count.
1162" This test needs to be run without any previous visual mode. Otherwise the
1163" count will use the count from the previous visual mode.
1164func Test_characterwise_visual_with_count()
1165 let after =<< trim [CODE]
1166 call setline(1, ['one two', 'three'])
1167 norm! l5vy
1168 call assert_equal("ne tw", @")
1169 call writefile(v:errors, 'Xtestout')
1170 qall!
1171 [CODE]
1172 if RunVim([], after, '')
1173 call assert_equal([], readfile('Xtestout'))
1174 call delete('Xtestout')
1175 endif
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01001176endfunc
1177
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001178" Test for visually selecting an inner block (iB)
1179func Test_visual_inner_block()
1180 new
1181 call setline(1, ['one', '{', 'two', '{', 'three', '}', 'four', '}', 'five'])
1182 call cursor(5, 1)
1183 " visually select all the lines in the block and then execute iB
1184 call feedkeys("ViB\<C-C>", 'xt')
1185 call assert_equal([0, 5, 1, 0], getpos("'<"))
1186 call assert_equal([0, 5, 6, 0], getpos("'>"))
1187 " visually select two inner blocks
1188 call feedkeys("ViBiB\<C-C>", 'xt')
1189 call assert_equal([0, 3, 1, 0], getpos("'<"))
1190 call assert_equal([0, 7, 5, 0], getpos("'>"))
1191 " try to select non-existing inner block
1192 call cursor(5, 1)
1193 call assert_beeps('normal ViBiBiB')
zeertzjqc029c132024-03-28 11:37:26 +01001194 " try to select an unclosed inner block
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001195 8,9d
1196 call cursor(5, 1)
1197 call assert_beeps('normal ViBiB')
Christian Brabandtc9a1e252025-01-11 15:25:00 +01001198 bw!
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001199endfunc
1200
Bram Moolenaarcd942772020-08-22 21:08:44 +02001201func Test_visual_put_in_block()
1202 new
1203 call setline(1, ['xxxx', 'yyy', 'zzzz'])
1204 normal 1G2yl
1205 exe "normal 1G2l\<C-V>jjlp"
1206 call assert_equal(['xxxx', 'yxx', 'zzxx'], getline(1, 3))
1207 bwipe!
1208endfunc
1209
Christian Brabandt2fa93842021-05-30 22:17:25 +02001210func Test_visual_put_in_block_using_zp()
1211 new
1212 " paste using zP
Bram Moolenaar94722c52023-01-28 19:19:03 +00001213 call setline(1, ['/path;text', '/path;text', '/path;text', '',
1214 \ '/subdir',
Christian Brabandt2fa93842021-05-30 22:17:25 +02001215 \ '/longsubdir',
1216 \ '/longlongsubdir'])
1217 exe "normal! 5G\<c-v>2j$y"
1218 norm! 1Gf;zP
1219 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1220 %d
1221 " paste using zP
Bram Moolenaar94722c52023-01-28 19:19:03 +00001222 call setline(1, ['/path;text', '/path;text', '/path;text', '',
1223 \ '/subdir',
Christian Brabandt2fa93842021-05-30 22:17:25 +02001224 \ '/longsubdir',
1225 \ '/longlongsubdir'])
1226 exe "normal! 5G\<c-v>2j$y"
1227 norm! 1Gf;hzp
1228 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1229 bwipe!
1230endfunc
1231
Christian Brabandt544a38e2021-06-10 19:39:11 +02001232func Test_visual_put_in_block_using_zy_and_zp()
1233 new
1234
1235 " Test 1) Paste using zp - after the cursor without trailing spaces
Bram Moolenaar94722c52023-01-28 19:19:03 +00001236 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001237 \ 'texttext /subdir columntext',
1238 \ 'texttext /longsubdir columntext',
1239 \ 'texttext /longlongsubdir columntext'])
1240 exe "normal! 5G0f/\<c-v>2jezy"
1241 norm! 1G0f;hzp
1242 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1243
1244 " Test 2) Paste using zP - in front of the cursor without trailing spaces
1245 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001246 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001247 \ 'texttext /subdir columntext',
1248 \ 'texttext /longsubdir columntext',
1249 \ 'texttext /longlongsubdir columntext'])
1250 exe "normal! 5G0f/\<c-v>2jezy"
1251 norm! 1G0f;zP
1252 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1253
1254 " Test 3) Paste using p - with trailing spaces
1255 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001256 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001257 \ 'texttext /subdir columntext',
1258 \ 'texttext /longsubdir columntext',
1259 \ 'texttext /longlongsubdir columntext'])
1260 exe "normal! 5G0f/\<c-v>2jezy"
1261 norm! 1G0f;hp
1262 call assert_equal(['/path/subdir ;text', '/path/longsubdir ;text', '/path/longlongsubdir;text'], getline(1, 3))
1263
1264 " Test 4) Paste using P - with trailing spaces
1265 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001266 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001267 \ 'texttext /subdir columntext',
1268 \ 'texttext /longsubdir columntext',
1269 \ 'texttext /longlongsubdir columntext'])
1270 exe "normal! 5G0f/\<c-v>2jezy"
1271 norm! 1G0f;P
1272 call assert_equal(['/path/subdir ;text', '/path/longsubdir ;text', '/path/longlongsubdir;text'], getline(1, 3))
1273
1274 " Test 5) Yank with spaces inside the block
1275 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001276 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001277 \ 'texttext /sub dir/ columntext',
1278 \ 'texttext /lon gsubdir/ columntext',
1279 \ 'texttext /lon glongsubdir/ columntext'])
1280 exe "normal! 5G0f/\<c-v>2jf/zy"
1281 norm! 1G0f;zP
1282 call assert_equal(['/path/sub dir/;text', '/path/lon gsubdir/;text', '/path/lon glongsubdir/;text'], getline(1, 3))
1283 bwipe!
1284endfunc
1285
Bram Moolenaar7d7bcc62021-06-28 21:54:27 +02001286func Test_visual_put_blockedit_zy_and_zp()
1287 new
1288
1289 call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
1290 exe "normal! gg0\<c-v>2j$zy"
1291 norm! 5gg0zP
1292 call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
1293 "
1294 " now with blockmode editing
1295 sil %d
1296 :set ve=block
1297 call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
1298 exe "normal! gg0\<c-v>2j$zy"
1299 norm! 5gg0zP
1300 call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
1301 set ve&vim
1302 bw!
1303endfunc
1304
Bram Moolenaar44db8212022-01-25 21:26:17 +00001305func Test_visual_block_yank_zy()
1306 new
1307 " this was reading before the start of the line
1308 exe "norm o\<C-T>\<Esc>\<C-V>zy"
1309 bwipe!
1310endfunc
1311
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001312func Test_visual_block_with_virtualedit()
1313 CheckScreendump
1314
1315 let lines =<< trim END
1316 call setline(1, ['aaaaaa', 'bbbb', 'cc'])
1317 set virtualedit=block
1318 normal G
1319 END
Bram Moolenaar5b148ef2022-10-15 21:35:56 +01001320 call writefile(lines, 'XTest_block', 'D')
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001321
1322 let buf = RunVimInTerminal('-S XTest_block', {'rows': 8, 'cols': 50})
1323 call term_sendkeys(buf, "\<C-V>gg$")
1324 call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit', {})
1325
Bram Moolenaarb17ab862021-07-03 22:15:17 +02001326 call term_sendkeys(buf, "\<Esc>gg\<C-V>G$")
1327 call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit2', {})
1328
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001329 " clean up
1330 call term_sendkeys(buf, "\<Esc>")
1331 call StopVimInTerminal(buf)
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001332endfunc
1333
Bram Moolenaar615ddd52021-11-17 18:00:31 +00001334func Test_visual_block_ctrl_w_f()
dundargocc57b5bc2022-11-02 13:30:51 +00001335 " Empty block selected in new buffer should not result in an error.
Bram Moolenaar615ddd52021-11-17 18:00:31 +00001336 au! BufNew foo sil norm f
1337 edit foo
1338
1339 au! BufNew
1340endfunc
1341
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001342func Test_visual_block_append_invalid_char()
1343 " this was going over the end of the line
Bram Moolenaar262898a2022-01-17 17:52:22 +00001344 set isprint=@,161-255
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001345 new
1346 call setline(1, [' let xxx', 'xxxxxˆ', 'xxxxxxxxxxx'])
1347 exe "normal 0\<C-V>jjA-\<Esc>"
1348 call assert_equal([' - let xxx', 'xxxxx ', 'xxxxxxxx-xxx'], getline(1, 3))
1349 bwipe!
Bram Moolenaar262898a2022-01-17 17:52:22 +00001350 set isprint&
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001351endfunc
1352
Bram Moolenaar7ce5b2b2022-05-16 19:40:59 +01001353func Test_visual_block_with_substitute()
1354 " this was reading beyond the end of the line
1355 new
1356 norm a0)
1357 sil! norm  O
1358 s/)
1359 sil! norm 
1360 bwipe!
1361endfunc
1362
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001363func Test_visual_reselect_with_count()
Bram Moolenaar8f531662023-02-01 17:33:18 +00001364 enew
1365 call setline(1, ['aaaaaa', ' bbbb', ' bbbb'])
1366 exe "normal! 2Gw\<C-V>jed"
1367 exe "normal! gg0lP"
1368 call assert_equal(['abbbbaaaaa', 'bbbb ', ' '], getline(1, '$'))
1369
1370 exe "normal! 1vr."
1371 call assert_equal(['a....aaaaa', '✗.... ', ' '], getline(1, '$'))
1372
1373 bwipe!
1374
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001375 " this was causing an illegal memory access
1376 let lines =<< trim END
1377
1378
1379
1380 :
1381 r<sfile>
1382 exe "%norm e3\<c-v>kr\t"
1383 :
1384
1385 :
1386 END
Bram Moolenaar5b148ef2022-10-15 21:35:56 +01001387 call writefile(lines, 'XvisualReselect', 'D')
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001388 source XvisualReselect
1389
1390 bwipe!
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001391endfunc
1392
Bram Moolenaar79c11e32023-01-10 17:29:29 +00001393func Test_visual_reselect_exclusive()
1394 new
1395 call setline(1, ['abcde', 'abcde'])
1396 set selection=exclusive
1397 normal 1G0viwd
1398 normal 2G01vd
1399 call assert_equal(['', ''], getline(1, 2))
1400
1401 set selection&
1402 bwipe!
1403endfunc
1404
Bram Moolenaar57df9e82022-01-20 12:10:48 +00001405func Test_visual_block_insert_round_off()
1406 new
1407 " The number of characters are tuned to fill a 4096 byte allocated block,
1408 " so that valgrind reports going over the end.
1409 call setline(1, ['xxxxx', repeat('0', 1350), "\t", repeat('x', 60)])
1410 exe "normal gg0\<C-V>GI" .. repeat('0', 1320) .. "\<Esc>"
1411 bwipe!
1412endfunc
1413
Bram Moolenaar05b27612022-01-20 13:32:50 +00001414" this was causing an ml_get error
1415func Test_visual_exchange_windows()
1416 enew!
1417 new
1418 call setline(1, ['foo', 'bar'])
1419 exe "normal G\<C-V>gg\<C-W>\<C-X>OO\<Esc>"
1420 bwipe!
1421 bwipe!
1422endfunc
1423
Bram Moolenaardc5490e2022-01-25 13:52:53 +00001424" this was leaving the end of the Visual area beyond the end of a line
1425func Test_visual_ex_copy_line()
1426 new
1427 call setline(1, ["aaa", "bbbbbbbbbxbb"])
1428 /x
1429 exe "normal ggvjfxO"
1430 t0
1431 normal gNU
1432 bwipe!
1433endfunc
1434
Bram Moolenaar8d02ce12022-01-25 18:24:00 +00001435" This was leaving the end of the Visual area beyond the end of a line.
1436" Set 'undolevels' to start a new undo block.
1437func Test_visual_undo_deletes_last_line()
1438 new
1439 call setline(1, ["aaa", "ccc", "dyd"])
1440 set undolevels=100
1441 exe "normal obbbbbbbbbxbb\<Esc>"
1442 set undolevels=100
1443 /y
1444 exe "normal ggvjfxO"
1445 undo
1446 normal gNU
Shougo Matsushitafb552072022-01-28 16:01:13 +00001447
Bram Moolenaar8d02ce12022-01-25 18:24:00 +00001448 bwipe!
1449endfunc
1450
Shougo Matsushitafb552072022-01-28 16:01:13 +00001451func Test_visual_paste()
1452 new
1453
1454 " v_p overwrites unnamed register.
1455 call setline(1, ['xxxx'])
1456 call setreg('"', 'foo')
1457 call setreg('-', 'bar')
zeertzjq6bf821e2022-02-07 10:33:20 +00001458 normal gg0vp
1459 call assert_equal('x', @")
1460 call assert_equal('x', @-)
1461 call assert_equal('fooxxx', getline(1))
1462 normal $vp
1463 call assert_equal('x', @")
1464 call assert_equal('x', @-)
1465 call assert_equal('fooxxx', getline(1))
1466 " Test with a different register as unnamed register.
1467 call setline(2, ['baz'])
1468 normal 2gg0"rD
1469 call assert_equal('baz', @")
1470 normal gg0vp
1471 call assert_equal('f', @")
1472 call assert_equal('f', @-)
1473 call assert_equal('bazooxxx', getline(1))
1474 normal $vp
1475 call assert_equal('x', @")
1476 call assert_equal('x', @-)
1477 call assert_equal('bazooxxf', getline(1))
Shougo Matsushitafb552072022-01-28 16:01:13 +00001478
Shougo Matsushita509142a2022-05-06 11:45:09 +01001479 bwipe!
1480endfunc
1481
1482func Test_visual_paste_clipboard()
1483 CheckFeature clipboard_working
1484
1485 if has('gui')
1486 " auto select feature breaks tests
1487 set guioptions-=a
1488 endif
1489
1490 " v_P does not overwrite unnamed register.
1491 call setline(1, ['xxxx'])
1492 call setreg('"', 'foo')
1493 call setreg('-', 'bar')
1494 normal gg0vP
1495 call assert_equal('foo', @")
1496 call assert_equal('bar', @-)
1497 call assert_equal('fooxxx', getline(1))
1498 normal $vP
1499 call assert_equal('foo', @")
1500 call assert_equal('bar', @-)
1501 call assert_equal('fooxxfoo', getline(1))
1502 " Test with a different register as unnamed register.
1503 call setline(2, ['baz'])
1504 normal 2gg0"rD
1505 call assert_equal('baz', @")
1506 normal gg0vP
1507 call assert_equal('baz', @")
1508 call assert_equal('bar', @-)
1509 call assert_equal('bazooxxfoo', getline(1))
1510 normal $vP
1511 call assert_equal('baz', @")
1512 call assert_equal('bar', @-)
1513 call assert_equal('bazooxxfobaz', getline(1))
1514
1515 " Test for unnamed clipboard
1516 set clipboard=unnamed
1517 call setline(1, ['xxxx'])
1518 call setreg('"', 'foo')
1519 call setreg('-', 'bar')
1520 call setreg('*', 'baz')
1521 normal gg0vP
1522 call assert_equal('foo', @")
1523 call assert_equal('bar', @-)
1524 call assert_equal('baz', @*)
1525 call assert_equal('bazxxx', getline(1))
1526
1527 " Test for unnamedplus clipboard
1528 if has('unnamedplus')
1529 set clipboard=unnamedplus
Shougo Matsushitafb552072022-01-28 16:01:13 +00001530 call setline(1, ['xxxx'])
1531 call setreg('"', 'foo')
1532 call setreg('-', 'bar')
Shougo Matsushita509142a2022-05-06 11:45:09 +01001533 call setreg('+', 'baz')
zeertzjq6bf821e2022-02-07 10:33:20 +00001534 normal gg0vP
1535 call assert_equal('foo', @")
Shougo Matsushita509142a2022-05-06 11:45:09 +01001536 call assert_equal('bar', @-)
1537 call assert_equal('baz', @+)
1538 call assert_equal('bazxxx', getline(1))
Shougo Matsushitafb552072022-01-28 16:01:13 +00001539 endif
1540
Shougo Matsushita509142a2022-05-06 11:45:09 +01001541 set clipboard&
1542 if has('gui')
1543 set guioptions&
1544 endif
Shougo Matsushitafb552072022-01-28 16:01:13 +00001545 bwipe!
1546endfunc
Christian Brabandt544a38e2021-06-10 19:39:11 +02001547
Bram Moolenaar3d51ce12022-07-01 15:26:15 +01001548func Test_visual_area_adjusted_when_hiding()
1549 " The Visual area ended after the end of the line after :hide
1550 call setline(1, 'xxx')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001551 vsplit Xvaafile
Bram Moolenaar3d51ce12022-07-01 15:26:15 +01001552 call setline(1, 'xxxxxxxx')
1553 norm! $o
1554 hid
1555 norm! zW
1556 bwipe!
1557 bwipe!
1558endfunc
1559
Bram Moolenaarcfeb8a52022-08-13 14:09:44 +01001560func Test_switch_buffer_ends_visual_mode()
1561 enew
1562 call setline(1, 'foo')
1563 set hidden
1564 set virtualedit=all
1565 let buf1 = bufnr()
1566 enew
1567 let buf2 = bufnr()
1568 call setline(1, ['', '', '', ''])
1569 call cursor(4, 5)
1570 call feedkeys("\<C-V>3k4h", 'xt')
1571 exe 'buffer' buf1
1572 call assert_equal('n', mode())
1573
1574 set nohidden
1575 set virtualedit=
1576 bwipe!
1577 exe 'bwipe!' buf2
1578endfunc
1579
Pavel Mayorove1121b12023-02-20 14:35:20 +00001580" Check fix for the heap-based buffer overflow bug found in the function
1581" utfc_ptr2len and reported at
1582" https://huntr.dev/bounties/ae933869-a1ec-402a-bbea-d51764c6618e
1583func Test_heap_buffer_overflow()
1584 enew
1585 set updatecount=0
1586
1587 norm R0
1588 split other
1589 norm R000
1590 exe "norm \<C-V>l"
1591 ball
1592 call assert_equal(getpos("."), getpos("v"))
1593 call assert_equal('n', mode())
1594 norm zW
1595
1596 %bwipe!
1597 set updatecount&
1598endfunc
1599
zeertzjq8fc6a1d2023-08-20 18:12:54 +02001600" Test Visual highlight with cursor at end of screen line and 'showbreak'
1601func Test_visual_hl_with_showbreak()
1602 CheckScreendump
1603
Yee Cheng Chine70587d2025-02-13 20:55:45 +01001604 " Redraw at the end is necessary due to https://github.com/vim/vim/issues/16620
zeertzjq8fc6a1d2023-08-20 18:12:54 +02001605 let lines =<< trim END
1606 setlocal showbreak=+
1607 call setline(1, repeat('a', &columns + 10))
1608 normal g$v4lo
Yee Cheng Chine70587d2025-02-13 20:55:45 +01001609 redraw
zeertzjq8fc6a1d2023-08-20 18:12:54 +02001610 END
1611 call writefile(lines, 'XTest_visual_sbr', 'D')
1612
1613 let buf = RunVimInTerminal('-S XTest_visual_sbr', {'rows': 6, 'cols': 50})
1614 call VerifyScreenDump(buf, 'Test_visual_hl_with_showbreak', {})
1615
1616 " clean up
1617 call term_sendkeys(buf, "\<Esc>")
1618 call StopVimInTerminal(buf)
1619endfunc
Pavel Mayorove1121b12023-02-20 14:35:20 +00001620
Christian Brabandt476733f2023-09-19 20:41:51 +02001621func Test_Visual_r_CTRL_C()
1622 new
1623 " visual r_cmd
1624 call setline(1, [' '])
1625 call feedkeys("\<c-v>$r\<c-c>", 'tx')
1626 call assert_equal([''], getline(1, 1))
1627
1628 " visual gr_cmd
1629 call setline(1, [' '])
1630 call feedkeys("\<c-v>$gr\<c-c>", 'tx')
1631 call assert_equal([''], getline(1, 1))
1632 bw!
zeertzjqec149242023-12-19 20:28:31 +01001633endfunc
1634
1635func Test_visual_drag_out_of_window()
1636 rightbelow vnew
1637 call setline(1, '123456789')
1638 set mouse=a
1639 func ClickExpr(off)
1640 call test_setmouse(1, getwininfo(win_getid())[0].wincol + a:off)
1641 return "\<LeftMouse>"
1642 endfunc
1643 func DragExpr(off)
1644 call test_setmouse(1, getwininfo(win_getid())[0].wincol + a:off)
1645 return "\<LeftDrag>"
1646 endfunc
1647
1648 nnoremap <expr> <F2> ClickExpr(5)
1649 nnoremap <expr> <F3> DragExpr(-1)
1650 redraw
1651 call feedkeys("\<F2>\<F3>\<LeftRelease>", 'tx')
1652 call assert_equal([1, 6], [col('.'), col('v')])
1653 call feedkeys("\<Esc>", 'tx')
1654
1655 nnoremap <expr> <F2> ClickExpr(6)
1656 nnoremap <expr> <F3> DragExpr(-2)
1657 redraw
1658 call feedkeys("\<F2>\<F3>\<LeftRelease>", 'tx')
1659 call assert_equal([1, 7], [col('.'), col('v')])
1660 call feedkeys("\<Esc>", 'tx')
1661
1662 nunmap <F2>
1663 nunmap <F3>
1664 delfunc ClickExpr
1665 delfunc DragExpr
1666 set mouse&
1667 bwipe!
1668endfunc
Christian Brabandt476733f2023-09-19 20:41:51 +02001669
Christian Brabandt7c71db32024-01-22 20:12:34 +01001670func Test_visual_substitute_visual()
1671 new
1672 call setline(1, ['one', 'two', 'three'])
1673 call feedkeys("Gk\<C-V>j$:s/\\%V\\_.*\\%V/foobar\<CR>", 'tx')
1674 call assert_equal(['one', 'foobar'], getline(1, '$'))
1675 bwipe!
1676endfunc
1677
zeertzjq701ad502024-05-23 07:47:55 +02001678func Test_virtualedit_exclusive_selection()
1679 new
1680 set virtualedit=all selection=exclusive
1681
1682 call setline(1, "a\tb")
1683 normal! 0v8ly
1684 call assert_equal("a\t", getreg('"'))
1685 normal! 0v6ly
1686 call assert_equal('a ', getreg('"'))
1687 normal! 06lv2ly
1688 call assert_equal(' ', getreg('"'))
1689
1690 set virtualedit& selection&
1691 bwipe!
1692endfunc
1693
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001694func Test_visual_getregion()
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001695 let lines =<< trim END
1696 new
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001697
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001698 call setline(1, ['one', 'two', 'three'])
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001699
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001700 #" Visual mode
1701 call cursor(1, 1)
1702 call feedkeys("\<ESC>vjl", 'tx')
zeertzjqc95e64f2024-05-20 14:00:31 +02001703
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001704 call assert_equal(['one', 'tw'],
1705 \ 'v'->getpos()->getregion(getpos('.')))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001706 call assert_equal([
1707 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1708 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
1709 \ ],
1710 \ 'v'->getpos()->getregionpos(getpos('.')))
zeertzjqc95e64f2024-05-20 14:00:31 +02001711
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001712 call assert_equal(['one', 'tw'],
1713 \ '.'->getpos()->getregion(getpos('v')))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001714 call assert_equal([
1715 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1716 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
1717 \ ],
1718 \ '.'->getpos()->getregionpos(getpos('v')))
zeertzjqc95e64f2024-05-20 14:00:31 +02001719
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001720 call assert_equal(['o'],
1721 \ 'v'->getpos()->getregion(getpos('v')))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001722 call assert_equal([
1723 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
1724 \ ],
1725 \ 'v'->getpos()->getregionpos(getpos('v')))
zeertzjqc95e64f2024-05-20 14:00:31 +02001726
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001727 call assert_equal(['w'],
1728 \ '.'->getpos()->getregion(getpos('.'), {'type': 'v' }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001729 call assert_equal([
1730 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 0]],
1731 \ ],
1732 \ '.'->getpos()->getregionpos(getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02001733
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001734 call assert_equal(['one', 'two'],
1735 \ getpos('.')->getregion(getpos('v'), {'type': 'V' }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001736 call assert_equal([
1737 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1738 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1739 \ ],
1740 \ getpos('.')->getregionpos(getpos('v'), {'type': 'V' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02001741
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001742 call assert_equal(['on', 'tw'],
1743 \ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001744 call assert_equal([
1745 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
1746 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]],
1747 \ ],
1748 \ getpos('.')->getregionpos(getpos('v'), {'type': "\<C-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001749
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001750 #" Line visual mode
1751 call cursor(1, 1)
1752 call feedkeys("\<ESC>Vl", 'tx')
1753 call assert_equal(['one'],
1754 \ getregion(getpos('v'), getpos('.'), {'type': 'V' }))
1755 call assert_equal(['one'],
1756 \ getregion(getpos('.'), getpos('v'), {'type': 'V' }))
1757 call assert_equal(['one'],
1758 \ getregion(getpos('v'), getpos('v'), {'type': 'V' }))
1759 call assert_equal(['one'],
1760 \ getregion(getpos('.'), getpos('.'), {'type': 'V' }))
1761 call assert_equal(['on'],
1762 \ getpos('.')->getregion(getpos('v'), {'type': 'v' }))
1763 call assert_equal(['on'],
1764 \ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001765
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001766 #" Block visual mode
1767 call cursor(1, 1)
1768 call feedkeys("\<ESC>\<C-v>ll", 'tx')
1769 call assert_equal(['one'],
1770 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1771 call assert_equal(['one'],
1772 \ getregion(getpos('.'), getpos('v'), {'type': "\<C-v>" }))
1773 call assert_equal(['o'],
1774 \ getregion(getpos('v'), getpos('v'), {'type': "\<C-v>" }))
1775 call assert_equal(['e'],
1776 \ getregion(getpos('.'), getpos('.'), {'type': "\<C-v>" }))
1777 call assert_equal(['one'],
1778 \ '.'->getpos()->getregion(getpos('v'), {'type': 'V' }))
1779 call assert_equal(['one'],
1780 \ '.'->getpos()->getregion(getpos('v'), {'type': 'v' }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001781
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001782 #" Using Marks
1783 call setpos("'a", [0, 2, 3, 0])
1784 call cursor(1, 1)
1785 call assert_equal(['one', 'two'],
1786 \ "'a"->getpos()->getregion(getpos('.'), {'type': 'v' }))
1787 call assert_equal(['one', 'two'],
1788 \ "."->getpos()->getregion(getpos("'a"), {'type': 'v' }))
1789 call assert_equal(['one', 'two'],
1790 \ "."->getpos()->getregion(getpos("'a"), {'type': 'V' }))
1791 call assert_equal(['two'],
1792 \ "'a"->getpos()->getregion(getpos("'a"), {'type': 'V' }))
1793 call assert_equal(['one', 'two'],
1794 \ "."->getpos()->getregion(getpos("'a"), {'type': "\<c-v>" }))
zeertzjq2ffdae72024-05-02 13:06:24 +02001795 call feedkeys("\<ESC>jVj\<ESC>", 'tx')
1796 call assert_equal(['two', 'three'], getregion(getpos("'<"), getpos("'>")))
1797 call assert_equal(['two', 'three'], getregion(getpos("'>"), getpos("'<")))
Shougo Matsushita19b71882024-02-28 22:48:12 +01001798
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001799 #" Using List
1800 call cursor(1, 1)
1801 call assert_equal(['one', 'two'],
1802 \ [0, 2, 3, 0]->getregion(getpos('.'), {'type': 'v' }))
1803 call assert_equal(['one', 'two'],
1804 \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': 'v' }))
1805 call assert_equal(['one', 'two'],
1806 \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': 'V' }))
1807 call assert_equal(['two'],
1808 \ [0, 2, 3, 0]->getregion([0, 2, 3, 0], {'type': 'V' }))
1809 call assert_equal(['one', 'two'],
1810 \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': "\<c-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001811
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001812 #" Multiline with line visual mode
1813 call cursor(1, 1)
1814 call feedkeys("\<ESC>Vjj", 'tx')
1815 call assert_equal(['one', 'two', 'three'],
1816 \ getregion(getpos('v'), getpos('.'), {'type': 'V' }))
zeertzjq2b09de92024-05-24 07:48:51 +02001817 call assert_equal([
1818 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1819 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1820 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1821 \ ],
1822 \ getregionpos(getpos('v'), getpos('.'), {'type': 'V' }))
1823 call assert_equal([
1824 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
1825 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
1826 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 0]],
1827 \ ],
1828 \ getregionpos(getpos('v'), getpos('.'),
1829 \ {'type': 'V', 'eol': v:true }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001830
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001831 #" Multiline with block visual mode
1832 call cursor(1, 1)
1833 call feedkeys("\<ESC>\<C-v>jj", 'tx')
1834 call assert_equal(['o', 't', 't'],
1835 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02001836 call assert_equal([
1837 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
1838 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
1839 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 1, 0]],
1840 \ ],
1841 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001842
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001843 call cursor(1, 1)
1844 call feedkeys("\<ESC>\<C-v>jj$", 'tx')
1845 call assert_equal(['one', 'two', 'three'],
1846 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02001847 call assert_equal([
1848 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1849 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1850 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1851 \ ],
1852 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1853 call assert_equal([
1854 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1855 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1856 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1857 \ ],
1858 \ getregionpos(getpos('v'), getpos('.'),
1859 \ {'type': "\<C-v>", 'eol': v:true }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001860
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001861 #" 'virtualedit'
1862 set virtualedit=all
zeertzjq2b09de92024-05-24 07:48:51 +02001863
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001864 call cursor(1, 1)
1865 call feedkeys("\<ESC>\<C-v>10ljj$", 'tx')
1866 call assert_equal(['one ', 'two ', 'three '],
1867 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02001868 call assert_equal([
1869 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1870 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1871 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1872 \ ],
1873 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1874 call assert_equal([
1875 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 3]],
1876 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 3]],
1877 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 1]],
1878 \ ],
1879 \ getregionpos(getpos('v'), getpos('.'),
1880 \ {'type': "\<C-v>", 'eol': v:true }))
1881
1882 call cursor(3, 5)
1883 call feedkeys("\<ESC>\<C-v>hkk", 'tx')
1884 call assert_equal([' ', ' ', 'ee'],
1885 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1886 call assert_equal([
1887 \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
1888 \ [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
1889 \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
1890 \ ],
1891 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1892 call assert_equal([
1893 \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 2]],
1894 \ [[bufnr('%'), 2, 4, 0], [bufnr('%'), 2, 4, 2]],
1895 \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
1896 \ ],
1897 \ getregionpos(getpos('v'), getpos('.'),
1898 \ {'type': "\<C-v>", 'eol': v:true }))
1899
1900 call cursor(3, 5)
1901 call feedkeys("\<ESC>\<C-v>kk", 'tx')
1902 call assert_equal([' ', ' ', 'e'],
1903 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1904 call assert_equal([
1905 \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
1906 \ [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
1907 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
1908 \ ],
1909 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1910 call assert_equal([
1911 \ [[bufnr('%'), 1, 4, 1], [bufnr('%'), 1, 4, 2]],
1912 \ [[bufnr('%'), 2, 4, 1], [bufnr('%'), 2, 4, 2]],
1913 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
1914 \ ],
1915 \ getregionpos(getpos('v'), getpos('.'),
1916 \ {'type': "\<C-v>", 'eol': v:true }))
1917
1918 call cursor(1, 3)
1919 call feedkeys("\<ESC>vjj4l", 'tx')
1920 call assert_equal(['e', 'two', 'three '],
1921 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1922 call assert_equal([
1923 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
1924 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1925 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1926 \ ],
1927 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1928 call assert_equal([
1929 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
1930 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
1931 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
1932 \ ],
1933 \ getregionpos(getpos('v'), getpos('.'),
1934 \ {'type': 'v', 'eol': v:true }))
1935
1936 call cursor(1, 3)
1937 call feedkeys("\<ESC>lvjj3l", 'tx')
1938 call assert_equal(['', 'two', 'three '],
1939 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1940 call assert_equal([
1941 \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
1942 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1943 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1944 \ ],
1945 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1946 call assert_equal([
1947 \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 0]],
1948 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
1949 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
1950 \ ],
1951 \ getregionpos(getpos('v'), getpos('.'),
1952 \ {'type': 'v', 'eol': v:true }))
1953
1954 call cursor(3, 5)
1955 call feedkeys("\<ESC>v3l", 'tx')
1956 call assert_equal(['e '],
1957 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1958 call assert_equal([
1959 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
1960 \ ],
1961 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1962 call assert_equal([
1963 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 6, 3]],
1964 \ ],
1965 \ getregionpos(getpos('v'), getpos('.'),
1966 \ {'type': 'v', 'eol': v:true }))
1967
1968 call cursor(3, 5)
1969 call feedkeys("\<ESC>lv3l", 'tx')
1970 call assert_equal([' '],
1971 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1972 call assert_equal([
1973 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
1974 \ ],
1975 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1976 call assert_equal([
1977 \ [[bufnr('%'), 3, 6, 0], [bufnr('%'), 3, 6, 4]],
1978 \ ],
1979 \ getregionpos(getpos('v'), getpos('.'),
1980 \ {'type': 'v', 'eol': v:true }))
1981
1982 call cursor(3, 5)
1983 call feedkeys("\<ESC>3lv3l", 'tx')
1984 call assert_equal([' '],
1985 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1986 call assert_equal([
1987 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
1988 \ ],
1989 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1990 call assert_equal([
1991 \ [[bufnr('%'), 3, 6, 2], [bufnr('%'), 3, 6, 6]],
1992 \ ],
1993 \ getregionpos(getpos('v'), getpos('.'),
1994 \ {'type': 'v', 'eol': v:true }))
1995
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001996 set virtualedit&
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001997
zeertzjq26dd09a2024-03-10 15:46:58 +01001998 #" using wrong types for positions
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001999 call cursor(1, 1)
2000 call feedkeys("\<ESC>vjj$", 'tx')
2001 call assert_fails("call getregion(1, 2)", 'E1211:')
2002 call assert_fails("call getregion(getpos('.'), {})", 'E1211:')
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002003 call assert_fails(':echo "."->getpos()->getregion("$", [])', 'E1211:')
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002004 call assert_fails("call getregionpos(1, 2)", 'E1211:')
2005 call assert_fails("call getregionpos(getpos('.'), {})", 'E1211:')
2006 call assert_fails(':echo "."->getpos()->getregionpos("$", [])', 'E1211:')
Shougo Matsushita19b71882024-02-28 22:48:12 +01002007
zeertzjq26dd09a2024-03-10 15:46:58 +01002008 #" using invalid value for "type"
2009 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002010 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
zeertzjqafc22952024-05-24 19:07:12 +02002011 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': 'v0' })", 'E475:')
2012 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': 'v0' })", 'E475:')
2013 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': 'V0' })", 'E475:')
2014 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': 'V0' })", 'E475:')
2015 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
2016 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
2017 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
2018 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
zeertzjq26dd09a2024-03-10 15:46:58 +01002019
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002020 #" using a mark from another buffer to current buffer
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002021 new
zeertzjq26dd09a2024-03-10 15:46:58 +01002022 LET g:buf = bufnr()
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002023 call setline(1, range(10))
2024 normal! GmA
2025 wincmd p
zeertzjq26dd09a2024-03-10 15:46:58 +01002026 call assert_equal([g:buf, 10, 1, 0], getpos("'A"))
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002027 call assert_equal([], getregion(getpos('.'), getpos("'A"), {'type': 'v' }))
2028 call assert_equal([], getregion(getpos("'A"), getpos('.'), {'type': 'v' }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002029 call assert_equal([], getregionpos(getpos('.'), getpos("'A"), {'type': 'v' }))
2030 call assert_equal([], getregionpos(getpos("'A"), getpos('.'), {'type': 'v' }))
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002031
zeertzjq26dd09a2024-03-10 15:46:58 +01002032 #" using two marks from another buffer
2033 wincmd p
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002034 normal! GmB
2035 wincmd p
zeertzjq26dd09a2024-03-10 15:46:58 +01002036 call assert_equal([g:buf, 10, 1, 0], getpos("'B"))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002037 call assert_equal(['9'],
2038 \ getregion(getpos("'B"), getpos("'A"), {'type': 'v' }))
2039 call assert_equal([
2040 \ [[g:buf, 10, 1, 0], [g:buf, 10, 1, 0]],
2041 \ ],
2042 \ getregionpos(getpos("'B"), getpos("'A"), {'type': 'v' }))
zeertzjq26dd09a2024-03-10 15:46:58 +01002043
2044 #" using two positions from another buffer
2045 for type in ['v', 'V', "\<C-V>"]
2046 for exclusive in [v:false, v:true]
2047 call assert_equal(range(10)->mapnew('string(v:val)'),
zeertzjq5406eb82024-03-11 21:36:42 +01002048 \ getregion([g:buf, 1, 1, 0], [g:buf, 10, 2, 0],
2049 \ {'type': type, 'exclusive': exclusive }))
zeertzjq26dd09a2024-03-10 15:46:58 +01002050 call assert_equal(range(10)->mapnew('string(v:val)'),
zeertzjq5406eb82024-03-11 21:36:42 +01002051 \ getregion([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
2052 \ {'type': type, 'exclusive': exclusive }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002053 call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
2054 \ getregionpos([g:buf, 1, 1, 0], [g:buf, 10, 2, 0],
2055 \ {'type': type, 'exclusive': exclusive }))
2056 call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
2057 \ getregionpos([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
2058 \ {'type': type, 'exclusive': exclusive }))
zeertzjq26dd09a2024-03-10 15:46:58 +01002059 endfor
2060 endfor
2061
2062 #" using invalid positions in buffer
2063 call assert_fails('call getregion([g:buf, 0, 1, 0], [g:buf, 10, 2, 0])', 'E966:')
2064 call assert_fails('call getregion([g:buf, 10, 2, 0], [g:buf, 0, 1, 0])', 'E966:')
2065 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 11, 2, 0])', 'E966:')
2066 call assert_fails('call getregion([g:buf, 11, 2, 0], [g:buf, 1, 1, 0])', 'E966:')
2067 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 0, 0])', 'E964:')
2068 call assert_fails('call getregion([g:buf, 10, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
2069 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 3, 0])', 'E964:')
2070 call assert_fails('call getregion([g:buf, 10, 3, 0], [g:buf, 1, 1, 0])', 'E964:')
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002071 call assert_fails('call getregion([g:buf, 1, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
2072 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 1, 0, 0])', 'E964:')
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002073
2074 #" using invalid buffer
zeertzjq26dd09a2024-03-10 15:46:58 +01002075 call assert_fails('call getregion([10000, 10, 1, 0], [10000, 10, 1, 0])', 'E681:')
2076
2077 exe $':{g:buf}bwipe!'
2078 unlet g:buf
zeertzjq2b09de92024-05-24 07:48:51 +02002079 bwipe!
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002080 END
2081 call v9.CheckLegacyAndVim9Success(lines)
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002082
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002083 let lines =<< trim END
2084 #" Selection in starts or ends in the middle of a multibyte character
2085 new
2086 call setline(1, [
2087 \ "abcdefghijk\u00ab",
2088 \ "\U0001f1e6\u00ab\U0001f1e7\u00ab\U0001f1e8\u00ab\U0001f1e9",
2089 \ "1234567890"
2090 \ ])
zeertzjqc95e64f2024-05-20 14:00:31 +02002091
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002092 call cursor(1, 3)
2093 call feedkeys("\<Esc>\<C-v>ljj", 'xt')
2094 call assert_equal(['cd', "\u00ab ", '34'],
2095 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002096 call assert_equal([
2097 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
2098 \ [[bufnr('%'), 2, 5, 0], [bufnr('%'), 2, 7, 1]],
2099 \ [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 4, 0]],
2100 \ ],
2101 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2102
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002103 call cursor(1, 4)
2104 call feedkeys("\<Esc>\<C-v>ljj", 'xt')
2105 call assert_equal(['de', "\U0001f1e7", '45'],
2106 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002107 call assert_equal([
2108 \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 5, 0]],
2109 \ [[bufnr('%'), 2, 7, 0], [bufnr('%'), 2, 10, 0]],
2110 \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
2111 \ ],
2112 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2113
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002114 call cursor(1, 5)
2115 call feedkeys("\<Esc>\<C-v>jj", 'xt')
2116 call assert_equal(['e', ' ', '5'],
2117 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002118 call assert_equal([
zeertzjqc95e64f2024-05-20 14:00:31 +02002119 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 5, 0]],
zeertzjqef733742024-05-26 18:42:18 +02002120 \ [[bufnr('%'), 2, 7, 1], [bufnr('%'), 2, 7, 2]],
zeertzjqc95e64f2024-05-20 14:00:31 +02002121 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
2122 \ ],
2123 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqef733742024-05-26 18:42:18 +02002124 call assert_equal(['efghijk«', '🇦«🇧«🇨«🇩', '12345'],
2125 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002126 call assert_equal([
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002127 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 13, 0]],
2128 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 22, 0]],
2129 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
2130 \ ],
2131 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002132
zeertzjqef733742024-05-26 18:42:18 +02002133 call cursor(1, 5)
2134 call feedkeys("\<Esc>\<C-v>5l2j", 'xt')
2135 call assert_equal(['efghij', ' «🇨« ', '567890'],
2136 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2137 call assert_equal([
2138 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 10, 0]],
2139 \ [[bufnr('%'), 2, 7, 1], [bufnr('%'), 2, 19, 1]],
2140 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 10, 0]],
2141 \ ],
2142 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2143
2144 call cursor(1, 4)
2145 call feedkeys("\<Esc>\<C-v>02j", 'xt')
2146 call assert_equal(['abcd', '🇦« ', '1234'],
2147 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2148 call assert_equal([
2149 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
2150 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 7, 1]],
2151 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 4, 0]],
2152 \ ],
2153 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2154
zeertzjq52a6f342024-05-22 16:42:44 +02002155 #" characterwise selection with multibyte chars
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002156 call cursor(1, 1)
2157 call feedkeys("\<Esc>vj", 'xt')
2158 call assert_equal(['abcdefghijk«', "\U0001f1e6"],
2159 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002160 call assert_equal([
2161 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
2162 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
2163 \ ],
2164 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
Shougo Matsushita19b71882024-02-28 22:48:12 +01002165
zeertzjq52a6f342024-05-22 16:42:44 +02002166 set selection=exclusive
2167 call feedkeys('l', 'xt')
2168 call assert_equal(['abcdefghijk«', "\U0001f1e6"],
2169 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2170 call assert_equal([
2171 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
2172 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
2173 \ ],
2174 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2175
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002176 #" marks on multibyte chars
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002177 call setpos("'a", [0, 1, 11, 0])
2178 call setpos("'b", [0, 2, 16, 0])
2179 call setpos("'c", [0, 2, 0, 0])
2180 call cursor(1, 1)
zeertzjqc95e64f2024-05-20 14:00:31 +02002181
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002182 call assert_equal(['ghijk', '🇨«🇩'],
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002183 \ getregion(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002184 call assert_equal([
2185 \ [[bufnr('%'), 1, 7, 0], [bufnr('%'), 1, 11, 0]],
2186 \ [[bufnr('%'), 2, 13, 0], [bufnr('%'), 2, 22, 0]],
2187 \ ],
2188 \ getregionpos(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
2189
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002190 call assert_equal(['k«', '🇦«🇧«🇨'],
2191 \ getregion(getpos("'a"), getpos("'b"), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002192 call assert_equal([
2193 \ [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
2194 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 16, 0]],
2195 \ ],
2196 \ getregionpos(getpos("'a"), getpos("'b"), {'type': 'v' }))
2197
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002198 call assert_equal(['k«'],
2199 \ getregion(getpos("'a"), getpos("'c"), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002200 call assert_equal([
2201 \ [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
2202 \ ],
2203 \ getregionpos(getpos("'a"), getpos("'c"), {'type': 'v' }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002204
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002205 #" use inclusive selection, although 'selection' is exclusive
2206 call setpos("'a", [0, 1, 11, 0])
2207 call setpos("'b", [0, 1, 1, 0])
2208 call assert_equal(['abcdefghijk'],
2209 \ getregion(getpos("'a"), getpos("'b"),
2210 \ {'type': "\<c-v>", 'exclusive': v:false }))
2211 call assert_equal(['abcdefghij'],
2212 \ getregion(getpos("'a"), getpos("'b"),
2213 \ {'type': "\<c-v>", 'exclusive': v:true }))
2214 call assert_equal(['abcdefghijk'],
2215 \ getregion(getpos("'a"), getpos("'b"),
2216 \ {'type': 'v', 'exclusive': 0 }))
2217 call assert_equal(['abcdefghij'],
2218 \ getregion(getpos("'a"), getpos("'b"),
2219 \ {'type': 'v', 'exclusive': 1 }))
2220 call assert_equal(['abcdefghijk«'],
2221 \ getregion(getpos("'a"), getpos("'b"),
2222 \ {'type': 'V', 'exclusive': 0 }))
2223 call assert_equal(['abcdefghijk«'],
2224 \ getregion(getpos("'a"), getpos("'b"),
2225 \ {'type': 'V', 'exclusive': 1 }))
zeertzjq2b09de92024-05-24 07:48:51 +02002226
2227 set selection&
2228 bwipe!
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002229 END
2230 call v9.CheckLegacyAndVim9Success(lines)
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002231
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002232 let lines =<< trim END
2233 #" Exclusive selection
2234 new
2235 set selection=exclusive
2236 call setline(1, ["a\tc", "x\tz", '', ''])
2237 call cursor(1, 1)
2238 call feedkeys("\<Esc>v2l", 'xt')
2239 call assert_equal(["a\t"],
2240 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2241 call cursor(1, 1)
2242 call feedkeys("\<Esc>v$G", 'xt')
2243 call assert_equal(["a\tc", "x\tz", ''],
2244 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2245 call cursor(1, 1)
2246 call feedkeys("\<Esc>v$j", 'xt')
2247 call assert_equal(["a\tc", "x\tz"],
2248 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2249 call cursor(1, 1)
2250 call feedkeys("\<Esc>\<C-v>$j", 'xt')
2251 call assert_equal(["a\tc", "x\tz"],
2252 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2253 call cursor(1, 1)
2254 call feedkeys("\<Esc>\<C-v>$G", 'xt')
2255 call assert_equal(["a", "x", '', ''],
2256 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2257 call cursor(1, 1)
2258 call feedkeys("\<Esc>wv2j", 'xt')
2259 call assert_equal(["c", "x\tz"],
2260 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2261 set selection&
zeertzjq52a6f342024-05-22 16:42:44 +02002262 bwipe!
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002263
2264 #" Exclusive selection 2
2265 new
2266 call setline(1, ["a\tc", "x\tz", '', ''])
zeertzjq701ad502024-05-23 07:47:55 +02002267
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002268 call cursor(1, 1)
2269 call feedkeys("\<Esc>v2l", 'xt')
2270 call assert_equal(["a\t"],
2271 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002272 call assert_equal([
2273 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
2274 \ ],
2275 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
2276
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002277 call cursor(1, 1)
2278 call feedkeys("\<Esc>v$G", 'xt')
2279 call assert_equal(["a\tc", "x\tz", ''],
2280 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002281 call assert_equal([
2282 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2283 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2284 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
2285 \ ],
2286 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
2287
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002288 call cursor(1, 1)
2289 call feedkeys("\<Esc>v$j", 'xt')
2290 call assert_equal(["a\tc", "x\tz"],
2291 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002292 call assert_equal([
2293 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2294 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2295 \ ],
2296 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
2297
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002298 call cursor(1, 1)
2299 call feedkeys("\<Esc>\<C-v>$j", 'xt')
2300 call assert_equal(["a\tc", "x\tz"],
2301 \ getregion(getpos('v'), getpos('.'),
2302 \ {'exclusive': v:true, 'type': "\<C-v>" }))
zeertzjq701ad502024-05-23 07:47:55 +02002303 call assert_equal([
2304 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2305 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2306 \ ],
2307 \ getregionpos(getpos('v'), getpos('.'),
2308 \ {'exclusive': v:true, 'type': "\<C-v>" }))
2309
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002310 call cursor(1, 1)
2311 call feedkeys("\<Esc>\<C-v>$G", 'xt')
2312 call assert_equal(["a", "x", '', ''],
2313 \ getregion(getpos('v'), getpos('.'),
2314 \ {'exclusive': v:true, 'type': "\<C-v>" }))
zeertzjq701ad502024-05-23 07:47:55 +02002315 call assert_equal([
2316 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
2317 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
2318 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
2319 \ [[bufnr('%'), 4, 0, 0], [bufnr('%'), 4, 0, 0]],
2320 \ ],
2321 \ getregionpos(getpos('v'), getpos('.'),
2322 \ {'exclusive': v:true, 'type': "\<C-v>" }))
2323
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002324 call cursor(1, 1)
2325 call feedkeys("\<Esc>wv2j", 'xt')
2326 call assert_equal(["c", "x\tz"],
2327 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002328 call assert_equal([
2329 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
2330 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2331 \ ],
2332 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002333
zeertzjq701ad502024-05-23 07:47:55 +02002334 #" 'virtualedit' with exclusive selection
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002335 set selection=exclusive
2336 set virtualedit=all
zeertzjqc95e64f2024-05-20 14:00:31 +02002337
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002338 call cursor(1, 1)
zeertzjq701ad502024-05-23 07:47:55 +02002339 call feedkeys("\<Esc>vj", 'xt')
2340 call assert_equal(["a\tc"],
2341 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2342 call assert_equal([
2343 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2344 \ ],
2345 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2346
2347 call cursor(1, 1)
2348 call feedkeys("\<Esc>v8l", 'xt')
2349 call assert_equal(["a\t"],
2350 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2351 call assert_equal([
2352 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
2353 \ ],
2354 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2355
2356 call cursor(1, 1)
2357 call feedkeys("\<Esc>v6l", 'xt')
2358 call assert_equal(['a '],
2359 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2360 call assert_equal([
2361 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 5]],
2362 \ ],
2363 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2364
2365 call cursor(1, 1)
2366 call feedkeys("\<Esc>6lv2l", 'xt')
2367 call assert_equal([' '],
2368 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2369 call assert_equal([
2370 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 0]],
2371 \ ],
2372 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2373
2374 call cursor(1, 1)
zeertzjq52a6f342024-05-22 16:42:44 +02002375 call feedkeys("\<Esc>lv2l", 'xt')
2376 call assert_equal([' '],
2377 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2378 call assert_equal([
2379 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
2380 \ ],
2381 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2382
2383 call cursor(1, 1)
2384 call feedkeys("\<Esc>2lv2l", 'xt')
2385 call assert_equal([' '],
2386 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2387 call assert_equal([
2388 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
2389 \ ],
2390 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2391
2392 call feedkeys('j', 'xt')
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002393 call assert_equal([' c', 'x '],
2394 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002395 call assert_equal([
2396 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
2397 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 3]],
2398 \ ],
2399 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2400
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002401 call cursor(1, 1)
zeertzjq52a6f342024-05-22 16:42:44 +02002402 call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
2403 call assert_equal([' ', ' '],
2404 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2405 call assert_equal([
2406 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 7]],
2407 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 7]],
2408 \ ],
2409 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2410
2411 call cursor(1, 1)
2412 call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
2413 call assert_equal([' ', ' ', ' '],
2414 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2415 call assert_equal([
2416 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
2417 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
zeertzjq2b09de92024-05-24 07:48:51 +02002418 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjq52a6f342024-05-22 16:42:44 +02002419 \ ],
2420 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002421 call assert_equal([
2422 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
2423 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
2424 \ [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 3]],
2425 \ ],
2426 \ getregionpos(getpos('v'), getpos('.'),
2427 \ {'type': "\<C-v>", "eol": v:true }))
zeertzjq52a6f342024-05-22 16:42:44 +02002428
2429 call cursor(1, 1)
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002430 call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
2431 call assert_equal([' ', ' ', ' '],
2432 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002433 call assert_equal([
zeertzjq52a6f342024-05-22 16:42:44 +02002434 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
2435 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
zeertzjq2b09de92024-05-24 07:48:51 +02002436 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjqc95e64f2024-05-20 14:00:31 +02002437 \ ],
2438 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002439 call assert_equal([
2440 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
2441 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
2442 \ [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 4]],
2443 \ ],
2444 \ getregionpos(getpos('v'), getpos('.'),
2445 \ {'type': "\<C-v>", "eol": v:true }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002446
zeertzjq701ad502024-05-23 07:47:55 +02002447 #" 'virtualedit' with inclusive selection
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002448 set selection&
2449
zeertzjq701ad502024-05-23 07:47:55 +02002450 call cursor(1, 1)
2451 call feedkeys("\<Esc>vj", 'xt')
2452 call assert_equal(["a\tc", 'x'],
2453 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2454 call assert_equal([
2455 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2456 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
2457 \ ],
2458 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2459
2460 call cursor(1, 1)
2461 call feedkeys("\<Esc>v8l", 'xt')
2462 call assert_equal(["a\tc"],
2463 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2464 call assert_equal([
2465 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2466 \ ],
2467 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2468
2469 call cursor(1, 1)
2470 call feedkeys("\<Esc>v6l", 'xt')
2471 call assert_equal(['a '],
2472 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2473 call assert_equal([
2474 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 6]],
2475 \ ],
2476 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2477
2478 call cursor(1, 1)
2479 call feedkeys("\<Esc>6lv2l", 'xt')
2480 call assert_equal([' c'],
2481 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2482 call assert_equal([
2483 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
2484 \ ],
2485 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2486
2487 call cursor(1, 1)
2488 call feedkeys("\<Esc>lv2l", 'xt')
2489 call assert_equal([' '],
2490 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2491 call assert_equal([
2492 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
2493 \ ],
2494 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2495
2496 call cursor(1, 1)
2497 call feedkeys("\<Esc>2lv2l", 'xt')
2498 call assert_equal([' '],
2499 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2500 call assert_equal([
2501 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
2502 \ ],
2503 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2504
2505 call feedkeys('j', 'xt')
2506 call assert_equal([' c', 'x '],
2507 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2508 call assert_equal([
2509 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
2510 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 4]],
2511 \ ],
2512 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2513
2514 call cursor(1, 1)
2515 call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
2516 call assert_equal([' c', ' z'],
2517 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2518 call assert_equal([
2519 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
2520 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 0]],
2521 \ ],
2522 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2523
2524 call cursor(1, 1)
2525 call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
2526 call assert_equal([' ', ' ', ' '],
2527 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2528 call assert_equal([
2529 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
2530 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
zeertzjq2b09de92024-05-24 07:48:51 +02002531 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjq701ad502024-05-23 07:47:55 +02002532 \ ],
2533 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002534 call assert_equal([
2535 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
2536 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
2537 \ [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 4]],
2538 \ ],
2539 \ getregionpos(getpos('v'), getpos('.'),
2540 \ {'type': "\<C-v>", "eol": v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002541
2542 call cursor(1, 1)
2543 call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
2544 call assert_equal([' ', ' ', ' '],
2545 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2546 call assert_equal([
2547 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
2548 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
zeertzjq2b09de92024-05-24 07:48:51 +02002549 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjq701ad502024-05-23 07:47:55 +02002550 \ ],
2551 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002552 call assert_equal([
2553 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
2554 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
2555 \ [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 5]],
2556 \ ],
2557 \ getregionpos(getpos('v'), getpos('.'),
2558 \ {'type': "\<C-v>", "eol": v:true }))
2559
2560 set virtualedit&
2561 bwipe!
2562 END
2563 call v9.CheckLegacyAndVim9Success(lines)
2564
2565 let lines =<< trim END
2566 #" 'virtualedit' with TABs at end of line
2567 new
2568 set virtualedit=all
2569 call setline(1, ["\t", "a\t", "aa\t"])
2570
2571 call feedkeys("gg06l\<C-v>3l2j", 'xt')
2572 call assert_equal([' ', ' ', ' '],
2573 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2574 call assert_equal([
2575 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
2576 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 0]],
2577 \ [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 3, 0]],
2578 \ ],
2579 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2580 call assert_equal([
2581 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
2582 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 2]],
2583 \ [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 4, 2]],
2584 \ ],
2585 \ getregionpos(getpos('v'), getpos('.'),
2586 \ {'type': "\<C-v>", "eol": v:true }))
2587
2588 call feedkeys("gg06lv3l", 'xt')
2589 call assert_equal([' '],
2590 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2591 call assert_equal([
2592 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
2593 \ ],
2594 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2595 call assert_equal([
2596 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
2597 \ ],
2598 \ getregionpos(getpos('v'), getpos('.'),
2599 \ {'type': 'v', "eol": v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002600
2601 set virtualedit&
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002602 bwipe!
2603 END
2604 call v9.CheckLegacyAndVim9Success(lines)
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002605endfunc
2606
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002607func Test_getregion_invalid_buf()
2608 new
2609 help
2610 call cursor(5, 7)
2611 norm! mA
2612 call cursor(5, 18)
2613 norm! mB
2614 call assert_equal(['Move around:'], getregion(getpos("'A"), getpos("'B")))
2615 " close the help window
2616 q
zeertzjq26dd09a2024-03-10 15:46:58 +01002617 call assert_fails("call getregion(getpos(\"'A\"), getpos(\"'B\"))", 'E681:')
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002618 bwipe!
2619endfunc
2620
zeertzjqafc22952024-05-24 19:07:12 +02002621func Test_getregion_after_yank()
2622 func! Check_Results(type)
2623 call assert_equal(g:expected_region,
2624 \ getregion(getpos("'["), getpos("']"), #{ type: a:type }))
2625 call assert_equal(g:expected_regionpos,
2626 \ getregionpos(getpos("'["), getpos("']"), #{ type: a:type }))
2627 call assert_equal(g:expected_region,
2628 \ getregion(getpos("']"), getpos("'["), #{ type: a:type }))
2629 call assert_equal(g:expected_regionpos,
2630 \ getregionpos(getpos("']"), getpos("'["), #{ type: a:type }))
2631 let g:checked = 1
2632 endfunc
2633
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002634 autocmd TextYankPost *
2635 \ : if v:event.operator ==? 'y'
zeertzjqafc22952024-05-24 19:07:12 +02002636 \ | call Check_Results(v:event.regtype)
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002637 \ | endif
zeertzjqafc22952024-05-24 19:07:12 +02002638
2639 new
2640 call setline(1, ['abcd', 'efghijk', 'lmn'])
2641
2642 let g:expected_region = ['abcd']
2643 let g:expected_regionpos = [
2644 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
2645 \ ]
2646 let g:checked = 0
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002647 normal yy
zeertzjqafc22952024-05-24 19:07:12 +02002648 call assert_equal(1, g:checked)
2649 call Check_Results(getregtype('"'))
2650
2651 let g:expected_region = ['cd', 'ghijk', 'n']
2652 let g:expected_regionpos = [
2653 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
2654 \ [[bufnr('%'), 2, 3, 0], [bufnr('%'), 2, 7, 0]],
2655 \ [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 3, 0]],
2656 \ ]
2657 let g:checked = 0
2658 call feedkeys("gg0ll\<C-V>jj$y", 'tx')
2659 call assert_equal(1, g:checked)
2660 call Check_Results(getregtype('"'))
zeertzjqdff55a32024-05-25 10:25:36 +02002661 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
zeertzjqafc22952024-05-24 19:07:12 +02002662
2663 let g:expected_region = ['bc', 'fg', 'mn']
2664 let g:expected_regionpos = [
2665 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 3, 0]],
2666 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 3, 0]],
2667 \ [[bufnr('%'), 3, 2, 0], [bufnr('%'), 3, 3, 0]],
2668 \ ]
2669 let g:checked = 0
2670 call feedkeys("gg0l\<C-V>jjly", 'tx')
2671 call assert_equal(1, g:checked)
2672 call Check_Results(getregtype('"'))
zeertzjqdff55a32024-05-25 10:25:36 +02002673 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2674
2675 bwipe!
2676
2677 new
2678 let lines = ['asdfghjkl', '«口=口»', 'qwertyuiop', '口口=口口', 'zxcvbnm']
2679 call setline(1, lines)
2680
2681 let g:expected_region = lines
2682 let g:expected_regionpos = [
2683 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 9, 0]],
2684 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 11, 0]],
2685 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 10, 0]],
2686 \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 13, 0]],
2687 \ [[bufnr('%'), 5, 1, 0], [bufnr('%'), 5, 7, 0]],
2688 \ ]
2689 let g:checked = 0
2690 call feedkeys('ggyG', 'tx')
2691 call assert_equal(1, g:checked)
2692 call Check_Results(getregtype('"'))
2693 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2694
2695 let g:expected_region = ['=口»', 'qwertyuiop', '口口=口']
2696 let g:expected_regionpos = [
2697 \ [[bufnr('%'), 2, 6, 0], [bufnr('%'), 2, 11, 0]],
2698 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 10, 0]],
2699 \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 10, 0]],
2700 \ ]
2701 let g:checked = 0
2702 call feedkeys('2gg02lv2j2ly', 'tx')
2703 call assert_equal(1, g:checked)
2704 call Check_Results(getregtype('"'))
2705 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2706
2707 let g:expected_region = ['asdf', '«口=', 'qwer', '口口', 'zxcv']
2708 let g:expected_regionpos = [
2709 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
2710 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 6, 0]],
2711 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 4, 0]],
2712 \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 6, 0]],
2713 \ [[bufnr('%'), 5, 1, 0], [bufnr('%'), 5, 4, 0]],
2714 \ ]
2715 let g:checked = 0
2716 call feedkeys("G0\<C-V>3l4ky", 'tx')
2717 call assert_equal(1, g:checked)
2718 call Check_Results(getregtype('"'))
2719 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2720
2721 let g:expected_region = ['ghjkl', '口»', 'tyuiop', '=口口', 'bnm']
2722 let g:expected_regionpos = [
2723 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 9, 0]],
2724 \ [[bufnr('%'), 2, 7, 0], [bufnr('%'), 2, 11, 0]],
2725 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 10, 0]],
2726 \ [[bufnr('%'), 4, 7, 0], [bufnr('%'), 4, 13, 0]],
2727 \ [[bufnr('%'), 5, 5, 0], [bufnr('%'), 5, 7, 0]],
2728 \ ]
2729 let g:checked = 0
2730 call feedkeys("G04l\<C-V>$4ky", 'tx')
2731 call assert_equal(1, g:checked)
2732 call Check_Results(getregtype('"'))
2733 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
zeertzjqafc22952024-05-24 19:07:12 +02002734
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002735 bwipe!
zeertzjqafc22952024-05-24 19:07:12 +02002736
2737 unlet g:expected_region
2738 unlet g:expected_regionpos
2739 unlet g:checked
2740 autocmd! TextYankPost
2741 delfunc Check_Results
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002742endfunc
2743
Christian Brabandtd5c8c092024-05-08 22:17:19 +02002744func Test_visual_block_cursor_delete()
2745 new
2746 call setline(1, 'ab')
2747 exe ":norm! $\<c-v>hI\<Del>\<ESC>"
2748 call assert_equal(['b'], getline(1, 1))
2749 bwipe!
2750endfunc
2751
Christian Brabandt1fb9eae2024-06-11 20:30:14 +02002752func Test_visual_block_cursor_insert_enter()
2753 new
2754 call setline(1, ['asdf asdf', 'asdf asdf', 'asdf asdf', 'asdf asdf'])
2755 call cursor(1, 5)
2756 exe ":norm! \<c-v>3jcw\<cr>"
2757 call assert_equal(['asdfw', 'asdf', 'asdfasdf', 'asdfasdf', 'asdfasdf'], getline(1, '$'))
2758 bwipe!
2759endfunc
2760
Christian Brabandtbb955892024-12-16 22:49:15 +01002761func Test_visual_block_exclusive_selection()
2762 new
2763 set selection=exclusive
2764 call setline(1, ['asöd asdf', 'asdf asdf', 'asd asdf', 'asdf asdf'])
2765 call cursor(1, 1)
2766 exe ":norm! \<c-v>eh3j~"
2767 call assert_equal(['ASÖd asdf', 'ASDf asdf', 'ASd asdf', 'ASDf asdf'], getline(1, '$'))
2768 exe ":norm! 1v~"
2769 call assert_equal(['asöd asdf', 'asdf asdf', 'asd asdf', 'asdf asdf'], getline(1, '$'))
2770 bwipe!
2771 set selection&vim
2772endfunc
2773
2774func Test_visual_block_exclusive_selection_adjusted()
2775 new
2776 " Test that the end-position of the visual selection is adjusted for exclusive selection
2777 set selection=exclusive
2778 call setline(1, ['asöd asdf ', 'asdf asdf ', 'asd asdf ', 'asdf asdf '])
2779 call cursor(1, 1)
2780 " inclusive motion
2781 exe ":norm! \<c-v>e3jy"
2782 call assert_equal([0, 4, 5, 0], getpos("'>"))
2783 " exclusive motion
2784 exe ":norm! \<c-v>ta3jy"
2785 call assert_equal([0, 4, 6, 0], getpos("'>"))
2786 " another inclusive motion
2787 exe ":norm! \<c-v>g_3jy"
2788 call assert_equal([0, 4, 10, 0], getpos("'>"))
2789
2790 " Reset selection option to Vim default
2791 set selection&vim
2792 call cursor(1, 1)
2793
2794 " inclusive motion
2795 exe ":norm! \<c-v>e3jy"
2796 call assert_equal([0, 4, 4, 0], getpos("'>"))
2797 " exclusive motion
2798 exe ":norm! \<c-v>ta3jy"
2799 call assert_equal([0, 4, 5, 0], getpos("'>"))
2800 " another inclusive motion
2801 exe ":norm! \<c-v>g_3jy"
2802 call assert_equal([0, 4, 9, 0], getpos("'>"))
2803 bwipe!
2804 set selection&vim
2805endfunc
2806
Christian Brabandtc9a1e252025-01-11 15:25:00 +01002807" the following caused a Heap-Overflow, because Vim was accessing outside of a
2808" line end
2809func Test_visual_pos_buffer_heap_overflow()
2810 set virtualedit=all
2811 args Xa Xb
2812 all
2813 call setline(1, ['', '', ''])
2814 call cursor(3, 1)
2815 wincmd w
2816 call setline(1, 'foobar')
2817 normal! $lv0
2818 all
2819 call setreg('"', 'baz')
2820 normal! [P
2821 set virtualedit=
2822 bw! Xa Xb
2823endfunc
2824
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +01002825" vim: shiftwidth=2 sts=2 expandtab