blob: 6c2ef59f9321eeec170f725e51d7991183cd75c5 [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
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001102" Test for starting linewise visual with a count.
1103" This test needs to be run without any previous visual mode. Otherwise the
1104" count will use the count from the previous visual mode.
1105func Test_linewise_visual_with_count()
1106 let after =<< trim [CODE]
1107 call setline(1, ['one', 'two', 'three', 'four'])
1108 norm! 3Vy
1109 call assert_equal("one\ntwo\nthree\n", @")
1110 call writefile(v:errors, 'Xtestout')
1111 qall!
1112 [CODE]
1113 if RunVim([], after, '')
1114 call assert_equal([], readfile('Xtestout'))
1115 call delete('Xtestout')
1116 endif
1117endfunc
1118
1119" Test for starting characterwise visual with a count.
1120" This test needs to be run without any previous visual mode. Otherwise the
1121" count will use the count from the previous visual mode.
1122func Test_characterwise_visual_with_count()
1123 let after =<< trim [CODE]
1124 call setline(1, ['one two', 'three'])
1125 norm! l5vy
1126 call assert_equal("ne tw", @")
1127 call writefile(v:errors, 'Xtestout')
1128 qall!
1129 [CODE]
1130 if RunVim([], after, '')
1131 call assert_equal([], readfile('Xtestout'))
1132 call delete('Xtestout')
1133 endif
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01001134endfunc
1135
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001136" Test for visually selecting an inner block (iB)
1137func Test_visual_inner_block()
1138 new
1139 call setline(1, ['one', '{', 'two', '{', 'three', '}', 'four', '}', 'five'])
1140 call cursor(5, 1)
1141 " visually select all the lines in the block and then execute iB
1142 call feedkeys("ViB\<C-C>", 'xt')
1143 call assert_equal([0, 5, 1, 0], getpos("'<"))
1144 call assert_equal([0, 5, 6, 0], getpos("'>"))
1145 " visually select two inner blocks
1146 call feedkeys("ViBiB\<C-C>", 'xt')
1147 call assert_equal([0, 3, 1, 0], getpos("'<"))
1148 call assert_equal([0, 7, 5, 0], getpos("'>"))
1149 " try to select non-existing inner block
1150 call cursor(5, 1)
1151 call assert_beeps('normal ViBiBiB')
zeertzjqc029c132024-03-28 11:37:26 +01001152 " try to select an unclosed inner block
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001153 8,9d
1154 call cursor(5, 1)
1155 call assert_beeps('normal ViBiB')
Christian Brabandtc9a1e252025-01-11 15:25:00 +01001156 bw!
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001157endfunc
1158
Bram Moolenaarcd942772020-08-22 21:08:44 +02001159func Test_visual_put_in_block()
1160 new
1161 call setline(1, ['xxxx', 'yyy', 'zzzz'])
1162 normal 1G2yl
1163 exe "normal 1G2l\<C-V>jjlp"
1164 call assert_equal(['xxxx', 'yxx', 'zzxx'], getline(1, 3))
1165 bwipe!
1166endfunc
1167
Christian Brabandt2fa93842021-05-30 22:17:25 +02001168func Test_visual_put_in_block_using_zp()
1169 new
1170 " paste using zP
Bram Moolenaar94722c52023-01-28 19:19:03 +00001171 call setline(1, ['/path;text', '/path;text', '/path;text', '',
1172 \ '/subdir',
Christian Brabandt2fa93842021-05-30 22:17:25 +02001173 \ '/longsubdir',
1174 \ '/longlongsubdir'])
1175 exe "normal! 5G\<c-v>2j$y"
1176 norm! 1Gf;zP
1177 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1178 %d
1179 " paste using zP
Bram Moolenaar94722c52023-01-28 19:19:03 +00001180 call setline(1, ['/path;text', '/path;text', '/path;text', '',
1181 \ '/subdir',
Christian Brabandt2fa93842021-05-30 22:17:25 +02001182 \ '/longsubdir',
1183 \ '/longlongsubdir'])
1184 exe "normal! 5G\<c-v>2j$y"
1185 norm! 1Gf;hzp
1186 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1187 bwipe!
1188endfunc
1189
Christian Brabandt544a38e2021-06-10 19:39:11 +02001190func Test_visual_put_in_block_using_zy_and_zp()
1191 new
1192
1193 " Test 1) Paste using zp - after the cursor without trailing spaces
Bram Moolenaar94722c52023-01-28 19:19:03 +00001194 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001195 \ 'texttext /subdir columntext',
1196 \ 'texttext /longsubdir columntext',
1197 \ 'texttext /longlongsubdir columntext'])
1198 exe "normal! 5G0f/\<c-v>2jezy"
1199 norm! 1G0f;hzp
1200 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1201
1202 " Test 2) Paste using zP - in front of the cursor without trailing spaces
1203 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001204 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001205 \ 'texttext /subdir columntext',
1206 \ 'texttext /longsubdir columntext',
1207 \ 'texttext /longlongsubdir columntext'])
1208 exe "normal! 5G0f/\<c-v>2jezy"
1209 norm! 1G0f;zP
1210 call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
1211
1212 " Test 3) Paste using p - with trailing spaces
1213 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001214 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001215 \ 'texttext /subdir columntext',
1216 \ 'texttext /longsubdir columntext',
1217 \ 'texttext /longlongsubdir columntext'])
1218 exe "normal! 5G0f/\<c-v>2jezy"
1219 norm! 1G0f;hp
1220 call assert_equal(['/path/subdir ;text', '/path/longsubdir ;text', '/path/longlongsubdir;text'], getline(1, 3))
1221
1222 " Test 4) Paste using P - with trailing spaces
1223 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001224 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001225 \ 'texttext /subdir columntext',
1226 \ 'texttext /longsubdir columntext',
1227 \ 'texttext /longlongsubdir columntext'])
1228 exe "normal! 5G0f/\<c-v>2jezy"
1229 norm! 1G0f;P
1230 call assert_equal(['/path/subdir ;text', '/path/longsubdir ;text', '/path/longlongsubdir;text'], getline(1, 3))
1231
1232 " Test 5) Yank with spaces inside the block
1233 %d
Bram Moolenaar94722c52023-01-28 19:19:03 +00001234 call setline(1, ['/path;text', '/path;text', '/path;text', '',
Christian Brabandt544a38e2021-06-10 19:39:11 +02001235 \ 'texttext /sub dir/ columntext',
1236 \ 'texttext /lon gsubdir/ columntext',
1237 \ 'texttext /lon glongsubdir/ columntext'])
1238 exe "normal! 5G0f/\<c-v>2jf/zy"
1239 norm! 1G0f;zP
1240 call assert_equal(['/path/sub dir/;text', '/path/lon gsubdir/;text', '/path/lon glongsubdir/;text'], getline(1, 3))
1241 bwipe!
1242endfunc
1243
Bram Moolenaar7d7bcc62021-06-28 21:54:27 +02001244func Test_visual_put_blockedit_zy_and_zp()
1245 new
1246
1247 call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
1248 exe "normal! gg0\<c-v>2j$zy"
1249 norm! 5gg0zP
1250 call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
1251 "
1252 " now with blockmode editing
1253 sil %d
1254 :set ve=block
1255 call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
1256 exe "normal! gg0\<c-v>2j$zy"
1257 norm! 5gg0zP
1258 call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
1259 set ve&vim
1260 bw!
1261endfunc
1262
Bram Moolenaar44db8212022-01-25 21:26:17 +00001263func Test_visual_block_yank_zy()
1264 new
1265 " this was reading before the start of the line
1266 exe "norm o\<C-T>\<Esc>\<C-V>zy"
1267 bwipe!
1268endfunc
1269
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001270func Test_visual_block_with_virtualedit()
1271 CheckScreendump
1272
1273 let lines =<< trim END
1274 call setline(1, ['aaaaaa', 'bbbb', 'cc'])
1275 set virtualedit=block
1276 normal G
1277 END
Bram Moolenaar5b148ef2022-10-15 21:35:56 +01001278 call writefile(lines, 'XTest_block', 'D')
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001279
1280 let buf = RunVimInTerminal('-S XTest_block', {'rows': 8, 'cols': 50})
1281 call term_sendkeys(buf, "\<C-V>gg$")
1282 call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit', {})
1283
Bram Moolenaarb17ab862021-07-03 22:15:17 +02001284 call term_sendkeys(buf, "\<Esc>gg\<C-V>G$")
1285 call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit2', {})
1286
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001287 " clean up
1288 call term_sendkeys(buf, "\<Esc>")
1289 call StopVimInTerminal(buf)
Bram Moolenaar9cee4a12021-07-03 15:08:37 +02001290endfunc
1291
Bram Moolenaar615ddd52021-11-17 18:00:31 +00001292func Test_visual_block_ctrl_w_f()
dundargocc57b5bc2022-11-02 13:30:51 +00001293 " Empty block selected in new buffer should not result in an error.
Bram Moolenaar615ddd52021-11-17 18:00:31 +00001294 au! BufNew foo sil norm f
1295 edit foo
1296
1297 au! BufNew
1298endfunc
1299
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001300func Test_visual_block_append_invalid_char()
1301 " this was going over the end of the line
Bram Moolenaar262898a2022-01-17 17:52:22 +00001302 set isprint=@,161-255
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001303 new
1304 call setline(1, [' let xxx', 'xxxxxˆ', 'xxxxxxxxxxx'])
1305 exe "normal 0\<C-V>jjA-\<Esc>"
1306 call assert_equal([' - let xxx', 'xxxxx ', 'xxxxxxxx-xxx'], getline(1, 3))
1307 bwipe!
Bram Moolenaar262898a2022-01-17 17:52:22 +00001308 set isprint&
Bram Moolenaar9f8c3042022-01-17 17:30:21 +00001309endfunc
1310
Bram Moolenaar7ce5b2b2022-05-16 19:40:59 +01001311func Test_visual_block_with_substitute()
1312 " this was reading beyond the end of the line
1313 new
1314 norm a0)
1315 sil! norm  O
1316 s/)
1317 sil! norm 
1318 bwipe!
1319endfunc
1320
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001321func Test_visual_reselect_with_count()
Bram Moolenaar8f531662023-02-01 17:33:18 +00001322 enew
1323 call setline(1, ['aaaaaa', ' bbbb', ' bbbb'])
1324 exe "normal! 2Gw\<C-V>jed"
1325 exe "normal! gg0lP"
1326 call assert_equal(['abbbbaaaaa', 'bbbb ', ' '], getline(1, '$'))
1327
1328 exe "normal! 1vr."
1329 call assert_equal(['a....aaaaa', '✗.... ', ' '], getline(1, '$'))
1330
1331 bwipe!
1332
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001333 " this was causing an illegal memory access
1334 let lines =<< trim END
1335
1336
1337
1338 :
1339 r<sfile>
1340 exe "%norm e3\<c-v>kr\t"
1341 :
1342
1343 :
1344 END
Bram Moolenaar5b148ef2022-10-15 21:35:56 +01001345 call writefile(lines, 'XvisualReselect', 'D')
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001346 source XvisualReselect
1347
1348 bwipe!
Bram Moolenaarb07626d2021-10-11 15:40:43 +01001349endfunc
1350
Bram Moolenaar79c11e32023-01-10 17:29:29 +00001351func Test_visual_reselect_exclusive()
1352 new
1353 call setline(1, ['abcde', 'abcde'])
1354 set selection=exclusive
1355 normal 1G0viwd
1356 normal 2G01vd
1357 call assert_equal(['', ''], getline(1, 2))
1358
1359 set selection&
1360 bwipe!
1361endfunc
1362
Bram Moolenaar57df9e82022-01-20 12:10:48 +00001363func Test_visual_block_insert_round_off()
1364 new
1365 " The number of characters are tuned to fill a 4096 byte allocated block,
1366 " so that valgrind reports going over the end.
1367 call setline(1, ['xxxxx', repeat('0', 1350), "\t", repeat('x', 60)])
1368 exe "normal gg0\<C-V>GI" .. repeat('0', 1320) .. "\<Esc>"
1369 bwipe!
1370endfunc
1371
Bram Moolenaar05b27612022-01-20 13:32:50 +00001372" this was causing an ml_get error
1373func Test_visual_exchange_windows()
1374 enew!
1375 new
1376 call setline(1, ['foo', 'bar'])
1377 exe "normal G\<C-V>gg\<C-W>\<C-X>OO\<Esc>"
1378 bwipe!
1379 bwipe!
1380endfunc
1381
Bram Moolenaardc5490e2022-01-25 13:52:53 +00001382" this was leaving the end of the Visual area beyond the end of a line
1383func Test_visual_ex_copy_line()
1384 new
1385 call setline(1, ["aaa", "bbbbbbbbbxbb"])
1386 /x
1387 exe "normal ggvjfxO"
1388 t0
1389 normal gNU
1390 bwipe!
1391endfunc
1392
Bram Moolenaar8d02ce12022-01-25 18:24:00 +00001393" This was leaving the end of the Visual area beyond the end of a line.
1394" Set 'undolevels' to start a new undo block.
1395func Test_visual_undo_deletes_last_line()
1396 new
1397 call setline(1, ["aaa", "ccc", "dyd"])
1398 set undolevels=100
1399 exe "normal obbbbbbbbbxbb\<Esc>"
1400 set undolevels=100
1401 /y
1402 exe "normal ggvjfxO"
1403 undo
1404 normal gNU
Shougo Matsushitafb552072022-01-28 16:01:13 +00001405
Bram Moolenaar8d02ce12022-01-25 18:24:00 +00001406 bwipe!
1407endfunc
1408
Shougo Matsushitafb552072022-01-28 16:01:13 +00001409func Test_visual_paste()
1410 new
1411
1412 " v_p overwrites unnamed register.
1413 call setline(1, ['xxxx'])
1414 call setreg('"', 'foo')
1415 call setreg('-', 'bar')
zeertzjq6bf821e2022-02-07 10:33:20 +00001416 normal gg0vp
1417 call assert_equal('x', @")
1418 call assert_equal('x', @-)
1419 call assert_equal('fooxxx', getline(1))
1420 normal $vp
1421 call assert_equal('x', @")
1422 call assert_equal('x', @-)
1423 call assert_equal('fooxxx', getline(1))
1424 " Test with a different register as unnamed register.
1425 call setline(2, ['baz'])
1426 normal 2gg0"rD
1427 call assert_equal('baz', @")
1428 normal gg0vp
1429 call assert_equal('f', @")
1430 call assert_equal('f', @-)
1431 call assert_equal('bazooxxx', getline(1))
1432 normal $vp
1433 call assert_equal('x', @")
1434 call assert_equal('x', @-)
1435 call assert_equal('bazooxxf', getline(1))
Shougo Matsushitafb552072022-01-28 16:01:13 +00001436
Shougo Matsushita509142a2022-05-06 11:45:09 +01001437 bwipe!
1438endfunc
1439
1440func Test_visual_paste_clipboard()
1441 CheckFeature clipboard_working
1442
1443 if has('gui')
1444 " auto select feature breaks tests
1445 set guioptions-=a
1446 endif
1447
1448 " v_P does not overwrite unnamed register.
1449 call setline(1, ['xxxx'])
1450 call setreg('"', 'foo')
1451 call setreg('-', 'bar')
1452 normal gg0vP
1453 call assert_equal('foo', @")
1454 call assert_equal('bar', @-)
1455 call assert_equal('fooxxx', getline(1))
1456 normal $vP
1457 call assert_equal('foo', @")
1458 call assert_equal('bar', @-)
1459 call assert_equal('fooxxfoo', getline(1))
1460 " Test with a different register as unnamed register.
1461 call setline(2, ['baz'])
1462 normal 2gg0"rD
1463 call assert_equal('baz', @")
1464 normal gg0vP
1465 call assert_equal('baz', @")
1466 call assert_equal('bar', @-)
1467 call assert_equal('bazooxxfoo', getline(1))
1468 normal $vP
1469 call assert_equal('baz', @")
1470 call assert_equal('bar', @-)
1471 call assert_equal('bazooxxfobaz', getline(1))
1472
1473 " Test for unnamed clipboard
1474 set clipboard=unnamed
1475 call setline(1, ['xxxx'])
1476 call setreg('"', 'foo')
1477 call setreg('-', 'bar')
1478 call setreg('*', 'baz')
1479 normal gg0vP
1480 call assert_equal('foo', @")
1481 call assert_equal('bar', @-)
1482 call assert_equal('baz', @*)
1483 call assert_equal('bazxxx', getline(1))
1484
1485 " Test for unnamedplus clipboard
1486 if has('unnamedplus')
1487 set clipboard=unnamedplus
Shougo Matsushitafb552072022-01-28 16:01:13 +00001488 call setline(1, ['xxxx'])
1489 call setreg('"', 'foo')
1490 call setreg('-', 'bar')
Shougo Matsushita509142a2022-05-06 11:45:09 +01001491 call setreg('+', 'baz')
zeertzjq6bf821e2022-02-07 10:33:20 +00001492 normal gg0vP
1493 call assert_equal('foo', @")
Shougo Matsushita509142a2022-05-06 11:45:09 +01001494 call assert_equal('bar', @-)
1495 call assert_equal('baz', @+)
1496 call assert_equal('bazxxx', getline(1))
Shougo Matsushitafb552072022-01-28 16:01:13 +00001497 endif
1498
Shougo Matsushita509142a2022-05-06 11:45:09 +01001499 set clipboard&
1500 if has('gui')
1501 set guioptions&
1502 endif
Shougo Matsushitafb552072022-01-28 16:01:13 +00001503 bwipe!
1504endfunc
Christian Brabandt544a38e2021-06-10 19:39:11 +02001505
Bram Moolenaar3d51ce12022-07-01 15:26:15 +01001506func Test_visual_area_adjusted_when_hiding()
1507 " The Visual area ended after the end of the line after :hide
1508 call setline(1, 'xxx')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001509 vsplit Xvaafile
Bram Moolenaar3d51ce12022-07-01 15:26:15 +01001510 call setline(1, 'xxxxxxxx')
1511 norm! $o
1512 hid
1513 norm! zW
1514 bwipe!
1515 bwipe!
1516endfunc
1517
Bram Moolenaarcfeb8a52022-08-13 14:09:44 +01001518func Test_switch_buffer_ends_visual_mode()
1519 enew
1520 call setline(1, 'foo')
1521 set hidden
1522 set virtualedit=all
1523 let buf1 = bufnr()
1524 enew
1525 let buf2 = bufnr()
1526 call setline(1, ['', '', '', ''])
1527 call cursor(4, 5)
1528 call feedkeys("\<C-V>3k4h", 'xt')
1529 exe 'buffer' buf1
1530 call assert_equal('n', mode())
1531
1532 set nohidden
1533 set virtualedit=
1534 bwipe!
1535 exe 'bwipe!' buf2
1536endfunc
1537
Pavel Mayorove1121b12023-02-20 14:35:20 +00001538" Check fix for the heap-based buffer overflow bug found in the function
1539" utfc_ptr2len and reported at
1540" https://huntr.dev/bounties/ae933869-a1ec-402a-bbea-d51764c6618e
1541func Test_heap_buffer_overflow()
1542 enew
1543 set updatecount=0
1544
1545 norm R0
1546 split other
1547 norm R000
1548 exe "norm \<C-V>l"
1549 ball
1550 call assert_equal(getpos("."), getpos("v"))
1551 call assert_equal('n', mode())
1552 norm zW
1553
1554 %bwipe!
1555 set updatecount&
1556endfunc
1557
zeertzjq8fc6a1d2023-08-20 18:12:54 +02001558" Test Visual highlight with cursor at end of screen line and 'showbreak'
1559func Test_visual_hl_with_showbreak()
1560 CheckScreendump
1561
Yee Cheng Chine70587d2025-02-13 20:55:45 +01001562 " Redraw at the end is necessary due to https://github.com/vim/vim/issues/16620
zeertzjq8fc6a1d2023-08-20 18:12:54 +02001563 let lines =<< trim END
1564 setlocal showbreak=+
1565 call setline(1, repeat('a', &columns + 10))
1566 normal g$v4lo
Yee Cheng Chine70587d2025-02-13 20:55:45 +01001567 redraw
zeertzjq8fc6a1d2023-08-20 18:12:54 +02001568 END
1569 call writefile(lines, 'XTest_visual_sbr', 'D')
1570
1571 let buf = RunVimInTerminal('-S XTest_visual_sbr', {'rows': 6, 'cols': 50})
1572 call VerifyScreenDump(buf, 'Test_visual_hl_with_showbreak', {})
1573
1574 " clean up
1575 call term_sendkeys(buf, "\<Esc>")
1576 call StopVimInTerminal(buf)
1577endfunc
Pavel Mayorove1121b12023-02-20 14:35:20 +00001578
Christian Brabandt476733f2023-09-19 20:41:51 +02001579func Test_Visual_r_CTRL_C()
1580 new
1581 " visual r_cmd
1582 call setline(1, [' '])
1583 call feedkeys("\<c-v>$r\<c-c>", 'tx')
1584 call assert_equal([''], getline(1, 1))
1585
1586 " visual gr_cmd
1587 call setline(1, [' '])
1588 call feedkeys("\<c-v>$gr\<c-c>", 'tx')
1589 call assert_equal([''], getline(1, 1))
1590 bw!
zeertzjqec149242023-12-19 20:28:31 +01001591endfunc
1592
1593func Test_visual_drag_out_of_window()
1594 rightbelow vnew
1595 call setline(1, '123456789')
1596 set mouse=a
1597 func ClickExpr(off)
1598 call test_setmouse(1, getwininfo(win_getid())[0].wincol + a:off)
1599 return "\<LeftMouse>"
1600 endfunc
1601 func DragExpr(off)
1602 call test_setmouse(1, getwininfo(win_getid())[0].wincol + a:off)
1603 return "\<LeftDrag>"
1604 endfunc
1605
1606 nnoremap <expr> <F2> ClickExpr(5)
1607 nnoremap <expr> <F3> DragExpr(-1)
1608 redraw
1609 call feedkeys("\<F2>\<F3>\<LeftRelease>", 'tx')
1610 call assert_equal([1, 6], [col('.'), col('v')])
1611 call feedkeys("\<Esc>", 'tx')
1612
1613 nnoremap <expr> <F2> ClickExpr(6)
1614 nnoremap <expr> <F3> DragExpr(-2)
1615 redraw
1616 call feedkeys("\<F2>\<F3>\<LeftRelease>", 'tx')
1617 call assert_equal([1, 7], [col('.'), col('v')])
1618 call feedkeys("\<Esc>", 'tx')
1619
1620 nunmap <F2>
1621 nunmap <F3>
1622 delfunc ClickExpr
1623 delfunc DragExpr
1624 set mouse&
1625 bwipe!
1626endfunc
Christian Brabandt476733f2023-09-19 20:41:51 +02001627
Christian Brabandt7c71db32024-01-22 20:12:34 +01001628func Test_visual_substitute_visual()
1629 new
1630 call setline(1, ['one', 'two', 'three'])
1631 call feedkeys("Gk\<C-V>j$:s/\\%V\\_.*\\%V/foobar\<CR>", 'tx')
1632 call assert_equal(['one', 'foobar'], getline(1, '$'))
1633 bwipe!
1634endfunc
1635
zeertzjq701ad502024-05-23 07:47:55 +02001636func Test_virtualedit_exclusive_selection()
1637 new
1638 set virtualedit=all selection=exclusive
1639
1640 call setline(1, "a\tb")
1641 normal! 0v8ly
1642 call assert_equal("a\t", getreg('"'))
1643 normal! 0v6ly
1644 call assert_equal('a ', getreg('"'))
1645 normal! 06lv2ly
1646 call assert_equal(' ', getreg('"'))
1647
1648 set virtualedit& selection&
1649 bwipe!
1650endfunc
1651
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001652func Test_visual_getregion()
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001653 let lines =<< trim END
1654 new
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001655
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001656 call setline(1, ['one', 'two', 'three'])
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001657
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001658 #" Visual mode
1659 call cursor(1, 1)
1660 call feedkeys("\<ESC>vjl", 'tx')
zeertzjqc95e64f2024-05-20 14:00:31 +02001661
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001662 call assert_equal(['one', 'tw'],
1663 \ 'v'->getpos()->getregion(getpos('.')))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001664 call assert_equal([
1665 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1666 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
1667 \ ],
1668 \ 'v'->getpos()->getregionpos(getpos('.')))
zeertzjqc95e64f2024-05-20 14:00:31 +02001669
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001670 call assert_equal(['one', 'tw'],
1671 \ '.'->getpos()->getregion(getpos('v')))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001672 call assert_equal([
1673 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1674 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
1675 \ ],
1676 \ '.'->getpos()->getregionpos(getpos('v')))
zeertzjqc95e64f2024-05-20 14:00:31 +02001677
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001678 call assert_equal(['o'],
1679 \ 'v'->getpos()->getregion(getpos('v')))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001680 call assert_equal([
1681 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
1682 \ ],
1683 \ 'v'->getpos()->getregionpos(getpos('v')))
zeertzjqc95e64f2024-05-20 14:00:31 +02001684
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001685 call assert_equal(['w'],
1686 \ '.'->getpos()->getregion(getpos('.'), {'type': 'v' }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001687 call assert_equal([
1688 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 0]],
1689 \ ],
1690 \ '.'->getpos()->getregionpos(getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02001691
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001692 call assert_equal(['one', 'two'],
1693 \ getpos('.')->getregion(getpos('v'), {'type': 'V' }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001694 call assert_equal([
1695 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1696 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1697 \ ],
1698 \ getpos('.')->getregionpos(getpos('v'), {'type': 'V' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02001699
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001700 call assert_equal(['on', 'tw'],
1701 \ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001702 call assert_equal([
1703 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
1704 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]],
1705 \ ],
1706 \ getpos('.')->getregionpos(getpos('v'), {'type': "\<C-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001707
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001708 #" Line visual mode
1709 call cursor(1, 1)
1710 call feedkeys("\<ESC>Vl", 'tx')
1711 call assert_equal(['one'],
1712 \ getregion(getpos('v'), getpos('.'), {'type': 'V' }))
1713 call assert_equal(['one'],
1714 \ getregion(getpos('.'), getpos('v'), {'type': 'V' }))
1715 call assert_equal(['one'],
1716 \ getregion(getpos('v'), getpos('v'), {'type': 'V' }))
1717 call assert_equal(['one'],
1718 \ getregion(getpos('.'), getpos('.'), {'type': 'V' }))
1719 call assert_equal(['on'],
1720 \ getpos('.')->getregion(getpos('v'), {'type': 'v' }))
1721 call assert_equal(['on'],
1722 \ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001723
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001724 #" Block visual mode
1725 call cursor(1, 1)
1726 call feedkeys("\<ESC>\<C-v>ll", 'tx')
1727 call assert_equal(['one'],
1728 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1729 call assert_equal(['one'],
1730 \ getregion(getpos('.'), getpos('v'), {'type': "\<C-v>" }))
1731 call assert_equal(['o'],
1732 \ getregion(getpos('v'), getpos('v'), {'type': "\<C-v>" }))
1733 call assert_equal(['e'],
1734 \ getregion(getpos('.'), getpos('.'), {'type': "\<C-v>" }))
1735 call assert_equal(['one'],
1736 \ '.'->getpos()->getregion(getpos('v'), {'type': 'V' }))
1737 call assert_equal(['one'],
1738 \ '.'->getpos()->getregion(getpos('v'), {'type': 'v' }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001739
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001740 #" Using Marks
1741 call setpos("'a", [0, 2, 3, 0])
1742 call cursor(1, 1)
1743 call assert_equal(['one', 'two'],
1744 \ "'a"->getpos()->getregion(getpos('.'), {'type': 'v' }))
1745 call assert_equal(['one', 'two'],
1746 \ "."->getpos()->getregion(getpos("'a"), {'type': 'v' }))
1747 call assert_equal(['one', 'two'],
1748 \ "."->getpos()->getregion(getpos("'a"), {'type': 'V' }))
1749 call assert_equal(['two'],
1750 \ "'a"->getpos()->getregion(getpos("'a"), {'type': 'V' }))
1751 call assert_equal(['one', 'two'],
1752 \ "."->getpos()->getregion(getpos("'a"), {'type': "\<c-v>" }))
zeertzjq2ffdae72024-05-02 13:06:24 +02001753 call feedkeys("\<ESC>jVj\<ESC>", 'tx')
1754 call assert_equal(['two', 'three'], getregion(getpos("'<"), getpos("'>")))
1755 call assert_equal(['two', 'three'], getregion(getpos("'>"), getpos("'<")))
Shougo Matsushita19b71882024-02-28 22:48:12 +01001756
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001757 #" Using List
1758 call cursor(1, 1)
1759 call assert_equal(['one', 'two'],
1760 \ [0, 2, 3, 0]->getregion(getpos('.'), {'type': 'v' }))
1761 call assert_equal(['one', 'two'],
1762 \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': 'v' }))
1763 call assert_equal(['one', 'two'],
1764 \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': 'V' }))
1765 call assert_equal(['two'],
1766 \ [0, 2, 3, 0]->getregion([0, 2, 3, 0], {'type': 'V' }))
1767 call assert_equal(['one', 'two'],
1768 \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': "\<c-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001769
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001770 #" Multiline with line visual mode
1771 call cursor(1, 1)
1772 call feedkeys("\<ESC>Vjj", 'tx')
1773 call assert_equal(['one', 'two', 'three'],
1774 \ getregion(getpos('v'), getpos('.'), {'type': 'V' }))
zeertzjq2b09de92024-05-24 07:48:51 +02001775 call assert_equal([
1776 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1777 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1778 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1779 \ ],
1780 \ getregionpos(getpos('v'), getpos('.'), {'type': 'V' }))
1781 call assert_equal([
1782 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
1783 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
1784 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 0]],
1785 \ ],
1786 \ getregionpos(getpos('v'), getpos('.'),
1787 \ {'type': 'V', 'eol': v:true }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001788
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001789 #" Multiline with block visual mode
1790 call cursor(1, 1)
1791 call feedkeys("\<ESC>\<C-v>jj", 'tx')
1792 call assert_equal(['o', 't', 't'],
1793 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02001794 call assert_equal([
1795 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
1796 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
1797 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 1, 0]],
1798 \ ],
1799 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001800
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001801 call cursor(1, 1)
1802 call feedkeys("\<ESC>\<C-v>jj$", 'tx')
1803 call assert_equal(['one', 'two', 'three'],
1804 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02001805 call assert_equal([
1806 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1807 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1808 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1809 \ ],
1810 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1811 call assert_equal([
1812 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1813 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1814 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1815 \ ],
1816 \ getregionpos(getpos('v'), getpos('.'),
1817 \ {'type': "\<C-v>", 'eol': v:true }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001818
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001819 #" 'virtualedit'
1820 set virtualedit=all
zeertzjq2b09de92024-05-24 07:48:51 +02001821
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001822 call cursor(1, 1)
1823 call feedkeys("\<ESC>\<C-v>10ljj$", 'tx')
1824 call assert_equal(['one ', 'two ', 'three '],
1825 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02001826 call assert_equal([
1827 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
1828 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1829 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1830 \ ],
1831 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1832 call assert_equal([
1833 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 3]],
1834 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 3]],
1835 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 1]],
1836 \ ],
1837 \ getregionpos(getpos('v'), getpos('.'),
1838 \ {'type': "\<C-v>", 'eol': v:true }))
1839
1840 call cursor(3, 5)
1841 call feedkeys("\<ESC>\<C-v>hkk", 'tx')
1842 call assert_equal([' ', ' ', 'ee'],
1843 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1844 call assert_equal([
1845 \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
1846 \ [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
1847 \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
1848 \ ],
1849 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1850 call assert_equal([
1851 \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 2]],
1852 \ [[bufnr('%'), 2, 4, 0], [bufnr('%'), 2, 4, 2]],
1853 \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
1854 \ ],
1855 \ getregionpos(getpos('v'), getpos('.'),
1856 \ {'type': "\<C-v>", 'eol': v:true }))
1857
1858 call cursor(3, 5)
1859 call feedkeys("\<ESC>\<C-v>kk", 'tx')
1860 call assert_equal([' ', ' ', 'e'],
1861 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1862 call assert_equal([
1863 \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
1864 \ [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
1865 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
1866 \ ],
1867 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
1868 call assert_equal([
1869 \ [[bufnr('%'), 1, 4, 1], [bufnr('%'), 1, 4, 2]],
1870 \ [[bufnr('%'), 2, 4, 1], [bufnr('%'), 2, 4, 2]],
1871 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
1872 \ ],
1873 \ getregionpos(getpos('v'), getpos('.'),
1874 \ {'type': "\<C-v>", 'eol': v:true }))
1875
1876 call cursor(1, 3)
1877 call feedkeys("\<ESC>vjj4l", 'tx')
1878 call assert_equal(['e', 'two', 'three '],
1879 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1880 call assert_equal([
1881 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
1882 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1883 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1884 \ ],
1885 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1886 call assert_equal([
1887 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
1888 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
1889 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
1890 \ ],
1891 \ getregionpos(getpos('v'), getpos('.'),
1892 \ {'type': 'v', 'eol': v:true }))
1893
1894 call cursor(1, 3)
1895 call feedkeys("\<ESC>lvjj3l", 'tx')
1896 call assert_equal(['', 'two', 'three '],
1897 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1898 call assert_equal([
1899 \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
1900 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
1901 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
1902 \ ],
1903 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1904 call assert_equal([
1905 \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 0]],
1906 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
1907 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
1908 \ ],
1909 \ getregionpos(getpos('v'), getpos('.'),
1910 \ {'type': 'v', 'eol': v:true }))
1911
1912 call cursor(3, 5)
1913 call feedkeys("\<ESC>v3l", 'tx')
1914 call assert_equal(['e '],
1915 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1916 call assert_equal([
1917 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
1918 \ ],
1919 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1920 call assert_equal([
1921 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 6, 3]],
1922 \ ],
1923 \ getregionpos(getpos('v'), getpos('.'),
1924 \ {'type': 'v', 'eol': v:true }))
1925
1926 call cursor(3, 5)
1927 call feedkeys("\<ESC>lv3l", 'tx')
1928 call assert_equal([' '],
1929 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1930 call assert_equal([
1931 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
1932 \ ],
1933 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1934 call assert_equal([
1935 \ [[bufnr('%'), 3, 6, 0], [bufnr('%'), 3, 6, 4]],
1936 \ ],
1937 \ getregionpos(getpos('v'), getpos('.'),
1938 \ {'type': 'v', 'eol': v:true }))
1939
1940 call cursor(3, 5)
1941 call feedkeys("\<ESC>3lv3l", 'tx')
1942 call assert_equal([' '],
1943 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
1944 call assert_equal([
1945 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
1946 \ ],
1947 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
1948 call assert_equal([
1949 \ [[bufnr('%'), 3, 6, 2], [bufnr('%'), 3, 6, 6]],
1950 \ ],
1951 \ getregionpos(getpos('v'), getpos('.'),
1952 \ {'type': 'v', 'eol': v:true }))
1953
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001954 set virtualedit&
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01001955
zeertzjq26dd09a2024-03-10 15:46:58 +01001956 #" using wrong types for positions
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001957 call cursor(1, 1)
1958 call feedkeys("\<ESC>vjj$", 'tx')
1959 call assert_fails("call getregion(1, 2)", 'E1211:')
1960 call assert_fails("call getregion(getpos('.'), {})", 'E1211:')
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001961 call assert_fails(':echo "."->getpos()->getregion("$", [])', 'E1211:')
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001962 call assert_fails("call getregionpos(1, 2)", 'E1211:')
1963 call assert_fails("call getregionpos(getpos('.'), {})", 'E1211:')
1964 call assert_fails(':echo "."->getpos()->getregionpos("$", [])', 'E1211:')
Shougo Matsushita19b71882024-02-28 22:48:12 +01001965
zeertzjq26dd09a2024-03-10 15:46:58 +01001966 #" using invalid value for "type"
1967 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001968 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
zeertzjqafc22952024-05-24 19:07:12 +02001969 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': 'v0' })", 'E475:')
1970 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': 'v0' })", 'E475:')
1971 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': 'V0' })", 'E475:')
1972 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': 'V0' })", 'E475:')
1973 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
1974 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
1975 call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
1976 call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
zeertzjq26dd09a2024-03-10 15:46:58 +01001977
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01001978 #" using a mark from another buffer to current buffer
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001979 new
zeertzjq26dd09a2024-03-10 15:46:58 +01001980 LET g:buf = bufnr()
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001981 call setline(1, range(10))
1982 normal! GmA
1983 wincmd p
zeertzjq26dd09a2024-03-10 15:46:58 +01001984 call assert_equal([g:buf, 10, 1, 0], getpos("'A"))
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01001985 call assert_equal([], getregion(getpos('.'), getpos("'A"), {'type': 'v' }))
1986 call assert_equal([], getregion(getpos("'A"), getpos('.'), {'type': 'v' }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001987 call assert_equal([], getregionpos(getpos('.'), getpos("'A"), {'type': 'v' }))
1988 call assert_equal([], getregionpos(getpos("'A"), getpos('.'), {'type': 'v' }))
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01001989
zeertzjq26dd09a2024-03-10 15:46:58 +01001990 #" using two marks from another buffer
1991 wincmd p
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01001992 normal! GmB
1993 wincmd p
zeertzjq26dd09a2024-03-10 15:46:58 +01001994 call assert_equal([g:buf, 10, 1, 0], getpos("'B"))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02001995 call assert_equal(['9'],
1996 \ getregion(getpos("'B"), getpos("'A"), {'type': 'v' }))
1997 call assert_equal([
1998 \ [[g:buf, 10, 1, 0], [g:buf, 10, 1, 0]],
1999 \ ],
2000 \ getregionpos(getpos("'B"), getpos("'A"), {'type': 'v' }))
zeertzjq26dd09a2024-03-10 15:46:58 +01002001
2002 #" using two positions from another buffer
2003 for type in ['v', 'V', "\<C-V>"]
2004 for exclusive in [v:false, v:true]
2005 call assert_equal(range(10)->mapnew('string(v:val)'),
zeertzjq5406eb82024-03-11 21:36:42 +01002006 \ getregion([g:buf, 1, 1, 0], [g:buf, 10, 2, 0],
2007 \ {'type': type, 'exclusive': exclusive }))
zeertzjq26dd09a2024-03-10 15:46:58 +01002008 call assert_equal(range(10)->mapnew('string(v:val)'),
zeertzjq5406eb82024-03-11 21:36:42 +01002009 \ getregion([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
2010 \ {'type': type, 'exclusive': exclusive }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002011 call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
2012 \ getregionpos([g:buf, 1, 1, 0], [g:buf, 10, 2, 0],
2013 \ {'type': type, 'exclusive': exclusive }))
2014 call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
2015 \ getregionpos([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
2016 \ {'type': type, 'exclusive': exclusive }))
zeertzjq26dd09a2024-03-10 15:46:58 +01002017 endfor
2018 endfor
2019
2020 #" using invalid positions in buffer
2021 call assert_fails('call getregion([g:buf, 0, 1, 0], [g:buf, 10, 2, 0])', 'E966:')
2022 call assert_fails('call getregion([g:buf, 10, 2, 0], [g:buf, 0, 1, 0])', 'E966:')
2023 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 11, 2, 0])', 'E966:')
2024 call assert_fails('call getregion([g:buf, 11, 2, 0], [g:buf, 1, 1, 0])', 'E966:')
2025 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 0, 0])', 'E964:')
2026 call assert_fails('call getregion([g:buf, 10, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
2027 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 3, 0])', 'E964:')
2028 call assert_fails('call getregion([g:buf, 10, 3, 0], [g:buf, 1, 1, 0])', 'E964:')
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002029 call assert_fails('call getregion([g:buf, 1, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
2030 call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 1, 0, 0])', 'E964:')
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002031
2032 #" using invalid buffer
zeertzjq26dd09a2024-03-10 15:46:58 +01002033 call assert_fails('call getregion([10000, 10, 1, 0], [10000, 10, 1, 0])', 'E681:')
2034
2035 exe $':{g:buf}bwipe!'
2036 unlet g:buf
zeertzjq2b09de92024-05-24 07:48:51 +02002037 bwipe!
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002038 END
2039 call v9.CheckLegacyAndVim9Success(lines)
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002040
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002041 let lines =<< trim END
2042 #" Selection in starts or ends in the middle of a multibyte character
2043 new
2044 call setline(1, [
2045 \ "abcdefghijk\u00ab",
2046 \ "\U0001f1e6\u00ab\U0001f1e7\u00ab\U0001f1e8\u00ab\U0001f1e9",
2047 \ "1234567890"
2048 \ ])
zeertzjqc95e64f2024-05-20 14:00:31 +02002049
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002050 call cursor(1, 3)
2051 call feedkeys("\<Esc>\<C-v>ljj", 'xt')
2052 call assert_equal(['cd', "\u00ab ", '34'],
2053 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002054 call assert_equal([
2055 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
2056 \ [[bufnr('%'), 2, 5, 0], [bufnr('%'), 2, 7, 1]],
2057 \ [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 4, 0]],
2058 \ ],
2059 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2060
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002061 call cursor(1, 4)
2062 call feedkeys("\<Esc>\<C-v>ljj", 'xt')
2063 call assert_equal(['de', "\U0001f1e7", '45'],
2064 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002065 call assert_equal([
2066 \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 5, 0]],
2067 \ [[bufnr('%'), 2, 7, 0], [bufnr('%'), 2, 10, 0]],
2068 \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
2069 \ ],
2070 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2071
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002072 call cursor(1, 5)
2073 call feedkeys("\<Esc>\<C-v>jj", 'xt')
2074 call assert_equal(['e', ' ', '5'],
2075 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002076 call assert_equal([
zeertzjqc95e64f2024-05-20 14:00:31 +02002077 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 5, 0]],
zeertzjqef733742024-05-26 18:42:18 +02002078 \ [[bufnr('%'), 2, 7, 1], [bufnr('%'), 2, 7, 2]],
zeertzjqc95e64f2024-05-20 14:00:31 +02002079 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
2080 \ ],
2081 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqef733742024-05-26 18:42:18 +02002082 call assert_equal(['efghijk«', '🇦«🇧«🇨«🇩', '12345'],
2083 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002084 call assert_equal([
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002085 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 13, 0]],
2086 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 22, 0]],
2087 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
2088 \ ],
2089 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002090
zeertzjqef733742024-05-26 18:42:18 +02002091 call cursor(1, 5)
2092 call feedkeys("\<Esc>\<C-v>5l2j", 'xt')
2093 call assert_equal(['efghij', ' «🇨« ', '567890'],
2094 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2095 call assert_equal([
2096 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 10, 0]],
2097 \ [[bufnr('%'), 2, 7, 1], [bufnr('%'), 2, 19, 1]],
2098 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 10, 0]],
2099 \ ],
2100 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2101
2102 call cursor(1, 4)
2103 call feedkeys("\<Esc>\<C-v>02j", 'xt')
2104 call assert_equal(['abcd', '🇦« ', '1234'],
2105 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2106 call assert_equal([
2107 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
2108 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 7, 1]],
2109 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 4, 0]],
2110 \ ],
2111 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2112
zeertzjq52a6f342024-05-22 16:42:44 +02002113 #" characterwise selection with multibyte chars
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002114 call cursor(1, 1)
2115 call feedkeys("\<Esc>vj", 'xt')
2116 call assert_equal(['abcdefghijk«', "\U0001f1e6"],
2117 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002118 call assert_equal([
2119 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
2120 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
2121 \ ],
2122 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
Shougo Matsushita19b71882024-02-28 22:48:12 +01002123
zeertzjq52a6f342024-05-22 16:42:44 +02002124 set selection=exclusive
2125 call feedkeys('l', 'xt')
2126 call assert_equal(['abcdefghijk«', "\U0001f1e6"],
2127 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2128 call assert_equal([
2129 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
2130 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
2131 \ ],
2132 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2133
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002134 #" marks on multibyte chars
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002135 call setpos("'a", [0, 1, 11, 0])
2136 call setpos("'b", [0, 2, 16, 0])
2137 call setpos("'c", [0, 2, 0, 0])
2138 call cursor(1, 1)
zeertzjqc95e64f2024-05-20 14:00:31 +02002139
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002140 call assert_equal(['ghijk', '🇨«🇩'],
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002141 \ getregion(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002142 call assert_equal([
2143 \ [[bufnr('%'), 1, 7, 0], [bufnr('%'), 1, 11, 0]],
2144 \ [[bufnr('%'), 2, 13, 0], [bufnr('%'), 2, 22, 0]],
2145 \ ],
2146 \ getregionpos(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
2147
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002148 call assert_equal(['k«', '🇦«🇧«🇨'],
2149 \ getregion(getpos("'a"), getpos("'b"), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002150 call assert_equal([
2151 \ [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
2152 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 16, 0]],
2153 \ ],
2154 \ getregionpos(getpos("'a"), getpos("'b"), {'type': 'v' }))
2155
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002156 call assert_equal(['k«'],
2157 \ getregion(getpos("'a"), getpos("'c"), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002158 call assert_equal([
2159 \ [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
2160 \ ],
2161 \ getregionpos(getpos("'a"), getpos("'c"), {'type': 'v' }))
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002162
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002163 #" use inclusive selection, although 'selection' is exclusive
2164 call setpos("'a", [0, 1, 11, 0])
2165 call setpos("'b", [0, 1, 1, 0])
2166 call assert_equal(['abcdefghijk'],
2167 \ getregion(getpos("'a"), getpos("'b"),
2168 \ {'type': "\<c-v>", 'exclusive': v:false }))
2169 call assert_equal(['abcdefghij'],
2170 \ getregion(getpos("'a"), getpos("'b"),
2171 \ {'type': "\<c-v>", 'exclusive': v:true }))
2172 call assert_equal(['abcdefghijk'],
2173 \ getregion(getpos("'a"), getpos("'b"),
2174 \ {'type': 'v', 'exclusive': 0 }))
2175 call assert_equal(['abcdefghij'],
2176 \ getregion(getpos("'a"), getpos("'b"),
2177 \ {'type': 'v', 'exclusive': 1 }))
2178 call assert_equal(['abcdefghijk«'],
2179 \ getregion(getpos("'a"), getpos("'b"),
2180 \ {'type': 'V', 'exclusive': 0 }))
2181 call assert_equal(['abcdefghijk«'],
2182 \ getregion(getpos("'a"), getpos("'b"),
2183 \ {'type': 'V', 'exclusive': 1 }))
zeertzjq2b09de92024-05-24 07:48:51 +02002184
2185 set selection&
2186 bwipe!
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002187 END
2188 call v9.CheckLegacyAndVim9Success(lines)
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002189
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002190 let lines =<< trim END
2191 #" Exclusive selection
2192 new
2193 set selection=exclusive
2194 call setline(1, ["a\tc", "x\tz", '', ''])
2195 call cursor(1, 1)
2196 call feedkeys("\<Esc>v2l", 'xt')
2197 call assert_equal(["a\t"],
2198 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2199 call cursor(1, 1)
2200 call feedkeys("\<Esc>v$G", 'xt')
2201 call assert_equal(["a\tc", "x\tz", ''],
2202 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2203 call cursor(1, 1)
2204 call feedkeys("\<Esc>v$j", 'xt')
2205 call assert_equal(["a\tc", "x\tz"],
2206 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2207 call cursor(1, 1)
2208 call feedkeys("\<Esc>\<C-v>$j", 'xt')
2209 call assert_equal(["a\tc", "x\tz"],
2210 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2211 call cursor(1, 1)
2212 call feedkeys("\<Esc>\<C-v>$G", 'xt')
2213 call assert_equal(["a", "x", '', ''],
2214 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2215 call cursor(1, 1)
2216 call feedkeys("\<Esc>wv2j", 'xt')
2217 call assert_equal(["c", "x\tz"],
2218 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2219 set selection&
zeertzjq52a6f342024-05-22 16:42:44 +02002220 bwipe!
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002221
2222 #" Exclusive selection 2
2223 new
2224 call setline(1, ["a\tc", "x\tz", '', ''])
zeertzjq701ad502024-05-23 07:47:55 +02002225
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002226 call cursor(1, 1)
2227 call feedkeys("\<Esc>v2l", 'xt')
2228 call assert_equal(["a\t"],
2229 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002230 call assert_equal([
2231 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
2232 \ ],
2233 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
2234
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002235 call cursor(1, 1)
2236 call feedkeys("\<Esc>v$G", 'xt')
2237 call assert_equal(["a\tc", "x\tz", ''],
2238 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002239 call assert_equal([
2240 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2241 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2242 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
2243 \ ],
2244 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
2245
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002246 call cursor(1, 1)
2247 call feedkeys("\<Esc>v$j", 'xt')
2248 call assert_equal(["a\tc", "x\tz"],
2249 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002250 call assert_equal([
2251 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2252 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2253 \ ],
2254 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
2255
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002256 call cursor(1, 1)
2257 call feedkeys("\<Esc>\<C-v>$j", 'xt')
2258 call assert_equal(["a\tc", "x\tz"],
2259 \ getregion(getpos('v'), getpos('.'),
2260 \ {'exclusive': v:true, 'type': "\<C-v>" }))
zeertzjq701ad502024-05-23 07:47:55 +02002261 call assert_equal([
2262 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2263 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2264 \ ],
2265 \ getregionpos(getpos('v'), getpos('.'),
2266 \ {'exclusive': v:true, 'type': "\<C-v>" }))
2267
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002268 call cursor(1, 1)
2269 call feedkeys("\<Esc>\<C-v>$G", 'xt')
2270 call assert_equal(["a", "x", '', ''],
2271 \ getregion(getpos('v'), getpos('.'),
2272 \ {'exclusive': v:true, 'type': "\<C-v>" }))
zeertzjq701ad502024-05-23 07:47:55 +02002273 call assert_equal([
2274 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
2275 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
2276 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
2277 \ [[bufnr('%'), 4, 0, 0], [bufnr('%'), 4, 0, 0]],
2278 \ ],
2279 \ getregionpos(getpos('v'), getpos('.'),
2280 \ {'exclusive': v:true, 'type': "\<C-v>" }))
2281
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002282 call cursor(1, 1)
2283 call feedkeys("\<Esc>wv2j", 'xt')
2284 call assert_equal(["c", "x\tz"],
2285 \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002286 call assert_equal([
2287 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
2288 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
2289 \ ],
2290 \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002291
zeertzjq701ad502024-05-23 07:47:55 +02002292 #" 'virtualedit' with exclusive selection
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002293 set selection=exclusive
2294 set virtualedit=all
zeertzjqc95e64f2024-05-20 14:00:31 +02002295
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002296 call cursor(1, 1)
zeertzjq701ad502024-05-23 07:47:55 +02002297 call feedkeys("\<Esc>vj", 'xt')
2298 call assert_equal(["a\tc"],
2299 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2300 call assert_equal([
2301 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2302 \ ],
2303 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2304
2305 call cursor(1, 1)
2306 call feedkeys("\<Esc>v8l", 'xt')
2307 call assert_equal(["a\t"],
2308 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2309 call assert_equal([
2310 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
2311 \ ],
2312 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2313
2314 call cursor(1, 1)
2315 call feedkeys("\<Esc>v6l", 'xt')
2316 call assert_equal(['a '],
2317 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2318 call assert_equal([
2319 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 5]],
2320 \ ],
2321 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2322
2323 call cursor(1, 1)
2324 call feedkeys("\<Esc>6lv2l", 'xt')
2325 call assert_equal([' '],
2326 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2327 call assert_equal([
2328 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 0]],
2329 \ ],
2330 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2331
2332 call cursor(1, 1)
zeertzjq52a6f342024-05-22 16:42:44 +02002333 call feedkeys("\<Esc>lv2l", 'xt')
2334 call assert_equal([' '],
2335 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2336 call assert_equal([
2337 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
2338 \ ],
2339 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2340
2341 call cursor(1, 1)
2342 call feedkeys("\<Esc>2lv2l", 'xt')
2343 call assert_equal([' '],
2344 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2345 call assert_equal([
2346 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
2347 \ ],
2348 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2349
2350 call feedkeys('j', 'xt')
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002351 call assert_equal([' c', 'x '],
2352 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002353 call assert_equal([
2354 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
2355 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 3]],
2356 \ ],
2357 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2358
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002359 call cursor(1, 1)
zeertzjq52a6f342024-05-22 16:42:44 +02002360 call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
2361 call assert_equal([' ', ' '],
2362 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2363 call assert_equal([
2364 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 7]],
2365 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 7]],
2366 \ ],
2367 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2368
2369 call cursor(1, 1)
2370 call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
2371 call assert_equal([' ', ' ', ' '],
2372 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2373 call assert_equal([
2374 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
2375 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
zeertzjq2b09de92024-05-24 07:48:51 +02002376 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjq52a6f342024-05-22 16:42:44 +02002377 \ ],
2378 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002379 call assert_equal([
2380 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
2381 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
2382 \ [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 3]],
2383 \ ],
2384 \ getregionpos(getpos('v'), getpos('.'),
2385 \ {'type': "\<C-v>", "eol": v:true }))
zeertzjq52a6f342024-05-22 16:42:44 +02002386
2387 call cursor(1, 1)
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002388 call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
2389 call assert_equal([' ', ' ', ' '],
2390 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002391 call assert_equal([
zeertzjq52a6f342024-05-22 16:42:44 +02002392 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
2393 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
zeertzjq2b09de92024-05-24 07:48:51 +02002394 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjqc95e64f2024-05-20 14:00:31 +02002395 \ ],
2396 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002397 call assert_equal([
2398 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
2399 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
2400 \ [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 4]],
2401 \ ],
2402 \ getregionpos(getpos('v'), getpos('.'),
2403 \ {'type': "\<C-v>", "eol": v:true }))
zeertzjqc95e64f2024-05-20 14:00:31 +02002404
zeertzjq701ad502024-05-23 07:47:55 +02002405 #" 'virtualedit' with inclusive selection
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002406 set selection&
2407
zeertzjq701ad502024-05-23 07:47:55 +02002408 call cursor(1, 1)
2409 call feedkeys("\<Esc>vj", 'xt')
2410 call assert_equal(["a\tc", 'x'],
2411 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2412 call assert_equal([
2413 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2414 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
2415 \ ],
2416 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2417
2418 call cursor(1, 1)
2419 call feedkeys("\<Esc>v8l", 'xt')
2420 call assert_equal(["a\tc"],
2421 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2422 call assert_equal([
2423 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
2424 \ ],
2425 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2426
2427 call cursor(1, 1)
2428 call feedkeys("\<Esc>v6l", 'xt')
2429 call assert_equal(['a '],
2430 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2431 call assert_equal([
2432 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 6]],
2433 \ ],
2434 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2435
2436 call cursor(1, 1)
2437 call feedkeys("\<Esc>6lv2l", 'xt')
2438 call assert_equal([' c'],
2439 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2440 call assert_equal([
2441 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
2442 \ ],
2443 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2444
2445 call cursor(1, 1)
2446 call feedkeys("\<Esc>lv2l", 'xt')
2447 call assert_equal([' '],
2448 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2449 call assert_equal([
2450 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
2451 \ ],
2452 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2453
2454 call cursor(1, 1)
2455 call feedkeys("\<Esc>2lv2l", 'xt')
2456 call assert_equal([' '],
2457 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2458 call assert_equal([
2459 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
2460 \ ],
2461 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2462
2463 call feedkeys('j', 'xt')
2464 call assert_equal([' c', 'x '],
2465 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2466 call assert_equal([
2467 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
2468 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 4]],
2469 \ ],
2470 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2471
2472 call cursor(1, 1)
2473 call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
2474 call assert_equal([' c', ' z'],
2475 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2476 call assert_equal([
2477 \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
2478 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 0]],
2479 \ ],
2480 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2481
2482 call cursor(1, 1)
2483 call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
2484 call assert_equal([' ', ' ', ' '],
2485 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2486 call assert_equal([
2487 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
2488 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
zeertzjq2b09de92024-05-24 07:48:51 +02002489 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjq701ad502024-05-23 07:47:55 +02002490 \ ],
2491 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002492 call assert_equal([
2493 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
2494 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
2495 \ [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 4]],
2496 \ ],
2497 \ getregionpos(getpos('v'), getpos('.'),
2498 \ {'type': "\<C-v>", "eol": v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002499
2500 call cursor(1, 1)
2501 call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
2502 call assert_equal([' ', ' ', ' '],
2503 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2504 call assert_equal([
2505 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
2506 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
zeertzjq2b09de92024-05-24 07:48:51 +02002507 \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
zeertzjq701ad502024-05-23 07:47:55 +02002508 \ ],
2509 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
zeertzjq2b09de92024-05-24 07:48:51 +02002510 call assert_equal([
2511 \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
2512 \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
2513 \ [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 5]],
2514 \ ],
2515 \ getregionpos(getpos('v'), getpos('.'),
2516 \ {'type': "\<C-v>", "eol": v:true }))
2517
2518 set virtualedit&
2519 bwipe!
2520 END
2521 call v9.CheckLegacyAndVim9Success(lines)
2522
2523 let lines =<< trim END
2524 #" 'virtualedit' with TABs at end of line
2525 new
2526 set virtualedit=all
2527 call setline(1, ["\t", "a\t", "aa\t"])
2528
2529 call feedkeys("gg06l\<C-v>3l2j", 'xt')
2530 call assert_equal([' ', ' ', ' '],
2531 \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2532 call assert_equal([
2533 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
2534 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 0]],
2535 \ [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 3, 0]],
2536 \ ],
2537 \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
2538 call assert_equal([
2539 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
2540 \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 2]],
2541 \ [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 4, 2]],
2542 \ ],
2543 \ getregionpos(getpos('v'), getpos('.'),
2544 \ {'type': "\<C-v>", "eol": v:true }))
2545
2546 call feedkeys("gg06lv3l", 'xt')
2547 call assert_equal([' '],
2548 \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
2549 call assert_equal([
2550 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
2551 \ ],
2552 \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
2553 call assert_equal([
2554 \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
2555 \ ],
2556 \ getregionpos(getpos('v'), getpos('.'),
2557 \ {'type': 'v', "eol": v:true }))
zeertzjq701ad502024-05-23 07:47:55 +02002558
2559 set virtualedit&
Yegappan Lakshmanan4d55c542024-02-29 17:30:43 +01002560 bwipe!
2561 END
2562 call v9.CheckLegacyAndVim9Success(lines)
Shougo Matsushita3f905ab2024-02-21 00:02:45 +01002563endfunc
2564
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002565func Test_getregion_invalid_buf()
2566 new
2567 help
2568 call cursor(5, 7)
2569 norm! mA
2570 call cursor(5, 18)
2571 norm! mB
2572 call assert_equal(['Move around:'], getregion(getpos("'A"), getpos("'B")))
2573 " close the help window
2574 q
zeertzjq26dd09a2024-03-10 15:46:58 +01002575 call assert_fails("call getregion(getpos(\"'A\"), getpos(\"'B\"))", 'E681:')
Shougo Matsushita84bf6e62024-03-06 21:10:18 +01002576 bwipe!
2577endfunc
2578
zeertzjqafc22952024-05-24 19:07:12 +02002579func Test_getregion_after_yank()
2580 func! Check_Results(type)
2581 call assert_equal(g:expected_region,
2582 \ getregion(getpos("'["), getpos("']"), #{ type: a:type }))
2583 call assert_equal(g:expected_regionpos,
2584 \ getregionpos(getpos("'["), getpos("']"), #{ type: a:type }))
2585 call assert_equal(g:expected_region,
2586 \ getregion(getpos("']"), getpos("'["), #{ type: a:type }))
2587 call assert_equal(g:expected_regionpos,
2588 \ getregionpos(getpos("']"), getpos("'["), #{ type: a:type }))
2589 let g:checked = 1
2590 endfunc
2591
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002592 autocmd TextYankPost *
2593 \ : if v:event.operator ==? 'y'
zeertzjqafc22952024-05-24 19:07:12 +02002594 \ | call Check_Results(v:event.regtype)
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002595 \ | endif
zeertzjqafc22952024-05-24 19:07:12 +02002596
2597 new
2598 call setline(1, ['abcd', 'efghijk', 'lmn'])
2599
2600 let g:expected_region = ['abcd']
2601 let g:expected_regionpos = [
2602 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
2603 \ ]
2604 let g:checked = 0
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002605 normal yy
zeertzjqafc22952024-05-24 19:07:12 +02002606 call assert_equal(1, g:checked)
2607 call Check_Results(getregtype('"'))
2608
2609 let g:expected_region = ['cd', 'ghijk', 'n']
2610 let g:expected_regionpos = [
2611 \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
2612 \ [[bufnr('%'), 2, 3, 0], [bufnr('%'), 2, 7, 0]],
2613 \ [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 3, 0]],
2614 \ ]
2615 let g:checked = 0
2616 call feedkeys("gg0ll\<C-V>jj$y", 'tx')
2617 call assert_equal(1, g:checked)
2618 call Check_Results(getregtype('"'))
zeertzjqdff55a32024-05-25 10:25:36 +02002619 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
zeertzjqafc22952024-05-24 19:07:12 +02002620
2621 let g:expected_region = ['bc', 'fg', 'mn']
2622 let g:expected_regionpos = [
2623 \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 3, 0]],
2624 \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 3, 0]],
2625 \ [[bufnr('%'), 3, 2, 0], [bufnr('%'), 3, 3, 0]],
2626 \ ]
2627 let g:checked = 0
2628 call feedkeys("gg0l\<C-V>jjly", 'tx')
2629 call assert_equal(1, g:checked)
2630 call Check_Results(getregtype('"'))
zeertzjqdff55a32024-05-25 10:25:36 +02002631 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2632
2633 bwipe!
2634
2635 new
2636 let lines = ['asdfghjkl', '«口=口»', 'qwertyuiop', '口口=口口', 'zxcvbnm']
2637 call setline(1, lines)
2638
2639 let g:expected_region = lines
2640 let g:expected_regionpos = [
2641 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 9, 0]],
2642 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 11, 0]],
2643 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 10, 0]],
2644 \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 13, 0]],
2645 \ [[bufnr('%'), 5, 1, 0], [bufnr('%'), 5, 7, 0]],
2646 \ ]
2647 let g:checked = 0
2648 call feedkeys('ggyG', 'tx')
2649 call assert_equal(1, g:checked)
2650 call Check_Results(getregtype('"'))
2651 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2652
2653 let g:expected_region = ['=口»', 'qwertyuiop', '口口=口']
2654 let g:expected_regionpos = [
2655 \ [[bufnr('%'), 2, 6, 0], [bufnr('%'), 2, 11, 0]],
2656 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 10, 0]],
2657 \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 10, 0]],
2658 \ ]
2659 let g:checked = 0
2660 call feedkeys('2gg02lv2j2ly', 'tx')
2661 call assert_equal(1, g:checked)
2662 call Check_Results(getregtype('"'))
2663 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2664
2665 let g:expected_region = ['asdf', '«口=', 'qwer', '口口', 'zxcv']
2666 let g:expected_regionpos = [
2667 \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
2668 \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 6, 0]],
2669 \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 4, 0]],
2670 \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 6, 0]],
2671 \ [[bufnr('%'), 5, 1, 0], [bufnr('%'), 5, 4, 0]],
2672 \ ]
2673 let g:checked = 0
2674 call feedkeys("G0\<C-V>3l4ky", 'tx')
2675 call assert_equal(1, g:checked)
2676 call Check_Results(getregtype('"'))
2677 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
2678
2679 let g:expected_region = ['ghjkl', '口»', 'tyuiop', '=口口', 'bnm']
2680 let g:expected_regionpos = [
2681 \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 9, 0]],
2682 \ [[bufnr('%'), 2, 7, 0], [bufnr('%'), 2, 11, 0]],
2683 \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 10, 0]],
2684 \ [[bufnr('%'), 4, 7, 0], [bufnr('%'), 4, 13, 0]],
2685 \ [[bufnr('%'), 5, 5, 0], [bufnr('%'), 5, 7, 0]],
2686 \ ]
2687 let g:checked = 0
2688 call feedkeys("G04l\<C-V>$4ky", 'tx')
2689 call assert_equal(1, g:checked)
2690 call Check_Results(getregtype('"'))
2691 call assert_equal(g:expected_region, getreg('"', v:true, v:true))
zeertzjqafc22952024-05-24 19:07:12 +02002692
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002693 bwipe!
zeertzjqafc22952024-05-24 19:07:12 +02002694
2695 unlet g:expected_region
2696 unlet g:expected_regionpos
2697 unlet g:checked
2698 autocmd! TextYankPost
2699 delfunc Check_Results
Shougo Matsushitab4757e62024-05-07 20:49:24 +02002700endfunc
2701
Christian Brabandtd5c8c092024-05-08 22:17:19 +02002702func Test_visual_block_cursor_delete()
2703 new
2704 call setline(1, 'ab')
2705 exe ":norm! $\<c-v>hI\<Del>\<ESC>"
2706 call assert_equal(['b'], getline(1, 1))
2707 bwipe!
2708endfunc
2709
Christian Brabandt1fb9eae2024-06-11 20:30:14 +02002710func Test_visual_block_cursor_insert_enter()
2711 new
2712 call setline(1, ['asdf asdf', 'asdf asdf', 'asdf asdf', 'asdf asdf'])
2713 call cursor(1, 5)
2714 exe ":norm! \<c-v>3jcw\<cr>"
2715 call assert_equal(['asdfw', 'asdf', 'asdfasdf', 'asdfasdf', 'asdfasdf'], getline(1, '$'))
2716 bwipe!
2717endfunc
2718
Christian Brabandtbb955892024-12-16 22:49:15 +01002719func Test_visual_block_exclusive_selection()
2720 new
2721 set selection=exclusive
2722 call setline(1, ['asöd asdf', 'asdf asdf', 'asd asdf', 'asdf asdf'])
2723 call cursor(1, 1)
2724 exe ":norm! \<c-v>eh3j~"
2725 call assert_equal(['ASÖd asdf', 'ASDf asdf', 'ASd asdf', 'ASDf asdf'], getline(1, '$'))
2726 exe ":norm! 1v~"
2727 call assert_equal(['asöd asdf', 'asdf asdf', 'asd asdf', 'asdf asdf'], getline(1, '$'))
2728 bwipe!
2729 set selection&vim
2730endfunc
2731
2732func Test_visual_block_exclusive_selection_adjusted()
2733 new
2734 " Test that the end-position of the visual selection is adjusted for exclusive selection
2735 set selection=exclusive
2736 call setline(1, ['asöd asdf ', 'asdf asdf ', 'asd asdf ', 'asdf asdf '])
2737 call cursor(1, 1)
2738 " inclusive motion
2739 exe ":norm! \<c-v>e3jy"
2740 call assert_equal([0, 4, 5, 0], getpos("'>"))
2741 " exclusive motion
2742 exe ":norm! \<c-v>ta3jy"
2743 call assert_equal([0, 4, 6, 0], getpos("'>"))
2744 " another inclusive motion
2745 exe ":norm! \<c-v>g_3jy"
2746 call assert_equal([0, 4, 10, 0], getpos("'>"))
2747
2748 " Reset selection option to Vim default
2749 set selection&vim
2750 call cursor(1, 1)
2751
2752 " inclusive motion
2753 exe ":norm! \<c-v>e3jy"
2754 call assert_equal([0, 4, 4, 0], getpos("'>"))
2755 " exclusive motion
2756 exe ":norm! \<c-v>ta3jy"
2757 call assert_equal([0, 4, 5, 0], getpos("'>"))
2758 " another inclusive motion
2759 exe ":norm! \<c-v>g_3jy"
2760 call assert_equal([0, 4, 9, 0], getpos("'>"))
2761 bwipe!
2762 set selection&vim
2763endfunc
2764
Christian Brabandtc9a1e252025-01-11 15:25:00 +01002765" the following caused a Heap-Overflow, because Vim was accessing outside of a
2766" line end
2767func Test_visual_pos_buffer_heap_overflow()
2768 set virtualedit=all
2769 args Xa Xb
2770 all
2771 call setline(1, ['', '', ''])
2772 call cursor(3, 1)
2773 wincmd w
2774 call setline(1, 'foobar')
2775 normal! $lv0
2776 all
2777 call setreg('"', 'baz')
2778 normal! [P
2779 set virtualedit=
2780 bw! Xa Xb
2781endfunc
2782
Bram Moolenaar6f1f0ca2019-12-01 18:16:18 +01002783" vim: shiftwidth=2 sts=2 expandtab