1" Tests for defining text property types and adding text properties to the 2" buffer. 3 4if !has('textprop') 5 finish 6endif 7 8source screendump.vim 9 10" test length zero 11 12func Test_proptype_global() 13 call prop_type_add('comment', {'highlight': 'Directory', 'priority': 123, 'start_incl': 1, 'end_incl': 1}) 14 let proptypes = prop_type_list() 15 call assert_equal(1, len(proptypes)) 16 call assert_equal('comment', proptypes[0]) 17 18 let proptype = prop_type_get('comment') 19 call assert_equal('Directory', proptype['highlight']) 20 call assert_equal(123, proptype['priority']) 21 call assert_equal(1, proptype['start_incl']) 22 call assert_equal(1, proptype['end_incl']) 23 24 call prop_type_delete('comment') 25 call assert_equal(0, len(prop_type_list())) 26 27 call prop_type_add('one', {}) 28 call assert_equal(1, len(prop_type_list())) 29 let proptype = prop_type_get('one') 30 call assert_false(has_key(proptype, 'highlight')) 31 call assert_equal(0, proptype['priority']) 32 call assert_equal(0, proptype['start_incl']) 33 call assert_equal(0, proptype['end_incl']) 34 35 call prop_type_add('two', {}) 36 call assert_equal(2, len(prop_type_list())) 37 call prop_type_delete('one') 38 call assert_equal(1, len(prop_type_list())) 39 call prop_type_delete('two') 40 call assert_equal(0, len(prop_type_list())) 41endfunc 42 43func Test_proptype_buf() 44 let bufnr = bufnr('') 45 call prop_type_add('comment', {'bufnr': bufnr, 'highlight': 'Directory', 'priority': 123, 'start_incl': 1, 'end_incl': 1}) 46 let proptypes = prop_type_list({'bufnr': bufnr}) 47 call assert_equal(1, len(proptypes)) 48 call assert_equal('comment', proptypes[0]) 49 50 let proptype = prop_type_get('comment', {'bufnr': bufnr}) 51 call assert_equal('Directory', proptype['highlight']) 52 call assert_equal(123, proptype['priority']) 53 call assert_equal(1, proptype['start_incl']) 54 call assert_equal(1, proptype['end_incl']) 55 56 call prop_type_delete('comment', {'bufnr': bufnr}) 57 call assert_equal(0, len(prop_type_list({'bufnr': bufnr}))) 58 59 call prop_type_add('one', {'bufnr': bufnr}) 60 let proptype = prop_type_get('one', {'bufnr': bufnr}) 61 call assert_false(has_key(proptype, 'highlight')) 62 call assert_equal(0, proptype['priority']) 63 call assert_equal(0, proptype['start_incl']) 64 call assert_equal(0, proptype['end_incl']) 65 66 call prop_type_add('two', {'bufnr': bufnr}) 67 call assert_equal(2, len(prop_type_list({'bufnr': bufnr}))) 68 call prop_type_delete('one', {'bufnr': bufnr}) 69 call assert_equal(1, len(prop_type_list({'bufnr': bufnr}))) 70 call prop_type_delete('two', {'bufnr': bufnr}) 71 call assert_equal(0, len(prop_type_list({'bufnr': bufnr}))) 72 73 call assert_fails("call prop_type_add('one', {'bufnr': 98764})", "E158:") 74endfunc 75 76func AddPropTypes() 77 call prop_type_add('one', {}) 78 call prop_type_add('two', {}) 79 call prop_type_add('three', {}) 80 call prop_type_add('whole', {}) 81endfunc 82 83func DeletePropTypes() 84 call prop_type_delete('one') 85 call prop_type_delete('two') 86 call prop_type_delete('three') 87 call prop_type_delete('whole') 88endfunc 89 90func SetupPropsInFirstLine() 91 call setline(1, 'one two three') 92 call prop_add(1, 1, {'length': 3, 'id': 11, 'type': 'one'}) 93 call prop_add(1, 5, {'length': 3, 'id': 12, 'type': 'two'}) 94 call prop_add(1, 9, {'length': 5, 'id': 13, 'type': 'three'}) 95 call prop_add(1, 1, {'length': 13, 'id': 14, 'type': 'whole'}) 96endfunc 97 98func Get_expected_props() 99 return [ 100 \ {'col': 1, 'length': 13, 'id': 14, 'type': 'whole', 'start': 1, 'end': 1}, 101 \ {'col': 1, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1}, 102 \ {'col': 5, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1}, 103 \ {'col': 9, 'length': 5, 'id': 13, 'type': 'three', 'start': 1, 'end': 1}, 104 \ ] 105endfunc 106 107func Test_prop_add() 108 new 109 call AddPropTypes() 110 call SetupPropsInFirstLine() 111 let expected_props = Get_expected_props() 112 call assert_equal(expected_props, prop_list(1)) 113 call assert_fails("call prop_add(10, 1, {'length': 1, 'id': 14, 'type': 'whole'})", 'E966:') 114 call assert_fails("call prop_add(1, 22, {'length': 1, 'id': 14, 'type': 'whole'})", 'E964:') 115 116 " Insert a line above, text props must still be there. 117 call append(0, 'empty') 118 call assert_equal(expected_props, prop_list(2)) 119 " Delete a line above, text props must still be there. 120 1del 121 call assert_equal(expected_props, prop_list(1)) 122 123 " Prop without length or end column is zero length 124 call prop_clear(1) 125 call prop_add(1, 5, {'type': 'two'}) 126 let expected = [{'col': 5, 'length': 0, 'type': 'two', 'id': 0, 'start': 1, 'end': 1}] 127 call assert_equal(expected, prop_list(1)) 128 129 call assert_fails("call prop_add(1, 5, {'type': 'two', 'bufnr': 234343})", 'E158:') 130 131 call DeletePropTypes() 132 bwipe! 133endfunc 134 135func Test_prop_remove() 136 new 137 call AddPropTypes() 138 call SetupPropsInFirstLine() 139 let props = Get_expected_props() 140 call assert_equal(props, prop_list(1)) 141 142 " remove by id 143 call assert_equal(1, prop_remove({'id': 12}, 1)) 144 unlet props[2] 145 call assert_equal(props, prop_list(1)) 146 147 " remove by type 148 call assert_equal(1, prop_remove({'type': 'one'}, 1)) 149 unlet props[1] 150 call assert_equal(props, prop_list(1)) 151 152 " remove from unknown buffer 153 call assert_fails("call prop_remove({'type': 'one', 'bufnr': 123456}, 1)", 'E158:') 154 155 call DeletePropTypes() 156 bwipe! 157endfunc 158 159func SetupOneLine() 160 call setline(1, 'xonex xtwoxx') 161 normal gg0 162 call AddPropTypes() 163 call prop_add(1, 2, {'length': 3, 'id': 11, 'type': 'one'}) 164 call prop_add(1, 8, {'length': 3, 'id': 12, 'type': 'two'}) 165 let expected = [ 166 \ {'col': 2, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1}, 167 \ {'col': 8, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1}, 168 \] 169 call assert_equal(expected, prop_list(1)) 170 return expected 171endfunc 172 173func Test_prop_add_remove_buf() 174 new 175 let bufnr = bufnr('') 176 call AddPropTypes() 177 for lnum in range(1, 4) 178 call setline(lnum, 'one two three') 179 endfor 180 wincmd w 181 for lnum in range(1, 4) 182 call prop_add(lnum, 1, {'length': 3, 'id': 11, 'type': 'one', 'bufnr': bufnr}) 183 call prop_add(lnum, 5, {'length': 3, 'id': 12, 'type': 'two', 'bufnr': bufnr}) 184 call prop_add(lnum, 11, {'length': 3, 'id': 13, 'type': 'three', 'bufnr': bufnr}) 185 endfor 186 187 let props = [ 188 \ {'col': 1, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1}, 189 \ {'col': 5, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1}, 190 \ {'col': 11, 'length': 3, 'id': 13, 'type': 'three', 'start': 1, 'end': 1}, 191 \] 192 call assert_equal(props, prop_list(1, {'bufnr': bufnr})) 193 194 " remove by id 195 let before_props = deepcopy(props) 196 unlet props[1] 197 198 call prop_remove({'id': 12, 'bufnr': bufnr}, 1) 199 call assert_equal(props, prop_list(1, {'bufnr': bufnr})) 200 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr})) 201 call assert_equal(before_props, prop_list(3, {'bufnr': bufnr})) 202 call assert_equal(before_props, prop_list(4, {'bufnr': bufnr})) 203 204 call prop_remove({'id': 12, 'bufnr': bufnr}, 3, 4) 205 call assert_equal(props, prop_list(1, {'bufnr': bufnr})) 206 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr})) 207 call assert_equal(props, prop_list(3, {'bufnr': bufnr})) 208 call assert_equal(props, prop_list(4, {'bufnr': bufnr})) 209 210 call prop_remove({'id': 12, 'bufnr': bufnr}) 211 for lnum in range(1, 4) 212 call assert_equal(props, prop_list(lnum, {'bufnr': bufnr})) 213 endfor 214 215 " remove by type 216 let before_props = deepcopy(props) 217 unlet props[0] 218 219 call prop_remove({'type': 'one', 'bufnr': bufnr}, 1) 220 call assert_equal(props, prop_list(1, {'bufnr': bufnr})) 221 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr})) 222 call assert_equal(before_props, prop_list(3, {'bufnr': bufnr})) 223 call assert_equal(before_props, prop_list(4, {'bufnr': bufnr})) 224 225 call prop_remove({'type': 'one', 'bufnr': bufnr}, 3, 4) 226 call assert_equal(props, prop_list(1, {'bufnr': bufnr})) 227 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr})) 228 call assert_equal(props, prop_list(3, {'bufnr': bufnr})) 229 call assert_equal(props, prop_list(4, {'bufnr': bufnr})) 230 231 call prop_remove({'type': 'one', 'bufnr': bufnr}) 232 for lnum in range(1, 4) 233 call assert_equal(props, prop_list(lnum, {'bufnr': bufnr})) 234 endfor 235 236 call DeletePropTypes() 237 wincmd w 238 bwipe! 239endfunc 240 241func Test_prop_backspace() 242 new 243 set bs=2 244 let expected = SetupOneLine() " 'xonex xtwoxx' 245 246 exe "normal 0li\<BS>\<Esc>fxli\<BS>\<Esc>" 247 call assert_equal('one xtwoxx', getline(1)) 248 let expected[0].col = 1 249 let expected[1].col = 6 250 call assert_equal(expected, prop_list(1)) 251 252 call DeletePropTypes() 253 bwipe! 254 set bs& 255endfunc 256 257func Test_prop_replace() 258 new 259 set bs=2 260 let expected = SetupOneLine() " 'xonex xtwoxx' 261 262 exe "normal 0Ryyy\<Esc>" 263 call assert_equal('yyyex xtwoxx', getline(1)) 264 call assert_equal(expected, prop_list(1)) 265 266 exe "normal ftRyy\<BS>" 267 call assert_equal('yyyex xywoxx', getline(1)) 268 call assert_equal(expected, prop_list(1)) 269 270 exe "normal 0fwRyy\<BS>" 271 call assert_equal('yyyex xyyoxx', getline(1)) 272 call assert_equal(expected, prop_list(1)) 273 274 exe "normal 0foRyy\<BS>\<BS>" 275 call assert_equal('yyyex xyyoxx', getline(1)) 276 call assert_equal(expected, prop_list(1)) 277 278 call DeletePropTypes() 279 bwipe! 280 set bs& 281endfunc 282 283func Test_prop_open_line() 284 new 285 286 " open new line, props stay in top line 287 let expected = SetupOneLine() " 'xonex xtwoxx' 288 exe "normal o\<Esc>" 289 call assert_equal('xonex xtwoxx', getline(1)) 290 call assert_equal('', getline(2)) 291 call assert_equal(expected, prop_list(1)) 292 call DeletePropTypes() 293 294 " move all props to next line 295 let expected = SetupOneLine() " 'xonex xtwoxx' 296 exe "normal 0i\<CR>\<Esc>" 297 call assert_equal('', getline(1)) 298 call assert_equal('xonex xtwoxx', getline(2)) 299 call assert_equal(expected, prop_list(2)) 300 call DeletePropTypes() 301 302 " split just before prop, move all props to next line 303 let expected = SetupOneLine() " 'xonex xtwoxx' 304 exe "normal 0li\<CR>\<Esc>" 305 call assert_equal('x', getline(1)) 306 call assert_equal('onex xtwoxx', getline(2)) 307 let expected[0].col -= 1 308 let expected[1].col -= 1 309 call assert_equal(expected, prop_list(2)) 310 call DeletePropTypes() 311 312 " split inside prop, split first prop 313 let expected = SetupOneLine() " 'xonex xtwoxx' 314 exe "normal 0lli\<CR>\<Esc>" 315 call assert_equal('xo', getline(1)) 316 call assert_equal('nex xtwoxx', getline(2)) 317 let exp_first = [deepcopy(expected[0])] 318 let exp_first[0].length = 1 319 call assert_equal(exp_first, prop_list(1)) 320 let expected[0].col = 1 321 let expected[0].length = 2 322 let expected[1].col -= 2 323 call assert_equal(expected, prop_list(2)) 324 call DeletePropTypes() 325 326 " split just after first prop, second prop move to next line 327 let expected = SetupOneLine() " 'xonex xtwoxx' 328 exe "normal 0fea\<CR>\<Esc>" 329 call assert_equal('xone', getline(1)) 330 call assert_equal('x xtwoxx', getline(2)) 331 let exp_first = expected[0:0] 332 call assert_equal(exp_first, prop_list(1)) 333 let expected = expected[1:1] 334 let expected[0].col -= 4 335 call assert_equal(expected, prop_list(2)) 336 call DeletePropTypes() 337 338 bwipe! 339 set bs& 340endfunc 341 342func Test_prop_clear() 343 new 344 call AddPropTypes() 345 call SetupPropsInFirstLine() 346 call assert_equal(Get_expected_props(), prop_list(1)) 347 348 call prop_clear(1) 349 call assert_equal([], prop_list(1)) 350 351 call DeletePropTypes() 352 bwipe! 353endfunc 354 355func Test_prop_clear_buf() 356 new 357 call AddPropTypes() 358 call SetupPropsInFirstLine() 359 let bufnr = bufnr('') 360 wincmd w 361 call assert_equal(Get_expected_props(), prop_list(1, {'bufnr': bufnr})) 362 363 call prop_clear(1, 1, {'bufnr': bufnr}) 364 call assert_equal([], prop_list(1, {'bufnr': bufnr})) 365 366 wincmd w 367 call DeletePropTypes() 368 bwipe! 369endfunc 370 371func Test_prop_setline() 372 new 373 call AddPropTypes() 374 call SetupPropsInFirstLine() 375 call assert_equal(Get_expected_props(), prop_list(1)) 376 377 call setline(1, 'foobar') 378 call assert_equal([], prop_list(1)) 379 380 call DeletePropTypes() 381 bwipe! 382endfunc 383 384func Test_prop_setbufline() 385 new 386 call AddPropTypes() 387 call SetupPropsInFirstLine() 388 let bufnr = bufnr('') 389 wincmd w 390 call assert_equal(Get_expected_props(), prop_list(1, {'bufnr': bufnr})) 391 392 call setbufline(bufnr, 1, 'foobar') 393 call assert_equal([], prop_list(1, {'bufnr': bufnr})) 394 395 wincmd w 396 call DeletePropTypes() 397 bwipe! 398endfunc 399 400func Test_prop_substitute() 401 new 402 " Set first line to 'one two three' 403 call AddPropTypes() 404 call SetupPropsInFirstLine() 405 let expected_props = Get_expected_props() 406 call assert_equal(expected_props, prop_list(1)) 407 408 " Change "n" in "one" to XX: 'oXXe two three' 409 s/n/XX/ 410 let expected_props[0].length += 1 411 let expected_props[1].length += 1 412 let expected_props[2].col += 1 413 let expected_props[3].col += 1 414 call assert_equal(expected_props, prop_list(1)) 415 416 " Delete "t" in "two" and "three" to XX: 'oXXe wo hree' 417 s/t//g 418 let expected_props[0].length -= 2 419 let expected_props[2].length -= 1 420 let expected_props[3].length -= 1 421 let expected_props[3].col -= 1 422 call assert_equal(expected_props, prop_list(1)) 423 424 " Split the line by changing w to line break: 'oXXe ', 'o hree' 425 " The long prop is split and spans both lines. 426 " The props on "two" and "three" move to the next line. 427 s/w/\r/ 428 let new_props = [ 429 \ copy(expected_props[0]), 430 \ copy(expected_props[2]), 431 \ copy(expected_props[3]), 432 \ ] 433 let expected_props[0].length = 5 434 unlet expected_props[3] 435 unlet expected_props[2] 436 call assert_equal(expected_props, prop_list(1)) 437 438 let new_props[0].length = 6 439 let new_props[1].col = 1 440 let new_props[1].length = 1 441 let new_props[2].col = 3 442 call assert_equal(new_props, prop_list(2)) 443 444 call DeletePropTypes() 445 bwipe! 446endfunc 447 448func Test_prop_change_indent() 449 call prop_type_add('comment', {'highlight': 'Directory'}) 450 new 451 call setline(1, [' xxx', 'yyyyy']) 452 call prop_add(2, 2, {'length': 2, 'type': 'comment'}) 453 let expect = {'col': 2, 'length': 2, 'type': 'comment', 'start': 1, 'end': 1, 'id': 0} 454 call assert_equal([expect], prop_list(2)) 455 456 set shiftwidth=3 457 normal 2G>> 458 call assert_equal(' yyyyy', getline(2)) 459 let expect.col += 3 460 call assert_equal([expect], prop_list(2)) 461 462 normal 2G== 463 call assert_equal(' yyyyy', getline(2)) 464 let expect.col = 6 465 call assert_equal([expect], prop_list(2)) 466 467 call prop_clear(2) 468 call prop_add(2, 2, {'length': 5, 'type': 'comment'}) 469 let expect.col = 2 470 let expect.length = 5 471 call assert_equal([expect], prop_list(2)) 472 473 normal 2G<< 474 call assert_equal(' yyyyy', getline(2)) 475 let expect.length = 2 476 call assert_equal([expect], prop_list(2)) 477 478 set shiftwidth& 479 call prop_type_delete('comment') 480endfunc 481 482" Setup a three line prop in lines 2 - 4. 483" Add short props in line 1 and 5. 484func Setup_three_line_prop() 485 new 486 call setline(1, ['one', 'twotwo', 'three', 'fourfour', 'five']) 487 call prop_add(1, 2, {'length': 1, 'type': 'comment'}) 488 call prop_add(2, 4, {'end_lnum': 4, 'end_col': 5, 'type': 'comment'}) 489 call prop_add(5, 2, {'length': 1, 'type': 'comment'}) 490endfunc 491 492func Test_prop_multiline() 493 call prop_type_add('comment', {'highlight': 'Directory'}) 494 new 495 call setline(1, ['xxxxxxx', 'yyyyyyyyy', 'zzzzzzzz']) 496 497 " start halfway line 1, end halfway line 3 498 call prop_add(1, 3, {'end_lnum': 3, 'end_col': 5, 'type': 'comment'}) 499 let expect1 = {'col': 3, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0} 500 call assert_equal([expect1], prop_list(1)) 501 let expect2 = {'col': 1, 'length': 10, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0} 502 call assert_equal([expect2], prop_list(2)) 503 let expect3 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0} 504 call assert_equal([expect3], prop_list(3)) 505 call prop_clear(1, 3) 506 507 " include all three lines 508 call prop_add(1, 1, {'end_lnum': 3, 'end_col': 999, 'type': 'comment'}) 509 let expect1.col = 1 510 let expect1.length = 8 511 call assert_equal([expect1], prop_list(1)) 512 call assert_equal([expect2], prop_list(2)) 513 let expect3.length = 9 514 call assert_equal([expect3], prop_list(3)) 515 call prop_clear(1, 3) 516 517 bwipe! 518 519 " Test deleting the first line of a multi-line prop. 520 call Setup_three_line_prop() 521 let expect_short = {'col': 2, 'length': 1, 'type': 'comment', 'start': 1, 'end': 1, 'id': 0} 522 call assert_equal([expect_short], prop_list(1)) 523 let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0} 524 call assert_equal([expect2], prop_list(2)) 525 2del 526 call assert_equal([expect_short], prop_list(1)) 527 let expect2 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0} 528 call assert_equal([expect2], prop_list(2)) 529 bwipe! 530 531 " Test deleting the last line of a multi-line prop. 532 call Setup_three_line_prop() 533 let expect3 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0} 534 call assert_equal([expect3], prop_list(3)) 535 let expect4 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0} 536 call assert_equal([expect4], prop_list(4)) 537 4del 538 let expect3.end = 1 539 call assert_equal([expect3], prop_list(3)) 540 call assert_equal([expect_short], prop_list(4)) 541 bwipe! 542 543 " Test appending a line below the multi-line text prop start. 544 call Setup_three_line_prop() 545 let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0} 546 call assert_equal([expect2], prop_list(2)) 547 call append(2, "new line") 548 call assert_equal([expect2], prop_list(2)) 549 let expect3 = {'col': 1, 'length': 9, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0} 550 call assert_equal([expect3], prop_list(3)) 551 bwipe! 552 553 call prop_type_delete('comment') 554endfunc 555 556func Test_prop_byteoff() 557 call prop_type_add('comment', {'highlight': 'Directory'}) 558 new 559 call setline(1, ['line1', 'second line', '']) 560 set ff=unix 561 call assert_equal(19, line2byte(3)) 562 call prop_add(1, 1, {'end_col': 3, 'type': 'comment'}) 563 call assert_equal(19, line2byte(3)) 564 565 bwipe! 566 call prop_type_delete('comment') 567endfunc 568 569func Test_prop_undo() 570 new 571 call prop_type_add('comment', {'highlight': 'Directory'}) 572 call setline(1, ['oneone', 'twotwo', 'three']) 573 " Set 'undolevels' to break changes into undo-able pieces. 574 set ul& 575 576 call prop_add(1, 3, {'end_col': 5, 'type': 'comment'}) 577 let expected = [{'col': 3, 'length': 2, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ] 578 call assert_equal(expected, prop_list(1)) 579 580 " Insert a character, then undo. 581 exe "normal 0lllix\<Esc>" 582 set ul& 583 let expected[0].length = 3 584 call assert_equal(expected, prop_list(1)) 585 undo 586 let expected[0].length = 2 587 call assert_equal(expected, prop_list(1)) 588 589 " Delete a character, then undo 590 exe "normal 0lllx" 591 set ul& 592 let expected[0].length = 1 593 call assert_equal(expected, prop_list(1)) 594 undo 595 let expected[0].length = 2 596 call assert_equal(expected, prop_list(1)) 597 598 " Delete the line, then undo 599 1d 600 set ul& 601 call assert_equal([], prop_list(1)) 602 undo 603 call assert_equal(expected, prop_list(1)) 604 605 " Insert a character, delete two characters, then undo with "U" 606 exe "normal 0lllix\<Esc>" 607 set ul& 608 let expected[0].length = 3 609 call assert_equal(expected, prop_list(1)) 610 exe "normal 0lllxx" 611 set ul& 612 let expected[0].length = 1 613 call assert_equal(expected, prop_list(1)) 614 normal U 615 let expected[0].length = 2 616 call assert_equal(expected, prop_list(1)) 617 618 " substitute a word, then undo 619 call setline(1, 'the number 123 is highlighted.') 620 call prop_add(1, 12, {'length': 3, 'type': 'comment'}) 621 let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ] 622 call assert_equal(expected, prop_list(1)) 623 set ul& 624 1s/number/foo 625 let expected[0].col = 9 626 call assert_equal(expected, prop_list(1)) 627 undo 628 let expected[0].col = 12 629 call assert_equal(expected, prop_list(1)) 630 call prop_clear(1) 631 632 " substitute with backslash 633 call setline(1, 'the number 123 is highlighted.') 634 call prop_add(1, 12, {'length': 3, 'type': 'comment'}) 635 let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ] 636 call assert_equal(expected, prop_list(1)) 637 1s/the/\The 638 call assert_equal(expected, prop_list(1)) 639 1s/^/\\ 640 let expected[0].col += 1 641 call assert_equal(expected, prop_list(1)) 642 1s/^/\~ 643 let expected[0].col += 1 644 call assert_equal(expected, prop_list(1)) 645 1s/123/12\\3 646 let expected[0].length += 1 647 call assert_equal(expected, prop_list(1)) 648 call prop_clear(1) 649 650 bwipe! 651 call prop_type_delete('comment') 652endfunc 653 654" screenshot test with textprop highlighting 655func Test_textprop_screenshot_various() 656 " The Vim running in the terminal needs to use utf-8. 657 if !CanRunVimInTerminal() || g:orig_encoding != 'utf-8' 658 throw 'Skipped: cannot make screendumps or not using utf-8' 659 endif 660 call writefile([ 661 \ "call setline(1, [" 662 \ .. "'One two'," 663 \ .. "'Numbér 123 änd thœn 4¾7.'," 664 \ .. "'--aa--bb--cc--dd--'," 665 \ .. "'// comment with error in it'," 666 \ .. "'first line'," 667 \ .. "' second line '," 668 \ .. "'third line'," 669 \ .. "' fourth line'," 670 \ .. "])", 671 \ "hi NumberProp ctermfg=blue", 672 \ "hi LongProp ctermbg=yellow", 673 \ "hi BackgroundProp ctermbg=lightgrey", 674 \ "hi UnderlineProp cterm=underline", 675 \ "call prop_type_add('number', {'highlight': 'NumberProp'})", 676 \ "call prop_type_add('long', {'highlight': 'LongProp'})", 677 \ "call prop_type_add('start', {'highlight': 'NumberProp', 'start_incl': 1})", 678 \ "call prop_type_add('end', {'highlight': 'NumberProp', 'end_incl': 1})", 679 \ "call prop_type_add('both', {'highlight': 'NumberProp', 'start_incl': 1, 'end_incl': 1})", 680 \ "call prop_type_add('background', {'highlight': 'BackgroundProp', 'combine': 1})", 681 \ "call prop_type_add('error', {'highlight': 'UnderlineProp', 'combine': 1})", 682 \ "call prop_add(1, 4, {'end_lnum': 3, 'end_col': 3, 'type': 'long'})", 683 \ "call prop_add(2, 9, {'length': 3, 'type': 'number'})", 684 \ "call prop_add(2, 24, {'length': 4, 'type': 'number'})", 685 \ "call prop_add(3, 3, {'length': 2, 'type': 'number'})", 686 \ "call prop_add(3, 7, {'length': 2, 'type': 'start'})", 687 \ "call prop_add(3, 11, {'length': 2, 'type': 'end'})", 688 \ "call prop_add(3, 15, {'length': 2, 'type': 'both'})", 689 \ "call prop_add(4, 12, {'length': 10, 'type': 'background'})", 690 \ "call prop_add(4, 17, {'length': 5, 'type': 'error'})", 691 \ "call prop_add(5, 7, {'length': 4, 'type': 'long'})", 692 \ "call prop_add(6, 1, {'length': 8, 'type': 'long'})", 693 \ "call prop_add(8, 1, {'length': 1, 'type': 'long'})", 694 \ "call prop_add(8, 11, {'length': 4, 'type': 'long'})", 695 \ "set number cursorline", 696 \ "hi clear SpellBad", 697 \ "set spell", 698 \ "syn match Comment '//.*'", 699 \ "hi Comment ctermfg=green", 700 \ "normal 3G0llix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>", 701 \ "normal 3G0lli\<BS>\<Esc>", 702 \ "normal 6G0i\<BS>\<Esc>", 703 \ "normal 3J", 704 \ "normal 3G", 705 \], 'XtestProp') 706 let buf = RunVimInTerminal('-S XtestProp', {'rows': 8}) 707 call VerifyScreenDump(buf, 'Test_textprop_01', {}) 708 709 " clean up 710 call StopVimInTerminal(buf) 711 call delete('XtestProp') 712endfunc 713 714func RunTestVisualBlock(width, dump) 715 call writefile([ 716 \ "call setline(1, [" 717 \ .. "'xxxxxxxxx 123 x'," 718 \ .. "'xxxxxxxx 123 x'," 719 \ .. "'xxxxxxx 123 x'," 720 \ .. "'xxxxxx 123 x'," 721 \ .. "'xxxxx 123 x'," 722 \ .. "'xxxx 123 xx'," 723 \ .. "'xxx 123 xxx'," 724 \ .. "'xx 123 xxxx'," 725 \ .. "'x 123 xxxxx'," 726 \ .. "' 123 xxxxxx'," 727 \ .. "])", 728 \ "hi SearchProp ctermbg=yellow", 729 \ "call prop_type_add('search', {'highlight': 'SearchProp'})", 730 \ "call prop_add(1, 11, {'length': 3, 'type': 'search'})", 731 \ "call prop_add(2, 10, {'length': 3, 'type': 'search'})", 732 \ "call prop_add(3, 9, {'length': 3, 'type': 'search'})", 733 \ "call prop_add(4, 8, {'length': 3, 'type': 'search'})", 734 \ "call prop_add(5, 7, {'length': 3, 'type': 'search'})", 735 \ "call prop_add(6, 6, {'length': 3, 'type': 'search'})", 736 \ "call prop_add(7, 5, {'length': 3, 'type': 'search'})", 737 \ "call prop_add(8, 4, {'length': 3, 'type': 'search'})", 738 \ "call prop_add(9, 3, {'length': 3, 'type': 'search'})", 739 \ "call prop_add(10, 2, {'length': 3, 'type': 'search'})", 740 \ "normal 1G6|\<C-V>" .. repeat('l', a:width - 1) .. "10jx", 741 \], 'XtestPropVis') 742 let buf = RunVimInTerminal('-S XtestPropVis', {'rows': 12}) 743 call VerifyScreenDump(buf, 'Test_textprop_vis_' .. a:dump, {}) 744 745 " clean up 746 call StopVimInTerminal(buf) 747 call delete('XtestPropVis') 748endfunc 749 750" screenshot test with Visual block mode operations 751func Test_textprop_screenshot_visual() 752 if !CanRunVimInTerminal() 753 throw 'Skipped: cannot make screendumps' 754 endif 755 756 " Delete two columns while text props are three chars wide. 757 call RunTestVisualBlock(2, '01') 758 759 " Same, but delete four columns 760 call RunTestVisualBlock(4, '02') 761endfunc 762 763" Adding a text property to a new buffer should not fail 764func Test_textprop_empty_buffer() 765 call prop_type_add('comment', {'highlight': 'Search'}) 766 new 767 call prop_add(1, 1, {'type': 'comment'}) 768 close 769 call prop_type_delete('comment') 770endfunc 771 772" Adding a text property to an empty buffer and then editing another 773func Test_textprop_empty_buffer_next() 774 call prop_type_add("xxx", {}) 775 call prop_add(1, 1, {"type": "xxx"}) 776 next X 777 call prop_type_delete('xxx') 778endfunc 779 780func Test_textprop_remove_from_buf() 781 new 782 let buf = bufnr('') 783 call prop_type_add('one', {'bufnr': buf}) 784 call prop_add(1, 1, {'type': 'one', 'id': 234}) 785 file x 786 edit y 787 call prop_remove({'id': 234, 'bufnr': buf}, 1) 788 call prop_type_delete('one', {'bufnr': buf}) 789 bwipe! x 790 close 791endfunc 792