1" Test for textobjects 2 3source check.vim 4CheckFeature textobjects 5 6func CpoM(line, useM, expected) 7 new 8 9 if a:useM 10 set cpoptions+=M 11 else 12 set cpoptions-=M 13 endif 14 15 call setline(1, a:line) 16 17 call setreg('"', '') 18 normal! ggfrmavi)y 19 call assert_equal(getreg('"'), a:expected[0]) 20 21 call setreg('"', '') 22 normal! `afbmavi)y 23 call assert_equal(getreg('"'), a:expected[1]) 24 25 call setreg('"', '') 26 normal! `afgmavi)y 27 call assert_equal(getreg('"'), a:expected[2]) 28 29 q! 30endfunc 31 32func Test_inner_block_without_cpo_M() 33 call CpoM('(red \(blue) green)', 0, ['red \(blue', 'red \(blue', '']) 34endfunc 35 36func Test_inner_block_with_cpo_M_left_backslash() 37 call CpoM('(red \(blue) green)', 1, ['red \(blue) green', 'blue', 'red \(blue) green']) 38endfunc 39 40func Test_inner_block_with_cpo_M_right_backslash() 41 call CpoM('(red (blue\) green)', 1, ['red (blue\) green', 'blue\', 'red (blue\) green']) 42endfunc 43 44func Test_quote_selection_selection_exclusive() 45 new 46 call setline(1, "a 'bcde' f") 47 set selection=exclusive 48 49 exe "norm! fdvhi'y" 50 call assert_equal('bcde', @") 51 52 let @"='dummy' 53 exe "norm! $gevi'y" 54 call assert_equal('bcde', @") 55 56 let @"='dummy' 57 exe "norm! 0fbhvi'y" 58 call assert_equal('bcde', @") 59 60 set selection&vim 61 bw! 62endfunc 63 64func Test_quote_selection_selection_exclusive_abort() 65 new 66 set selection=exclusive 67 call setline(1, "'abzzc'") 68 let exp_curs = [0, 1, 6, 0] 69 call cursor(1,1) 70 exe 'norm! fcdvi"' 71 " make sure to end visual mode to have a clear state 72 exe "norm! \<esc>" 73 call assert_equal(exp_curs, getpos('.')) 74 call cursor(1,1) 75 exe 'norm! fcvi"' 76 exe "norm! \<esc>" 77 call assert_equal(exp_curs, getpos('.')) 78 call cursor(1,2) 79 exe 'norm! vfcoi"' 80 exe "norm! \<esc>" 81 let exp_curs = [0, 1, 2, 0] 82 let exp_visu = [0, 1, 7, 0] 83 call assert_equal(exp_curs, getpos('.')) 84 call assert_equal(exp_visu, getpos("'>")) 85 set selection&vim 86 bw! 87endfunc 88 89" Tests for string and html text objects 90func Test_string_html_objects() 91 enew! 92 93 let t = '"wo\"rd\\" foo' 94 put =t 95 normal! da" 96 call assert_equal('foo', getline('.')) 97 98 let t = "'foo' 'bar' 'piep'" 99 put =t 100 normal! 0va'a'rx 101 call assert_equal("xxxxxxxxxxxx'piep'", getline('.')) 102 103 let t = "bla bla `quote` blah" 104 put =t 105 normal! 02f`da` 106 call assert_equal("bla bla blah", getline('.')) 107 108 let t = 'out " in "noXno"' 109 put =t 110 normal! 0fXdi" 111 call assert_equal('out " in ""', getline('.')) 112 113 let t = "\"'\" 'blah' rep 'buh'" 114 put =t 115 normal! 03f'vi'ry 116 call assert_equal("\"'\" 'blah'yyyyy'buh'", getline('.')) 117 118 set quoteescape=+*- 119 let t = "bla `s*`d-`+++`l**` b`la" 120 put =t 121 normal! di` 122 call assert_equal("bla `` b`la", getline('.')) 123 124 let t = 'voo "nah" sdf " asdf" sdf " sdf" sd' 125 put =t 126 normal! $F"va"oha"i"rz 127 call assert_equal('voo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzsd', getline('.')) 128 129 let t = "-<b>asdf<i>Xasdf</i>asdf</b>-" 130 put =t 131 normal! fXdit 132 call assert_equal('-<b>asdf<i></i>asdf</b>-', getline('.')) 133 134 let t = "-<b>asdX<i>a<i />sdf</i>asdf</b>-" 135 put =t 136 normal! 0fXdit 137 call assert_equal('-<b></b>-', getline('.')) 138 139 let t = "-<b>asdf<i>Xasdf</i>asdf</b>-" 140 put =t 141 normal! fXdat 142 call assert_equal('-<b>asdfasdf</b>-', getline('.')) 143 144 let t = "-<b>asdX<i>as<b />df</i>asdf</b>-" 145 put =t 146 normal! 0fXdat 147 call assert_equal('--', getline('.')) 148 149 let t = "-<b>\ninnertext object\n</b>" 150 put =t 151 normal! dit 152 call assert_equal('-<b></b>', getline('.')) 153 154 " copy the tag block from leading indentation before the start tag 155 let t = " <b>\ntext\n</b>" 156 $put =t 157 normal! 2kvaty 158 call assert_equal("<b>\ntext\n</b>", @") 159 160 " copy the tag block from the end tag 161 let t = "<title>\nwelcome\n</title>" 162 $put =t 163 normal! $vaty 164 call assert_equal("<title>\nwelcome\n</title>", @") 165 166 " copy the outer tag block from a tag without an end tag 167 let t = "<html>\n<title>welcome\n</html>" 168 $put =t 169 normal! k$vaty 170 call assert_equal("<html>\n<title>welcome\n</html>", @") 171 172 " nested tag that has < in a different line from > 173 let t = "<div><div\n></div></div>" 174 $put =t 175 normal! k0vaty 176 call assert_equal("<div><div\n></div></div>", @") 177 178 " nested tag with attribute that has < in a different line from > 179 let t = "<div><div\nattr=\"attr\"\n></div></div>" 180 $put =t 181 normal! 2k0vaty 182 call assert_equal("<div><div\nattr=\"attr\"\n></div></div>", @") 183 184 set quoteescape& 185 enew! 186endfunc 187 188func Test_empty_html_tag() 189 new 190 call setline(1, '<div></div>') 191 normal 0citxxx 192 call assert_equal('<div>xxx</div>', getline(1)) 193 194 call setline(1, '<div></div>') 195 normal 0f<cityyy 196 call assert_equal('<div>yyy</div>', getline(1)) 197 198 call setline(1, '<div></div>') 199 normal 0f<vitsaaa 200 call assert_equal('aaa', getline(1)) 201 202 " selecting a tag block in an non-empty blank line should fail 203 call setline(1, ' ') 204 call assert_beeps('normal $vaty') 205 206 bwipe! 207endfunc 208 209" Tests for match() and matchstr() 210func Test_match() 211 call assert_equal("b", matchstr("abcd", ".", 0, 2)) 212 call assert_equal("bc", matchstr("abcd", "..", 0, 2)) 213 call assert_equal("c", matchstr("abcd", ".", 2, 0)) 214 call assert_equal("a", matchstr("abcd", ".", 0, -1)) 215 call assert_equal(-1, match("abcd", ".", 0, 5)) 216 call assert_equal(0, match("abcd", ".", 0, -1)) 217 call assert_equal(0, match('abc', '.', 0, 1)) 218 call assert_equal(1, match('abc', '.', 0, 2)) 219 call assert_equal(2, match('abc', '.', 0, 3)) 220 call assert_equal(-1, match('abc', '.', 0, 4)) 221 call assert_equal(1, match('abc', '.', 1, 1)) 222 call assert_equal(2, match('abc', '.', 2, 1)) 223 call assert_equal(-1, match('abc', '.', 3, 1)) 224 call assert_equal(3, match('abc', '$', 0, 1)) 225 call assert_equal(-1, match('abc', '$', 0, 2)) 226 call assert_equal(3, match('abc', '$', 1, 1)) 227 call assert_equal(3, match('abc', '$', 2, 1)) 228 call assert_equal(3, match('abc', '$', 3, 1)) 229 call assert_equal(-1, match('abc', '$', 4, 1)) 230 call assert_equal(0, match('abc', '\zs', 0, 1)) 231 call assert_equal(1, match('abc', '\zs', 0, 2)) 232 call assert_equal(2, match('abc', '\zs', 0, 3)) 233 call assert_equal(3, match('abc', '\zs', 0, 4)) 234 call assert_equal(-1, match('abc', '\zs', 0, 5)) 235 call assert_equal(1, match('abc', '\zs', 1, 1)) 236 call assert_equal(2, match('abc', '\zs', 2, 1)) 237 call assert_equal(3, match('abc', '\zs', 3, 1)) 238 call assert_equal(-1, match('abc', '\zs', 4, 1)) 239endfunc 240 241" This was causing an illegal memory access 242func Test_inner_tag() 243 new 244 norm ixxx 245 call feedkeys("v", 'xt') 246 insert 247x 248x 249. 250 norm it 251 q! 252endfunc 253 254func Test_sentence() 255 enew! 256 call setline(1, 'A sentence. A sentence? A sentence!') 257 258 normal yis 259 call assert_equal('A sentence.', @") 260 normal yas 261 call assert_equal('A sentence. ', @") 262 263 normal ) 264 265 normal yis 266 call assert_equal('A sentence?', @") 267 normal yas 268 call assert_equal('A sentence? ', @") 269 270 normal ) 271 272 normal yis 273 call assert_equal('A sentence!', @") 274 normal yas 275 call assert_equal(' A sentence!', @") 276 277 normal 0 278 normal 2yis 279 call assert_equal('A sentence. ', @") 280 normal 3yis 281 call assert_equal('A sentence. A sentence?', @") 282 normal 2yas 283 call assert_equal('A sentence. A sentence? ', @") 284 285 %delete _ 286endfunc 287 288func Test_sentence_with_quotes() 289 enew! 290 call setline(1, 'A "sentence." A sentence.') 291 292 normal yis 293 call assert_equal('A "sentence."', @") 294 normal yas 295 call assert_equal('A "sentence." ', @") 296 297 normal ) 298 299 normal yis 300 call assert_equal('A sentence.', @") 301 normal yas 302 call assert_equal(' A sentence.', @") 303 304 %delete _ 305endfunc 306 307func Test_sentence_with_cursor_on_delimiter() 308 enew! 309 call setline(1, "A '([sentence.])' A sentence.") 310 311 normal! 15|yis 312 call assert_equal("A '([sentence.])'", @") 313 normal! 15|yas 314 call assert_equal("A '([sentence.])' ", @") 315 316 normal! 16|yis 317 call assert_equal("A '([sentence.])'", @") 318 normal! 16|yas 319 call assert_equal("A '([sentence.])' ", @") 320 321 normal! 17|yis 322 call assert_equal("A '([sentence.])'", @") 323 normal! 17|yas 324 call assert_equal("A '([sentence.])' ", @") 325 326 " don't get stuck on a quote at the start of a sentence 327 %delete _ 328 call setline(1, ['A sentence.', '"A sentence"?', 'A sentence!']) 329 normal gg)) 330 call assert_equal(3, getcurpos()[1]) 331 332 %delete _ 333 call setline(1, ['A sentence.', "'A sentence'?", 'A sentence!']) 334 normal gg)) 335 call assert_equal(3, getcurpos()[1]) 336 337 %delete _ 338endfunc 339 340" Test for the paragraph (ap) text object 341func Test_paragraph() 342 new 343 call setline(1, ['First line.', 'Second line.', 'Third line.']) 344 call cursor(2, 1) 345 normal vapy 346 call assert_equal("First line.\nSecond line.\nThird line.\n", @") 347 348 call cursor(2, 1) 349 call assert_beeps('normal vapapy') 350 351 call setline(1, ['First line.', 'Second line.', ' ', '']) 352 call cursor(1, 1) 353 normal vapy 354 call assert_equal("First line.\nSecond line.\n \n\n", @") 355 356 call setline(1, ['', '', '', 'First line.', 'Second line.']) 357 call cursor(2, 1) 358 normal yap 359 call assert_equal("\n\n\nFirst line.\nSecond line.\n", @") 360 call assert_beeps('normal 3yap') 361 exe "normal \<C-C>" 362 363 %d 364 call setline(1, [' ', ' ', ' ']) 365 call cursor(2, 1) 366 normal Vipy 367 call assert_equal(" \n \n \n", @") 368 call cursor(2, 1) 369 call assert_beeps("normal Vipip") 370 exe "normal \<C-C>" 371 372 close! 373endfunc 374 375" Tests for text object aw 376func Test_textobj_a_word() 377 new 378 call append(0, ['foobar,eins,foobar', 'foo,zwei,foo ']) 379 " diw 380 norm! 1gg0diw 381 call assert_equal([',eins,foobar', 'foo,zwei,foo ', ''], getline(1,'$')) 382 " daw 383 norm! 2ggEdaw 384 call assert_equal([',eins,foobar', 'foo,zwei,', ''], getline(1, '$')) 385 " daw the last word in a line 386 call setline(1, ['foo bar', 'foo bar', '']) 387 call cursor(1, 5) 388 normal daw 389 call assert_equal('foo', getline(1)) 390 " aw in visual mode 391 call cursor(2, 5) 392 normal! vawx 393 call assert_equal('foo', getline(2)) 394 %d 395 call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "]) 396 " diW 397 norm! 2ggwd2iW 398 call assert_equal(['foo eins foobar', 'foo foo ', ''], getline(1,'$')) 399 " daW 400 norm! 1ggd2aW 401 call assert_equal(['foobar', 'foo foo ', ''], getline(1,'$')) 402 403 %d 404 call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "]) 405 " aw in visual line mode switches to characterwise mode 406 norm! 2gg$Vawd 407 call assert_equal(['foo eins foobar', 'foo zwei foo'], getline(1,'$')) 408 norm! 1gg$Viwd 409 call assert_equal(['foo eins ', 'foo zwei foo'], getline(1,'$')) 410 411 " visually selecting a tab before a word with 'selection' set to 'exclusive' 412 set selection=exclusive 413 normal gg3lvlawy 414 call assert_equal("\teins", @") 415 " visually selecting a tab before a word with 'selection' set to 'inclusive' 416 set selection=inclusive 417 normal gg3lvlawy 418 call assert_equal("\teins\t", @") 419 set selection& 420 421 " selecting a word with no non-space characters in a buffer fails 422 %d 423 call setline(1, ' ') 424 call assert_beeps('normal 3lyaw') 425 426 " visually selecting words backwards with no more words to select 427 call setline(1, 'one two') 428 call assert_beeps('normal 2lvh2aw') 429 exe "normal \<C-C>" 430 call assert_beeps('normal $vh3aw') 431 exe "normal \<C-C>" 432 call setline(1, ['', 'one two']) 433 call assert_beeps('normal 2G2lvh3aw') 434 exe "normal \<C-C>" 435 436 " selecting words forward with no more words to select 437 %d 438 call setline(1, 'one a') 439 call assert_beeps('normal 0y3aw') 440 call setline(1, 'one two ') 441 call assert_beeps('normal 0y3aw') 442 call assert_beeps('normal 03ly2aw') 443 444 " clean up 445 bw! 446endfunc 447 448" Test for is and as text objects 449func Test_textobj_sentence() 450 new 451 call append(0, ['This is a test. With some sentences!', '', 452 \ 'Even with a question? And one more. And no sentence here']) 453 " Test for dis - does not remove trailing whitespace 454 norm! 1gg0dis 455 call assert_equal([' With some sentences!', '', 456 \ 'Even with a question? And one more. And no sentence here', ''], 457 \ getline(1,'$')) 458 " Test for das - removes leading whitespace 459 norm! 3ggf?ldas 460 call assert_equal([' With some sentences!', '', 461 \ 'Even with a question? And no sentence here', ''], getline(1,'$')) 462 " when used in visual mode, is made characterwise 463 norm! 3gg$Visy 464 call assert_equal('v', visualmode()) 465 " reset visualmode() 466 norm! 3ggVy 467 norm! 3gg$Vasy 468 call assert_equal('v', visualmode()) 469 " basic testing for textobjects a< and at 470 %d 471 call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' ']) 472 " a< 473 norm! 1gg0da< 474 call assert_equal([' ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) 475 norm! 1pj 476 call assert_equal([' <div>', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) 477 " at 478 norm! d2at 479 call assert_equal([' '], getline(1,'$')) 480 %d 481 call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' ']) 482 " i< 483 norm! 1gg0di< 484 call assert_equal(['<> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) 485 norm! 1Pj 486 call assert_equal(['<div> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) 487 norm! d2it 488 call assert_equal(['<div></div>',' '], getline(1,'$')) 489 " basic testing for a[ and i[ text object 490 %d 491 call setline(1, [' ', '[', 'one [two]', 'thre', ']']) 492 norm! 3gg0di[ 493 call assert_equal([' ', '[', ']'], getline(1,'$')) 494 call setline(1, [' ', '[', 'one [two]', 'thre', ']']) 495 norm! 3gg0ftd2a[ 496 call assert_equal([' '], getline(1,'$')) 497 498 " clean up 499 bw! 500endfunc 501 502" Test for quote (', " and `) textobjects 503func Test_textobj_quote() 504 new 505 506 " Test for i" when cursor is in front of a quoted object 507 call append(0, 'foo "bar"') 508 norm! 1gg0di" 509 call assert_equal(['foo ""', ''], getline(1,'$')) 510 511 " Test for visually selecting an inner quote 512 %d 513 " extend visual selection from one quote to the next 514 call setline(1, 'color "red" color "blue"') 515 call cursor(1, 7) 516 normal v4li"y 517 call assert_equal('"red" color "blue', @") 518 519 " try to extend visual selection from one quote to a non-existing quote 520 call setline(1, 'color "red" color blue') 521 call cursor(1, 7) 522 call feedkeys('v4li"y', 'xt') 523 call assert_equal('"red"', @") 524 525 " try to extend visual selection from one quote to a next partial quote 526 call setline(1, 'color "red" color "blue') 527 call cursor(1, 7) 528 normal v4li"y 529 call assert_equal('"red" color ', @") 530 531 " select a quote backwards in visual mode 532 call cursor(1, 12) 533 normal vhi"y 534 call assert_equal('red" ', @") 535 call assert_equal(8, col('.')) 536 537 " select a quote backwards in visual mode from outside the quote 538 call cursor(1, 17) 539 normal v2hi"y 540 call assert_equal('red', @") 541 call assert_equal(8, col('.')) 542 543 " visually selecting a quote with 'selection' set to 'exclusive' 544 call setline(1, 'He said "How are you?"') 545 set selection=exclusive 546 normal 012lv2li"y 547 call assert_equal('How are you?', @") 548 set selection& 549 550 " try copy a quote object with a single quote in the line 551 call setline(1, "Smith's car") 552 call cursor(1, 6) 553 call assert_beeps("normal yi'") 554 call assert_beeps("normal 2lyi'") 555 556 " selecting space before and after a quoted string 557 call setline(1, "some 'special' string") 558 normal 0ya' 559 call assert_equal("'special' ", @") 560 call setline(1, "some 'special'string") 561 normal 0ya' 562 call assert_equal(" 'special'", @") 563 564 close! 565endfunc 566 567" Test for i(, i<, etc. when cursor is in front of a block 568func Test_textobj_find_paren_forward() 569 new 570 571 " i< and a> when cursor is in front of a block 572 call setline(1, '#include <foo.h>') 573 normal 0yi< 574 call assert_equal('foo.h', @") 575 normal 0ya> 576 call assert_equal('<foo.h>', @") 577 578 " 2i(, 3i( in front of a block enters second/third nested '(' 579 call setline(1, 'foo (bar (baz (quux)))') 580 normal 0yi) 581 call assert_equal('bar (baz (quux))', @") 582 normal 02yi) 583 call assert_equal('baz (quux)', @") 584 normal 03yi) 585 call assert_equal('quux', @") 586 587 " 3i( in front of a block doesn't enter third but un-nested '(' 588 call setline(1, 'foo (bar (baz) (quux))') 589 normal 03di) 590 call assert_equal('foo (bar (baz) (quux))', getline(1)) 591 normal 02di) 592 call assert_equal('foo (bar () (quux))', getline(1)) 593 normal 0di) 594 call assert_equal('foo ()', getline(1)) 595 596 close! 597endfunc 598 599" vim: shiftwidth=2 sts=2 expandtab 600