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