blob: 2665faa451d7f34b5da792a2e9e2f5754662a7d4 [file] [log] [blame]
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +01001" Tests for various Visual modes.
Bram Moolenaarc3c766e2017-03-08 22:55:19 +01002
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02003source shared.vim
Bram Moolenaar7d7bcc62021-06-28 21:54:27 +02004source check.vim
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02005source screendump.vim
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01006import './vim9.vim' as v9
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02007
Bram Moolenaar019b9c62016-03-05 17:26:00 +01008func Test_block_shift_multibyte()
Bram Moolenaarf8eb9c52017-01-02 17:31:24 +01009 " Uses double-wide character.
Bram Moolenaar019b9c62016-03-05 17:26:00 +010010 split
11 call setline(1, ['xヹxxx', 'ヹxxx'])
12 exe "normal 1G0l\<C-V>jl>"
13 call assert_equal('x ヹxxx', getline(1))
14 call assert_equal(' ヹxxx', getline(2))
15 q!
16endfunc
Bram Moolenaarf8eb9c52017-01-02 17:31:24 +010017
Bram Moolenaarbae5a172017-08-06 15:42:06 +020018func Test_block_shift_overflow()
19 " This used to cause a multiplication overflow followed by a crash.
20 new
21 normal ii
22 exe "normal \<C-V>876543210>"
23 q!
24endfunc
25
Bram Moolenaarf8eb9c52017-01-02 17:31:24 +010026func Test_dotregister_paste()
27 new
28 exe "norm! ihello world\<esc>"
29 norm! 0ve".p
30 call assert_equal('hello world world', getline(1))
31 q!
32endfunc
Bram Moolenaar23fa81d2017-02-01 21:50:21 +010033
34func Test_Visual_ctrl_o()
35 new
36 call setline(1, ['one', 'two', 'three'])
37 call cursor(1,2)
38 set noshowmode
39 set tw=0
40 call feedkeys("\<c-v>jjlIa\<c-\>\<c-o>:set tw=88\<cr>\<esc>", 'tx')
41 call assert_equal(['oane', 'tawo', 'tahree'], getline(1, 3))
42 call assert_equal(88, &tw)
43 set tw&
44 bw!
45endfu
Bram Moolenaar84b2a382017-02-17 11:40:00 +010046
47func Test_Visual_vapo()
48 new
49 normal oxx
50 normal vapo
51 bwipe!
52endfunc
Bram Moolenaar46522af2017-02-18 23:12:01 +010053
54func Test_Visual_inner_quote()
55 new
56 normal oxX
57 normal vki'
58 bwipe!
59endfunc
Bram Moolenaar75373f32017-08-07 22:02:30 +020060
61" Test for Visual mode not being reset causing E315 error.
62func TriggerTheProblem()
63 " At this point there is no visual selection because :call reset it.
64 " Let's restore the selection:
65 normal gv
66 '<,'>del _
67 try
68 exe "normal \<Esc>"
69 catch /^Vim\%((\a\+)\)\=:E315/
70 echom 'Snap! E315 error!'
Bram Moolenaar63e82db2018-03-06 12:10:48 +010071 let g:msg = 'Snap! E315 error!'
Bram Moolenaar75373f32017-08-07 22:02:30 +020072 endtry
73endfunc
74
75func Test_visual_mode_reset()
Bram Moolenaar75373f32017-08-07 22:02:30 +020076 enew
Bram Moolenaar63e82db2018-03-06 12:10:48 +010077 let g:msg = "Everything's fine."
Bram Moolenaar75373f32017-08-07 22:02:30 +020078 enew
79 setl buftype=nofile
80 call append(line('$'), 'Delete this line.')
81
82 " NOTE: this has to be done by a call to a function because executing :del
83 " the ex-way will require the colon operator which resets the visual mode
84 " thus preventing the problem:
85 exe "normal! GV:call TriggerTheProblem()\<CR>"
86 call assert_equal("Everything's fine.", g:msg)
Bram Moolenaar75373f32017-08-07 22:02:30 +020087endfunc
Bram Moolenaar67418d92017-10-15 22:07:39 +020088
Bram Moolenaar15993ce2017-10-26 20:21:44 +020089" Test for visual block shift and tab characters.
90func Test_block_shift_tab()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +020091 new
Bram Moolenaar15993ce2017-10-26 20:21:44 +020092 call append(0, repeat(['one two three'], 5))
93 call cursor(1,1)
94 exe "normal i\<C-G>u"
95 exe "normal fe\<C-V>4jR\<Esc>ugvr1"
96 call assert_equal('on1 two three', getline(1))
97 call assert_equal('on1 two three', getline(2))
98 call assert_equal('on1 two three', getline(5))
99
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200100 %d _
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200101 call append(0, repeat(['abcdefghijklmnopqrstuvwxyz'], 5))
102 call cursor(1,1)
103 exe "normal \<C-V>4jI \<Esc>j<<11|D"
104 exe "normal j7|a\<Tab>\<Tab>"
105 exe "normal j7|a\<Tab>\<Tab> "
106 exe "normal j7|a\<Tab> \<Tab>\<Esc>4k13|\<C-V>4j<"
107 call assert_equal(' abcdefghijklmnopqrstuvwxyz', getline(1))
108 call assert_equal('abcdefghij', getline(2))
109 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(3))
110 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(4))
111 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(5))
112
113 %s/\s\+//g
114 call cursor(1,1)
115 exe "normal \<C-V>4jI \<Esc>j<<"
116 exe "normal j7|a\<Tab>\<Tab>"
117 exe "normal j7|a\<Tab>\<Tab>\<Tab>\<Tab>\<Tab>"
118 exe "normal j7|a\<Tab> \<Tab>\<Tab>\<Esc>4k13|\<C-V>4j3<"
119 call assert_equal(' abcdefghijklmnopqrstuvwxyz', getline(1))
120 call assert_equal('abcdefghij', getline(2))
121 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(3))
122 call assert_equal(" abc\<Tab>\<Tab>defghijklmnopqrstuvwxyz", getline(4))
123 call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(5))
124
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200125 " Test for block shift with space characters at the beginning and with
126 " 'noexpandtab' and 'expandtab'
127 %d _
128 call setline(1, [" 1", " 2", " 3"])
129 setlocal shiftwidth=2 noexpandtab
130 exe "normal gg\<C-V>3j>"
131 call assert_equal(["\t1", "\t2", "\t3"], getline(1, '$'))
132 %d _
133 call setline(1, [" 1", " 2", " 3"])
134 setlocal shiftwidth=2 expandtab
135 exe "normal gg\<C-V>3j>"
136 call assert_equal([" 1", " 2", " 3"], getline(1, '$'))
137 setlocal shiftwidth&
138
139 bw!
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200140endfunc
141
142" Tests Blockwise Visual when there are TABs before the text.
143func Test_blockwise_visual()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200144 new
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200145 call append(0, ['123456',
146 \ '234567',
147 \ '345678',
148 \ '',
149 \ 'test text test tex start here',
150 \ "\t\tsome text",
151 \ "\t\ttest text",
152 \ 'test text'])
153 call cursor(1,1)
154 exe "normal /start here$\<CR>"
155 exe 'normal "by$' . "\<C-V>jjlld"
156 exe "normal /456$\<CR>"
157 exe "normal \<C-V>jj" . '"bP'
158 call assert_equal(['123start here56',
159 \ '234start here67',
160 \ '345start here78',
161 \ '',
162 \ 'test text test tex rt here',
163 \ "\t\tsomext",
164 \ "\t\ttesext"], getline(1, 7))
165
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200166 bw!
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200167endfunc
168
Bram Moolenaar2e949762018-05-20 14:06:38 +0200169" Test swapping corners in blockwise visual mode with o and O
170func Test_blockwise_visual_o_O()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200171 new
Bram Moolenaar2e949762018-05-20 14:06:38 +0200172
173 exe "norm! 10i.\<Esc>Y4P3lj\<C-V>4l2jr "
174 exe "norm! gvO\<Esc>ra"
175 exe "norm! gvO\<Esc>rb"
176 exe "norm! gvo\<C-c>rc"
177 exe "norm! gvO\<C-c>rd"
Bram Moolenaar1671f442020-03-10 07:48:13 +0100178 set selection=exclusive
179 exe "norm! gvOo\<C-c>re"
180 call assert_equal('...a be.', getline(4))
181 exe "norm! gvOO\<C-c>rf"
182 set selection&
Bram Moolenaar2e949762018-05-20 14:06:38 +0200183
184 call assert_equal(['..........',
185 \ '...c d..',
186 \ '... ..',
Bram Moolenaar1671f442020-03-10 07:48:13 +0100187 \ '...a bf.',
Bram Moolenaar2e949762018-05-20 14:06:38 +0200188 \ '..........'], getline(1, '$'))
189
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200190 bw!
Bram Moolenaar2e949762018-05-20 14:06:38 +0200191endfun
192
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200193" Test Virtual replace mode.
194func Test_virtual_replace()
Bram Moolenaardf0d24b2018-03-06 14:22:58 +0100195 if exists('&t_kD')
196 let save_t_kD = &t_kD
197 endif
198 if exists('&t_kb')
199 let save_t_kb = &t_kb
200 endif
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200201 exe "set t_kD=\<C-V>x7f t_kb=\<C-V>x08"
202 enew!
203 exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
204 call cursor(1,1)
205 set ai bs=2
206 exe "normal gR0\<C-D> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
207 call assert_equal([' 1',
208 \ ' A',
209 \ ' BCDEFGHIJ',
210 \ ' KL',
211 \ ' MNO',
212 \ ' PQR',
213 \ ], getline(1, 6))
214 normal G
215 mark a
216 exe "normal o0\<C-D>\nabcdefghi\njk\tlmn\n opq\trst\n\<C-D>uvwxyz\n"
217 exe "normal 'ajgR0\<C-D> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR" . repeat("\<BS>", 29)
218 call assert_equal([' 1',
219 \ 'abcdefghi',
220 \ 'jk lmn',
221 \ ' opq rst',
222 \ 'uvwxyz'], getline(7, 11))
223 normal G
224 exe "normal iab\tcdefghi\tjkl"
225 exe "normal 0gRAB......CDEFGHI.J\<Esc>o"
226 exe "normal iabcdefghijklmnopqrst\<Esc>0gRAB\tIJKLMNO\tQR"
227 call assert_equal(['AB......CDEFGHI.Jkl',
228 \ 'AB IJKLMNO QRst'], getline(12, 13))
Bram Moolenaar845e0ee2020-06-20 16:05:32 +0200229
230 " Test inserting Tab with 'noexpandtab' and 'softabstop' set to 4
231 %d
232 call setline(1, 'aaaaaaaaaaaaa')
233 set softtabstop=4
234 exe "normal gggR\<Tab>\<Tab>x"
235 call assert_equal("\txaaaa", getline(1))
236 set softtabstop&
237
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200238 enew!
Bram Moolenaare7808482018-03-06 13:17:23 +0100239 set noai bs&vim
Bram Moolenaardf0d24b2018-03-06 14:22:58 +0100240 if exists('save_t_kD')
241 let &t_kD = save_t_kD
242 endif
243 if exists('save_t_kb')
244 let &t_kb = save_t_kb
245 endif
Bram Moolenaar63e82db2018-03-06 12:10:48 +0100246endfunc
247
248" Test Virtual replace mode.
249func Test_virtual_replace2()
250 enew!
251 set bs=2
252 exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
253 call cursor(1,1)
254 " Test 1: Test that del deletes the newline
255 exe "normal gR0\<del> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
256 call assert_equal(['0 1',
257 \ 'A',
258 \ 'BCDEFGHIJ',
259 \ ' KL',
260 \ 'MNO',
261 \ 'PQR',
262 \ ], getline(1, 6))
263 " Test 2:
264 " a newline is not deleted, if no newline has been added in virtual replace mode
265 %d_
266 call setline(1, ['abcd', 'efgh', 'ijkl'])
267 call cursor(2,1)
268 exe "norm! gR1234\<cr>5\<bs>\<bs>\<bs>"
269 call assert_equal(['abcd',
270 \ '123h',
271 \ 'ijkl'], getline(1, '$'))
272 " Test 3:
273 " a newline is deleted, if a newline has been inserted before in virtual replace mode
274 %d_
275 call setline(1, ['abcd', 'efgh', 'ijkl'])
276 call cursor(2,1)
277 exe "norm! gR1234\<cr>\<cr>56\<bs>\<bs>\<bs>"
278 call assert_equal(['abcd',
279 \ '1234',
280 \ 'ijkl'], getline(1, '$'))
281 " Test 4:
282 " delete add a newline, delete it, add it again and check undo
283 %d_
284 call setline(1, ['abcd', 'efgh', 'ijkl'])
285 call cursor(2,1)
286 " break undo sequence explicitly
287 let &ul = &ul
288 exe "norm! gR1234\<cr>\<bs>\<del>56\<cr>"
289 let &ul = &ul
290 call assert_equal(['abcd',
291 \ '123456',
292 \ ''], getline(1, '$'))
293 norm! u
294 call assert_equal(['abcd',
295 \ 'efgh',
296 \ 'ijkl'], getline(1, '$'))
Bram Moolenaarca68ae12020-03-30 19:32:53 +0200297
298 " Test for truncating spaces in a newly added line using 'autoindent' if
299 " characters are not added to that line.
300 %d_
301 call setline(1, [' app', ' bee', ' cat'])
302 setlocal autoindent
303 exe "normal gg$gRt\n\nr"
304 call assert_equal([' apt', '', ' rat'], getline(1, '$'))
305
Bram Moolenaar63e82db2018-03-06 12:10:48 +0100306 " clean up
307 %d_
308 set bs&vim
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200309endfunc
Bram Moolenaar6d3a1942019-01-03 23:10:32 +0100310
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100311func Test_Visual_word_textobject()
312 new
313 call setline(1, ['First sentence. Second sentence.'])
314
315 " When start and end of visual area are identical, 'aw' or 'iw' select
316 " the whole word.
317 norm! 1go2fcvawy
318 call assert_equal('Second ', @")
319 norm! 1go2fcviwy
320 call assert_equal('Second', @")
321
322 " When start and end of visual area are not identical, 'aw' or 'iw'
323 " extend the word in direction of the end of the visual area.
324 norm! 1go2fcvlawy
325 call assert_equal('cond ', @")
326 norm! gv2awy
327 call assert_equal('cond sentence.', @")
328
329 norm! 1go2fcvliwy
330 call assert_equal('cond', @")
331 norm! gv2iwy
332 call assert_equal('cond sentence', @")
333
334 " Extend visual area in opposite direction.
335 norm! 1go2fcvhawy
336 call assert_equal(' Sec', @")
337 norm! gv2awy
338 call assert_equal(' sentence. Sec', @")
339
340 norm! 1go2fcvhiwy
341 call assert_equal('Sec', @")
342 norm! gv2iwy
343 call assert_equal('. Sec', @")
344
345 bwipe!
346endfunc
347
Bram Moolenaar6d3a1942019-01-03 23:10:32 +0100348func Test_Visual_sentence_textobject()
349 new
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100350 call setline(1, ['First sentence. Second sentence. Third', 'sentence. Fourth sentence'])
Bram Moolenaar6d3a1942019-01-03 23:10:32 +0100351
352 " When start and end of visual area are identical, 'as' or 'is' select
353 " the whole sentence.
354 norm! 1gofdvasy
355 call assert_equal('Second sentence. ', @")
356 norm! 1gofdvisy
357 call assert_equal('Second sentence.', @")
358
359 " When start and end of visual area are not identical, 'as' or 'is'
360 " extend the sentence in direction of the end of the visual area.
361 norm! 1gofdvlasy
362 call assert_equal('d sentence. ', @")
363 norm! gvasy
364 call assert_equal("d sentence. Third\nsentence. ", @")
365
366 norm! 1gofdvlisy
367 call assert_equal('d sentence.', @")
368 norm! gvisy
369 call assert_equal('d sentence. ', @")
370 norm! gvisy
371 call assert_equal("d sentence. Third\nsentence.", @")
372
373 " Extend visual area in opposite direction.
374 norm! 1gofdvhasy
375 call assert_equal(' Second', @")
376 norm! gvasy
377 call assert_equal("First sentence. Second", @")
378
379 norm! 1gofdvhisy
380 call assert_equal('Second', @")
381 norm! gvisy
382 call assert_equal(' Second', @")
383 norm! gvisy
384 call assert_equal('First sentence. Second', @")
385
386 bwipe!
387endfunc
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100388
389func Test_Visual_paragraph_textobject()
390 new
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200391 let lines =<< trim [END]
392 First line.
393
394 Second line.
395 Third line.
396 Fourth line.
397 Fifth line.
398
399 Sixth line.
400 [END]
401 call setline(1, lines)
Bram Moolenaar81b1ba42019-01-13 16:12:40 +0100402
403 " When start and end of visual area are identical, 'ap' or 'ip' select
404 " the whole paragraph.
405 norm! 4ggvapy
406 call assert_equal("Second line.\nThird line.\nFourth line.\nFifth line.\n\n", @")
407 norm! 4ggvipy
408 call assert_equal("Second line.\nThird line.\nFourth line.\nFifth line.\n", @")
409
410 " When start and end of visual area are not identical, 'ap' or 'ip'
411 " extend the sentence in direction of the end of the visual area.
412 " FIXME: actually, it is not sufficient to have different start and
413 " end of visual selection, the start line and end line have to differ,
414 " which is not consistent with the documentation.
415 norm! 4ggVjapy
416 call assert_equal("Third line.\nFourth line.\nFifth line.\n\n", @")
417 norm! gvapy
418 call assert_equal("Third line.\nFourth line.\nFifth line.\n\nSixth line.\n", @")
419 norm! 4ggVjipy
420 call assert_equal("Third line.\nFourth line.\nFifth line.\n", @")
421 norm! gvipy
422 call assert_equal("Third line.\nFourth line.\nFifth line.\n\n", @")
423 norm! gvipy
424 call assert_equal("Third line.\nFourth line.\nFifth line.\n\nSixth line.\n", @")
425
426 " Extend visual area in opposite direction.
427 norm! 5ggVkapy
428 call assert_equal("\nSecond line.\nThird line.\nFourth line.\n", @")
429 norm! gvapy
430 call assert_equal("First line.\n\nSecond line.\nThird line.\nFourth line.\n", @")
431 norm! 5ggVkipy
432 call assert_equal("Second line.\nThird line.\nFourth line.\n", @")
433 norma gvipy
434 call assert_equal("\nSecond line.\nThird line.\nFourth line.\n", @")
435 norm! gvipy
436 call assert_equal("First line.\n\nSecond line.\nThird line.\nFourth line.\n", @")
437
438 bwipe!
439endfunc
Bram Moolenaar19a66852019-03-07 11:25:32 +0100440
441func Test_curswant_not_changed()
442 new
443 call setline(1, ['one', 'two'])
444 au InsertLeave * call getcurpos()
445 call feedkeys("gg0\<C-V>jI123 \<Esc>j", 'xt')
446 call assert_equal([0, 2, 1, 0, 1], getcurpos())
447
448 bwipe!
449 au! InsertLeave
450endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +0200451
452" Tests for "vaBiB", end could be wrong.
453func Test_Visual_Block()
454 new
455 a
456- Bug in "vPPPP" on this text:
457 {
458 cmd;
459 {
460 cmd;\t/* <-- Start cursor here */
461 {
462 }
463 }
464 }
465.
466 normal gg
467 call search('Start cursor here')
468 normal vaBiBD
469 call assert_equal(['- Bug in "vPPPP" on this text:',
470 \ "\t{",
471 \ "\t}"], getline(1, '$'))
472
Christian Brabandtc9a1e252025-01-11 15:25:00 +0100473 bw!
Bram Moolenaarc6b37db2019-04-27 18:00:34 +0200474endfunc
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +0100475
476" Test for 'p'ut in visual block mode
477func Test_visual_block_put()
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200478 new
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +0100479 call append(0, ['One', 'Two', 'Three'])
480 normal gg
481 yank
482 call feedkeys("jl\<C-V>ljp", 'xt')
483 call assert_equal(['One', 'T', 'Tee', 'One', ''], getline(1, '$'))
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200484 bw!
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +0100485endfunc
486
Bram Moolenaar36343ae2022-10-15 19:04:05 +0100487func Test_visual_block_put_invalid()
488 enew!
489 behave mswin
490 norm yy
491 norm v)Ps/^/
492 " this was causing the column to become negative
493 silent norm ggv)P
494
495 bwipe!
496 behave xterm
497endfunc
498
Bram Moolenaar309976e2019-12-05 18:16:33 +0100499" Visual modes (v V CTRL-V) followed by an operator; count; repeating
500func Test_visual_mode_op()
501 new
502 call append(0, '')
503
504 call setline(1, 'apple banana cherry')
505 call cursor(1, 1)
506 normal lvld.l3vd.
507 call assert_equal('a y', getline(1))
508
509 call setline(1, ['line 1 line 1', 'line 2 line 2', 'line 3 line 3',
510 \ 'line 4 line 4', 'line 5 line 5', 'line 6 line 6'])
511 call cursor(1, 1)
512 exe "normal Vcnewline\<Esc>j.j2Vd."
513 call assert_equal(['newline', 'newline'], getline(1, '$'))
514
515 call deletebufline('', 1, '$')
516 call setline(1, ['xxxxxxxxxxxxx', 'xxxxxxxxxxxxx', 'xxxxxxxxxxxxx',
517 \ 'xxxxxxxxxxxxx'])
518 exe "normal \<C-V>jlc \<Esc>l.l2\<C-V>c----\<Esc>l."
519 call assert_equal([' --------x',
520 \ ' --------x',
521 \ 'xxxx--------x',
522 \ 'xxxx--------x'], getline(1, '$'))
523
524 bwipe!
525endfunc
526
527" Visual mode maps (movement and text object)
528" Visual mode maps; count; repeating
529" - Simple
530" - With an Ex command (custom text object)
531func Test_visual_mode_maps()
532 new
533 call append(0, '')
534
535 func SelectInCaps()
536 let [line1, col1] = searchpos('\u', 'bcnW')
537 let [line2, col2] = searchpos('.\u', 'nW')
538 call setpos("'<", [0, line1, col1, 0])
539 call setpos("'>", [0, line2, col2, 0])
540 normal! gv
541 endfunction
542
543 vnoremap W /\u/s-1<CR>
544 vnoremap iW :<C-U>call SelectInCaps()<CR>
545
546 call setline(1, 'KiwiRaspberryDateWatermelonPeach')
547 call cursor(1, 1)
548 exe "normal vWcNo\<Esc>l.fD2vd."
549 call assert_equal('NoNoberryach', getline(1))
550
551 call setline(1, 'JambuRambutanBananaTangerineMango')
552 call cursor(1, 1)
553 exe "normal llviWc-\<Esc>l.l2vdl."
554 call assert_equal('--ago', getline(1))
555
556 vunmap W
557 vunmap iW
558 bwipe!
559 delfunc SelectInCaps
560endfunc
561
562" Operator-pending mode maps (movement and text object)
563" - Simple
564" - With Ex command moving the cursor
565" - With Ex command and Visual selection (custom text object)
566func Test_visual_oper_pending_mode_maps()
567 new
568 call append(0, '')
569
570 func MoveToCap()
571 call search('\u', 'W')
572 endfunction
573
574 func SelectInCaps()
575 let [line1, col1] = searchpos('\u', 'bcnW')
576 let [line2, col2] = searchpos('.\u', 'nW')
577 call setpos("'<", [0, line1, col1, 0])
578 call setpos("'>", [0, line2, col2, 0])
579 normal! gv
580 endfunction
581
582 onoremap W /\u/<CR>
583 onoremap <Leader>W :<C-U>call MoveToCap()<CR>
584 onoremap iW :<C-U>call SelectInCaps()<CR>
585
586 call setline(1, 'PineappleQuinceLoganberryOrangeGrapefruitKiwiZ')
587 call cursor(1, 1)
588 exe "normal cW-\<Esc>l.l2.l."
589 call assert_equal('----Z', getline(1))
590
591 call setline(1, 'JuniperDurianZ')
592 call cursor(1, 1)
593 exe "normal g?\WfD."
594 call assert_equal('WhavcreQhevnaZ', getline(1))
595
596 call setline(1, 'LemonNectarineZ')
597 call cursor(1, 1)
598 exe "normal yiWPlciWNew\<Esc>fr."
599 call assert_equal('LemonNewNewZ', getline(1))
600
601 ounmap W
602 ounmap <Leader>W
603 ounmap iW
604 bwipe!
605 delfunc MoveToCap
606 delfunc SelectInCaps
607endfunc
608
609" Patch 7.3.879: Properly abort Operator-pending mode for "dv:<Esc>" etc.
610func Test_op_pend_mode_abort()
611 new
612 call append(0, '')
613
614 call setline(1, ['zzzz', 'zzzz'])
615 call cursor(1, 1)
616
617 exe "normal dV:\<CR>dv:\<CR>"
618 call assert_equal(['zzz'], getline(1, 2))
619 set nomodifiable
620 call assert_fails('exe "normal d:\<CR>"', 'E21:')
621 set modifiable
622 call feedkeys("dv:\<Esc>dV:\<Esc>", 'xt')
623 call assert_equal(['zzz'], getline(1, 2))
624 set nomodifiable
625 let v:errmsg = ''
626 call feedkeys("d:\<Esc>", 'xt')
627 call assert_true(v:errmsg !~# '^E21:')
628 set modifiable
629
630 bwipe!
631endfunc
632
633func Test_characterwise_visual_mode()
634 new
635
636 " characterwise visual mode: replace last line
637 $put ='a'
638 let @" = 'x'
639 normal v$p
640 call assert_equal('x', getline('$'))
641
642 " characterwise visual mode: delete middle line
643 call deletebufline('', 1, '$')
644 call append('$', ['a', 'b', 'c'])
645 normal G
646 normal kkv$d
647 call assert_equal(['', 'b', 'c'], getline(1, '$'))
648
649 " characterwise visual mode: delete middle two lines
650 call deletebufline('', 1, '$')
651 call append('$', ['a', 'b', 'c'])
652 normal Gkkvj$d
653 call assert_equal(['', 'c'], getline(1, '$'))
654
655 " characterwise visual mode: delete last line
656 call deletebufline('', 1, '$')
657 call append('$', ['a', 'b', 'c'])
658 normal Gv$d
659 call assert_equal(['', 'a', 'b', ''], getline(1, '$'))
660
661 " characterwise visual mode: delete last two lines
662 call deletebufline('', 1, '$')
663 call append('$', ['a', 'b', 'c'])
664 normal Gkvj$d
665 call assert_equal(['', 'a', ''], getline(1, '$'))
666
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200667 " characterwise visual mode: use a count with the visual mode from the last
668 " line in the buffer
669 %d _
670 call setline(1, ['one', 'two', 'three', 'four'])
671 norm! vj$y
672 norm! G1vy
673 call assert_equal('four', @")
674
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200675 " characterwise visual mode: replace a single character line and the eol
676 %d _
677 call setline(1, "a")
678 normal v$rx
679 call assert_equal(['x'], getline(1, '$'))
680
Bram Moolenaar6ecf58b2021-12-16 10:05:41 +0000681 " replace a character with composing characters
682 call setline(1, "xã̳x")
683 normal gg0lvrb
684 call assert_equal("xbx", getline(1))
685
Bram Moolenaar309976e2019-12-05 18:16:33 +0100686 bwipe!
687endfunc
688
Bram Moolenaar309976e2019-12-05 18:16:33 +0100689func Test_visual_mode_put()
690 new
691
692 " v_p: replace last character with line register at middle line
693 call append('$', ['aaa', 'bbb', 'ccc'])
694 normal G
695 -2yank
696 normal k$vp
697 call assert_equal(['', 'aaa', 'bb', 'aaa', '', 'ccc'], getline(1, '$'))
698
699 " v_p: replace last character with line register at middle line selecting
700 " newline
701 call deletebufline('', 1, '$')
702 call append('$', ['aaa', 'bbb', 'ccc'])
703 normal G
704 -2yank
705 normal k$v$p
706 call assert_equal(['', 'aaa', 'bb', 'aaa', 'ccc'], getline(1, '$'))
707
708 " v_p: replace last character with line register at last line
709 call deletebufline('', 1, '$')
710 call append('$', ['aaa', 'bbb', 'ccc'])
711 normal G
712 -2yank
713 normal $vp
714 call assert_equal(['', 'aaa', 'bbb', 'cc', 'aaa', ''], getline(1, '$'))
715
716 " v_p: replace last character with line register at last line selecting
717 " newline
718 call deletebufline('', 1, '$')
719 call append('$', ['aaa', 'bbb', 'ccc'])
720 normal G
721 -2yank
722 normal $v$p
723 call assert_equal(['', 'aaa', 'bbb', 'cc', 'aaa', ''], getline(1, '$'))
724
725 bwipe!
726endfunc
727
Bram Moolenaar515545e2020-03-22 14:08:59 +0100728func Test_gv_with_exclusive_selection()
Bram Moolenaar309976e2019-12-05 18:16:33 +0100729 new
730
Bram Moolenaar515545e2020-03-22 14:08:59 +0100731 " gv with exclusive selection after an operation
Bram Moolenaar309976e2019-12-05 18:16:33 +0100732 call append('$', ['zzz ', 'äà '])
733 set selection=exclusive
734 normal Gkv3lyjv3lpgvcxxx
735 call assert_equal(['', 'zzz ', 'xxx '], getline(1, '$'))
736
Bram Moolenaar515545e2020-03-22 14:08:59 +0100737 " gv with exclusive selection without an operation
Bram Moolenaar309976e2019-12-05 18:16:33 +0100738 call deletebufline('', 1, '$')
739 call append('$', 'zzz ')
740 set selection=exclusive
741 exe "normal G0v3l\<Esc>gvcxxx"
742 call assert_equal(['', 'xxx '], getline(1, '$'))
743
744 set selection&vim
745 bwipe!
746endfunc
747
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100748" Tests for the visual block mode commands
749func Test_visual_block_mode()
750 new
751 call append(0, '')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100752 call setline(1, repeat(['abcdefghijklm'], 5))
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100753 call cursor(1, 1)
754
755 " Test shift-right of a block
756 exe "normal jllll\<C-V>jj>wll\<C-V>jlll>"
757 " Test shift-left of a block
758 exe "normal G$hhhh\<C-V>kk<"
759 " Test block-insert
760 exe "normal Gkl\<C-V>kkkIxyz"
761 " Test block-replace
762 exe "normal Gllll\<C-V>kkklllrq"
763 " Test block-change
764 exe "normal G$khhh\<C-V>hhkkcmno"
765 call assert_equal(['axyzbcdefghijklm',
766 \ 'axyzqqqq mno ghijklm',
767 \ 'axyzqqqqef mno ghijklm',
768 \ 'axyzqqqqefgmnoklm',
769 \ 'abcdqqqqijklm'], getline(1, 5))
770
Bram Moolenaar1671f442020-03-10 07:48:13 +0100771 " Test 'C' to change till the end of the line
772 call cursor(3, 4)
773 exe "normal! \<C-V>j3lCooo"
774 call assert_equal(['axyooo', 'axyooo'], getline(3, 4))
775
776 " Test 'D' to delete till the end of the line
777 call cursor(3, 3)
778 exe "normal! \<C-V>j2lD"
779 call assert_equal(['ax', 'ax'], getline(3, 4))
780
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200781 " Test block insert with a short line that ends before the block
782 %d _
783 call setline(1, [" one", "a", " two"])
784 exe "normal gg\<C-V>2jIx"
785 call assert_equal([" xone", "a", " xtwo"], getline(1, '$'))
786
787 " Test block append at EOL with '$' and without '$'
788 %d _
789 call setline(1, ["one", "a", "two"])
790 exe "normal gg$\<C-V>2jAx"
791 call assert_equal(["onex", "ax", "twox"], getline(1, '$'))
792 %d _
793 call setline(1, ["one", "a", "two"])
794 exe "normal gg3l\<C-V>2jAx"
795 call assert_equal(["onex", "a x", "twox"], getline(1, '$'))
796
797 " Test block replace with an empty line in the middle and use $ to jump to
798 " the end of the line.
799 %d _
800 call setline(1, ['one', '', 'two'])
801 exe "normal gg$\<C-V>2jrx"
802 call assert_equal(["onx", "", "twx"], getline(1, '$'))
803
804 " Test block replace with an empty line in the middle and move cursor to the
805 " end of the line
806 %d _
807 call setline(1, ['one', '', 'two'])
808 exe "normal gg2l\<C-V>2jrx"
809 call assert_equal(["onx", "", "twx"], getline(1, '$'))
810
811 " Replace odd number of characters with a multibyte character
812 %d _
813 call setline(1, ['abcd', 'efgh'])
814 exe "normal ggl\<C-V>2ljr\u1100"
815 call assert_equal(["a\u1100 ", "e\u1100 "], getline(1, '$'))
816
817 " During visual block append, if the cursor moved outside of the selected
818 " range, then the edit should not be applied to the block.
819 %d _
820 call setline(1, ['aaa', 'bbb', 'ccc'])
821 exe "normal 2G\<C-V>jAx\<Up>"
822 call assert_equal(['aaa', 'bxbb', 'ccc'], getline(1, '$'))
823
824 " During visual block append, if the cursor is moved before the start of the
825 " block, then the new text should be appended there.
826 %d _
827 call setline(1, ['aaa', 'bbb', 'ccc'])
828 exe "normal $\<C-V>2jA\<Left>x"
Bram Moolenaar4067bd32021-06-29 18:54:35 +0200829 call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$'))
Yegappan Lakshmanan59b26232021-06-05 20:59:22 +0200830 " Repeat the previous test but use 'l' to move the cursor instead of '$'
831 call setline(1, ['aaa', 'bbb', 'ccc'])
832 exe "normal! gg2l\<C-V>2jA\<Left>x"
833 call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$'))
Bram Moolenaar3e72dca2021-05-29 16:30:12 +0200834
835 " Change a characterwise motion to a blockwise motion using CTRL-V
836 %d _
837 call setline(1, ['123', '456', '789'])
838 exe "normal ld\<C-V>j"
839 call assert_equal(['13', '46', '789'], getline(1, '$'))
840
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +0200841 " Test from ':help v_b_I_example'
842 %d _
843 setlocal tabstop=8 shiftwidth=4
844 let lines =<< trim END
845 abcdefghijklmnopqrstuvwxyz
846 abc defghijklmnopqrstuvwxyz
847 abcdef ghi jklmnopqrstuvwxyz
848 abcdefghijklmnopqrstuvwxyz
849 END
850 call setline(1, lines)
851 exe "normal ggfo\<C-V>3jISTRING"
852 let expected =<< trim END
853 abcdefghijklmnSTRINGopqrstuvwxyz
854 abc STRING defghijklmnopqrstuvwxyz
855 abcdef ghi STRING jklmnopqrstuvwxyz
856 abcdefghijklmnSTRINGopqrstuvwxyz
857 END
858 call assert_equal(expected, getline(1, '$'))
859
860 " Test from ':help v_b_A_example'
861 %d _
862 let lines =<< trim END
863 abcdefghijklmnopqrstuvwxyz
864 abc defghijklmnopqrstuvwxyz
865 abcdef ghi jklmnopqrstuvwxyz
866 abcdefghijklmnopqrstuvwxyz
867 END
868 call setline(1, lines)
869 exe "normal ggfo\<C-V>3j$ASTRING"
870 let expected =<< trim END
871 abcdefghijklmnopqrstuvwxyzSTRING
872 abc defghijklmnopqrstuvwxyzSTRING
873 abcdef ghi jklmnopqrstuvwxyzSTRING
874 abcdefghijklmnopqrstuvwxyzSTRING
875 END
876 call assert_equal(expected, getline(1, '$'))
877
878 " Test from ':help v_b_<_example'
879 %d _
880 let lines =<< trim END
881 abcdefghijklmnopqrstuvwxyz
882 abc defghijklmnopqrstuvwxyz
883 abcdef ghi jklmnopqrstuvwxyz
884 abcdefghijklmnopqrstuvwxyz
885 END
886 call setline(1, lines)
887 exe "normal ggfo\<C-V>3j3l<.."
888 let expected =<< trim END
889 abcdefghijklmnopqrstuvwxyz
890 abc defghijklmnopqrstuvwxyz
891 abcdef ghi jklmnopqrstuvwxyz
892 abcdefghijklmnopqrstuvwxyz
893 END
894 call assert_equal(expected, getline(1, '$'))
895
896 " Test from ':help v_b_>_example'
897 %d _
898 let lines =<< trim END
899 abcdefghijklmnopqrstuvwxyz
900 abc defghijklmnopqrstuvwxyz
901 abcdef ghi jklmnopqrstuvwxyz
902 abcdefghijklmnopqrstuvwxyz
903 END
904 call setline(1, lines)
905 exe "normal ggfo\<C-V>3j>.."
906 let expected =<< trim END
907 abcdefghijklmn opqrstuvwxyz
908 abc defghijklmnopqrstuvwxyz
909 abcdef ghi jklmnopqrstuvwxyz
910 abcdefghijklmn opqrstuvwxyz
911 END
912 call assert_equal(expected, getline(1, '$'))
913
914 " Test from ':help v_b_r_example'
915 %d _
916 let lines =<< trim END
917 abcdefghijklmnopqrstuvwxyz
918 abc defghijklmnopqrstuvwxyz
919 abcdef ghi jklmnopqrstuvwxyz
920 abcdefghijklmnopqrstuvwxyz
921 END
922 call setline(1, lines)
923 exe "normal ggfo\<C-V>5l3jrX"
924 let expected =<< trim END
925 abcdefghijklmnXXXXXXuvwxyz
926 abc XXXXXXhijklmnopqrstuvwxyz
927 abcdef ghi XXXXXX jklmnopqrstuvwxyz
928 abcdefghijklmnXXXXXXuvwxyz
929 END
930 call assert_equal(expected, getline(1, '$'))
931
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100932 bwipe!
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +0200933 set tabstop& shiftwidth&
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100934endfunc
935
Bram Moolenaar21492742021-06-04 21:57:57 +0200936func Test_visual_force_motion_feedkeys()
937 onoremap <expr> i- execute('let g:mode = mode(1)')->slice(0, 0)
938 call feedkeys('dvi-', 'x')
939 call assert_equal('nov', g:mode)
940 call feedkeys('di-', 'x')
941 call assert_equal('no', g:mode)
942 ounmap i-
943endfunc
944
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +0100945" Test block-insert using cursor keys for movement
946func Test_visual_block_insert_cursor_keys()
947 new
948 call append(0, ['aaaaaa', 'bbbbbb', 'cccccc', 'dddddd'])
949 call cursor(1, 1)
950
951 exe "norm! l\<C-V>jjjlllI\<Right>\<Right> \<Esc>"
952 call assert_equal(['aaa aaa', 'bbb bbb', 'ccc ccc', 'ddd ddd'],
953 \ getline(1, 4))
954
955 call deletebufline('', 1, '$')
956 call setline(1, ['xaaa', 'bbbb', 'cccc', 'dddd'])
957 call cursor(1, 1)
958 exe "norm! \<C-V>jjjI<>\<Left>p\<Esc>"
959 call assert_equal(['<p>xaaa', '<p>bbbb', '<p>cccc', '<p>dddd'],
960 \ getline(1, 4))
961 bwipe!
962endfunc
963
964func Test_visual_block_create()
965 new
966 call append(0, '')
967 " Test for Visual block was created with the last <C-v>$
968 call setline(1, ['A23', '4567'])
969 call cursor(1, 1)
970 exe "norm! l\<C-V>j$Aab\<Esc>"
971 call assert_equal(['A23ab', '4567ab'], getline(1, 2))
972
973 " Test for Visual block was created with the middle <C-v>$ (1)
974 call deletebufline('', 1, '$')
975 call setline(1, ['B23', '4567'])
976 call cursor(1, 1)
977 exe "norm! l\<C-V>j$hAab\<Esc>"
978 call assert_equal(['B23 ab', '4567ab'], getline(1, 2))
979
980 " Test for Visual block was created with the middle <C-v>$ (2)
981 call deletebufline('', 1, '$')
982 call setline(1, ['C23', '4567'])
983 call cursor(1, 1)
984 exe "norm! l\<C-V>j$hhAab\<Esc>"
985 call assert_equal(['C23ab', '456ab7'], getline(1, 2))
986 bwipe!
987endfunc
988
989" Test for Visual block insert when virtualedit=all
990func Test_virtualedit_visual_block()
991 set ve=all
992 new
993 call append(0, ["\t\tline1", "\t\tline2", "\t\tline3"])
994 call cursor(1, 1)
995 exe "norm! 07l\<C-V>jjIx\<Esc>"
996 call assert_equal([" x \tline1",
997 \ " x \tline2",
998 \ " x \tline3"], getline(1, 3))
999
1000 " Test for Visual block append when virtualedit=all
1001 exe "norm! 012l\<C-v>jjAx\<Esc>"
1002 call assert_equal([' x x line1',
1003 \ ' x x line2',
1004 \ ' x x line3'], getline(1, 3))
1005 set ve=
1006 bwipe!
1007endfunc
1008
1009" Test for changing case
1010func Test_visual_change_case()
1011 new
zeertzjqe7102202024-02-13 20:32:04 +01001012 " gUe must uppercase a whole word, also when ß changes to
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +01001013 exe "normal Gothe youtußeuu end\<Esc>Ypk0wgUe\r"
1014 " gUfx must uppercase until x, inclusive.
1015 exe "normal O- youßtußexu -\<Esc>0fogUfx\r"
1016 " VU must uppercase a whole line
1017 exe "normal YpkVU\r"
1018 " same, when it's the last line in the buffer
1019 exe "normal YPGi111\<Esc>VUddP\r"
1020 " Uppercase two lines
1021 exe "normal Oblah di\rdoh dut\<Esc>VkUj\r"
1022 " Uppercase part of two lines
1023 exe "normal ddppi333\<Esc>k0i222\<Esc>fyllvjfuUk"
glepnirbd1232a2024-02-12 22:14:53 +01001024 call assert_equal(['the YOUTUẞEUU end', '- yOUẞTUẞEXu -',
1025 \ 'THE YOUTUẞEUU END', '111THE YOUTUẞEUU END', 'BLAH DI', 'DOH DUT',
1026 \ '222the yoUTUẞEUU END', '333THE YOUTUßeuu end'], getline(2, '$'))
Bram Moolenaar1f3e7d32019-12-06 20:43:36 +01001027 bwipe!
1028endfunc
1029
1030" Test for Visual replace using Enter or NL
1031func Test_visual_replace_crnl()
1032 new
1033 exe "normal G3o123456789\e2k05l\<C-V>2jr\r"
1034 exe "normal G3o98765\e2k02l\<C-V>2jr\<C-V>\r\n"
1035 exe "normal G3o123456789\e2k05l\<C-V>2jr\n"
1036 exe "normal G3o98765\e2k02l\<C-V>2jr\<C-V>\n"
1037 call assert_equal(['12345', '789', '12345', '789', '12345', '789', "98\r65",
1038 \ "98\r65", "98\r65", '12345', '789', '12345', '789', '12345', '789',
1039 \ "98\n65", "98\n65", "98\n65"], getline(2, '$'))
1040 bwipe!
1041endfunc
1042
1043func Test_ve_block_curpos()
1044 new
1045 " Test cursor position. When ve=block and Visual block mode and $gj
1046 call append(0, ['12345', '789'])
1047 call cursor(1, 3)
1048 set virtualedit=block
1049 exe "norm! \<C-V>$gj\<Esc>"
1050 call assert_equal([0, 2, 4, 0], getpos("'>"))
1051 set virtualedit=
1052 bwipe!
1053endfunc
1054
1055" Test for block_insert when replacing spaces in front of the a with tabs
1056func Test_block_insert_replace_tabs()
1057 new
1058 set ts=8 sts=4 sw=4
1059 call append(0, ["#define BO_ALL\t 0x0001",
1060 \ "#define BO_BS\t 0x0002",
1061 \ "#define BO_CRSR\t 0x0004"])
1062 call cursor(1, 1)
1063 exe "norm! f0\<C-V>2jI\<tab>\<esc>"
1064 call assert_equal([
1065 \ "#define BO_ALL\t\t0x0001",
1066 \ "#define BO_BS\t \t0x0002",
1067 \ "#define BO_CRSR\t \t0x0004", ''], getline(1, '$'))
1068 set ts& sts& sw&
1069 bwipe!
1070endfunc
1071
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001072" Test for * register in :
1073func Test_star_register()
1074 call assert_fails('*bfirst', 'E16:')
1075 new
1076 call setline(1, ['foo', 'bar', 'baz', 'qux'])
1077 exe "normal jVj\<ESC>"
1078 *yank r
1079 call assert_equal("bar\nbaz\n", @r)
1080
1081 delmarks < >
1082 call assert_fails('*yank', 'E20:')
Christian Brabandtc9a1e252025-01-11 15:25:00 +01001083 bw!
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01001084endfunc
1085
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01001086" Test for changing text in visual mode with 'exclusive' selection
1087func Test_exclusive_selection()
1088 new
1089 call setline(1, ['one', 'two'])
1090 set selection=exclusive
1091 call feedkeys("vwcabc", 'xt')
1092 call assert_equal('abctwo', getline(1))
1093 call setline(1, ["\tone"])
1094 set virtualedit=all
1095 call feedkeys('0v2lcl', 'xt')
1096 call assert_equal('l one', getline(1))
1097 set virtualedit&
1098 set selection&
Christian Brabandtc9a1e252025-01-11 15:25:00 +01001099 bw!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01001100endfunc
1101
Jim Zhouc8cce712025-03-05 20:47:29 +01001102" Test for inclusive motion in visual mode with 'exclusive' selection
1103func Test_inclusive_motion_selection_exclusive()
1104 func s:compare_exclu_inclu(line, keys, expected_exclu)
1105 let msg = "data: '" . a:line . "' operation: '" . a:keys . "'"
1106 call setline(1, a:line)
1107 set selection=exclusive
1108 call feedkeys(a:keys, 'xt')
1109 call assert_equal(a:expected_exclu, getpos('.'), msg)
1110 let pos_ex = col('.')
1111 set selection=inclusive
1112 call feedkeys(a:keys, 'xt')
1113 let pos_in = col('.')
1114 call assert_equal(1, pos_ex - pos_in, msg)
1115 endfunc
1116
1117 new
1118 " Test 'e' motion
1119 set selection=exclusive
1120 call setline(1, 'eins zwei drei')
1121 norm! ggvey
1122 call assert_equal('eins', @")
1123 call setline(1, 'abc(abc)abc')
1124 norm! ggveeed
1125 call assert_equal(')abc', getline(1))
1126 call setline(1, 'abc(abc)abc')
1127 norm! gg3lvey
1128 call assert_equal('(abc', @")
1129 call s:compare_exclu_inclu('abc(abc)abc', 'ggveee', [0, 1, 8, 0])
1130 " Test 'f' motion
1131 call s:compare_exclu_inclu('geschwindigkeit', 'ggvfefe', [0, 1, 14, 0])
1132 call s:compare_exclu_inclu('loooooooooooong', 'ggv2fo2fo2fo', [0, 1, 8, 0])
1133 " Test 't' motion
1134 call s:compare_exclu_inclu('geschwindigkeit', 'ggv2te', [0, 1, 13, 0])
1135 call s:compare_exclu_inclu('loooooooooooong', 'gglv2to2to2to', [0, 1, 6, 0])
1136 " Test ';' motion
1137 call s:compare_exclu_inclu('geschwindigkeit', 'ggvfi;;', [0, 1, 15, 0])
1138 call s:compare_exclu_inclu('geschwindigkeit', 'ggvti;;', [0, 1, 14, 0])
1139 call s:compare_exclu_inclu('loooooooooooong', 'ggv2fo;;', [0, 1, 6, 0])
1140 call s:compare_exclu_inclu('loooooooooooong', 'ggvl2to;;', [0, 1, 6, 0])
1141 " Clean up
1142 set selection&
1143 bw!
1144endfunc
1145
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001146" Test for starting linewise visual with a count.
1147" This test needs to be run without any previous visual mode. Otherwise the
1148" count will use the count from the previous visual mode.
1149func Test_linewise_visual_with_count()
1150 let after =<< trim [CODE]
1151 call setline(1, ['one', 'two', 'three', 'four'])
1152 norm! 3Vy
1153 call assert_equal("one\ntwo\nthree\n", @")
1154 call writefile(v:errors, 'Xtestout')
1155 qall!
1156 [CODE]
1157 if RunVim([], after, '')
1158 call assert_equal([], readfile('Xtestout'))
1159 call delete('Xtestout')
1160 endif
1161endfunc
1162
1163" Test for starting characterwise visual with a count.
1164" This test needs to be run without any previous visual mode. Otherwise the
1165" count will use the count from the previous visual mode.
1166func Test_characterwise_visual_with_count()
1167 let after =<< trim [CODE]
1168 call setline(1, ['one two', 'three'])
1169 norm! l5vy
1170 call assert_equal("ne tw", @")
1171 call writefile(v:errors, 'Xtestout')
1172 qall!
1173 [CODE]
1174 if RunVim([], after, '')
1175 call assert_equal([], readfile('Xtestout'))
1176 call delete('Xtestout')
1177 endif
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01001178endfunc
1179
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001180" Test for visually selecting an inner block (iB)
1181func Test_visual_inner_block()
1182 new
1183 call setline(1, ['one', '{', 'two', '{', 'three', '}', 'four', '}', 'five'])
1184 call cursor(5, 1)
1185 " visually select all the lines in the block and then execute iB
1186 call feedkeys("ViB\<C-C>", 'xt')
1187 call assert_equal([0, 5, 1, 0], getpos("'<"))
1188 call assert_equal([0, 5, 6, 0], getpos("'>"))
1189 " visually select two inner blocks
1190 call feedkeys("ViBiB\<C-C>", 'xt')
1191 call assert_equal([0, 3, 1, 0], getpos("'<"))
1192 call assert_equal([0, 7, 5, 0], getpos("'>"))
1193 " try to select non-existing inner block
1194 call cursor(5, 1)
1195 call assert_beeps('normal ViBiBiB')
zeertzjqc029c132024-03-28 11:37:26 +01001196 " try to select an unclosed inner block
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001197 8,9d
1198 call cursor(5, 1)
1199 call assert_beeps('normal ViBiB')
Christian Brabandtc9a1e252025-01-11 15:25:00 +01001200 bw!
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001201endfunc
1202
Bram Moolenaarcd942772020-08-22 21:08:44 +02001203func Test_visual_put_in_block()
1204 new
1205 call setline(1, ['xxxx', 'yyy', 'zzzz'])
1206 normal 1G2yl
1207 exe "normal 1G2l\<C-V>jjlp"
1208 call assert_equal(['xxxx', 'yxx', 'zzxx'], getline(1, 3))
1209 bwipe!
1210endfunc
1211
Christian Brabandt2fa93842021-05-30 22:17:25 +02001212func Test_visual_put_in_block_using_zp()
1213 new
1214 " paste using zP
Bram Moolenaar94722c52023-01-28 19:19:03 +00001215 call setline(1, ['/path;text', '/path;text', '/path;text', '',
1216 \ '/subdir',
Christian Brabandt2fa93842021-05-30 22:17:25 +02001217 \ '/longsubdir',
1218 \ '/longlongsubdir'])
1219 exe "normal! 5G\<c-v>2j$y"
1220 norm! 1Gf;zP
1221 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1222 %d
1223 " paste using zP
Bram Moolenaar94722c52023-01-28 19:19:03 +00001224 call setline(1, ['/path;text', '/path;text', '/path;text', '',
1225 \ '/subdir',
Christian Brabandt2fa93842021-05-30 22:17:25 +02001226 \ '/longsubdir',
1227 \ '/longlongsubdir'])
1228 exe "normal! 5G\<c-v>2j$y"
1229 norm! 1Gf;hzp
1230 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1231 bwipe!
1232endfunc
1233
Christian Brabandt544a38e2021-06-10 19:39:11 +02001234func Test_visual_put_in_block_using_zy_and_zp()
1235 new
1236
1237 " Test 1) Paste using zp - after the cursor without trailing spaces
Bram Moolenaar94722c52023-01-28 19:19:03 +00001238 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001239 \ 'texttext /subdir columntext',
1240 \ 'texttext /longsubdir columntext',
1241 \ 'texttext /longlongsubdir columntext'])
1242 exe "normal! 5G0f/\<c-v>2jezy"
1243 norm! 1G0f;hzp
1244 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1245
1246 " Test 2) Paste using zP - in front of the cursor without trailing spaces
1247 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001248 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001249 \ 'texttext /subdir columntext',
1250 \ 'texttext /longsubdir columntext',
1251 \ 'texttext /longlongsubdir columntext'])
1252 exe "normal! 5G0f/\<c-v>2jezy"
1253 norm! 1G0f;zP
1254 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1255
1256 " Test 3) Paste using p - with trailing spaces
1257 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001258 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001259 \ 'texttext /subdir columntext',
1260 \ 'texttext /longsubdir columntext',
1261 \ 'texttext /longlongsubdir columntext'])
1262 exe "normal! 5G0f/\<c-v>2jezy"
1263 norm! 1G0f;hp
1264 call assert_equal(['/path/subdir ;text', '/path/longsubdir ;text', '/path/longlongsubdir;text'], getline(1, 3))
1265
1266 " Test 4) Paste using P - with trailing spaces
1267 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001268 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001269 \ 'texttext /subdir columntext',
1270 \ 'texttext /longsubdir columntext',
1271 \ 'texttext /longlongsubdir columntext'])
1272 exe "normal! 5G0f/\<c-v>2jezy"
1273 norm! 1G0f;P
1274 call assert_equal(['/path/subdir ;text', '/path/longsubdir ;text', '/path/longlongsubdir;text'], getline(1, 3))
1275
1276 " Test 5) Yank with spaces inside the block
1277 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001278 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001279 \ 'texttext /sub dir/ columntext',
1280 \ 'texttext /lon gsubdir/ columntext',
1281 \ 'texttext /lon glongsubdir/ columntext'])
1282 exe "normal! 5G0f/\<c-v>2jf/zy"
1283 norm! 1G0f;zP
1284 call assert_equal(['/path/sub dir/;text', '/path/lon gsubdir/;text', '/path/lon glongsubdir/;text'], getline(1, 3))
1285 bwipe!
1286endfunc
1287
Bram Moolenaar7d7bcc62021-06-28 21:54:27 +02001288func Test_visual_put_blockedit_zy_and_zp()
1289 new
1290
1291 call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
1292 exe "normal! gg0\<c-v>2j$zy"
1293 norm! 5gg0zP
1294 call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
1295 "
1296 " now with blockmode editing
1297 sil %d
1298 :set ve=block
1299 call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
1300 exe "normal! gg0\<c-v>2j$zy"
1301 norm! 5gg0zP
1302 call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
1303 set ve&vim
1304 bw!
1305endfunc
1306
Bram Moolenaar44db8212022-01-25 21:26:17 +00001307func Test_visual_block_yank_zy()
1308 new
1309 " this was reading before the start of the line
1310 exe "norm o\<C-T>\<Esc>\<C-V>zy"
1311 bwipe!
1312endfunc
1313
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001314func Test_visual_block_with_virtualedit()
1315 CheckScreendump
1316
1317 let lines =<< trim END
1318 call setline(1, ['aaaaaa', 'bbbb', 'cc'])
1319 set virtualedit=block
1320 normal G
1321 END
Bram Moolenaar5b148ef2022-10-15 21:35:56 +01001322 call writefile(lines, 'XTest_block', 'D')
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001323
1324 let buf = RunVimInTerminal('-S XTest_block', {'rows': 8, 'cols': 50})
1325 call term_sendkeys(buf, "\<C-V>gg$")
1326 call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit', {})
1327
Bram Moolenaarb17ab862021-07-03 22:15:17 +02001328 call term_sendkeys(buf, "\<Esc>gg\<C-V>G$")
1329 call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit2', {})
1330
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001331 " clean up
1332 call term_sendkeys(buf, "\<Esc>")
1333 call StopVimInTerminal(buf)
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001334endfunc
1335
Bram Moolenaar615ddd52021-11-17 18:00:31 +00001336func Test_visual_block_ctrl_w_f()
dundargocc57b5bc2022-11-02 13:30:51 +00001337 " Empty block selected in new buffer should not result in an error.
Bram Moolenaar615ddd52021-11-17 18:00:31 +00001338 au! BufNew foo sil norm f
1339 edit foo
1340
1341 au! BufNew
1342endfunc
1343
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001344func Test_visual_block_append_invalid_char()
1345 " this was going over the end of the line
Bram Moolenaar262898a2022-01-17 17:52:22 +00001346 set isprint=@,161-255
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001347 new
1348 call setline(1, [' let xxx', 'xxxxxˆ', 'xxxxxxxxxxx'])
1349 exe "normal 0\<C-V>jjA-\<Esc>"
1350 call assert_equal([' - let xxx', 'xxxxx ', 'xxxxxxxx-xxx'], getline(1, 3))
1351 bwipe!
Bram Moolenaar262898a2022-01-17 17:52:22 +00001352 set isprint&
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001353endfunc
1354
Bram Moolenaar7ce5b2b2022-05-16 19:40:59 +01001355func Test_visual_block_with_substitute()
1356 " this was reading beyond the end of the line
1357 new
1358 norm a0)
1359 sil! norm  O
1360 s/)
1361 sil! norm 
1362 bwipe!
1363endfunc
1364
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001365func Test_visual_reselect_with_count()
Bram Moolenaar8f531662023-02-01 17:33:18 +00001366 enew
1367 call setline(1, ['aaaaaa', ' bbbb', ' bbbb'])
1368 exe "normal! 2Gw\<C-V>jed"
1369 exe "normal! gg0lP"
1370 call assert_equal(['abbbbaaaaa', 'bbbb ', ' '], getline(1, '$'))
1371
1372 exe "normal! 1vr."
1373 call assert_equal(['a....aaaaa', '✗.... ', ' '], getline(1, '$'))
1374
1375 bwipe!
1376
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001377 " this was causing an illegal memory access
1378 let lines =<< trim END
1379
1380
1381
1382 :
1383 r<sfile>
1384 exe "%norm e3\<c-v>kr\t"
1385 :
1386
1387 :
1388 END
Bram Moolenaar5b148ef2022-10-15 21:35:56 +01001389 call writefile(lines, 'XvisualReselect', 'D')
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001390 source XvisualReselect
1391
1392 bwipe!
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001393endfunc
1394
Bram Moolenaar79c11e32023-01-10 17:29:29 +00001395func Test_visual_reselect_exclusive()
1396 new
1397 call setline(1, ['abcde', 'abcde'])
1398 set selection=exclusive
1399 normal 1G0viwd
1400 normal 2G01vd
1401 call assert_equal(['', ''], getline(1, 2))
1402
1403 set selection&
1404 bwipe!
1405endfunc
1406
Bram Moolenaar57df9e82022-01-20 12:10:48 +00001407func Test_visual_block_insert_round_off()
1408 new
1409 " The number of characters are tuned to fill a 4096 byte allocated block,
1410 " so that valgrind reports going over the end.
1411 call setline(1, ['xxxxx', repeat('0', 1350), "\t", repeat('x', 60)])
1412 exe "normal gg0\<C-V>GI" .. repeat('0', 1320) .. "\<Esc>"
1413 bwipe!
1414endfunc
1415
Bram Moolenaar05b27612022-01-20 13:32:50 +00001416" this was causing an ml_get error
1417func Test_visual_exchange_windows()
1418 enew!
1419 new
1420 call setline(1, ['foo', 'bar'])
1421 exe "normal G\<C-V>gg\<C-W>\<C-X>OO\<Esc>"
1422 bwipe!
1423 bwipe!
1424endfunc
1425
Bram Moolenaardc5490e2022-01-25 13:52:53 +00001426" this was leaving the end of the Visual area beyond the end of a line
1427func Test_visual_ex_copy_line()
1428 new
1429 call setline(1, ["aaa", "bbbbbbbbbxbb"])
1430 /x
1431 exe "normal ggvjfxO"
1432 t0
1433 normal gNU
1434 bwipe!
1435endfunc
1436
Bram Moolenaar8d02ce12022-01-25 18:24:00 +00001437" This was leaving the end of the Visual area beyond the end of a line.
1438" Set 'undolevels' to start a new undo block.
1439func Test_visual_undo_deletes_last_line()
1440 new
1441 call setline(1, ["aaa", "ccc", "dyd"])
1442 set undolevels=100
1443 exe "normal obbbbbbbbbxbb\<Esc>"
1444 set undolevels=100
1445 /y
1446 exe "normal ggvjfxO"
1447 undo
1448 normal gNU
Shougo Matsushitafb552072022-01-28 16:01:13 +00001449
Bram Moolenaar8d02ce12022-01-25 18:24:00 +00001450 bwipe!
1451endfunc
1452
Shougo Matsushitafb552072022-01-28 16:01:13 +00001453func Test_visual_paste()
1454 new
1455
1456 " v_p overwrites unnamed register.
1457 call setline(1, ['xxxx'])
1458 call setreg('"', 'foo')
1459 call setreg('-', 'bar')
zeertzjq6bf821e2022-02-07 10:33:20 +00001460 normal gg0vp
1461 call assert_equal('x', @")
1462 call assert_equal('x', @-)
1463 call assert_equal('fooxxx', getline(1))
1464 normal $vp
1465 call assert_equal('x', @")
1466 call assert_equal('x', @-)
1467 call assert_equal('fooxxx', getline(1))
1468 " Test with a different register as unnamed register.
1469 call setline(2, ['baz'])
1470 normal 2gg0"rD
1471 call assert_equal('baz', @")
1472 normal gg0vp
1473 call assert_equal('f', @")
1474 call assert_equal('f', @-)
1475 call assert_equal('bazooxxx', getline(1))
1476 normal $vp
1477 call assert_equal('x', @")
1478 call assert_equal('x', @-)
1479 call assert_equal('bazooxxf', getline(1))
Shougo Matsushitafb552072022-01-28 16:01:13 +00001480
Shougo Matsushita509142a2022-05-06 11:45:09 +01001481 bwipe!
1482endfunc
1483
1484func Test_visual_paste_clipboard()
1485 CheckFeature clipboard_working
1486
1487 if has('gui')
1488 " auto select feature breaks tests
1489 set guioptions-=a
1490 endif
1491
1492 " v_P does not overwrite unnamed register.
1493 call setline(1, ['xxxx'])
1494 call setreg('"', 'foo')
1495 call setreg('-', 'bar')
1496 normal gg0vP
1497 call assert_equal('foo', @")
1498 call assert_equal('bar', @-)
1499 call assert_equal('fooxxx', getline(1))
1500 normal $vP
1501 call assert_equal('foo', @")
1502 call assert_equal('bar', @-)
1503 call assert_equal('fooxxfoo', getline(1))
1504 " Test with a different register as unnamed register.
1505 call setline(2, ['baz'])
1506 normal 2gg0"rD
1507 call assert_equal('baz', @")
1508 normal gg0vP
1509 call assert_equal('baz', @")
1510 call assert_equal('bar', @-)
1511 call assert_equal('bazooxxfoo', getline(1))
1512 normal $vP
1513 call assert_equal('baz', @")
1514 call assert_equal('bar', @-)
1515 call assert_equal('bazooxxfobaz', getline(1))
1516
1517 " Test for unnamed clipboard
1518 set clipboard=unnamed
1519 call setline(1, ['xxxx'])
1520 call setreg('"', 'foo')
1521 call setreg('-', 'bar')
1522 call setreg('*', 'baz')
1523 normal gg0vP
1524 call assert_equal('foo', @")
1525 call assert_equal('bar', @-)
1526 call assert_equal('baz', @*)
1527 call assert_equal('bazxxx', getline(1))
1528
1529 " Test for unnamedplus clipboard
1530 if has('unnamedplus')
1531 set clipboard=unnamedplus
Shougo Matsushitafb552072022-01-28 16:01:13 +00001532 call setline(1, ['xxxx'])
1533 call setreg('"', 'foo')
1534 call setreg('-', 'bar')
Shougo Matsushita509142a2022-05-06 11:45:09 +01001535 call setreg('+', 'baz')
zeertzjq6bf821e2022-02-07 10:33:20 +00001536 normal gg0vP
1537 call assert_equal('foo', @")
Shougo Matsushita509142a2022-05-06 11:45:09 +01001538 call assert_equal('bar', @-)
1539 call assert_equal('baz', @+)
1540 call assert_equal('bazxxx', getline(1))
Shougo Matsushitafb552072022-01-28 16:01:13 +00001541 endif
1542
Shougo Matsushita509142a2022-05-06 11:45:09 +01001543 set clipboard&
1544 if has('gui')
1545 set guioptions&
1546 endif
Shougo Matsushitafb552072022-01-28 16:01:13 +00001547 bwipe!
1548endfunc
Christian Brabandt544a38e2021-06-10 19:39:11 +02001549
Bram Moolenaar3d51ce12022-07-01 15:26:15 +01001550func Test_visual_area_adjusted_when_hiding()
1551 " The Visual area ended after the end of the line after :hide
1552 call setline(1, 'xxx')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001553 vsplit Xvaafile
Bram Moolenaar3d51ce12022-07-01 15:26:15 +01001554 call setline(1, 'xxxxxxxx')
1555 norm! $o
1556 hid
1557 norm! zW
1558 bwipe!
1559 bwipe!
1560endfunc
1561
Bram Moolenaarcfeb8a52022-08-13 14:09:44 +01001562func Test_switch_buffer_ends_visual_mode()
1563 enew
1564 call setline(1, 'foo')
1565 set hidden
1566 set virtualedit=all
1567 let buf1 = bufnr()
1568 enew
1569 let buf2 = bufnr()
1570 call setline(1, ['', '', '', ''])
1571 call cursor(4, 5)
1572 call feedkeys("\<C-V>3k4h", 'xt')
1573 exe 'buffer' buf1
1574 call assert_equal('n', mode())
1575
1576 set nohidden
1577 set virtualedit=
1578 bwipe!
1579 exe 'bwipe!' buf2
1580endfunc
1581
Pavel Mayorove1121b12023-02-20 14:35:20 +00001582" Check fix for the heap-based buffer overflow bug found in the function
1583" utfc_ptr2len and reported at
1584" https://huntr.dev/bounties/ae933869-a1ec-402a-bbea-d51764c6618e
1585func Test_heap_buffer_overflow()
1586 enew
1587 set updatecount=0
1588
1589 norm R0
1590 split other
1591 norm R000
1592 exe "norm \<C-V>l"
1593 ball
1594 call assert_equal(getpos("."), getpos("v"))
1595 call assert_equal('n', mode())
1596 norm zW
1597
1598 %bwipe!
1599 set updatecount&
1600endfunc
1601
zeertzjq8fc6a1d2023-08-20 18:12:54 +02001602" Test Visual highlight with cursor at end of screen line and 'showbreak'
1603func Test_visual_hl_with_showbreak()
1604 CheckScreendump
1605
Yee Cheng Chine70587d2025-02-13 20:55:45 +01001606 " Redraw at the end is necessary due to https://github.com/vim/vim/issues/16620
zeertzjq8fc6a1d2023-08-20 18:12:54 +02001607 let lines =<< trim END
1608 setlocal showbreak=+
1609 call setline(1, repeat('a', &columns + 10))
1610 normal g$v4lo
Yee Cheng Chine70587d2025-02-13 20:55:45 +01001611 redraw
zeertzjq8fc6a1d2023-08-20 18:12:54 +02001612 END
1613 call writefile(lines, 'XTest_visual_sbr', 'D')
1614
1615 let buf = RunVimInTerminal('-S XTest_visual_sbr', {'rows': 6, 'cols': 50})
1616 call VerifyScreenDump(buf, 'Test_visual_hl_with_showbreak', {})
1617
1618 " clean up
1619 call term_sendkeys(buf, "\<Esc>")
1620 call StopVimInTerminal(buf)
1621endfunc
Pavel Mayorove1121b12023-02-20 14:35:20 +00001622
Christian Brabandt476733f2023-09-19 20:41:51 +02001623func Test_Visual_r_CTRL_C()
1624 new
1625 " visual r_cmd
1626 call setline(1, [' '])
1627 call feedkeys("\<c-v>$r\<c-c>", 'tx')
1628 call assert_equal([''], getline(1, 1))
1629
1630 " visual gr_cmd
1631 call setline(1, [' '])
1632 call feedkeys("\<c-v>$gr\<c-c>", 'tx')
1633 call assert_equal([''], getline(1, 1))
1634 bw!
zeertzjqec149242023-12-19 20:28:31 +01001635endfunc
1636
1637func Test_visual_drag_out_of_window()
1638 rightbelow vnew
1639 call setline(1, '123456789')
1640 set mouse=a
1641 func ClickExpr(off)
1642 call test_setmouse(1, getwininfo(win_getid())[0].wincol + a:off)
1643 return "\<LeftMouse>"
1644 endfunc
1645 func DragExpr(off)
1646 call test_setmouse(1, getwininfo(win_getid())[0].wincol + a:off)
1647 return "\<LeftDrag>"
1648 endfunc
1649
1650 nnoremap <expr> <F2> ClickExpr(5)
1651 nnoremap <expr> <F3> DragExpr(-1)
1652 redraw
1653 call feedkeys("\<F2>\<F3>\<LeftRelease>", 'tx')
1654 call assert_equal([1, 6], [col('.'), col('v')])
1655 call feedkeys("\<Esc>", 'tx')
1656
1657 nnoremap <expr> <F2> ClickExpr(6)
1658 nnoremap <expr> <F3> DragExpr(-2)
1659 redraw
1660 call feedkeys("\<F2>\<F3>\<LeftRelease>", 'tx')
1661 call assert_equal([1, 7], [col('.'), col('v')])
1662 call feedkeys("\<Esc>", 'tx')
1663
1664 nunmap <F2>
1665 nunmap <F3>
1666 delfunc ClickExpr
1667 delfunc DragExpr
1668 set mouse&
1669 bwipe!
1670endfunc
Christian Brabandt476733f2023-09-19 20:41:51 +02001671
Christian Brabandt7c71db32024-01-22 20:12:34 +01001672func Test_visual_substitute_visual()
1673 new
1674 call setline(1, ['one', 'two', 'three'])
1675 call feedkeys("Gk\<C-V>j$:s/\\%V\\_.*\\%V/foobar\<CR>", 'tx')
1676 call assert_equal(['one', 'foobar'], getline(1, '$'))
1677 bwipe!
1678endfunc
1679
zeertzjq701ad502024-05-23 07:47:55 +02001680func Test_virtualedit_exclusive_selection()
1681 new
1682 set virtualedit=all selection=exclusive
1683
1684 call setline(1, "a\tb")
1685 normal! 0v8ly
1686 call assert_equal("a\t", getreg('"'))
1687 normal! 0v6ly
1688 call assert_equal('a ', getreg('"'))
1689 normal! 06lv2ly
1690 call assert_equal(' ', getreg('"'))
1691
1692 set virtualedit& selection&
1693 bwipe!
1694endfunc
1695
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001696func Test_visual_getregion()
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001697 let lines =<< trim END
1698 new
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001699
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001700 call setline(1, ['one', 'two', 'three'])
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001701
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001702 #" Visual mode
1703 call cursor(1, 1)
1704 call feedkeys("\<ESC>vjl", 'tx')
zeertzjqc95e64f2024-05-20 14:00:31 +02001705
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001706 call assert_equal(['one', 'tw'],
1707 \ 'v'->getpos()->getregion(getpos('.')))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001708 call assert_equal([
1709 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1710 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
1711 \ ],
1712 \ 'v'->getpos()->getregionpos(getpos('.')))
zeertzjqc95e64f2024-05-20 14:00:31 +02001713
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001714 call assert_equal(['one', 'tw'],
1715 \ '.'->getpos()->getregion(getpos('v')))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001716 call assert_equal([
1717 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1718 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
1719 \ ],
1720 \ '.'->getpos()->getregionpos(getpos('v')))
zeertzjqc95e64f2024-05-20 14:00:31 +02001721
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001722 call assert_equal(['o'],
1723 \ 'v'->getpos()->getregion(getpos('v')))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001724 call assert_equal([
1725 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
1726 \ ],
1727 \ 'v'->getpos()->getregionpos(getpos('v')))
zeertzjqc95e64f2024-05-20 14:00:31 +02001728
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001729 call assert_equal(['w'],
1730 \ '.'->getpos()->getregion(getpos('.'), {'type': 'v' }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001731 call assert_equal([
1732 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 0]],
1733 \ ],
1734 \ '.'->getpos()->getregionpos(getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02001735
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001736 call assert_equal(['one', 'two'],
1737 \ getpos('.')->getregion(getpos('v'), {'type': 'V' }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001738 call assert_equal([
1739 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1740 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1741 \ ],
1742 \ getpos('.')->getregionpos(getpos('v'), {'type': 'V' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02001743
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001744 call assert_equal(['on', 'tw'],
1745 \ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001746 call assert_equal([
1747 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
1748 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]],
1749 \ ],
1750 \ getpos('.')->getregionpos(getpos('v'), {'type': "\<C-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001751
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001752 #" Line visual mode
1753 call cursor(1, 1)
1754 call feedkeys("\<ESC>Vl", 'tx')
1755 call assert_equal(['one'],
1756 \ getregion(getpos('v'), getpos('.'), {'type': 'V' }))
1757 call assert_equal(['one'],
1758 \ getregion(getpos('.'), getpos('v'), {'type': 'V' }))
1759 call assert_equal(['one'],
1760 \ getregion(getpos('v'), getpos('v'), {'type': 'V' }))
1761 call assert_equal(['one'],
1762 \ getregion(getpos('.'), getpos('.'), {'type': 'V' }))
1763 call assert_equal(['on'],
1764 \ getpos('.')->getregion(getpos('v'), {'type': 'v' }))
1765 call assert_equal(['on'],
1766 \ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001767
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001768 #" Block visual mode
1769 call cursor(1, 1)
1770 call feedkeys("\<ESC>\<C-v>ll", 'tx')
1771 call assert_equal(['one'],
1772 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1773 call assert_equal(['one'],
1774 \ getregion(getpos('.'), getpos('v'), {'type': "\<C-v>" }))
1775 call assert_equal(['o'],
1776 \ getregion(getpos('v'), getpos('v'), {'type': "\<C-v>" }))
1777 call assert_equal(['e'],
1778 \ getregion(getpos('.'), getpos('.'), {'type': "\<C-v>" }))
1779 call assert_equal(['one'],
1780 \ '.'->getpos()->getregion(getpos('v'), {'type': 'V' }))
1781 call assert_equal(['one'],
1782 \ '.'->getpos()->getregion(getpos('v'), {'type': 'v' }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001783
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001784 #" Using Marks
1785 call setpos("'a", [0, 2, 3, 0])
1786 call cursor(1, 1)
1787 call assert_equal(['one', 'two'],
1788 \ "'a"->getpos()->getregion(getpos('.'), {'type': 'v' }))
1789 call assert_equal(['one', 'two'],
1790 \ "."->getpos()->getregion(getpos("'a"), {'type': 'v' }))
1791 call assert_equal(['one', 'two'],
1792 \ "."->getpos()->getregion(getpos("'a"), {'type': 'V' }))
1793 call assert_equal(['two'],
1794 \ "'a"->getpos()->getregion(getpos("'a"), {'type': 'V' }))
1795 call assert_equal(['one', 'two'],
1796 \ "."->getpos()->getregion(getpos("'a"), {'type': "\<c-v>" }))
zeertzjq2ffdae72024-05-02 13:06:24 +02001797 call feedkeys("\<ESC>jVj\<ESC>", 'tx')
1798 call assert_equal(['two', 'three'], getregion(getpos("'<"), getpos("'>")))
1799 call assert_equal(['two', 'three'], getregion(getpos("'>"), getpos("'<")))
Shougo Matsushita19b71882024-02-28 22:48:12 +01001800
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001801 #" Using List
1802 call cursor(1, 1)
1803 call assert_equal(['one', 'two'],
1804 \ [0, 2, 3, 0]->getregion(getpos('.'), {'type': 'v' }))
1805 call assert_equal(['one', 'two'],
1806 \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': 'v' }))
1807 call assert_equal(['one', 'two'],
1808 \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': 'V' }))
1809 call assert_equal(['two'],
1810 \ [0, 2, 3, 0]->getregion([0, 2, 3, 0], {'type': 'V' }))
1811 call assert_equal(['one', 'two'],
1812 \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': "\<c-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001813
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001814 #" Multiline with line visual mode
1815 call cursor(1, 1)
1816 call feedkeys("\<ESC>Vjj", 'tx')
1817 call assert_equal(['one', 'two', 'three'],
1818 \ getregion(getpos('v'), getpos('.'), {'type': 'V' }))
zeertzjq2b09de92024-05-24 07:48:51 +02001819 call assert_equal([
1820 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1821 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1822 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1823 \ ],
1824 \ getregionpos(getpos('v'), getpos('.'), {'type': 'V' }))
1825 call assert_equal([
1826 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
1827 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
1828 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 0]],
1829 \ ],
1830 \ getregionpos(getpos('v'), getpos('.'),
1831 \ {'type': 'V', 'eol': v:true }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001832
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001833 #" Multiline with block visual mode
1834 call cursor(1, 1)
1835 call feedkeys("\<ESC>\<C-v>jj", 'tx')
1836 call assert_equal(['o', 't', 't'],
1837 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02001838 call assert_equal([
1839 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
1840 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
1841 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 1, 0]],
1842 \ ],
1843 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001844
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001845 call cursor(1, 1)
1846 call feedkeys("\<ESC>\<C-v>jj$", 'tx')
1847 call assert_equal(['one', 'two', 'three'],
1848 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02001849 call assert_equal([
1850 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1851 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1852 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1853 \ ],
1854 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1855 call assert_equal([
1856 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1857 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1858 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1859 \ ],
1860 \ getregionpos(getpos('v'), getpos('.'),
1861 \ {'type': "\<C-v>", 'eol': v:true }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001862
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001863 #" 'virtualedit'
1864 set virtualedit=all
zeertzjq2b09de92024-05-24 07:48:51 +02001865
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001866 call cursor(1, 1)
1867 call feedkeys("\<ESC>\<C-v>10ljj$", 'tx')
1868 call assert_equal(['one ', 'two ', 'three '],
1869 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02001870 call assert_equal([
1871 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1872 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1873 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1874 \ ],
1875 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1876 call assert_equal([
1877 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 3]],
1878 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 3]],
1879 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 1]],
1880 \ ],
1881 \ getregionpos(getpos('v'), getpos('.'),
1882 \ {'type': "\<C-v>", 'eol': v:true }))
1883
1884 call cursor(3, 5)
1885 call feedkeys("\<ESC>\<C-v>hkk", 'tx')
1886 call assert_equal([' ', ' ', 'ee'],
1887 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1888 call assert_equal([
1889 \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
1890 \ [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
1891 \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
1892 \ ],
1893 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1894 call assert_equal([
1895 \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 2]],
1896 \ [[bufnr('%'), 2, 4, 0], [bufnr('%'), 2, 4, 2]],
1897 \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
1898 \ ],
1899 \ getregionpos(getpos('v'), getpos('.'),
1900 \ {'type': "\<C-v>", 'eol': v:true }))
1901
1902 call cursor(3, 5)
1903 call feedkeys("\<ESC>\<C-v>kk", 'tx')
1904 call assert_equal([' ', ' ', 'e'],
1905 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1906 call assert_equal([
1907 \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
1908 \ [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
1909 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
1910 \ ],
1911 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1912 call assert_equal([
1913 \ [[bufnr('%'), 1, 4, 1], [bufnr('%'), 1, 4, 2]],
1914 \ [[bufnr('%'), 2, 4, 1], [bufnr('%'), 2, 4, 2]],
1915 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
1916 \ ],
1917 \ getregionpos(getpos('v'), getpos('.'),
1918 \ {'type': "\<C-v>", 'eol': v:true }))
1919
1920 call cursor(1, 3)
1921 call feedkeys("\<ESC>vjj4l", 'tx')
1922 call assert_equal(['e', 'two', 'three '],
1923 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1924 call assert_equal([
1925 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
1926 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1927 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1928 \ ],
1929 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1930 call assert_equal([
1931 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
1932 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
1933 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
1934 \ ],
1935 \ getregionpos(getpos('v'), getpos('.'),
1936 \ {'type': 'v', 'eol': v:true }))
1937
1938 call cursor(1, 3)
1939 call feedkeys("\<ESC>lvjj3l", 'tx')
1940 call assert_equal(['', 'two', 'three '],
1941 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1942 call assert_equal([
1943 \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
1944 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1945 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1946 \ ],
1947 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1948 call assert_equal([
1949 \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 0]],
1950 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
1951 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
1952 \ ],
1953 \ getregionpos(getpos('v'), getpos('.'),
1954 \ {'type': 'v', 'eol': v:true }))
1955
1956 call cursor(3, 5)
1957 call feedkeys("\<ESC>v3l", 'tx')
1958 call assert_equal(['e '],
1959 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1960 call assert_equal([
1961 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
1962 \ ],
1963 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1964 call assert_equal([
1965 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 6, 3]],
1966 \ ],
1967 \ getregionpos(getpos('v'), getpos('.'),
1968 \ {'type': 'v', 'eol': v:true }))
1969
1970 call cursor(3, 5)
1971 call feedkeys("\<ESC>lv3l", 'tx')
1972 call assert_equal([' '],
1973 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1974 call assert_equal([
1975 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
1976 \ ],
1977 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1978 call assert_equal([
1979 \ [[bufnr('%'), 3, 6, 0], [bufnr('%'), 3, 6, 4]],
1980 \ ],
1981 \ getregionpos(getpos('v'), getpos('.'),
1982 \ {'type': 'v', 'eol': v:true }))
1983
1984 call cursor(3, 5)
1985 call feedkeys("\<ESC>3lv3l", 'tx')
1986 call assert_equal([' '],
1987 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1988 call assert_equal([
1989 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
1990 \ ],
1991 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1992 call assert_equal([
1993 \ [[bufnr('%'), 3, 6, 2], [bufnr('%'), 3, 6, 6]],
1994 \ ],
1995 \ getregionpos(getpos('v'), getpos('.'),
1996 \ {'type': 'v', 'eol': v:true }))
1997
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001998 set virtualedit&
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001999
zeertzjq26dd09a2024-03-10 15:46:58 +01002000 #" using wrong types for positions
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002001 call cursor(1, 1)
2002 call feedkeys("\<ESC>vjj$", 'tx')
2003 call assert_fails("call getregion(1, 2)", 'E1211:')
2004 call assert_fails("call getregion(getpos('.'), {})", 'E1211:')
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002005 call assert_fails(':echo "."->getpos()->getregion("$", [])', 'E1211:')
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002006 call assert_fails("call getregionpos(1, 2)", 'E1211:')
2007 call assert_fails("call getregionpos(getpos('.'), {})", 'E1211:')
2008 call assert_fails(':echo "."->getpos()->getregionpos("$", [])', 'E1211:')
Shougo Matsushita19b71882024-02-28 22:48:12 +01002009
zeertzjq26dd09a2024-03-10 15:46:58 +01002010 #" using invalid value for "type"
2011 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002012 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
zeertzjqafc22952024-05-24 19:07:12 +02002013 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': 'V0' })", 'E475:')
2016 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': 'V0' })", 'E475:')
2017 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
2018 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
2019 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
2020 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
zeertzjq26dd09a2024-03-10 15:46:58 +01002021
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002022 #" using a mark from another buffer to current buffer
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002023 new
zeertzjq26dd09a2024-03-10 15:46:58 +01002024 LET g:buf = bufnr()
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002025 call setline(1, range(10))
2026 normal! GmA
2027 wincmd p
zeertzjq26dd09a2024-03-10 15:46:58 +01002028 call assert_equal([g:buf, 10, 1, 0], getpos("'A"))
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002029 call assert_equal([], getregion(getpos('.'), getpos("'A"), {'type': 'v' }))
2030 call assert_equal([], getregion(getpos("'A"), getpos('.'), {'type': 'v' }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002031 call assert_equal([], getregionpos(getpos('.'), getpos("'A"), {'type': 'v' }))
2032 call assert_equal([], getregionpos(getpos("'A"), getpos('.'), {'type': 'v' }))
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002033
zeertzjq26dd09a2024-03-10 15:46:58 +01002034 #" using two marks from another buffer
2035 wincmd p
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002036 normal! GmB
2037 wincmd p
zeertzjq26dd09a2024-03-10 15:46:58 +01002038 call assert_equal([g:buf, 10, 1, 0], getpos("'B"))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002039 call assert_equal(['9'],
2040 \ getregion(getpos("'B"), getpos("'A"), {'type': 'v' }))
2041 call assert_equal([
2042 \ [[g:buf, 10, 1, 0], [g:buf, 10, 1, 0]],
2043 \ ],
2044 \ getregionpos(getpos("'B"), getpos("'A"), {'type': 'v' }))
zeertzjq26dd09a2024-03-10 15:46:58 +01002045
2046 #" using two positions from another buffer
2047 for type in ['v', 'V', "\<C-V>"]
2048 for exclusive in [v:false, v:true]
2049 call assert_equal(range(10)->mapnew('string(v:val)'),
zeertzjq5406eb82024-03-11 21:36:42 +01002050 \ getregion([g:buf, 1, 1, 0], [g:buf, 10, 2, 0],
2051 \ {'type': type, 'exclusive': exclusive }))
zeertzjq26dd09a2024-03-10 15:46:58 +01002052 call assert_equal(range(10)->mapnew('string(v:val)'),
zeertzjq5406eb82024-03-11 21:36:42 +01002053 \ getregion([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
2054 \ {'type': type, 'exclusive': exclusive }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002055 call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
2056 \ getregionpos([g:buf, 1, 1, 0], [g:buf, 10, 2, 0],
2057 \ {'type': type, 'exclusive': exclusive }))
2058 call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
2059 \ getregionpos([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
2060 \ {'type': type, 'exclusive': exclusive }))
zeertzjq26dd09a2024-03-10 15:46:58 +01002061 endfor
2062 endfor
2063
2064 #" using invalid positions in buffer
2065 call assert_fails('call getregion([g:buf, 0, 1, 0], [g:buf, 10, 2, 0])', 'E966:')
2066 call assert_fails('call getregion([g:buf, 10, 2, 0], [g:buf, 0, 1, 0])', 'E966:')
2067 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 11, 2, 0])', 'E966:')
2068 call assert_fails('call getregion([g:buf, 11, 2, 0], [g:buf, 1, 1, 0])', 'E966:')
2069 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 0, 0])', 'E964:')
2070 call assert_fails('call getregion([g:buf, 10, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
2071 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 3, 0])', 'E964:')
2072 call assert_fails('call getregion([g:buf, 10, 3, 0], [g:buf, 1, 1, 0])', 'E964:')
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002073 call assert_fails('call getregion([g:buf, 1, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
2074 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 1, 0, 0])', 'E964:')
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002075
2076 #" using invalid buffer
zeertzjq26dd09a2024-03-10 15:46:58 +01002077 call assert_fails('call getregion([10000, 10, 1, 0], [10000, 10, 1, 0])', 'E681:')
2078
2079 exe $':{g:buf}bwipe!'
2080 unlet g:buf
zeertzjq2b09de92024-05-24 07:48:51 +02002081 bwipe!
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002082 END
2083 call v9.CheckLegacyAndVim9Success(lines)
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002084
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002085 let lines =<< trim END
2086 #" Selection in starts or ends in the middle of a multibyte character
2087 new
2088 call setline(1, [
2089 \ "abcdefghijk\u00ab",
2090 \ "\U0001f1e6\u00ab\U0001f1e7\u00ab\U0001f1e8\u00ab\U0001f1e9",
2091 \ "1234567890"
2092 \ ])
zeertzjqc95e64f2024-05-20 14:00:31 +02002093
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002094 call cursor(1, 3)
2095 call feedkeys("\<Esc>\<C-v>ljj", 'xt')
2096 call assert_equal(['cd', "\u00ab ", '34'],
2097 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002098 call assert_equal([
2099 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
2100 \ [[bufnr('%'), 2, 5, 0], [bufnr('%'), 2, 7, 1]],
2101 \ [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 4, 0]],
2102 \ ],
2103 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2104
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002105 call cursor(1, 4)
2106 call feedkeys("\<Esc>\<C-v>ljj", 'xt')
2107 call assert_equal(['de', "\U0001f1e7", '45'],
2108 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002109 call assert_equal([
2110 \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 5, 0]],
2111 \ [[bufnr('%'), 2, 7, 0], [bufnr('%'), 2, 10, 0]],
2112 \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
2113 \ ],
2114 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2115
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002116 call cursor(1, 5)
2117 call feedkeys("\<Esc>\<C-v>jj", 'xt')
2118 call assert_equal(['e', ' ', '5'],
2119 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002120 call assert_equal([
zeertzjqc95e64f2024-05-20 14:00:31 +02002121 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 5, 0]],
zeertzjqef733742024-05-26 18:42:18 +02002122 \ [[bufnr('%'), 2, 7, 1], [bufnr('%'), 2, 7, 2]],
zeertzjqc95e64f2024-05-20 14:00:31 +02002123 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
2124 \ ],
2125 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqef733742024-05-26 18:42:18 +02002126 call assert_equal(['efghijk«', '🇦«🇧«🇨«🇩', '12345'],
2127 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002128 call assert_equal([
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002129 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 13, 0]],
2130 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 22, 0]],
2131 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
2132 \ ],
2133 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002134
zeertzjqef733742024-05-26 18:42:18 +02002135 call cursor(1, 5)
2136 call feedkeys("\<Esc>\<C-v>5l2j", 'xt')
2137 call assert_equal(['efghij', ' «🇨« ', '567890'],
2138 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2139 call assert_equal([
2140 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 10, 0]],
2141 \ [[bufnr('%'), 2, 7, 1], [bufnr('%'), 2, 19, 1]],
2142 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 10, 0]],
2143 \ ],
2144 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2145
2146 call cursor(1, 4)
2147 call feedkeys("\<Esc>\<C-v>02j", 'xt')
2148 call assert_equal(['abcd', '🇦« ', '1234'],
2149 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2150 call assert_equal([
2151 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
2152 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 7, 1]],
2153 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 4, 0]],
2154 \ ],
2155 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2156
zeertzjq52a6f342024-05-22 16:42:44 +02002157 #" characterwise selection with multibyte chars
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002158 call cursor(1, 1)
2159 call feedkeys("\<Esc>vj", 'xt')
2160 call assert_equal(['abcdefghijk«', "\U0001f1e6"],
2161 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002162 call assert_equal([
2163 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
2164 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
2165 \ ],
2166 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
Shougo Matsushita19b71882024-02-28 22:48:12 +01002167
zeertzjq52a6f342024-05-22 16:42:44 +02002168 set selection=exclusive
2169 call feedkeys('l', 'xt')
2170 call assert_equal(['abcdefghijk«', "\U0001f1e6"],
2171 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2172 call assert_equal([
2173 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
2174 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
2175 \ ],
2176 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2177
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002178 #" marks on multibyte chars
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002179 call setpos("'a", [0, 1, 11, 0])
2180 call setpos("'b", [0, 2, 16, 0])
2181 call setpos("'c", [0, 2, 0, 0])
2182 call cursor(1, 1)
zeertzjqc95e64f2024-05-20 14:00:31 +02002183
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002184 call assert_equal(['ghijk', '🇨«🇩'],
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002185 \ getregion(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002186 call assert_equal([
2187 \ [[bufnr('%'), 1, 7, 0], [bufnr('%'), 1, 11, 0]],
2188 \ [[bufnr('%'), 2, 13, 0], [bufnr('%'), 2, 22, 0]],
2189 \ ],
2190 \ getregionpos(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
2191
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002192 call assert_equal(['k«', '🇦«🇧«🇨'],
2193 \ getregion(getpos("'a"), getpos("'b"), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002194 call assert_equal([
2195 \ [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
2196 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 16, 0]],
2197 \ ],
2198 \ getregionpos(getpos("'a"), getpos("'b"), {'type': 'v' }))
2199
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002200 call assert_equal(['k«'],
2201 \ getregion(getpos("'a"), getpos("'c"), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002202 call assert_equal([
2203 \ [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
2204 \ ],
2205 \ getregionpos(getpos("'a"), getpos("'c"), {'type': 'v' }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002206
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002207 #" use inclusive selection, although 'selection' is exclusive
2208 call setpos("'a", [0, 1, 11, 0])
2209 call setpos("'b", [0, 1, 1, 0])
2210 call assert_equal(['abcdefghijk'],
2211 \ getregion(getpos("'a"), getpos("'b"),
2212 \ {'type': "\<c-v>", 'exclusive': v:false }))
2213 call assert_equal(['abcdefghij'],
2214 \ getregion(getpos("'a"), getpos("'b"),
2215 \ {'type': "\<c-v>", 'exclusive': v:true }))
2216 call assert_equal(['abcdefghijk'],
2217 \ getregion(getpos("'a"), getpos("'b"),
2218 \ {'type': 'v', 'exclusive': 0 }))
2219 call assert_equal(['abcdefghij'],
2220 \ getregion(getpos("'a"), getpos("'b"),
2221 \ {'type': 'v', 'exclusive': 1 }))
2222 call assert_equal(['abcdefghijk«'],
2223 \ getregion(getpos("'a"), getpos("'b"),
2224 \ {'type': 'V', 'exclusive': 0 }))
2225 call assert_equal(['abcdefghijk«'],
2226 \ getregion(getpos("'a"), getpos("'b"),
2227 \ {'type': 'V', 'exclusive': 1 }))
zeertzjq2b09de92024-05-24 07:48:51 +02002228
2229 set selection&
2230 bwipe!
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002231 END
2232 call v9.CheckLegacyAndVim9Success(lines)
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002233
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002234 let lines =<< trim END
2235 #" Exclusive selection
2236 new
2237 set selection=exclusive
2238 call setline(1, ["a\tc", "x\tz", '', ''])
2239 call cursor(1, 1)
2240 call feedkeys("\<Esc>v2l", 'xt')
2241 call assert_equal(["a\t"],
2242 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2243 call cursor(1, 1)
2244 call feedkeys("\<Esc>v$G", 'xt')
2245 call assert_equal(["a\tc", "x\tz", ''],
2246 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2247 call cursor(1, 1)
2248 call feedkeys("\<Esc>v$j", 'xt')
2249 call assert_equal(["a\tc", "x\tz"],
2250 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2251 call cursor(1, 1)
2252 call feedkeys("\<Esc>\<C-v>$j", 'xt')
2253 call assert_equal(["a\tc", "x\tz"],
2254 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2255 call cursor(1, 1)
2256 call feedkeys("\<Esc>\<C-v>$G", 'xt')
2257 call assert_equal(["a", "x", '', ''],
2258 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2259 call cursor(1, 1)
2260 call feedkeys("\<Esc>wv2j", 'xt')
2261 call assert_equal(["c", "x\tz"],
2262 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2263 set selection&
zeertzjq52a6f342024-05-22 16:42:44 +02002264 bwipe!
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002265
2266 #" Exclusive selection 2
2267 new
2268 call setline(1, ["a\tc", "x\tz", '', ''])
zeertzjq701ad502024-05-23 07:47:55 +02002269
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002270 call cursor(1, 1)
2271 call feedkeys("\<Esc>v2l", 'xt')
2272 call assert_equal(["a\t"],
2273 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002274 call assert_equal([
2275 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
2276 \ ],
2277 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
2278
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002279 call cursor(1, 1)
2280 call feedkeys("\<Esc>v$G", 'xt')
2281 call assert_equal(["a\tc", "x\tz", ''],
2282 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002283 call assert_equal([
2284 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2285 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2286 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
2287 \ ],
2288 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
2289
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002290 call cursor(1, 1)
2291 call feedkeys("\<Esc>v$j", 'xt')
2292 call assert_equal(["a\tc", "x\tz"],
2293 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002294 call assert_equal([
2295 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2296 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2297 \ ],
2298 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
2299
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002300 call cursor(1, 1)
2301 call feedkeys("\<Esc>\<C-v>$j", 'xt')
2302 call assert_equal(["a\tc", "x\tz"],
2303 \ getregion(getpos('v'), getpos('.'),
2304 \ {'exclusive': v:true, 'type': "\<C-v>" }))
zeertzjq701ad502024-05-23 07:47:55 +02002305 call assert_equal([
2306 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2307 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2308 \ ],
2309 \ getregionpos(getpos('v'), getpos('.'),
2310 \ {'exclusive': v:true, 'type': "\<C-v>" }))
2311
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002312 call cursor(1, 1)
2313 call feedkeys("\<Esc>\<C-v>$G", 'xt')
2314 call assert_equal(["a", "x", '', ''],
2315 \ getregion(getpos('v'), getpos('.'),
2316 \ {'exclusive': v:true, 'type': "\<C-v>" }))
zeertzjq701ad502024-05-23 07:47:55 +02002317 call assert_equal([
2318 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
2319 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
2320 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
2321 \ [[bufnr('%'), 4, 0, 0], [bufnr('%'), 4, 0, 0]],
2322 \ ],
2323 \ getregionpos(getpos('v'), getpos('.'),
2324 \ {'exclusive': v:true, 'type': "\<C-v>" }))
2325
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002326 call cursor(1, 1)
2327 call feedkeys("\<Esc>wv2j", 'xt')
2328 call assert_equal(["c", "x\tz"],
2329 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002330 call assert_equal([
2331 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
2332 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2333 \ ],
2334 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002335
zeertzjq701ad502024-05-23 07:47:55 +02002336 #" 'virtualedit' with exclusive selection
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002337 set selection=exclusive
2338 set virtualedit=all
zeertzjqc95e64f2024-05-20 14:00:31 +02002339
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002340 call cursor(1, 1)
zeertzjq701ad502024-05-23 07:47:55 +02002341 call feedkeys("\<Esc>vj", 'xt')
2342 call assert_equal(["a\tc"],
2343 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2344 call assert_equal([
2345 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2346 \ ],
2347 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2348
2349 call cursor(1, 1)
2350 call feedkeys("\<Esc>v8l", 'xt')
2351 call assert_equal(["a\t"],
2352 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2353 call assert_equal([
2354 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
2355 \ ],
2356 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2357
2358 call cursor(1, 1)
2359 call feedkeys("\<Esc>v6l", 'xt')
2360 call assert_equal(['a '],
2361 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2362 call assert_equal([
2363 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 5]],
2364 \ ],
2365 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2366
2367 call cursor(1, 1)
2368 call feedkeys("\<Esc>6lv2l", 'xt')
2369 call assert_equal([' '],
2370 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2371 call assert_equal([
2372 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 0]],
2373 \ ],
2374 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2375
2376 call cursor(1, 1)
zeertzjq52a6f342024-05-22 16:42:44 +02002377 call feedkeys("\<Esc>lv2l", 'xt')
2378 call assert_equal([' '],
2379 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2380 call assert_equal([
2381 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
2382 \ ],
2383 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2384
2385 call cursor(1, 1)
2386 call feedkeys("\<Esc>2lv2l", 'xt')
2387 call assert_equal([' '],
2388 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2389 call assert_equal([
2390 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
2391 \ ],
2392 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2393
2394 call feedkeys('j', 'xt')
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002395 call assert_equal([' c', 'x '],
2396 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002397 call assert_equal([
2398 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
2399 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 3]],
2400 \ ],
2401 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2402
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002403 call cursor(1, 1)
zeertzjq52a6f342024-05-22 16:42:44 +02002404 call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
2405 call assert_equal([' ', ' '],
2406 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2407 call assert_equal([
2408 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 7]],
2409 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 7]],
2410 \ ],
2411 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2412
2413 call cursor(1, 1)
2414 call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
2415 call assert_equal([' ', ' ', ' '],
2416 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2417 call assert_equal([
2418 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
2419 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
zeertzjq2b09de92024-05-24 07:48:51 +02002420 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjq52a6f342024-05-22 16:42:44 +02002421 \ ],
2422 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002423 call assert_equal([
2424 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
2425 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
2426 \ [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 3]],
2427 \ ],
2428 \ getregionpos(getpos('v'), getpos('.'),
2429 \ {'type': "\<C-v>", "eol": v:true }))
zeertzjq52a6f342024-05-22 16:42:44 +02002430
2431 call cursor(1, 1)
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002432 call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
2433 call assert_equal([' ', ' ', ' '],
2434 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002435 call assert_equal([
zeertzjq52a6f342024-05-22 16:42:44 +02002436 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
2437 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
zeertzjq2b09de92024-05-24 07:48:51 +02002438 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjqc95e64f2024-05-20 14:00:31 +02002439 \ ],
2440 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002441 call assert_equal([
2442 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
2443 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
2444 \ [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 4]],
2445 \ ],
2446 \ getregionpos(getpos('v'), getpos('.'),
2447 \ {'type': "\<C-v>", "eol": v:true }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002448
zeertzjq701ad502024-05-23 07:47:55 +02002449 #" 'virtualedit' with inclusive selection
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002450 set selection&
2451
zeertzjq701ad502024-05-23 07:47:55 +02002452 call cursor(1, 1)
2453 call feedkeys("\<Esc>vj", 'xt')
2454 call assert_equal(["a\tc", 'x'],
2455 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2456 call assert_equal([
2457 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2458 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
2459 \ ],
2460 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2461
2462 call cursor(1, 1)
2463 call feedkeys("\<Esc>v8l", 'xt')
2464 call assert_equal(["a\tc"],
2465 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2466 call assert_equal([
2467 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2468 \ ],
2469 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2470
2471 call cursor(1, 1)
2472 call feedkeys("\<Esc>v6l", 'xt')
2473 call assert_equal(['a '],
2474 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2475 call assert_equal([
2476 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 6]],
2477 \ ],
2478 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2479
2480 call cursor(1, 1)
2481 call feedkeys("\<Esc>6lv2l", 'xt')
2482 call assert_equal([' c'],
2483 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2484 call assert_equal([
2485 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
2486 \ ],
2487 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2488
2489 call cursor(1, 1)
2490 call feedkeys("\<Esc>lv2l", 'xt')
2491 call assert_equal([' '],
2492 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2493 call assert_equal([
2494 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
2495 \ ],
2496 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2497
2498 call cursor(1, 1)
2499 call feedkeys("\<Esc>2lv2l", 'xt')
2500 call assert_equal([' '],
2501 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2502 call assert_equal([
2503 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
2504 \ ],
2505 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2506
2507 call feedkeys('j', 'xt')
2508 call assert_equal([' c', 'x '],
2509 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2510 call assert_equal([
2511 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
2512 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 4]],
2513 \ ],
2514 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2515
2516 call cursor(1, 1)
2517 call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
2518 call assert_equal([' c', ' z'],
2519 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2520 call assert_equal([
2521 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
2522 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 0]],
2523 \ ],
2524 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2525
2526 call cursor(1, 1)
2527 call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
2528 call assert_equal([' ', ' ', ' '],
2529 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2530 call assert_equal([
2531 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
2532 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
zeertzjq2b09de92024-05-24 07:48:51 +02002533 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjq701ad502024-05-23 07:47:55 +02002534 \ ],
2535 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002536 call assert_equal([
2537 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
2538 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
2539 \ [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 4]],
2540 \ ],
2541 \ getregionpos(getpos('v'), getpos('.'),
2542 \ {'type': "\<C-v>", "eol": v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002543
2544 call cursor(1, 1)
2545 call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
2546 call assert_equal([' ', ' ', ' '],
2547 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2548 call assert_equal([
2549 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
2550 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
zeertzjq2b09de92024-05-24 07:48:51 +02002551 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjq701ad502024-05-23 07:47:55 +02002552 \ ],
2553 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002554 call assert_equal([
2555 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
2556 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
2557 \ [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 5]],
2558 \ ],
2559 \ getregionpos(getpos('v'), getpos('.'),
2560 \ {'type': "\<C-v>", "eol": v:true }))
2561
2562 set virtualedit&
2563 bwipe!
2564 END
2565 call v9.CheckLegacyAndVim9Success(lines)
2566
2567 let lines =<< trim END
2568 #" 'virtualedit' with TABs at end of line
2569 new
2570 set virtualedit=all
2571 call setline(1, ["\t", "a\t", "aa\t"])
2572
2573 call feedkeys("gg06l\<C-v>3l2j", 'xt')
2574 call assert_equal([' ', ' ', ' '],
2575 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2576 call assert_equal([
2577 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
2578 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 0]],
2579 \ [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 3, 0]],
2580 \ ],
2581 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2582 call assert_equal([
2583 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
2584 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 2]],
2585 \ [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 4, 2]],
2586 \ ],
2587 \ getregionpos(getpos('v'), getpos('.'),
2588 \ {'type': "\<C-v>", "eol": v:true }))
2589
2590 call feedkeys("gg06lv3l", 'xt')
2591 call assert_equal([' '],
2592 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2593 call assert_equal([
2594 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
2595 \ ],
2596 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2597 call assert_equal([
2598 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
2599 \ ],
2600 \ getregionpos(getpos('v'), getpos('.'),
2601 \ {'type': 'v', "eol": v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002602
2603 set virtualedit&
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002604 bwipe!
2605 END
2606 call v9.CheckLegacyAndVim9Success(lines)
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002607endfunc
2608
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002609func Test_getregion_invalid_buf()
2610 new
2611 help
2612 call cursor(5, 7)
2613 norm! mA
2614 call cursor(5, 18)
2615 norm! mB
2616 call assert_equal(['Move around:'], getregion(getpos("'A"), getpos("'B")))
2617 " close the help window
2618 q
zeertzjq26dd09a2024-03-10 15:46:58 +01002619 call assert_fails("call getregion(getpos(\"'A\"), getpos(\"'B\"))", 'E681:')
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002620 bwipe!
2621endfunc
2622
zeertzjqafc22952024-05-24 19:07:12 +02002623func Test_getregion_after_yank()
2624 func! Check_Results(type)
2625 call assert_equal(g:expected_region,
2626 \ getregion(getpos("'["), getpos("']"), #{ type: a:type }))
2627 call assert_equal(g:expected_regionpos,
2628 \ getregionpos(getpos("'["), getpos("']"), #{ type: a:type }))
2629 call assert_equal(g:expected_region,
2630 \ getregion(getpos("']"), getpos("'["), #{ type: a:type }))
2631 call assert_equal(g:expected_regionpos,
2632 \ getregionpos(getpos("']"), getpos("'["), #{ type: a:type }))
2633 let g:checked = 1
2634 endfunc
2635
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002636 autocmd TextYankPost *
2637 \ : if v:event.operator ==? 'y'
zeertzjqafc22952024-05-24 19:07:12 +02002638 \ | call Check_Results(v:event.regtype)
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002639 \ | endif
zeertzjqafc22952024-05-24 19:07:12 +02002640
2641 new
2642 call setline(1, ['abcd', 'efghijk', 'lmn'])
2643
2644 let g:expected_region = ['abcd']
2645 let g:expected_regionpos = [
2646 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
2647 \ ]
2648 let g:checked = 0
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002649 normal yy
zeertzjqafc22952024-05-24 19:07:12 +02002650 call assert_equal(1, g:checked)
2651 call Check_Results(getregtype('"'))
2652
2653 let g:expected_region = ['cd', 'ghijk', 'n']
2654 let g:expected_regionpos = [
2655 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
2656 \ [[bufnr('%'), 2, 3, 0], [bufnr('%'), 2, 7, 0]],
2657 \ [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 3, 0]],
2658 \ ]
2659 let g:checked = 0
2660 call feedkeys("gg0ll\<C-V>jj$y", 'tx')
2661 call assert_equal(1, g:checked)
2662 call Check_Results(getregtype('"'))
zeertzjqdff55a32024-05-25 10:25:36 +02002663 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
zeertzjqafc22952024-05-24 19:07:12 +02002664
2665 let g:expected_region = ['bc', 'fg', 'mn']
2666 let g:expected_regionpos = [
2667 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 3, 0]],
2668 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 3, 0]],
2669 \ [[bufnr('%'), 3, 2, 0], [bufnr('%'), 3, 3, 0]],
2670 \ ]
2671 let g:checked = 0
2672 call feedkeys("gg0l\<C-V>jjly", 'tx')
2673 call assert_equal(1, g:checked)
2674 call Check_Results(getregtype('"'))
zeertzjqdff55a32024-05-25 10:25:36 +02002675 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2676
2677 bwipe!
2678
2679 new
2680 let lines = ['asdfghjkl', '«口=口»', 'qwertyuiop', '口口=口口', 'zxcvbnm']
2681 call setline(1, lines)
2682
2683 let g:expected_region = lines
2684 let g:expected_regionpos = [
2685 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 9, 0]],
2686 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 11, 0]],
2687 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 10, 0]],
2688 \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 13, 0]],
2689 \ [[bufnr('%'), 5, 1, 0], [bufnr('%'), 5, 7, 0]],
2690 \ ]
2691 let g:checked = 0
2692 call feedkeys('ggyG', 'tx')
2693 call assert_equal(1, g:checked)
2694 call Check_Results(getregtype('"'))
2695 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2696
2697 let g:expected_region = ['=口»', 'qwertyuiop', '口口=口']
2698 let g:expected_regionpos = [
2699 \ [[bufnr('%'), 2, 6, 0], [bufnr('%'), 2, 11, 0]],
2700 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 10, 0]],
2701 \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 10, 0]],
2702 \ ]
2703 let g:checked = 0
2704 call feedkeys('2gg02lv2j2ly', 'tx')
2705 call assert_equal(1, g:checked)
2706 call Check_Results(getregtype('"'))
2707 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2708
2709 let g:expected_region = ['asdf', '«口=', 'qwer', '口口', 'zxcv']
2710 let g:expected_regionpos = [
2711 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
2712 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 6, 0]],
2713 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 4, 0]],
2714 \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 6, 0]],
2715 \ [[bufnr('%'), 5, 1, 0], [bufnr('%'), 5, 4, 0]],
2716 \ ]
2717 let g:checked = 0
2718 call feedkeys("G0\<C-V>3l4ky", 'tx')
2719 call assert_equal(1, g:checked)
2720 call Check_Results(getregtype('"'))
2721 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2722
2723 let g:expected_region = ['ghjkl', '口»', 'tyuiop', '=口口', 'bnm']
2724 let g:expected_regionpos = [
2725 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 9, 0]],
2726 \ [[bufnr('%'), 2, 7, 0], [bufnr('%'), 2, 11, 0]],
2727 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 10, 0]],
2728 \ [[bufnr('%'), 4, 7, 0], [bufnr('%'), 4, 13, 0]],
2729 \ [[bufnr('%'), 5, 5, 0], [bufnr('%'), 5, 7, 0]],
2730 \ ]
2731 let g:checked = 0
2732 call feedkeys("G04l\<C-V>$4ky", 'tx')
2733 call assert_equal(1, g:checked)
2734 call Check_Results(getregtype('"'))
2735 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
zeertzjqafc22952024-05-24 19:07:12 +02002736
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002737 bwipe!
zeertzjqafc22952024-05-24 19:07:12 +02002738
2739 unlet g:expected_region
2740 unlet g:expected_regionpos
2741 unlet g:checked
2742 autocmd! TextYankPost
2743 delfunc Check_Results
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002744endfunc
2745
Christian Brabandtd5c8c092024-05-08 22:17:19 +02002746func Test_visual_block_cursor_delete()
2747 new
2748 call setline(1, 'ab')
2749 exe ":norm! $\<c-v>hI\<Del>\<ESC>"
2750 call assert_equal(['b'], getline(1, 1))
2751 bwipe!
2752endfunc
2753
Christian Brabandt1fb9eae2024-06-11 20:30:14 +02002754func Test_visual_block_cursor_insert_enter()
2755 new
2756 call setline(1, ['asdf asdf', 'asdf asdf', 'asdf asdf', 'asdf asdf'])
2757 call cursor(1, 5)
2758 exe ":norm! \<c-v>3jcw\<cr>"
2759 call assert_equal(['asdfw', 'asdf', 'asdfasdf', 'asdfasdf', 'asdfasdf'], getline(1, '$'))
2760 bwipe!
2761endfunc
2762
Christian Brabandtbb955892024-12-16 22:49:15 +01002763func Test_visual_block_exclusive_selection()
2764 new
2765 set selection=exclusive
2766 call setline(1, ['asöd asdf', 'asdf asdf', 'asd asdf', 'asdf asdf'])
2767 call cursor(1, 1)
2768 exe ":norm! \<c-v>eh3j~"
2769 call assert_equal(['ASÖd asdf', 'ASDf asdf', 'ASd asdf', 'ASDf asdf'], getline(1, '$'))
2770 exe ":norm! 1v~"
2771 call assert_equal(['asöd asdf', 'asdf asdf', 'asd asdf', 'asdf asdf'], getline(1, '$'))
2772 bwipe!
2773 set selection&vim
2774endfunc
2775
2776func Test_visual_block_exclusive_selection_adjusted()
2777 new
2778 " Test that the end-position of the visual selection is adjusted for exclusive selection
2779 set selection=exclusive
2780 call setline(1, ['asöd asdf ', 'asdf asdf ', 'asd asdf ', 'asdf asdf '])
2781 call cursor(1, 1)
2782 " inclusive motion
2783 exe ":norm! \<c-v>e3jy"
2784 call assert_equal([0, 4, 5, 0], getpos("'>"))
2785 " exclusive motion
2786 exe ":norm! \<c-v>ta3jy"
2787 call assert_equal([0, 4, 6, 0], getpos("'>"))
2788 " another inclusive motion
2789 exe ":norm! \<c-v>g_3jy"
2790 call assert_equal([0, 4, 10, 0], getpos("'>"))
2791
2792 " Reset selection option to Vim default
2793 set selection&vim
2794 call cursor(1, 1)
2795
2796 " inclusive motion
2797 exe ":norm! \<c-v>e3jy"
2798 call assert_equal([0, 4, 4, 0], getpos("'>"))
2799 " exclusive motion
2800 exe ":norm! \<c-v>ta3jy"
2801 call assert_equal([0, 4, 5, 0], getpos("'>"))
2802 " another inclusive motion
2803 exe ":norm! \<c-v>g_3jy"
2804 call assert_equal([0, 4, 9, 0], getpos("'>"))
2805 bwipe!
2806 set selection&vim
2807endfunc
2808
Christian Brabandtc9a1e252025-01-11 15:25:00 +01002809" the following caused a Heap-Overflow, because Vim was accessing outside of a
2810" line end
2811func Test_visual_pos_buffer_heap_overflow()
2812 set virtualedit=all
2813 args Xa Xb
2814 all
2815 call setline(1, ['', '', ''])
2816 call cursor(3, 1)
2817 wincmd w
2818 call setline(1, 'foobar')
2819 normal! $lv0
2820 all
2821 call setreg('"', 'baz')
2822 normal! [P
2823 set virtualedit=
2824 bw! Xa Xb
2825endfunc
2826
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +01002827" vim: shiftwidth=2 sts=2 expandtab