1" Test for the search command 2 3source shared.vim 4source screendump.vim 5source check.vim 6 7func Test_search_cmdline() 8 if !exists('+incsearch') 9 return 10 endif 11 " need to disable char_avail, 12 " so that expansion of commandline works 13 call test_override("char_avail", 1) 14 new 15 call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar']) 16 " Test 1 17 " CTRL-N / CTRL-P skips through the previous search history 18 set noincsearch 19 :1 20 call feedkeys("/foobar\<cr>", 'tx') 21 call feedkeys("/the\<cr>",'tx') 22 call assert_equal('the', @/) 23 call feedkeys("/thes\<C-P>\<C-P>\<cr>",'tx') 24 call assert_equal('foobar', @/) 25 26 " Test 2 27 " Ctrl-G goes from one match to the next 28 " until the end of the buffer 29 set incsearch nowrapscan 30 :1 31 " first match 32 call feedkeys("/the\<cr>", 'tx') 33 call assert_equal(' 2 these', getline('.')) 34 :1 35 " second match 36 call feedkeys("/the\<C-G>\<cr>", 'tx') 37 call assert_equal(' 3 the', getline('.')) 38 call assert_equal([0, 0, 0, 0], getpos('"')) 39 :1 40 " third match 41 call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx') 42 call assert_equal(' 4 their', getline('.')) 43 :1 44 " fourth match 45 call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx') 46 call assert_equal(' 5 there', getline('.')) 47 :1 48 " fifth match 49 call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx') 50 call assert_equal(' 6 their', getline('.')) 51 :1 52 " sixth match 53 call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx') 54 call assert_equal(' 7 the', getline('.')) 55 :1 56 " seventh match 57 call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx') 58 call assert_equal(' 8 them', getline('.')) 59 :1 60 " eighth match 61 call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx') 62 call assert_equal(' 9 these', getline('.')) 63 :1 64 " no further match 65 call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx') 66 call assert_equal(' 9 these', getline('.')) 67 call assert_equal([0, 0, 0, 0], getpos('"')) 68 69 " Test 3 70 " Ctrl-G goes from one match to the next 71 " and continues back at the top 72 set incsearch wrapscan 73 :1 74 " first match 75 call feedkeys("/the\<cr>", 'tx') 76 call assert_equal(' 2 these', getline('.')) 77 :1 78 " second match 79 call feedkeys("/the\<C-G>\<cr>", 'tx') 80 call assert_equal(' 3 the', getline('.')) 81 :1 82 " third match 83 call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx') 84 call assert_equal(' 4 their', getline('.')) 85 :1 86 " fourth match 87 call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx') 88 call assert_equal(' 5 there', getline('.')) 89 :1 90 " fifth match 91 call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx') 92 call assert_equal(' 6 their', getline('.')) 93 :1 94 " sixth match 95 call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx') 96 call assert_equal(' 7 the', getline('.')) 97 :1 98 " seventh match 99 call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx') 100 call assert_equal(' 8 them', getline('.')) 101 :1 102 " eighth match 103 call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx') 104 call assert_equal(' 9 these', getline('.')) 105 :1 106 " back at first match 107 call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx') 108 call assert_equal(' 2 these', getline('.')) 109 110 " Test 4 111 " CTRL-T goes to the previous match 112 set incsearch nowrapscan 113 $ 114 " first match 115 call feedkeys("?the\<cr>", 'tx') 116 call assert_equal(' 9 these', getline('.')) 117 $ 118 " first match 119 call feedkeys("?the\<C-G>\<cr>", 'tx') 120 call assert_equal(' 9 these', getline('.')) 121 $ 122 " second match 123 call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx') 124 call assert_equal(' 8 them', getline('.')) 125 $ 126 " last match 127 call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx') 128 call assert_equal(' 2 these', getline('.')) 129 $ 130 " last match 131 call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx') 132 call assert_equal(' 2 these', getline('.')) 133 134 " Test 5 135 " CTRL-T goes to the previous match 136 set incsearch wrapscan 137 $ 138 " first match 139 call feedkeys("?the\<cr>", 'tx') 140 call assert_equal(' 9 these', getline('.')) 141 $ 142 " first match at the top 143 call feedkeys("?the\<C-G>\<cr>", 'tx') 144 call assert_equal(' 2 these', getline('.')) 145 $ 146 " second match 147 call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx') 148 call assert_equal(' 8 them', getline('.')) 149 $ 150 " last match 151 call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx') 152 call assert_equal(' 2 these', getline('.')) 153 $ 154 " back at the bottom of the buffer 155 call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx') 156 call assert_equal(' 9 these', getline('.')) 157 158 " Test 6 159 " CTRL-L adds to the search pattern 160 set incsearch wrapscan 161 1 162 " first match 163 call feedkeys("/the\<c-l>\<cr>", 'tx') 164 call assert_equal(' 2 these', getline('.')) 165 1 166 " go to next match of 'thes' 167 call feedkeys("/the\<c-l>\<C-G>\<cr>", 'tx') 168 call assert_equal(' 9 these', getline('.')) 169 1 170 " wrap around 171 call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx') 172 call assert_equal(' 2 these', getline('.')) 173 1 174 " wrap around 175 set nowrapscan 176 call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx') 177 call assert_equal(' 9 these', getline('.')) 178 179 " Test 7 180 " <bs> remove from match, but stay at current match 181 set incsearch wrapscan 182 1 183 " first match 184 call feedkeys("/thei\<cr>", 'tx') 185 call assert_equal(' 4 their', getline('.')) 186 1 187 " delete one char, add another 188 call feedkeys("/thei\<bs>s\<cr>", 'tx') 189 call assert_equal(' 2 these', getline('.')) 190 1 191 " delete one char, add another, go to previous match, add one char 192 call feedkeys("/thei\<bs>s\<bs>\<C-T>\<c-l>\<cr>", 'tx') 193 call assert_equal(' 9 these', getline('.')) 194 1 195 " delete all chars, start from the beginning again 196 call feedkeys("/them". repeat("\<bs>",4).'the\>'."\<cr>", 'tx') 197 call assert_equal(' 3 the', getline('.')) 198 199 " clean up 200 call test_override("char_avail", 0) 201 bw! 202endfunc 203 204func Test_search_cmdline2() 205 if !exists('+incsearch') 206 return 207 endif 208 " need to disable char_avail, 209 " so that expansion of commandline works 210 call test_override("char_avail", 1) 211 new 212 call setline(1, [' 1', ' 2 these', ' 3 the theother']) 213 " Test 1 214 " Ctrl-T goes correctly back and forth 215 set incsearch 216 1 217 " first match 218 call feedkeys("/the\<cr>", 'tx') 219 call assert_equal(' 2 these', getline('.')) 220 1 221 " go to next match (on next line) 222 call feedkeys("/the\<C-G>\<cr>", 'tx') 223 call assert_equal(' 3 the theother', getline('.')) 224 1 225 " go to next match (still on line 3) 226 call feedkeys("/the\<C-G>\<C-G>\<cr>", 'tx') 227 call assert_equal(' 3 the theother', getline('.')) 228 1 229 " go to next match (still on line 3) 230 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<cr>", 'tx') 231 call assert_equal(' 3 the theother', getline('.')) 232 1 233 " go to previous match (on line 3) 234 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<cr>", 'tx') 235 call assert_equal(' 3 the theother', getline('.')) 236 1 237 " go to previous match (on line 3) 238 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<cr>", 'tx') 239 call assert_equal(' 3 the theother', getline('.')) 240 1 241 " go to previous match (on line 2) 242 call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx') 243 call assert_equal(' 2 these', getline('.')) 244 1 245 " go to previous match (on line 2) 246 call feedkeys("/the\<C-G>\<C-R>\<C-W>\<cr>", 'tx') 247 call assert_equal('theother', @/) 248 249 " Test 2: keep the view, 250 " after deleting a character from the search cmd 251 call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar']) 252 resize 5 253 1 254 call feedkeys("/foo\<bs>\<cr>", 'tx') 255 redraw 256 call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview()) 257 258 " remove all history entries 259 for i in range(11) 260 call histdel('/') 261 endfor 262 263 " Test 3: reset the view, 264 " after deleting all characters from the search cmd 265 norm! 1gg0 266 " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>", 267 " nor "/foo\<c-u>\<cr>" works to delete the commandline. 268 " In that case Vim should return "E35 no previous regular expression", 269 " but it looks like Vim still sees /foo and therefore the test fails. 270 " Therefore, disabling this test 271 "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35') 272 "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview()) 273 274 " clean up 275 set noincsearch 276 call test_override("char_avail", 0) 277 bw! 278endfunc 279 280func Test_use_sub_pat() 281 split 282 let @/ = '' 283 func X() 284 s/^/a/ 285 / 286 endfunc 287 call X() 288 bwipe! 289endfunc 290 291func Test_searchpair() 292 new 293 call setline(1, ['other code', 'here [', ' [', ' " cursor here', ' ]]']) 294 295 4 296 call assert_equal(3, searchpair('\[', '', ']', 'bW')) 297 call assert_equal([0, 3, 2, 0], getpos('.')) 298 4 299 call assert_equal(2, searchpair('\[', '', ']', 'bWr')) 300 call assert_equal([0, 2, 6, 0], getpos('.')) 301 4 302 call assert_equal(1, searchpair('\[', '', ']', 'bWm')) 303 call assert_equal([0, 3, 2, 0], getpos('.')) 304 4|norm ^ 305 call assert_equal(5, searchpair('\[', '', ']', 'Wn')) 306 call assert_equal([0, 4, 2, 0], getpos('.')) 307 4 308 call assert_equal(2, searchpair('\[', '', ']', 'bW', 309 \ 'getline(".") =~ "^\\s*\["')) 310 call assert_equal([0, 2, 6, 0], getpos('.')) 311 set nomagic 312 4 313 call assert_equal(3, searchpair('\[', '', ']', 'bW')) 314 call assert_equal([0, 3, 2, 0], getpos('.')) 315 set magic 316 4|norm ^ 317 call assert_equal(0, searchpair('{', '', '}', 'bW')) 318 call assert_equal([0, 4, 2, 0], getpos('.')) 319 320 %d 321 call setline(1, ['if 1', ' if 2', ' else', ' endif 2', 'endif 1']) 322 323 /\<if 1 324 call assert_equal(5, searchpair('\<if\>', '\<else\>', '\<endif\>', 'W')) 325 call assert_equal([0, 5, 1, 0], getpos('.')) 326 /\<if 2 327 call assert_equal(3, searchpair('\<if\>', '\<else\>', '\<endif\>', 'W')) 328 call assert_equal([0, 3, 3, 0], getpos('.')) 329 330 q! 331endfunc 332 333func Test_searchpairpos() 334 new 335 call setline(1, ['other code', 'here [', ' [', ' " cursor here', ' ]]']) 336 337 4 338 call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW')) 339 call assert_equal([0, 3, 2, 0], getpos('.')) 340 4 341 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr')) 342 call assert_equal([0, 2, 6, 0], getpos('.')) 343 4|norm ^ 344 call assert_equal([5, 2], searchpairpos('\[', '', ']', 'Wn')) 345 call assert_equal([0, 4, 2, 0], getpos('.')) 346 4 347 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bW', 348 \ 'getline(".") =~ "^\\s*\["')) 349 call assert_equal([0, 2, 6, 0], getpos('.')) 350 4 351 call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr')) 352 call assert_equal([0, 2, 6, 0], getpos('.')) 353 set nomagic 354 4 355 call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW')) 356 call assert_equal([0, 3, 2, 0], getpos('.')) 357 set magic 358 4|norm ^ 359 call assert_equal([0, 0], searchpairpos('{', '', '}', 'bW')) 360 call assert_equal([0, 4, 2, 0], getpos('.')) 361 362 %d 363 call setline(1, ['if 1', ' if 2', ' else', ' endif 2', 'endif 1']) 364 /\<if 1 365 call assert_equal([5, 1], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W')) 366 call assert_equal([0, 5, 1, 0], getpos('.')) 367 /\<if 2 368 call assert_equal([3, 3], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W')) 369 call assert_equal([0, 3, 3, 0], getpos('.')) 370 371 q! 372endfunc 373 374func Test_searchpair_errors() 375 call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: using List as a String') 376 call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String') 377 call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String') 378 call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags') 379 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 0, 99, 100)", 'E475: Invalid argument: 0') 380 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99') 381 call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100') 382 call assert_fails("call searchpair('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e') 383 call assert_fails("call searchpair('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn') 384endfunc 385 386func Test_searchpairpos_errors() 387 call assert_fails("call searchpairpos([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: using List as a String') 388 call assert_fails("call searchpairpos('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String') 389 call assert_fails("call searchpairpos('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String') 390 call assert_fails("call searchpairpos('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags') 391 call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 0, 99, 100)", 'E475: Invalid argument: 0') 392 call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99') 393 call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100') 394 call assert_fails("call searchpairpos('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e') 395 call assert_fails("call searchpairpos('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn') 396endfunc 397 398func Test_searchpair_skip() 399 func Zero() 400 return 0 401 endfunc 402 func Partial(x) 403 return a:x 404 endfunc 405 new 406 call setline(1, ['{', 'foo', 'foo', 'foo', '}']) 407 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', '')) 408 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', '0')) 409 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', {-> 0})) 410 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Zero'))) 411 3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Partial', [0]))) 412 bw! 413endfunc 414 415func Test_searchpair_leak() 416 new 417 call setline(1, 'if one else another endif') 418 419 " The error in the skip expression caused memory to leak. 420 call assert_fails("call searchpair('\\<if\\>', '\\<else\\>', '\\<endif\\>', '', '\"foo\" 2')", 'E15:') 421 422 bwipe! 423endfunc 424 425func Test_searchc() 426 " These commands used to cause memory overflow in searchc(). 427 new 428 norm ixx 429 exe "norm 0t\u93cf" 430 bw! 431endfunc 432 433func Cmdline3_prep() 434 " need to disable char_avail, 435 " so that expansion of commandline works 436 call test_override("char_avail", 1) 437 new 438 call setline(1, [' 1', ' 2 the~e', ' 3 the theother']) 439 set incsearch 440endfunc 441 442func Incsearch_cleanup() 443 set noincsearch 444 call test_override("char_avail", 0) 445 bw! 446endfunc 447 448func Test_search_cmdline3() 449 if !exists('+incsearch') 450 return 451 endif 452 call Cmdline3_prep() 453 1 454 " first match 455 call feedkeys("/the\<c-l>\<cr>", 'tx') 456 call assert_equal(' 2 the~e', getline('.')) 457 458 call Incsearch_cleanup() 459endfunc 460 461func Test_search_cmdline3s() 462 if !exists('+incsearch') 463 return 464 endif 465 call Cmdline3_prep() 466 1 467 call feedkeys(":%s/the\<c-l>/xxx\<cr>", 'tx') 468 call assert_equal(' 2 xxxe', getline('.')) 469 undo 470 call feedkeys(":%subs/the\<c-l>/xxx\<cr>", 'tx') 471 call assert_equal(' 2 xxxe', getline('.')) 472 undo 473 call feedkeys(":%substitute/the\<c-l>/xxx\<cr>", 'tx') 474 call assert_equal(' 2 xxxe', getline('.')) 475 undo 476 call feedkeys(":%smagic/the.e/xxx\<cr>", 'tx') 477 call assert_equal(' 2 xxx', getline('.')) 478 undo 479 call assert_fails(":%snomagic/the.e/xxx\<cr>", 'E486') 480 " 481 call feedkeys(":%snomagic/the\\.e/xxx\<cr>", 'tx') 482 call assert_equal(' 2 xxx', getline('.')) 483 484 call Incsearch_cleanup() 485endfunc 486 487func Test_search_cmdline3g() 488 if !exists('+incsearch') 489 return 490 endif 491 call Cmdline3_prep() 492 1 493 call feedkeys(":g/the\<c-l>/d\<cr>", 'tx') 494 call assert_equal(' 3 the theother', getline(2)) 495 undo 496 call feedkeys(":global/the\<c-l>/d\<cr>", 'tx') 497 call assert_equal(' 3 the theother', getline(2)) 498 undo 499 call feedkeys(":g!/the\<c-l>/d\<cr>", 'tx') 500 call assert_equal(1, line('$')) 501 call assert_equal(' 2 the~e', getline(1)) 502 undo 503 call feedkeys(":global!/the\<c-l>/d\<cr>", 'tx') 504 call assert_equal(1, line('$')) 505 call assert_equal(' 2 the~e', getline(1)) 506 507 call Incsearch_cleanup() 508endfunc 509 510func Test_search_cmdline3v() 511 if !exists('+incsearch') 512 return 513 endif 514 call Cmdline3_prep() 515 1 516 call feedkeys(":v/the\<c-l>/d\<cr>", 'tx') 517 call assert_equal(1, line('$')) 518 call assert_equal(' 2 the~e', getline(1)) 519 undo 520 call feedkeys(":vglobal/the\<c-l>/d\<cr>", 'tx') 521 call assert_equal(1, line('$')) 522 call assert_equal(' 2 the~e', getline(1)) 523 524 call Incsearch_cleanup() 525endfunc 526 527func Test_search_cmdline4() 528 if !exists('+incsearch') 529 return 530 endif 531 " need to disable char_avail, 532 " so that expansion of commandline works 533 call test_override("char_avail", 1) 534 new 535 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third']) 536 set incsearch 537 $ 538 call feedkeys("?the\<c-g>\<cr>", 'tx') 539 call assert_equal(' 3 the third', getline('.')) 540 $ 541 call feedkeys("?the\<c-g>\<c-g>\<cr>", 'tx') 542 call assert_equal(' 1 the first', getline('.')) 543 $ 544 call feedkeys("?the\<c-g>\<c-g>\<c-g>\<cr>", 'tx') 545 call assert_equal(' 2 the second', getline('.')) 546 $ 547 call feedkeys("?the\<c-t>\<cr>", 'tx') 548 call assert_equal(' 1 the first', getline('.')) 549 $ 550 call feedkeys("?the\<c-t>\<c-t>\<cr>", 'tx') 551 call assert_equal(' 3 the third', getline('.')) 552 $ 553 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx') 554 call assert_equal(' 2 the second', getline('.')) 555 " clean up 556 set noincsearch 557 call test_override("char_avail", 0) 558 bw! 559endfunc 560 561func Test_search_cmdline5() 562 if !exists('+incsearch') 563 return 564 endif 565 " Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work 566 " regardless char_avail. 567 new 568 call setline(1, [' 1 the first', ' 2 the second', ' 3 the third', '']) 569 set incsearch 570 1 571 call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx') 572 call assert_equal(' 3 the third', getline('.')) 573 $ 574 call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx') 575 call assert_equal(' 1 the first', getline('.')) 576 " clean up 577 set noincsearch 578 bw! 579endfunc 580 581func Test_search_cmdline6() 582 " Test that consecutive matches 583 " are caught by <c-g>/<c-t> 584 if !exists('+incsearch') 585 return 586 endif 587 " need to disable char_avail, 588 " so that expansion of commandline works 589 call test_override("char_avail", 1) 590 new 591 call setline(1, [' bbvimb', '']) 592 set incsearch 593 " first match 594 norm! gg0 595 call feedkeys("/b\<cr>", 'tx') 596 call assert_equal([0,1,2,0], getpos('.')) 597 " second match 598 norm! gg0 599 call feedkeys("/b\<c-g>\<cr>", 'tx') 600 call assert_equal([0,1,3,0], getpos('.')) 601 " third match 602 norm! gg0 603 call feedkeys("/b\<c-g>\<c-g>\<cr>", 'tx') 604 call assert_equal([0,1,7,0], getpos('.')) 605 " first match again 606 norm! gg0 607 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx') 608 call assert_equal([0,1,2,0], getpos('.')) 609 set nowrapscan 610 " last match 611 norm! gg0 612 call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx') 613 call assert_equal([0,1,7,0], getpos('.')) 614 " clean up 615 set wrapscan&vim 616 set noincsearch 617 call test_override("char_avail", 0) 618 bw! 619endfunc 620 621func Test_search_cmdline7() 622 " Test that an pressing <c-g> in an empty command line 623 " does not move the cursor 624 if !exists('+incsearch') 625 return 626 endif 627 " need to disable char_avail, 628 " so that expansion of commandline works 629 call test_override("char_avail", 1) 630 new 631 let @/ = 'b' 632 call setline(1, [' bbvimb', '']) 633 set incsearch 634 " first match 635 norm! gg0 636 " moves to next match of previous search pattern, just like /<cr> 637 call feedkeys("/\<c-g>\<cr>", 'tx') 638 call assert_equal([0,1,2,0], getpos('.')) 639 " moves to next match of previous search pattern, just like /<cr> 640 call feedkeys("/\<cr>", 'tx') 641 call assert_equal([0,1,3,0], getpos('.')) 642 " moves to next match of previous search pattern, just like /<cr> 643 call feedkeys("/\<c-t>\<cr>", 'tx') 644 call assert_equal([0,1,7,0], getpos('.')) 645 646 " using an offset uses the last search pattern 647 call cursor(1, 1) 648 call setline(1, ['1 bbvimb', ' 2 bbvimb']) 649 let @/ = 'b' 650 call feedkeys("//e\<c-g>\<cr>", 'tx') 651 call assert_equal('1 bbvimb', getline('.')) 652 call assert_equal(4, col('.')) 653 654 set noincsearch 655 call test_override("char_avail", 0) 656 bw! 657endfunc 658 659func Test_search_cmdline8() 660 " Highlighting is cleared in all windows 661 " since hls applies to all windows 662 CheckOption incsearch 663 CheckFeature terminal 664 CheckNotGui 665 if has("win32") 666 throw "Skipped: Bug with sending <ESC> to terminal window not fixed yet" 667 endif 668 669 let h = winheight(0) 670 if h < 3 671 return 672 endif 673 " Prepare buffer text 674 let lines = ['abb vim vim vi', 'vimvivim'] 675 call writefile(lines, 'Xsearch.txt') 676 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3}) 677 678 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])}) 679 680 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>") 681 call term_sendkeys(buf, ":14vsp\<cr>") 682 call term_sendkeys(buf, "/vim\<cr>") 683 call term_sendkeys(buf, "/b\<esc>") 684 call term_sendkeys(buf, "gg0") 685 call term_wait(buf, 500) 686 let screen_line = term_scrape(buf, 1) 687 let [a0,a1,a2,a3] = [screen_line[3].attr, screen_line[4].attr, 688 \ screen_line[18].attr, screen_line[19].attr] 689 call assert_notequal(a0, a1) 690 call assert_notequal(a0, a3) 691 call assert_notequal(a1, a2) 692 call assert_equal(a0, a2) 693 call assert_equal(a1, a3) 694 " clean up 695 call delete('Xsearch.txt') 696 697 bwipe! 698endfunc 699 700" Tests for regexp with various magic settings 701func Test_search_regexp() 702 enew! 703 704 put ='1 a aa abb abbccc' 705 exe 'normal! /a*b\{2}c\+/e' . "\<CR>" 706 call assert_equal([0, 2, 17, 0], getpos('.')) 707 708 put ='2 d dd dee deefff' 709 exe 'normal! /\Md\*e\{2}f\+/e' . "\<CR>" 710 call assert_equal([0, 3, 17, 0], getpos('.')) 711 712 set nomagic 713 put ='3 g gg ghh ghhiii' 714 exe 'normal! /g\*h\{2}i\+/e' . "\<CR>" 715 call assert_equal([0, 4, 17, 0], getpos('.')) 716 717 put ='4 j jj jkk jkklll' 718 exe 'normal! /\mj*k\{2}l\+/e' . "\<CR>" 719 call assert_equal([0, 5, 17, 0], getpos('.')) 720 721 put ='5 m mm mnn mnnooo' 722 exe 'normal! /\vm*n{2}o+/e' . "\<CR>" 723 call assert_equal([0, 6, 17, 0], getpos('.')) 724 725 put ='6 x ^aa$ x' 726 exe 'normal! /\V^aa$' . "\<CR>" 727 call assert_equal([0, 7, 5, 0], getpos('.')) 728 729 set magic 730 put ='7 (a)(b) abbaa' 731 exe 'normal! /\v(a)(b)\2\1\1/e' . "\<CR>" 732 call assert_equal([0, 8, 14, 0], getpos('.')) 733 734 put ='8 axx [ab]xx' 735 exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>" 736 call assert_equal([0, 9, 7, 0], getpos('.')) 737 738 set undolevels=100 739 put ='9 foobar' 740 put ='' 741 exe "normal! a\<C-G>u\<Esc>" 742 normal G 743 exe 'normal! dv?bar?' . "\<CR>" 744 call assert_equal('9 foo', getline('.')) 745 call assert_equal([0, 10, 5, 0], getpos('.')) 746 call assert_equal(10, line('$')) 747 normal u 748 call assert_equal('9 foobar', getline('.')) 749 call assert_equal([0, 10, 6, 0], getpos('.')) 750 call assert_equal(11, line('$')) 751 752 set undolevels& 753 enew! 754endfunc 755 756func Test_search_cmdline_incsearch_highlight() 757 if !exists('+incsearch') 758 return 759 endif 760 set incsearch hlsearch 761 " need to disable char_avail, 762 " so that expansion of commandline works 763 call test_override("char_avail", 1) 764 new 765 call setline(1, ['aaa 1 the first', ' 2 the second', ' 3 the third']) 766 767 1 768 call feedkeys("/second\<cr>", 'tx') 769 call assert_equal('second', @/) 770 call assert_equal(' 2 the second', getline('.')) 771 772 " Canceling search won't change @/ 773 1 774 let @/ = 'last pattern' 775 call feedkeys("/third\<C-c>", 'tx') 776 call assert_equal('last pattern', @/) 777 call feedkeys("/third\<Esc>", 'tx') 778 call assert_equal('last pattern', @/) 779 call feedkeys("/3\<bs>\<bs>", 'tx') 780 call assert_equal('last pattern', @/) 781 call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx') 782 call assert_equal('last pattern', @/) 783 784 " clean up 785 set noincsearch nohlsearch 786 bw! 787endfunc 788 789func Test_search_cmdline_incsearch_highlight_attr() 790 CheckOption incsearch 791 CheckFeature terminal 792 CheckNotGui 793 794 let h = winheight(0) 795 if h < 3 796 return 797 endif 798 799 " Prepare buffer text 800 let lines = ['abb vim vim vi', 'vimvivim'] 801 call writefile(lines, 'Xsearch.txt') 802 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3}) 803 804 call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])}) 805 " wait for vim to complete initialization 806 call term_wait(buf) 807 808 " Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight 809 call term_sendkeys(buf, ":set incsearch hlsearch\<cr>") 810 call term_sendkeys(buf, '/b') 811 call term_wait(buf, 200) 812 let screen_line1 = term_scrape(buf, 1) 813 call assert_true(len(screen_line1) > 2) 814 " a0: attr_normal 815 let a0 = screen_line1[0].attr 816 " a1: attr_incsearch 817 let a1 = screen_line1[1].attr 818 " a2: attr_hlsearch 819 let a2 = screen_line1[2].attr 820 call assert_notequal(a0, a1) 821 call assert_notequal(a0, a2) 822 call assert_notequal(a1, a2) 823 call term_sendkeys(buf, "\<cr>gg0") 824 825 " Test incremental highlight search 826 call term_sendkeys(buf, "/vim") 827 call term_wait(buf, 200) 828 " Buffer: 829 " abb vim vim vi 830 " vimvivim 831 " Search: /vim 832 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,a0,a0,a0] 833 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2] 834 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr')) 835 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr')) 836 837 " Test <C-g> 838 call term_sendkeys(buf, "\<C-g>\<C-g>") 839 call term_wait(buf, 200) 840 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0] 841 let attr_line2 = [a1,a1,a1,a0,a0,a2,a2,a2] 842 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr')) 843 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr')) 844 845 " Test <C-t> 846 call term_sendkeys(buf, "\<C-t>") 847 call term_wait(buf, 200) 848 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0] 849 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2] 850 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr')) 851 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr')) 852 853 " Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight) 854 call term_sendkeys(buf, "\<cr>") 855 call term_wait(buf, 200) 856 let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0] 857 let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2] 858 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr')) 859 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr')) 860 861 " Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight) 862 call term_sendkeys(buf, ":1\<cr>") 863 call term_sendkeys(buf, ":set nohlsearch\<cr>") 864 call term_sendkeys(buf, "/vim") 865 call term_wait(buf, 200) 866 let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0] 867 let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0] 868 call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr')) 869 call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr')) 870 call delete('Xsearch.txt') 871 872 call delete('Xsearch.txt') 873 bwipe! 874endfunc 875 876func Test_incsearch_cmdline_modifier() 877 if !exists('+incsearch') 878 return 879 endif 880 call test_override("char_avail", 1) 881 new 882 call setline(1, ['foo']) 883 set incsearch 884 " Test that error E14 does not occur in parsing command modifier. 885 call feedkeys("V:tab", 'tx') 886 887 call Incsearch_cleanup() 888endfunc 889 890func Test_incsearch_scrolling() 891 if !CanRunVimInTerminal() 892 throw 'Skipped: cannot make screendumps' 893 endif 894 call assert_equal(0, &scrolloff) 895 call writefile([ 896 \ 'let dots = repeat(".", 120)', 897 \ 'set incsearch cmdheight=2 scrolloff=0', 898 \ 'call setline(1, [dots, dots, dots, "", "target", dots, dots])', 899 \ 'normal gg', 900 \ 'redraw', 901 \ ], 'Xscript') 902 let buf = RunVimInTerminal('-S Xscript', {'rows': 9, 'cols': 70}) 903 " Need to send one key at a time to force a redraw 904 call term_sendkeys(buf, '/') 905 sleep 100m 906 call term_sendkeys(buf, 't') 907 sleep 100m 908 call term_sendkeys(buf, 'a') 909 sleep 100m 910 call term_sendkeys(buf, 'r') 911 sleep 100m 912 call term_sendkeys(buf, 'g') 913 call VerifyScreenDump(buf, 'Test_incsearch_scrolling_01', {}) 914 915 call term_sendkeys(buf, "\<Esc>") 916 call StopVimInTerminal(buf) 917 call delete('Xscript') 918endfunc 919 920func Test_incsearch_search_dump() 921 if !exists('+incsearch') 922 return 923 endif 924 if !CanRunVimInTerminal() 925 throw 'Skipped: cannot make screendumps' 926 endif 927 call writefile([ 928 \ 'set incsearch hlsearch scrolloff=0', 929 \ 'for n in range(1, 8)', 930 \ ' call setline(n, "foo " . n)', 931 \ 'endfor', 932 \ '3', 933 \ ], 'Xis_search_script') 934 let buf = RunVimInTerminal('-S Xis_search_script', {'rows': 9, 'cols': 70}) 935 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by 936 " the 'ambiwidth' check. 937 sleep 100m 938 939 " Need to send one key at a time to force a redraw. 940 call term_sendkeys(buf, '/fo') 941 call VerifyScreenDump(buf, 'Test_incsearch_search_01', {}) 942 call term_sendkeys(buf, "\<Esc>") 943 sleep 100m 944 945 call term_sendkeys(buf, '/\v') 946 call VerifyScreenDump(buf, 'Test_incsearch_search_02', {}) 947 call term_sendkeys(buf, "\<Esc>") 948 949 call StopVimInTerminal(buf) 950 call delete('Xis_search_script') 951endfunc 952 953func Test_incsearch_substitute() 954 if !exists('+incsearch') 955 return 956 endif 957 call test_override("char_avail", 1) 958 new 959 set incsearch 960 for n in range(1, 10) 961 call setline(n, 'foo ' . n) 962 endfor 963 4 964 call feedkeys(":.,.+2s/foo\<BS>o\<BS>o/xxx\<cr>", 'tx') 965 call assert_equal('foo 3', getline(3)) 966 call assert_equal('xxx 4', getline(4)) 967 call assert_equal('xxx 5', getline(5)) 968 call assert_equal('xxx 6', getline(6)) 969 call assert_equal('foo 7', getline(7)) 970 971 call Incsearch_cleanup() 972endfunc 973 974" Similar to Test_incsearch_substitute() but with a screendump halfway. 975func Test_incsearch_substitute_dump() 976 if !exists('+incsearch') 977 return 978 endif 979 if !CanRunVimInTerminal() 980 throw 'Skipped: cannot make screendumps' 981 endif 982 call writefile([ 983 \ 'set incsearch hlsearch scrolloff=0', 984 \ 'for n in range(1, 10)', 985 \ ' call setline(n, "foo " . n)', 986 \ 'endfor', 987 \ 'call setline(11, "bar 11")', 988 \ '3', 989 \ ], 'Xis_subst_script') 990 let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70}) 991 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by 992 " the 'ambiwidth' check. 993 sleep 100m 994 995 " Need to send one key at a time to force a redraw. 996 " Select three lines at the cursor with typed pattern. 997 call term_sendkeys(buf, ':.,.+2s/') 998 sleep 100m 999 call term_sendkeys(buf, 'f') 1000 sleep 100m 1001 call term_sendkeys(buf, 'o') 1002 sleep 100m 1003 call term_sendkeys(buf, 'o') 1004 call VerifyScreenDump(buf, 'Test_incsearch_substitute_01', {}) 1005 call term_sendkeys(buf, "\<Esc>") 1006 1007 " Select three lines at the cursor using previous pattern. 1008 call term_sendkeys(buf, "/foo\<CR>") 1009 sleep 100m 1010 call term_sendkeys(buf, ':.,.+2s//') 1011 call VerifyScreenDump(buf, 'Test_incsearch_substitute_02', {}) 1012 1013 " Deleting last slash should remove the match. 1014 call term_sendkeys(buf, "\<BS>") 1015 call VerifyScreenDump(buf, 'Test_incsearch_substitute_03', {}) 1016 call term_sendkeys(buf, "\<Esc>") 1017 1018 " Reverse range is accepted 1019 call term_sendkeys(buf, ':5,2s/foo') 1020 call VerifyScreenDump(buf, 'Test_incsearch_substitute_04', {}) 1021 call term_sendkeys(buf, "\<Esc>") 1022 1023 " White space after the command is skipped 1024 call term_sendkeys(buf, ':2,3sub /fo') 1025 call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {}) 1026 call term_sendkeys(buf, "\<Esc>") 1027 1028 " Command modifiers are skipped 1029 call term_sendkeys(buf, ':above below browse botr confirm keepmar keepalt keeppat keepjum filter xxx hide lockm leftabove noau noswap rightbel sandbox silent silent! $tab top unsil vert verbose 4,5s/fo.') 1030 call VerifyScreenDump(buf, 'Test_incsearch_substitute_06', {}) 1031 call term_sendkeys(buf, "\<Esc>") 1032 1033 " Cursorline highlighting at match 1034 call term_sendkeys(buf, ":set cursorline\<CR>") 1035 call term_sendkeys(buf, 'G9G') 1036 call term_sendkeys(buf, ':9,11s/bar') 1037 call VerifyScreenDump(buf, 'Test_incsearch_substitute_07', {}) 1038 call term_sendkeys(buf, "\<Esc>") 1039 1040 " Cursorline highlighting at cursor when no match 1041 call term_sendkeys(buf, ':9,10s/bar') 1042 call VerifyScreenDump(buf, 'Test_incsearch_substitute_08', {}) 1043 call term_sendkeys(buf, "\<Esc>") 1044 1045 " Only \v handled as empty pattern, does not move cursor 1046 call term_sendkeys(buf, '3G4G') 1047 call term_sendkeys(buf, ":nohlsearch\<CR>") 1048 call term_sendkeys(buf, ':6,7s/\v') 1049 call VerifyScreenDump(buf, 'Test_incsearch_substitute_09', {}) 1050 call term_sendkeys(buf, "\<Esc>") 1051 1052 call term_sendkeys(buf, ":set nocursorline\<CR>") 1053 1054 " All matches are highlighted for 'hlsearch' after the incsearch canceled 1055 call term_sendkeys(buf, "1G*") 1056 call term_sendkeys(buf, ":2,5s/foo") 1057 sleep 100m 1058 call term_sendkeys(buf, "\<Esc>") 1059 call VerifyScreenDump(buf, 'Test_incsearch_substitute_10', {}) 1060 1061 call term_sendkeys(buf, ":split\<CR>") 1062 call term_sendkeys(buf, ":let @/ = 'xyz'\<CR>") 1063 call term_sendkeys(buf, ":%s/.") 1064 call VerifyScreenDump(buf, 'Test_incsearch_substitute_11', {}) 1065 call term_sendkeys(buf, "\<BS>") 1066 call VerifyScreenDump(buf, 'Test_incsearch_substitute_12', {}) 1067 call term_sendkeys(buf, "\<Esc>") 1068 call VerifyScreenDump(buf, 'Test_incsearch_substitute_13', {}) 1069 call term_sendkeys(buf, ":%bwipe!\<CR>") 1070 call term_sendkeys(buf, ":only!\<CR>") 1071 1072 " get :'<,'>s command in history 1073 call term_sendkeys(buf, ":set cmdheight=2\<CR>") 1074 call term_sendkeys(buf, "aasdfasdf\<Esc>") 1075 call term_sendkeys(buf, "V:s/a/b/g\<CR>") 1076 " Using '<,'> does not give E20 1077 call term_sendkeys(buf, ":new\<CR>") 1078 call term_sendkeys(buf, "aasdfasdf\<Esc>") 1079 call term_sendkeys(buf, ":\<Up>\<Up>") 1080 call VerifyScreenDump(buf, 'Test_incsearch_substitute_14', {}) 1081 call term_sendkeys(buf, "<Esc>") 1082 1083 call StopVimInTerminal(buf) 1084 call delete('Xis_subst_script') 1085endfunc 1086 1087func Test_incsearch_highlighting() 1088 if !exists('+incsearch') 1089 return 1090 endif 1091 if !CanRunVimInTerminal() 1092 throw 'Skipped: cannot make screendumps' 1093 endif 1094 1095 call writefile([ 1096 \ 'set incsearch hlsearch', 1097 \ 'call setline(1, "hello/there")', 1098 \ ], 'Xis_subst_hl_script') 1099 let buf = RunVimInTerminal('-S Xis_subst_hl_script', {'rows': 4, 'cols': 20}) 1100 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by 1101 " the 'ambiwidth' check. 1102 sleep 300m 1103 1104 " Using a different search delimiter should still highlight matches 1105 " that contain a '/'. 1106 call term_sendkeys(buf, ":%s;ello/the") 1107 call VerifyScreenDump(buf, 'Test_incsearch_substitute_15', {}) 1108 call term_sendkeys(buf, "<Esc>") 1109endfunc 1110 1111func Test_incsearch_with_change() 1112 if !has('timers') || !exists('+incsearch') || !CanRunVimInTerminal() 1113 throw 'Skipped: cannot make screendumps and/or timers feature and/or incsearch option missing' 1114 endif 1115 1116 call writefile([ 1117 \ 'set incsearch hlsearch scrolloff=0', 1118 \ 'call setline(1, ["one", "two ------ X", "three"])', 1119 \ 'call timer_start(200, { _ -> setline(2, "x")})', 1120 \ ], 'Xis_change_script') 1121 let buf = RunVimInTerminal('-S Xis_change_script', {'rows': 9, 'cols': 70}) 1122 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by 1123 " the 'ambiwidth' check. 1124 sleep 300m 1125 1126 " Highlight X, it will be deleted by the timer callback. 1127 call term_sendkeys(buf, ':%s/X') 1128 call VerifyScreenDump(buf, 'Test_incsearch_change_01', {}) 1129 call term_sendkeys(buf, "\<Esc>") 1130 1131 call StopVimInTerminal(buf) 1132 call delete('Xis_change_script') 1133endfunc 1134 1135" Similar to Test_incsearch_substitute_dump() for :sort 1136func Test_incsearch_sort_dump() 1137 if !exists('+incsearch') 1138 return 1139 endif 1140 if !CanRunVimInTerminal() 1141 throw 'Skipped: cannot make screendumps' 1142 endif 1143 call writefile([ 1144 \ 'set incsearch hlsearch scrolloff=0', 1145 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])', 1146 \ ], 'Xis_sort_script') 1147 let buf = RunVimInTerminal('-S Xis_sort_script', {'rows': 9, 'cols': 70}) 1148 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by 1149 " the 'ambiwidth' check. 1150 sleep 100m 1151 1152 " Need to send one key at a time to force a redraw. 1153 call term_sendkeys(buf, ':sort ni u /on') 1154 call VerifyScreenDump(buf, 'Test_incsearch_sort_01', {}) 1155 call term_sendkeys(buf, "\<Esc>") 1156 1157 call StopVimInTerminal(buf) 1158 call delete('Xis_sort_script') 1159endfunc 1160 1161" Similar to Test_incsearch_substitute_dump() for :vimgrep famiry 1162func Test_incsearch_vimgrep_dump() 1163 if !exists('+incsearch') 1164 return 1165 endif 1166 if !CanRunVimInTerminal() 1167 throw 'Skipped: cannot make screendumps' 1168 endif 1169 call writefile([ 1170 \ 'set incsearch hlsearch scrolloff=0', 1171 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])', 1172 \ ], 'Xis_vimgrep_script') 1173 let buf = RunVimInTerminal('-S Xis_vimgrep_script', {'rows': 9, 'cols': 70}) 1174 " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by 1175 " the 'ambiwidth' check. 1176 sleep 100m 1177 1178 " Need to send one key at a time to force a redraw. 1179 call term_sendkeys(buf, ':vimgrep on') 1180 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_01', {}) 1181 call term_sendkeys(buf, "\<Esc>") 1182 1183 call term_sendkeys(buf, ':vimg /on/ *.txt') 1184 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_02', {}) 1185 call term_sendkeys(buf, "\<Esc>") 1186 1187 call term_sendkeys(buf, ':vimgrepadd "\<on') 1188 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_03', {}) 1189 call term_sendkeys(buf, "\<Esc>") 1190 1191 call term_sendkeys(buf, ':lv "tha') 1192 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_04', {}) 1193 call term_sendkeys(buf, "\<Esc>") 1194 1195 call term_sendkeys(buf, ':lvimgrepa "the" **/*.txt') 1196 call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_05', {}) 1197 call term_sendkeys(buf, "\<Esc>") 1198 1199 call StopVimInTerminal(buf) 1200 call delete('Xis_vimgrep_script') 1201endfunc 1202 1203func Test_keep_last_search_pattern() 1204 if !exists('+incsearch') 1205 return 1206 endif 1207 new 1208 call setline(1, ['foo', 'foo', 'foo']) 1209 set incsearch 1210 call test_override("char_avail", 1) 1211 let @/ = 'bar' 1212 call feedkeys(":/foo/s//\<Esc>", 'ntx') 1213 call assert_equal('bar', @/) 1214 1215 " no error message if pattern not found 1216 call feedkeys(":/xyz/s//\<Esc>", 'ntx') 1217 call assert_equal('bar', @/) 1218 1219 bwipe! 1220 call test_override("ALL", 0) 1221 set noincsearch 1222endfunc 1223 1224func Test_word_under_cursor_after_match() 1225 if !exists('+incsearch') 1226 return 1227 endif 1228 new 1229 call setline(1, 'foo bar') 1230 set incsearch 1231 call test_override("char_avail", 1) 1232 try 1233 call feedkeys("/foo\<C-R>\<C-W>\<CR>", 'ntx') 1234 catch /E486:/ 1235 endtry 1236 call assert_equal('foobar', @/) 1237 1238 bwipe! 1239 call test_override("ALL", 0) 1240 set noincsearch 1241endfunc 1242 1243func Test_subst_word_under_cursor() 1244 if !exists('+incsearch') 1245 return 1246 endif 1247 new 1248 call setline(1, ['int SomeLongName;', 'for (xxx = 1; xxx < len; ++xxx)']) 1249 set incsearch 1250 call test_override("char_avail", 1) 1251 call feedkeys("/LongName\<CR>", 'ntx') 1252 call feedkeys(":%s/xxx/\<C-R>\<C-W>/g\<CR>", 'ntx') 1253 call assert_equal('for (SomeLongName = 1; SomeLongName < len; ++SomeLongName)', getline(2)) 1254 1255 bwipe! 1256 call test_override("ALL", 0) 1257 set noincsearch 1258endfunc 1259 1260func Test_search_undefined_behaviour() 1261 if !has("terminal") 1262 return 1263 endif 1264 let h = winheight(0) 1265 if h < 3 1266 return 1267 endif 1268 " did cause an undefined left shift 1269 let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3}) 1270 call assert_equal([''], getline(1, '$')) 1271 call term_sendkeys(g:buf, ":qa!\<cr>") 1272 bwipe! 1273endfunc 1274 1275func Test_search_undefined_behaviour2() 1276 call search("\%UC0000000") 1277endfunc 1278 1279" Test for search('multi-byte char', 'bce') 1280func Test_search_multibyte() 1281 let save_enc = &encoding 1282 set encoding=utf8 1283 enew! 1284 call append('$', 'A') 1285 call cursor(2, 1) 1286 call assert_equal(2, search('A', 'bce', line('.'))) 1287 enew! 1288 let &encoding = save_enc 1289endfunc 1290 1291" This was causing E874. Also causes an invalid read? 1292func Test_look_behind() 1293 new 1294 call setline(1, '0\|\&\n\@<=') 1295 call search(getline(".")) 1296 bwipe! 1297endfunc 1298 1299func Test_search_sentence() 1300 new 1301 " this used to cause a crash 1302 call assert_fails("/\\%')", 'E486') 1303 call assert_fails("/", 'E486') 1304 /\%'( 1305 / 1306endfunc 1307 1308" Test that there is no crash when there is a last search pattern but no last 1309" substitute pattern. 1310func Test_no_last_substitute_pat() 1311 " Use viminfo to set the last search pattern to a string and make the last 1312 " substitute pattern the most recent used and make it empty (NULL). 1313 call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo') 1314 rviminfo! Xviminfo 1315 call assert_fails('normal n', 'E35:') 1316 1317 call delete('Xviminfo') 1318endfunc 1319 1320func Test_search_Ctrl_L_combining() 1321 " Make sure, that Ctrl-L works correctly with combining characters. 1322 " It uses an artificial example of an 'a' with 4 combining chars: 1323 " 'a' U+0061 Dec:97 LATIN SMALL LETTER A a /\%u61\Z "\u0061" 1324 " ' ̀' U+0300 Dec:768 COMBINING GRAVE ACCENT ̀ /\%u300\Z "\u0300" 1325 " ' ́' U+0301 Dec:769 COMBINING ACUTE ACCENT ́ /\%u301\Z "\u0301" 1326 " ' ̇' U+0307 Dec:775 COMBINING DOT ABOVE ̇ /\%u307\Z "\u0307" 1327 " ' ̣' U+0323 Dec:803 COMBINING DOT BELOW ̣ /\%u323 "\u0323" 1328 " Those should also appear on the commandline 1329 if !exists('+incsearch') 1330 return 1331 endif 1332 call Cmdline3_prep() 1333 1 1334 let bufcontent = ['', 'Miạ̀́̇m'] 1335 call append('$', bufcontent) 1336 call feedkeys("/Mi\<c-l>\<c-l>\<cr>", 'tx') 1337 call assert_equal(5, line('.')) 1338 call assert_equal(bufcontent[1], @/) 1339 call Incsearch_cleanup() 1340endfunc 1341 1342func Test_large_hex_chars1() 1343 " This used to cause a crash, the character becomes an NFA state. 1344 try 1345 /\%Ufffffc23 1346 catch 1347 call assert_match('E678:', v:exception) 1348 endtry 1349 try 1350 set re=1 1351 /\%Ufffffc23 1352 catch 1353 call assert_match('E678:', v:exception) 1354 endtry 1355 set re& 1356endfunc 1357 1358func Test_large_hex_chars2() 1359 " This used to cause a crash, the character becomes an NFA state. 1360 try 1361 /[\Ufffffc1f] 1362 catch 1363 call assert_match('E486:', v:exception) 1364 endtry 1365 try 1366 set re=1 1367 /[\Ufffffc1f] 1368 catch 1369 call assert_match('E486:', v:exception) 1370 endtry 1371 set re& 1372endfunc 1373 1374func Test_one_error_msg() 1375 " This was also giving an internal error 1376 call assert_fails('call search(" \\((\\v[[=P=]]){185}+ ")', 'E871:') 1377endfunc 1378 1379func Test_incsearch_add_char_under_cursor() 1380 if !exists('+incsearch') 1381 return 1382 endif 1383 set incsearch 1384 new 1385 call setline(1, ['find match', 'anything']) 1386 1 1387 call test_override('char_avail', 1) 1388 call feedkeys("fc/m\<C-L>\<C-L>\<C-L>\<C-L>\<C-L>\<CR>", 'tx') 1389 call assert_equal('match', @/) 1390 call test_override('char_avail', 0) 1391 1392 set incsearch& 1393 bwipe! 1394endfunc 1395 1396" Test for the search() function with match at the cursor position 1397func Test_search_match_at_curpos() 1398 new 1399 call append(0, ['foobar', '', 'one two', '']) 1400 1401 normal gg 1402 1403 eval 'foobar'->search('c') 1404 call assert_equal([1, 1], [line('.'), col('.')]) 1405 1406 normal j 1407 call search('^$', 'c') 1408 call assert_equal([2, 1], [line('.'), col('.')]) 1409 1410 call search('^$', 'bc') 1411 call assert_equal([2, 1], [line('.'), col('.')]) 1412 1413 exe "normal /two\<CR>" 1414 call search('.', 'c') 1415 call assert_equal([3, 5], [line('.'), col('.')]) 1416 1417 close! 1418endfunc 1419 1420func Test_search_display_pattern() 1421 new 1422 call setline(1, ['foo', 'bar', 'foobar']) 1423 1424 call cursor(1, 1) 1425 let @/ = 'foo' 1426 let pat = @/->escape('()*?'. '\s\+') 1427 let g:a = execute(':unsilent :norm! n') 1428 call assert_match(pat, g:a) 1429 1430 " right-left 1431 if exists("+rightleft") 1432 set rl 1433 call cursor(1, 1) 1434 let @/ = 'foo' 1435 let pat = 'oof/\s\+' 1436 let g:a = execute(':unsilent :norm! n') 1437 call assert_match(pat, g:a) 1438 set norl 1439 endif 1440endfunc 1441 1442func Test_searchdecl() 1443 let lines =<< trim END 1444 int global; 1445 1446 func() 1447 { 1448 int global; 1449 if (cond) { 1450 int local; 1451 } 1452 int local; 1453 // comment 1454 } 1455 END 1456 new 1457 call setline(1, lines) 1458 10 1459 call assert_equal(0, searchdecl('local', 0, 0)) 1460 call assert_equal(7, getcurpos()[1]) 1461 1462 10 1463 call assert_equal(0, 'local'->searchdecl(0, 1)) 1464 call assert_equal(9, getcurpos()[1]) 1465 1466 10 1467 call assert_equal(0, searchdecl('global')) 1468 call assert_equal(5, getcurpos()[1]) 1469 1470 10 1471 call assert_equal(0, searchdecl('global', 1)) 1472 call assert_equal(1, getcurpos()[1]) 1473 1474 bwipe! 1475endfunc 1476 1477func Test_search_special() 1478 " this was causing illegal memory access and an endless loop 1479 set t_PE= 1480 exe "norm /\x80PS" 1481endfunc 1482 1483" Test for command failures when the last search pattern is not set. 1484" Need to run this in a new vim instance where last search pattern is not set. 1485func Test_search_with_no_last_pat() 1486 let lines =<< trim [SCRIPT] 1487 call assert_fails("normal i\<C-R>/\e", 'E35:') 1488 call assert_fails("exe '/'", 'E35:') 1489 call assert_fails("exe '?'", 'E35:') 1490 call assert_fails("/", 'E35:') 1491 call assert_fails("?", 'E35:') 1492 call assert_fails("normal n", 'E35:') 1493 call assert_fails("normal N", 'E35:') 1494 call assert_fails("normal gn", 'E35:') 1495 call assert_fails("normal gN", 'E35:') 1496 call assert_fails("normal cgn", 'E35:') 1497 call assert_fails("normal cgN", 'E35:') 1498 let p = [] 1499 let p = @/ 1500 call assert_equal('', p) 1501 call assert_fails("normal :\<C-R>/", 'E35:') 1502 call assert_fails("//p", 'E35:') 1503 call assert_fails(";//p", 'E35:') 1504 call assert_fails("??p", 'E35:') 1505 call assert_fails(";??p", 'E35:') 1506 call assert_fails('g//p', 'E476:') 1507 call assert_fails('v//p', 'E476:') 1508 call writefile(v:errors, 'Xresult') 1509 qall! 1510 [SCRIPT] 1511 call writefile(lines, 'Xscript') 1512 1513 if RunVim([], [], '--clean -S Xscript') 1514 call assert_equal([], readfile('Xresult')) 1515 endif 1516 call delete('Xscript') 1517 call delete('Xresult') 1518endfunc 1519 1520" Test for using tilde (~) atom in search. This should use the last used 1521" substitute pattern 1522func Test_search_tilde_pat() 1523 let lines =<< trim [SCRIPT] 1524 set regexpengine=1 1525 call assert_fails('exe "normal /~\<CR>"', 'E33:') 1526 call assert_fails('exe "normal ?~\<CR>"', 'E33:') 1527 set regexpengine=2 1528 call assert_fails('exe "normal /~\<CR>"', 'E383:') 1529 call assert_fails('exe "normal ?~\<CR>"', 'E383:') 1530 set regexpengine& 1531 call writefile(v:errors, 'Xresult') 1532 qall! 1533 [SCRIPT] 1534 call writefile(lines, 'Xscript') 1535 if RunVim([], [], '--clean -S Xscript') 1536 call assert_equal([], readfile('Xresult')) 1537 endif 1538 call delete('Xscript') 1539 call delete('Xresult') 1540endfunc 1541 1542" Test for searching a pattern that is not present with 'nowrapscan' 1543func Test_search_pat_not_found() 1544 new 1545 set nowrapscan 1546 let @/ = '1abcxyz2' 1547 call assert_fails('normal n', 'E385:') 1548 call assert_fails('normal N', 'E384:') 1549 set wrapscan& 1550 close 1551endfunc 1552 1553" Test for v:searchforward variable 1554func Test_searchforward_var() 1555 new 1556 call setline(1, ['foo', '', 'foo']) 1557 call cursor(2, 1) 1558 let @/ = 'foo' 1559 let v:searchforward = 0 1560 normal N 1561 call assert_equal(3, line('.')) 1562 call cursor(2, 1) 1563 let v:searchforward = 1 1564 normal N 1565 call assert_equal(1, line('.')) 1566 close! 1567endfunc 1568 1569" vim: shiftwidth=2 sts=2 expandtab 1570