1" Tests for the undo tree. 2" Since this script is sourced we need to explicitly break changes up in 3" undo-able pieces. Do that by setting 'undolevels'. 4" Also tests :earlier and :later. 5 6func Test_undotree() 7 new 8 9 normal! Aabc 10 set ul=100 11 let d = undotree() 12 call assert_equal(1, d.seq_last) 13 call assert_equal(1, d.seq_cur) 14 call assert_equal(0, d.save_last) 15 call assert_equal(0, d.save_cur) 16 call assert_equal(1, len(d.entries)) 17 call assert_equal(1, d.entries[0].newhead) 18 call assert_equal(1, d.entries[0].seq) 19 call assert_true(d.entries[0].time <= d.time_cur) 20 21 normal! Adef 22 set ul=100 23 let d = undotree() 24 call assert_equal(2, d.seq_last) 25 call assert_equal(2, d.seq_cur) 26 call assert_equal(0, d.save_last) 27 call assert_equal(0, d.save_cur) 28 call assert_equal(2, len(d.entries)) 29 call assert_equal(1, d.entries[0].seq) 30 call assert_equal(1, d.entries[1].newhead) 31 call assert_equal(2, d.entries[1].seq) 32 call assert_true(d.entries[1].time <= d.time_cur) 33 34 undo 35 set ul=100 36 let d = undotree() 37 call assert_equal(2, d.seq_last) 38 call assert_equal(1, d.seq_cur) 39 call assert_equal(0, d.save_last) 40 call assert_equal(0, d.save_cur) 41 call assert_equal(2, len(d.entries)) 42 call assert_equal(1, d.entries[0].seq) 43 call assert_equal(1, d.entries[1].curhead) 44 call assert_equal(1, d.entries[1].newhead) 45 call assert_equal(2, d.entries[1].seq) 46 call assert_true(d.entries[1].time == d.time_cur) 47 48 normal! Aghi 49 set ul=100 50 let d = undotree() 51 call assert_equal(3, d.seq_last) 52 call assert_equal(3, d.seq_cur) 53 call assert_equal(0, d.save_last) 54 call assert_equal(0, d.save_cur) 55 call assert_equal(2, len(d.entries)) 56 call assert_equal(1, d.entries[0].seq) 57 call assert_equal(2, d.entries[1].alt[0].seq) 58 call assert_equal(1, d.entries[1].newhead) 59 call assert_equal(3, d.entries[1].seq) 60 call assert_true(d.entries[1].time <= d.time_cur) 61 62 undo 63 set ul=100 64 let d = undotree() 65 call assert_equal(3, d.seq_last) 66 call assert_equal(1, d.seq_cur) 67 call assert_equal(0, d.save_last) 68 call assert_equal(0, d.save_cur) 69 call assert_equal(2, len(d.entries)) 70 call assert_equal(1, d.entries[0].seq) 71 call assert_equal(2, d.entries[1].alt[0].seq) 72 call assert_equal(1, d.entries[1].curhead) 73 call assert_equal(1, d.entries[1].newhead) 74 call assert_equal(3, d.entries[1].seq) 75 call assert_true(d.entries[1].time == d.time_cur) 76 77 w! Xtest 78 let d = undotree() 79 call assert_equal(1, d.save_cur) 80 call assert_equal(1, d.save_last) 81 call delete('Xtest') 82 bwipe! Xtest 83endfunc 84 85func FillBuffer() 86 for i in range(1,13) 87 put=i 88 " Set 'undolevels' to split undo. 89 exe "setg ul=" . &g:ul 90 endfor 91endfunc 92 93func Test_global_local_undolevels() 94 new one 95 set undolevels=5 96 call FillBuffer() 97 " will only undo the last 5 changes, end up with 13 - (5 + 1) = 7 lines 98 earlier 10 99 call assert_equal(5, &g:undolevels) 100 call assert_equal(-123456, &l:undolevels) 101 call assert_equal('7', getline('$')) 102 103 new two 104 setlocal undolevels=2 105 call FillBuffer() 106 " will only undo the last 2 changes, end up with 13 - (2 + 1) = 10 lines 107 earlier 10 108 call assert_equal(5, &g:undolevels) 109 call assert_equal(2, &l:undolevels) 110 call assert_equal('10', getline('$')) 111 112 setlocal ul=10 113 call assert_equal(5, &g:undolevels) 114 call assert_equal(10, &l:undolevels) 115 116 " Setting local value in "two" must not change local value in "one" 117 wincmd p 118 call assert_equal(5, &g:undolevels) 119 call assert_equal(-123456, &l:undolevels) 120 121 new three 122 setglobal ul=50 123 call assert_equal(50, &g:undolevels) 124 call assert_equal(-123456, &l:undolevels) 125 126 " Resetting the local 'undolevels' value to use the global value 127 setlocal undolevels=5 128 setlocal undolevels< 129 call assert_equal(-123456, &l:undolevels) 130 131 " Drop created windows 132 set ul& 133 new 134 only! 135endfunc 136 137func BackOne(expected) 138 call feedkeys('g-', 'xt') 139 call assert_equal(a:expected, getline(1)) 140endfunc 141 142func Test_undo_del_chars() 143 " Setup a buffer without creating undo entries 144 new 145 set ul=-1 146 call setline(1, ['123-456']) 147 set ul=100 148 1 149 call test_settime(100) 150 151 " Delete three characters and undo with g- 152 call feedkeys('x', 'xt') 153 call feedkeys('x', 'xt') 154 call feedkeys('x', 'xt') 155 call assert_equal('-456', getline(1)) 156 call BackOne('3-456') 157 call BackOne('23-456') 158 call BackOne('123-456') 159 call assert_fails("BackOne('123-456')") 160 161 :" Delete three other characters and go back in time with g- 162 call feedkeys('$x', 'xt') 163 call feedkeys('x', 'xt') 164 call feedkeys('x', 'xt') 165 call assert_equal('123-', getline(1)) 166 call test_settime(101) 167 168 call BackOne('123-4') 169 call BackOne('123-45') 170 " skips '123-456' because it's older 171 call BackOne('-456') 172 call BackOne('3-456') 173 call BackOne('23-456') 174 call BackOne('123-456') 175 call assert_fails("BackOne('123-456')") 176 normal 10g+ 177 call assert_equal('123-', getline(1)) 178 179 :" Jump two seconds and go some seconds forward and backward 180 call test_settime(103) 181 call feedkeys("Aa\<Esc>", 'xt') 182 call feedkeys("Ab\<Esc>", 'xt') 183 call feedkeys("Ac\<Esc>", 'xt') 184 call assert_equal('123-abc', getline(1)) 185 earlier 1s 186 call assert_equal('123-', getline(1)) 187 earlier 3s 188 call assert_equal('123-456', getline(1)) 189 later 1s 190 call assert_equal('123-', getline(1)) 191 later 1h 192 call assert_equal('123-abc', getline(1)) 193 194 close! 195endfunc 196 197func Test_undolist() 198 new 199 set ul=100 200 201 let a = execute('undolist') 202 call assert_equal("\nNothing to undo", a) 203 204 " 1 leaf (2 changes). 205 call feedkeys('achange1', 'xt') 206 call feedkeys('achange2', 'xt') 207 let a = execute('undolist') 208 call assert_match("^\nnumber changes when *saved\n *2 *2 .*$", a) 209 210 " 2 leaves. 211 call feedkeys('u', 'xt') 212 call feedkeys('achange3\<Esc>', 'xt') 213 let a = execute('undolist') 214 call assert_match("^\nnumber changes when *saved\n *2 *2 *.*\n *3 *2 .*$", a) 215 close! 216endfunc 217 218func Test_U_command() 219 new 220 set ul=100 221 call feedkeys("achange1\<Esc>", 'xt') 222 call feedkeys("achange2\<Esc>", 'xt') 223 norm! U 224 call assert_equal('', getline(1)) 225 norm! U 226 call assert_equal('change1change2', getline(1)) 227 close! 228endfunc 229 230func Test_undojoin() 231 new 232 call feedkeys("Goaaaa\<Esc>", 'xt') 233 call feedkeys("obbbb\<Esc>", 'xt') 234 call assert_equal(['aaaa', 'bbbb'], getline(2, '$')) 235 call feedkeys("u", 'xt') 236 call assert_equal(['aaaa'], getline(2, '$')) 237 call feedkeys("obbbb\<Esc>", 'xt') 238 undojoin 239 " Note: next change must not be as if typed 240 call feedkeys("occcc\<Esc>", 'x') 241 call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$')) 242 call feedkeys("u", 'xt') 243 call assert_equal(['aaaa'], getline(2, '$')) 244 bwipe! 245endfunc 246 247func Test_undojoin_redo() 248 new 249 call setline(1, ['first line', 'second line']) 250 call feedkeys("ixx\<Esc>", 'xt') 251 call feedkeys(":undojoin | redo\<CR>", 'xt') 252 call assert_equal('xxfirst line', getline(1)) 253 call assert_equal('second line', getline(2)) 254 bwipe! 255endfunc 256 257" undojoin not allowed after undo 258func Test_undojoin_after_undo() 259 new 260 call feedkeys("ixx\<Esc>u", 'xt') 261 call assert_fails(':undojoin', 'E790:') 262 bwipe! 263endfunc 264 265" undojoin is a noop when no change yet, or when 'undolevels' is negative 266func Test_undojoin_noop() 267 new 268 call feedkeys(":undojoin\<CR>", 'xt') 269 call assert_equal([''], getline(1, '$')) 270 setlocal undolevels=-1 271 call feedkeys("ixx\<Esc>u", 'xt') 272 call feedkeys(":undojoin\<CR>", 'xt') 273 call assert_equal(['xx'], getline(1, '$')) 274 bwipe! 275endfunc 276 277func Test_undo_write() 278 call delete('Xtest') 279 split Xtest 280 call feedkeys("ione one one\<Esc>", 'xt') 281 w! 282 call feedkeys("otwo\<Esc>", 'xt') 283 call feedkeys("otwo\<Esc>", 'xt') 284 w 285 call feedkeys("othree\<Esc>", 'xt') 286 call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$')) 287 earlier 1f 288 call assert_equal(['one one one', 'two', 'two'], getline(1, '$')) 289 earlier 1f 290 call assert_equal(['one one one'], getline(1, '$')) 291 earlier 1f 292 call assert_equal([''], getline(1, '$')) 293 later 1f 294 call assert_equal(['one one one'], getline(1, '$')) 295 later 1f 296 call assert_equal(['one one one', 'two', 'two'], getline(1, '$')) 297 later 1f 298 call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$')) 299 300 close! 301 call delete('Xtest') 302 bwipe! Xtest 303 304 call assert_fails('earlier xyz', 'E475:') 305endfunc 306 307func Test_insert_expr() 308 new 309 " calling setline() triggers undo sync 310 call feedkeys("oa\<Esc>", 'xt') 311 call feedkeys("ob\<Esc>", 'xt') 312 set ul=100 313 call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x') 314 call assert_equal(['a', 'b', '120', '34'], getline(2, '$')) 315 call feedkeys("u", 'x') 316 call assert_equal(['a', 'b', '12'], getline(2, '$')) 317 call feedkeys("u", 'x') 318 call assert_equal(['a', 'b'], getline(2, '$')) 319 320 call feedkeys("oc\<Esc>", 'xt') 321 set ul=100 322 call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x') 323 call assert_equal(['a', 'b', 'c', '120', '34'], getline(2, '$')) 324 call feedkeys("u", 'x') 325 call assert_equal(['a', 'b', 'c', '12'], getline(2, '$')) 326 327 call feedkeys("od\<Esc>", 'xt') 328 set ul=100 329 call feedkeys("o1\<Esc>a2\<C-R>=string(123)\<CR>\<Esc>", 'x') 330 call assert_equal(['a', 'b', 'c', '12', 'd', '12123'], getline(2, '$')) 331 call feedkeys("u", 'x') 332 call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$')) 333 334 close! 335endfunc 336 337func Test_undofile_earlier() 338 " Issue #1254 339 " create undofile with timestamps older than Vim startup time. 340 let t0 = localtime() - 43200 341 call test_settime(t0) 342 new Xfile 343 call feedkeys("ione\<Esc>", 'xt') 344 set ul=100 345 call test_settime(t0 + 1) 346 call feedkeys("otwo\<Esc>", 'xt') 347 set ul=100 348 call test_settime(t0 + 2) 349 call feedkeys("othree\<Esc>", 'xt') 350 set ul=100 351 w 352 wundo Xundofile 353 bwipe! 354 " restore normal timestamps. 355 call test_settime(0) 356 new Xfile 357 rundo Xundofile 358 earlier 1d 359 call assert_equal('', getline(1)) 360 bwipe! 361 call delete('Xfile') 362 call delete('Xundofile') 363endfunc 364 365func Test_wundo_errors() 366 new 367 call setline(1, 'hello') 368 call assert_fails('wundo! Xdoesnotexist/Xundofile', 'E828:') 369 bwipe! 370endfunc 371 372" Check that reading a truncated undo file doesn't hang. 373func Test_undofile_truncated() 374 new 375 call setline(1, 'hello') 376 set ul=100 377 wundo Xundofile 378 let contents = readfile('Xundofile', 'B') 379 380 " try several sizes 381 for size in range(20, 500, 33) 382 call writefile(contents[0:size], 'Xundofile') 383 call assert_fails('rundo Xundofile', 'E825:') 384 endfor 385 386 bwipe! 387 call delete('Xundofile') 388endfunc 389 390func Test_rundo_errors() 391 call assert_fails('rundo XfileDoesNotExist', 'E822:') 392 393 call writefile(['abc'], 'Xundofile') 394 call assert_fails('rundo Xundofile', 'E823:') 395 396 call delete('Xundofile') 397endfunc 398 399func Test_undofile_next() 400 set undofile 401 new Xfoo.txt 402 execute "norm ix\<c-g>uy\<c-g>uz\<Esc>" 403 write 404 bwipe 405 406 next Xfoo.txt 407 call assert_equal('xyz', getline(1)) 408 silent undo 409 call assert_equal('xy', getline(1)) 410 silent undo 411 call assert_equal('x', getline(1)) 412 bwipe! 413 414 call delete('Xfoo.txt') 415 call delete('.Xfoo.txt.un~') 416 set undofile& 417endfunc 418 419" Test for undo working properly when executing commands from a register. 420" Also test this in an empty buffer. 421func Test_cmd_in_reg_undo() 422 enew! 423 let @a = "Ox\<Esc>jAy\<Esc>kdd" 424 edit +/^$ test_undo.vim 425 normal @au 426 call assert_equal(0, &modified) 427 return 428 new 429 normal @au 430 call assert_equal(0, &modified) 431 only! 432 let @a = '' 433endfunc 434 435" This used to cause an illegal memory access 436func Test_undo_append() 437 new 438 call feedkeys("axx\<Esc>v", 'xt') 439 undo 440 norm o 441 quit 442endfunc 443 444func Test_undo_0() 445 new 446 set ul=100 447 normal i1 448 undo 449 normal i2 450 undo 451 normal i3 452 453 undo 0 454 let d = undotree() 455 call assert_equal('', getline(1)) 456 call assert_equal(0, d.seq_cur) 457 458 redo 459 let d = undotree() 460 call assert_equal('3', getline(1)) 461 call assert_equal(3, d.seq_cur) 462 463 undo 2 464 undo 0 465 let d = undotree() 466 call assert_equal('', getline(1)) 467 call assert_equal(0, d.seq_cur) 468 469 redo 470 let d = undotree() 471 call assert_equal('2', getline(1)) 472 call assert_equal(2, d.seq_cur) 473 474 undo 1 475 undo 0 476 let d = undotree() 477 call assert_equal('', getline(1)) 478 call assert_equal(0, d.seq_cur) 479 480 redo 481 let d = undotree() 482 call assert_equal('1', getline(1)) 483 call assert_equal(1, d.seq_cur) 484 485 bwipe! 486endfunc 487 488" undo or redo are noop if there is nothing to undo or redo 489func Test_undo_redo_noop() 490 new 491 call assert_fails('undo 2', 'E830:') 492 493 message clear 494 undo 495 let messages = split(execute('message'), "\n") 496 call assert_equal('Already at oldest change', messages[-1]) 497 498 message clear 499 redo 500 let messages = split(execute('message'), "\n") 501 call assert_equal('Already at newest change', messages[-1]) 502 503 bwipe! 504endfunc 505 506func Test_redo_empty_line() 507 new 508 exe "norm\x16r\x160" 509 exe "norm." 510 bwipe! 511endfunc 512 513funct Test_undofile() 514 " Test undofile() without setting 'undodir'. 515 if has('persistent_undo') 516 call assert_equal(fnamemodify('.Xundofoo.un~', ':p'), undofile('Xundofoo')) 517 else 518 call assert_equal('', undofile('Xundofoo')) 519 endif 520 call assert_equal('', undofile('')) 521 522 " Test undofile() with 'undodir' set to to an existing directory. 523 call mkdir('Xundodir') 524 set undodir=Xundodir 525 let cwd = getcwd() 526 if has('win32') 527 " Replace windows drive such as C:... into C%... 528 let cwd = substitute(cwd, '^\([a-zA-Z]\):', '\1%', 'g') 529 endif 530 let cwd = substitute(cwd . '/Xundofoo', '/', '%', 'g') 531 if has('persistent_undo') 532 call assert_equal('Xundodir/' . cwd, undofile('Xundofoo')) 533 else 534 call assert_equal('', undofile('Xundofoo')) 535 endif 536 call assert_equal('', undofile('')) 537 call delete('Xundodir', 'd') 538 539 " Test undofile() with 'undodir' set to a non-existing directory. 540 call assert_equal('', 'Xundofoo'->undofile()) 541 542 if !has('win32') && isdirectory('/tmp') 543 set undodir=/tmp 544 if has('osx') 545 call assert_equal('/tmp/%private%tmp%file', undofile('///tmp/file')) 546 else 547 call assert_equal('/tmp/%tmp%file', undofile('///tmp/file')) 548 endif 549 endif 550 551 set undodir& 552endfunc 553 554" Tests for the undo file 555" Explicitly break changes up in undo-able pieces by setting 'undolevels'. 556func Test_undofile_2() 557 set undolevels=100 undofile 558 edit Xtestfile 559 call append(0, 'this is one line') 560 call cursor(1, 1) 561 562 " first a simple one-line change. 563 set undolevels=100 564 s/one/ONE/ 565 set undolevels=100 566 write 567 bwipe! 568 edit Xtestfile 569 undo 570 call assert_equal('this is one line', getline(1)) 571 572 " change in original file fails check 573 set noundofile 574 edit! Xtestfile 575 s/line/Line/ 576 write 577 set undofile 578 bwipe! 579 edit Xtestfile 580 undo 581 call assert_equal('this is ONE Line', getline(1)) 582 583 " add 10 lines, delete 6 lines, undo 3 584 set undofile 585 call setbufline(0, 1, ['one', 'two', 'three', 'four', 'five', 'six', 586 \ 'seven', 'eight', 'nine', 'ten']) 587 set undolevels=100 588 normal 3Gdd 589 set undolevels=100 590 normal dd 591 set undolevels=100 592 normal dd 593 set undolevels=100 594 normal dd 595 set undolevels=100 596 normal dd 597 set undolevels=100 598 normal dd 599 set undolevels=100 600 write 601 bwipe! 602 edit Xtestfile 603 normal uuu 604 call assert_equal(['one', 'two', 'six', 'seven', 'eight', 'nine', 'ten'], 605 \ getline(1, '$')) 606 607 " Test that reading the undofiles when setting undofile works 608 set noundofile undolevels=0 609 exe "normal i\n" 610 undo 611 edit! Xtestfile 612 set undofile undolevels=100 613 normal uuuuuu 614 call assert_equal(['one', 'two', 'three', 'four', 'five', 'six', 'seven', 615 \ 'eight', 'nine', 'ten'], getline(1, '$')) 616 617 bwipe! 618 call delete('Xtestfile') 619 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~' 620 call delete(ufile) 621 set undofile& undolevels& 622endfunc 623 624" Test 'undofile' using a file encrypted with 'zip' crypt method 625func Test_undofile_cryptmethod_zip() 626 edit Xtestfile 627 set undofile cryptmethod=zip 628 call append(0, ['monday', 'tuesday', 'wednesday', 'thursday', 'friday']) 629 call cursor(5, 1) 630 631 set undolevels=100 632 normal kkkdd 633 set undolevels=100 634 normal dd 635 set undolevels=100 636 normal dd 637 set undolevels=100 638 " encrypt the file using key 'foobar' 639 call feedkeys("foobar\nfoobar\n") 640 X 641 write! 642 bwipe! 643 644 call feedkeys("foobar\n") 645 edit Xtestfile 646 set key= 647 normal uu 648 call assert_equal(['monday', 'wednesday', 'thursday', 'friday', ''], 649 \ getline(1, '$')) 650 651 bwipe! 652 call delete('Xtestfile') 653 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~' 654 call delete(ufile) 655 set undofile& undolevels& cryptmethod& 656endfunc 657 658" Test 'undofile' using a file encrypted with 'blowfish' crypt method 659func Test_undofile_cryptmethod_blowfish() 660 edit Xtestfile 661 set undofile cryptmethod=blowfish 662 call append(0, ['jan', 'feb', 'mar', 'apr', 'jun']) 663 call cursor(5, 1) 664 665 set undolevels=100 666 exe 'normal kk0ifoo ' 667 set undolevels=100 668 normal dd 669 set undolevels=100 670 exe 'normal ibar ' 671 set undolevels=100 672 " encrypt the file using key 'foobar' 673 call feedkeys("foobar\nfoobar\n") 674 X 675 write! 676 bwipe! 677 678 call feedkeys("foobar\n") 679 edit Xtestfile 680 set key= 681 call search('bar') 682 call assert_equal('bar apr', getline('.')) 683 undo 684 call assert_equal('apr', getline('.')) 685 undo 686 call assert_equal('foo mar', getline('.')) 687 undo 688 call assert_equal('mar', getline('.')) 689 690 bwipe! 691 call delete('Xtestfile') 692 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~' 693 call delete(ufile) 694 set undofile& undolevels& cryptmethod& 695endfunc 696 697" Test 'undofile' using a file encrypted with 'blowfish2' crypt method 698func Test_undofile_cryptmethod_blowfish2() 699 edit Xtestfile 700 set undofile cryptmethod=blowfish2 701 call append(0, ['jan', 'feb', 'mar', 'apr', 'jun']) 702 call cursor(5, 1) 703 704 set undolevels=100 705 exe 'normal kk0ifoo ' 706 set undolevels=100 707 normal dd 708 set undolevels=100 709 exe 'normal ibar ' 710 set undolevels=100 711 " encrypt the file using key 'foo2bar' 712 call feedkeys("foo2bar\nfoo2bar\n") 713 X 714 write! 715 bwipe! 716 717 call feedkeys("foo2bar\n") 718 edit Xtestfile 719 set key= 720 call search('bar') 721 call assert_equal('bar apr', getline('.')) 722 normal u 723 call assert_equal('apr', getline('.')) 724 normal u 725 call assert_equal('foo mar', getline('.')) 726 normal u 727 call assert_equal('mar', getline('.')) 728 729 bwipe! 730 call delete('Xtestfile') 731 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~' 732 call delete(ufile) 733 set undofile& undolevels& cryptmethod& 734endfunc 735 736" Test for redoing with incrementing numbered registers 737func Test_redo_repeat_numbered_register() 738 new 739 for [i, v] in [[1, 'one'], [2, 'two'], [3, 'three'], 740 \ [4, 'four'], [5, 'five'], [6, 'six'], 741 \ [7, 'seven'], [8, 'eight'], [9, 'nine']] 742 exe 'let @' .. i .. '="' .. v .. '\n"' 743 endfor 744 call feedkeys('"1p.........', 'xt') 745 call assert_equal(['', 'one', 'two', 'three', 'four', 'five', 'six', 746 \ 'seven', 'eight', 'nine', 'nine'], getline(1, '$')) 747 bwipe! 748endfunc 749 750" Test for redo in insert mode using CTRL-O with multibyte characters 751func Test_redo_multibyte_in_insert_mode() 752 new 753 call feedkeys("a\<C-K>ft", 'xt') 754 call feedkeys("uiHe\<C-O>.llo", 'xt') 755 call assert_equal("He\ufb05llo", getline(1)) 756 bwipe! 757endfunc 758 759" vim: shiftwidth=2 sts=2 expandtab 760