1 /* vi:set ts=8 sts=4 sw=4 noet: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 /* 11 * undo.c: multi level undo facility 12 * 13 * The saved lines are stored in a list of lists (one for each buffer): 14 * 15 * b_u_oldhead------------------------------------------------+ 16 * | 17 * V 18 * +--------------+ +--------------+ +--------------+ 19 * b_u_newhead--->| u_header | | u_header | | u_header | 20 * | uh_next------>| uh_next------>| uh_next---->NULL 21 * NULL<--------uh_prev |<---------uh_prev |<---------uh_prev | 22 * | uh_entry | | uh_entry | | uh_entry | 23 * +--------|-----+ +--------|-----+ +--------|-----+ 24 * | | | 25 * V V V 26 * +--------------+ +--------------+ +--------------+ 27 * | u_entry | | u_entry | | u_entry | 28 * | ue_next | | ue_next | | ue_next | 29 * +--------|-----+ +--------|-----+ +--------|-----+ 30 * | | | 31 * V V V 32 * +--------------+ NULL NULL 33 * | u_entry | 34 * | ue_next | 35 * +--------|-----+ 36 * | 37 * V 38 * etc. 39 * 40 * Each u_entry list contains the information for one undo or redo. 41 * curbuf->b_u_curhead points to the header of the last undo (the next redo), 42 * or is NULL if nothing has been undone (end of the branch). 43 * 44 * For keeping alternate undo/redo branches the uh_alt field is used. Thus at 45 * each point in the list a branch may appear for an alternate to redo. The 46 * uh_seq field is numbered sequentially to be able to find a newer or older 47 * branch. 48 * 49 * +---------------+ +---------------+ 50 * b_u_oldhead --->| u_header | | u_header | 51 * | uh_alt_next ---->| uh_alt_next ----> NULL 52 * NULL <----- uh_alt_prev |<------ uh_alt_prev | 53 * | uh_prev | | uh_prev | 54 * +-----|---------+ +-----|---------+ 55 * | | 56 * V V 57 * +---------------+ +---------------+ 58 * | u_header | | u_header | 59 * | uh_alt_next | | uh_alt_next | 60 * b_u_newhead --->| uh_alt_prev | | uh_alt_prev | 61 * | uh_prev | | uh_prev | 62 * +-----|---------+ +-----|---------+ 63 * | | 64 * V V 65 * NULL +---------------+ +---------------+ 66 * | u_header | | u_header | 67 * | uh_alt_next ---->| uh_alt_next | 68 * | uh_alt_prev |<------ uh_alt_prev | 69 * | uh_prev | | uh_prev | 70 * +-----|---------+ +-----|---------+ 71 * | | 72 * etc. etc. 73 * 74 * 75 * All data is allocated and will all be freed when the buffer is unloaded. 76 */ 77 78 // Uncomment the next line for including the u_check() function. This warns 79 // for errors in the debug information. 80 // #define U_DEBUG 1 81 #define UH_MAGIC 0x18dade // value for uh_magic when in use 82 #define UE_MAGIC 0xabc123 // value for ue_magic when in use 83 84 // Size of buffer used for encryption. 85 #define CRYPT_BUF_SIZE 8192 86 87 #include "vim.h" 88 89 // Structure passed around between functions. 90 // Avoids passing cryptstate_T when encryption not available. 91 typedef struct { 92 buf_T *bi_buf; 93 FILE *bi_fp; 94 #ifdef FEAT_CRYPT 95 cryptstate_T *bi_state; 96 char_u *bi_buffer; // CRYPT_BUF_SIZE, NULL when not buffering 97 size_t bi_used; // bytes written to/read from bi_buffer 98 size_t bi_avail; // bytes available in bi_buffer 99 #endif 100 } bufinfo_T; 101 102 103 static void u_unch_branch(u_header_T *uhp); 104 static u_entry_T *u_get_headentry(void); 105 static void u_getbot(void); 106 static void u_doit(int count); 107 static void u_undoredo(int undo); 108 static void u_undo_end(int did_undo, int absolute); 109 static void u_freeheader(buf_T *buf, u_header_T *uhp, u_header_T **uhpp); 110 static void u_freebranch(buf_T *buf, u_header_T *uhp, u_header_T **uhpp); 111 static void u_freeentries(buf_T *buf, u_header_T *uhp, u_header_T **uhpp); 112 static void u_freeentry(u_entry_T *, long); 113 #ifdef FEAT_PERSISTENT_UNDO 114 # ifdef FEAT_CRYPT 115 static int undo_flush(bufinfo_T *bi); 116 # endif 117 static int undo_read(bufinfo_T *bi, char_u *buffer, size_t size); 118 static int serialize_uep(bufinfo_T *bi, u_entry_T *uep); 119 static u_entry_T *unserialize_uep(bufinfo_T *bi, int *error, char_u *file_name); 120 static void serialize_pos(bufinfo_T *bi, pos_T pos); 121 static void unserialize_pos(bufinfo_T *bi, pos_T *pos); 122 static void serialize_visualinfo(bufinfo_T *bi, visualinfo_T *info); 123 static void unserialize_visualinfo(bufinfo_T *bi, visualinfo_T *info); 124 #endif 125 static void u_saveline(linenr_T lnum); 126 127 #define U_ALLOC_LINE(size) lalloc(size, FALSE) 128 129 // used in undo_end() to report number of added and deleted lines 130 static long u_newcount, u_oldcount; 131 132 /* 133 * When 'u' flag included in 'cpoptions', we behave like vi. Need to remember 134 * the action that "u" should do. 135 */ 136 static int undo_undoes = FALSE; 137 138 static int lastmark = 0; 139 140 #if defined(U_DEBUG) || defined(PROTO) 141 /* 142 * Check the undo structures for being valid. Print a warning when something 143 * looks wrong. 144 */ 145 static int seen_b_u_curhead; 146 static int seen_b_u_newhead; 147 static int header_count; 148 149 static void 150 u_check_tree(u_header_T *uhp, 151 u_header_T *exp_uh_next, 152 u_header_T *exp_uh_alt_prev) 153 { 154 u_entry_T *uep; 155 156 if (uhp == NULL) 157 return; 158 ++header_count; 159 if (uhp == curbuf->b_u_curhead && ++seen_b_u_curhead > 1) 160 { 161 emsg("b_u_curhead found twice (looping?)"); 162 return; 163 } 164 if (uhp == curbuf->b_u_newhead && ++seen_b_u_newhead > 1) 165 { 166 emsg("b_u_newhead found twice (looping?)"); 167 return; 168 } 169 170 if (uhp->uh_magic != UH_MAGIC) 171 emsg("uh_magic wrong (may be using freed memory)"); 172 else 173 { 174 // Check pointers back are correct. 175 if (uhp->uh_next.ptr != exp_uh_next) 176 { 177 emsg("uh_next wrong"); 178 smsg("expected: 0x%x, actual: 0x%x", 179 exp_uh_next, uhp->uh_next.ptr); 180 } 181 if (uhp->uh_alt_prev.ptr != exp_uh_alt_prev) 182 { 183 emsg("uh_alt_prev wrong"); 184 smsg("expected: 0x%x, actual: 0x%x", 185 exp_uh_alt_prev, uhp->uh_alt_prev.ptr); 186 } 187 188 // Check the undo tree at this header. 189 for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next) 190 { 191 if (uep->ue_magic != UE_MAGIC) 192 { 193 emsg("ue_magic wrong (may be using freed memory)"); 194 break; 195 } 196 } 197 198 // Check the next alt tree. 199 u_check_tree(uhp->uh_alt_next.ptr, uhp->uh_next.ptr, uhp); 200 201 // Check the next header in this branch. 202 u_check_tree(uhp->uh_prev.ptr, uhp, NULL); 203 } 204 } 205 206 static void 207 u_check(int newhead_may_be_NULL) 208 { 209 seen_b_u_newhead = 0; 210 seen_b_u_curhead = 0; 211 header_count = 0; 212 213 u_check_tree(curbuf->b_u_oldhead, NULL, NULL); 214 215 if (seen_b_u_newhead == 0 && curbuf->b_u_oldhead != NULL 216 && !(newhead_may_be_NULL && curbuf->b_u_newhead == NULL)) 217 semsg("b_u_newhead invalid: 0x%x", curbuf->b_u_newhead); 218 if (curbuf->b_u_curhead != NULL && seen_b_u_curhead == 0) 219 semsg("b_u_curhead invalid: 0x%x", curbuf->b_u_curhead); 220 if (header_count != curbuf->b_u_numhead) 221 { 222 emsg("b_u_numhead invalid"); 223 smsg("expected: %ld, actual: %ld", 224 (long)header_count, (long)curbuf->b_u_numhead); 225 } 226 } 227 #endif 228 229 /* 230 * Save the current line for both the "u" and "U" command. 231 * Careful: may trigger autocommands that reload the buffer. 232 * Returns OK or FAIL. 233 */ 234 int 235 u_save_cursor(void) 236 { 237 return (u_save((linenr_T)(curwin->w_cursor.lnum - 1), 238 (linenr_T)(curwin->w_cursor.lnum + 1))); 239 } 240 241 /* 242 * Save the lines between "top" and "bot" for both the "u" and "U" command. 243 * "top" may be 0 and bot may be curbuf->b_ml.ml_line_count + 1. 244 * Careful: may trigger autocommands that reload the buffer. 245 * Returns FAIL when lines could not be saved, OK otherwise. 246 */ 247 int 248 u_save(linenr_T top, linenr_T bot) 249 { 250 if (undo_off) 251 return OK; 252 253 if (top >= bot || bot > curbuf->b_ml.ml_line_count + 1) 254 return FAIL; // rely on caller to give an error message 255 256 if (top + 2 == bot) 257 u_saveline((linenr_T)(top + 1)); 258 259 return (u_savecommon(top, bot, (linenr_T)0, FALSE)); 260 } 261 262 /* 263 * Save the line "lnum" (used by ":s" and "~" command). 264 * The line is replaced, so the new bottom line is lnum + 1. 265 * Careful: may trigger autocommands that reload the buffer. 266 * Returns FAIL when lines could not be saved, OK otherwise. 267 */ 268 int 269 u_savesub(linenr_T lnum) 270 { 271 if (undo_off) 272 return OK; 273 274 return (u_savecommon(lnum - 1, lnum + 1, lnum + 1, FALSE)); 275 } 276 277 /* 278 * A new line is inserted before line "lnum" (used by :s command). 279 * The line is inserted, so the new bottom line is lnum + 1. 280 * Careful: may trigger autocommands that reload the buffer. 281 * Returns FAIL when lines could not be saved, OK otherwise. 282 */ 283 int 284 u_inssub(linenr_T lnum) 285 { 286 if (undo_off) 287 return OK; 288 289 return (u_savecommon(lnum - 1, lnum, lnum + 1, FALSE)); 290 } 291 292 /* 293 * Save the lines "lnum" - "lnum" + nlines (used by delete command). 294 * The lines are deleted, so the new bottom line is lnum, unless the buffer 295 * becomes empty. 296 * Careful: may trigger autocommands that reload the buffer. 297 * Returns FAIL when lines could not be saved, OK otherwise. 298 */ 299 int 300 u_savedel(linenr_T lnum, long nlines) 301 { 302 if (undo_off) 303 return OK; 304 305 return (u_savecommon(lnum - 1, lnum + nlines, 306 nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, FALSE)); 307 } 308 309 /* 310 * Return TRUE when undo is allowed. Otherwise give an error message and 311 * return FALSE. 312 */ 313 int 314 undo_allowed(void) 315 { 316 // Don't allow changes when 'modifiable' is off. 317 if (!curbuf->b_p_ma) 318 { 319 emsg(_(e_modifiable)); 320 return FALSE; 321 } 322 323 #ifdef HAVE_SANDBOX 324 // In the sandbox it's not allowed to change the text. 325 if (sandbox != 0) 326 { 327 emsg(_(e_sandbox)); 328 return FALSE; 329 } 330 #endif 331 332 // Don't allow changes in the buffer while editing the cmdline. The 333 // caller of getcmdline() may get confused. 334 if (textwinlock != 0 || textlock != 0) 335 { 336 emsg(_(e_textlock)); 337 return FALSE; 338 } 339 340 return TRUE; 341 } 342 343 /* 344 * Get the undolevel value for the current buffer. 345 */ 346 static long 347 get_undolevel(void) 348 { 349 if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL) 350 return p_ul; 351 return curbuf->b_p_ul; 352 } 353 354 /* 355 * u_save_line(): save an allocated copy of line "lnum" into "ul". 356 * Returns FAIL when out of memory. 357 */ 358 static int 359 u_save_line(undoline_T *ul, linenr_T lnum) 360 { 361 char_u *line = ml_get(lnum); 362 363 if (curbuf->b_ml.ml_line_len == 0) 364 { 365 ul->ul_len = 1; 366 ul->ul_line = vim_strsave((char_u *)""); 367 } 368 else 369 { 370 // This uses the length in the memline, thus text properties are 371 // included. 372 ul->ul_len = curbuf->b_ml.ml_line_len; 373 ul->ul_line = vim_memsave(line, ul->ul_len); 374 } 375 return ul->ul_line == NULL ? FAIL : OK; 376 } 377 378 /* 379 * return TRUE if line "lnum" has text property "flags". 380 */ 381 static int 382 has_prop_w_flags(linenr_T lnum, int flags) 383 { 384 char_u *props; 385 int i; 386 int proplen = get_text_props(curbuf, lnum, &props, FALSE); 387 388 for (i = 0; i < proplen; ++i) 389 { 390 textprop_T prop; 391 392 mch_memmove(&prop, props + i * sizeof prop, sizeof prop); 393 if (prop.tp_flags & flags) 394 return TRUE; 395 } 396 return FALSE; 397 } 398 399 /* 400 * Common code for various ways to save text before a change. 401 * "top" is the line above the first changed line. 402 * "bot" is the line below the last changed line. 403 * "newbot" is the new bottom line. Use zero when not known. 404 * "reload" is TRUE when saving for a buffer reload. 405 * Careful: may trigger autocommands that reload the buffer. 406 * Returns FAIL when lines could not be saved, OK otherwise. 407 */ 408 int 409 u_savecommon( 410 linenr_T top, 411 linenr_T bot, 412 linenr_T newbot, 413 int reload) 414 { 415 linenr_T lnum; 416 long i; 417 u_header_T *uhp; 418 u_header_T *old_curhead; 419 u_entry_T *uep; 420 u_entry_T *prev_uep; 421 long size; 422 423 if (!reload) 424 { 425 // When making changes is not allowed return FAIL. It's a crude way 426 // to make all change commands fail. 427 if (!undo_allowed()) 428 return FAIL; 429 430 #ifdef FEAT_NETBEANS_INTG 431 /* 432 * Netbeans defines areas that cannot be modified. Bail out here when 433 * trying to change text in a guarded area. 434 */ 435 if (netbeans_active()) 436 { 437 if (netbeans_is_guarded(top, bot)) 438 { 439 emsg(_(e_guarded)); 440 return FAIL; 441 } 442 if (curbuf->b_p_ro) 443 { 444 emsg(_(e_nbreadonly)); 445 return FAIL; 446 } 447 } 448 #endif 449 #ifdef FEAT_TERMINAL 450 // A change in a terminal buffer removes the highlighting. 451 term_change_in_curbuf(); 452 #endif 453 454 /* 455 * Saving text for undo means we are going to make a change. Give a 456 * warning for a read-only file before making the change, so that the 457 * FileChangedRO event can replace the buffer with a read-write version 458 * (e.g., obtained from a source control system). 459 */ 460 change_warning(0); 461 if (bot > curbuf->b_ml.ml_line_count + 1) 462 { 463 // This happens when the FileChangedRO autocommand changes the 464 // file in a way it becomes shorter. 465 emsg(_("E881: Line count changed unexpectedly")); 466 return FAIL; 467 } 468 } 469 470 #ifdef U_DEBUG 471 u_check(FALSE); 472 #endif 473 474 #ifdef FEAT_PROP_POPUP 475 // Include the line above if a text property continues from it. 476 // Include the line below if a text property continues to it. 477 if (bot - top > 1) 478 { 479 if (top > 0 && has_prop_w_flags(top + 1, TP_FLAG_CONT_PREV)) 480 --top; 481 if (bot <= curbuf->b_ml.ml_line_count 482 && has_prop_w_flags(bot - 1, TP_FLAG_CONT_NEXT)) 483 { 484 ++bot; 485 if (newbot != 0) 486 ++newbot; 487 } 488 } 489 #endif 490 491 size = bot - top - 1; 492 493 /* 494 * If curbuf->b_u_synced == TRUE make a new header. 495 */ 496 if (curbuf->b_u_synced) 497 { 498 #ifdef FEAT_JUMPLIST 499 // Need to create new entry in b_changelist. 500 curbuf->b_new_change = TRUE; 501 #endif 502 503 if (get_undolevel() >= 0) 504 { 505 /* 506 * Make a new header entry. Do this first so that we don't mess 507 * up the undo info when out of memory. 508 */ 509 uhp = U_ALLOC_LINE(sizeof(u_header_T)); 510 if (uhp == NULL) 511 goto nomem; 512 #ifdef U_DEBUG 513 uhp->uh_magic = UH_MAGIC; 514 #endif 515 } 516 else 517 uhp = NULL; 518 519 /* 520 * If we undid more than we redid, move the entry lists before and 521 * including curbuf->b_u_curhead to an alternate branch. 522 */ 523 old_curhead = curbuf->b_u_curhead; 524 if (old_curhead != NULL) 525 { 526 curbuf->b_u_newhead = old_curhead->uh_next.ptr; 527 curbuf->b_u_curhead = NULL; 528 } 529 530 /* 531 * free headers to keep the size right 532 */ 533 while (curbuf->b_u_numhead > get_undolevel() 534 && curbuf->b_u_oldhead != NULL) 535 { 536 u_header_T *uhfree = curbuf->b_u_oldhead; 537 538 if (uhfree == old_curhead) 539 // Can't reconnect the branch, delete all of it. 540 u_freebranch(curbuf, uhfree, &old_curhead); 541 else if (uhfree->uh_alt_next.ptr == NULL) 542 // There is no branch, only free one header. 543 u_freeheader(curbuf, uhfree, &old_curhead); 544 else 545 { 546 // Free the oldest alternate branch as a whole. 547 while (uhfree->uh_alt_next.ptr != NULL) 548 uhfree = uhfree->uh_alt_next.ptr; 549 u_freebranch(curbuf, uhfree, &old_curhead); 550 } 551 #ifdef U_DEBUG 552 u_check(TRUE); 553 #endif 554 } 555 556 if (uhp == NULL) // no undo at all 557 { 558 if (old_curhead != NULL) 559 u_freebranch(curbuf, old_curhead, NULL); 560 curbuf->b_u_synced = FALSE; 561 return OK; 562 } 563 564 uhp->uh_prev.ptr = NULL; 565 uhp->uh_next.ptr = curbuf->b_u_newhead; 566 uhp->uh_alt_next.ptr = old_curhead; 567 if (old_curhead != NULL) 568 { 569 uhp->uh_alt_prev.ptr = old_curhead->uh_alt_prev.ptr; 570 if (uhp->uh_alt_prev.ptr != NULL) 571 uhp->uh_alt_prev.ptr->uh_alt_next.ptr = uhp; 572 old_curhead->uh_alt_prev.ptr = uhp; 573 if (curbuf->b_u_oldhead == old_curhead) 574 curbuf->b_u_oldhead = uhp; 575 } 576 else 577 uhp->uh_alt_prev.ptr = NULL; 578 if (curbuf->b_u_newhead != NULL) 579 curbuf->b_u_newhead->uh_prev.ptr = uhp; 580 581 uhp->uh_seq = ++curbuf->b_u_seq_last; 582 curbuf->b_u_seq_cur = uhp->uh_seq; 583 uhp->uh_time = vim_time(); 584 uhp->uh_save_nr = 0; 585 curbuf->b_u_time_cur = uhp->uh_time + 1; 586 587 uhp->uh_walk = 0; 588 uhp->uh_entry = NULL; 589 uhp->uh_getbot_entry = NULL; 590 uhp->uh_cursor = curwin->w_cursor; // save cursor pos. for undo 591 if (virtual_active() && curwin->w_cursor.coladd > 0) 592 uhp->uh_cursor_vcol = getviscol(); 593 else 594 uhp->uh_cursor_vcol = -1; 595 596 // save changed and buffer empty flag for undo 597 uhp->uh_flags = (curbuf->b_changed ? UH_CHANGED : 0) + 598 ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0); 599 600 // save named marks and Visual marks for undo 601 mch_memmove(uhp->uh_namedm, curbuf->b_namedm, sizeof(pos_T) * NMARKS); 602 uhp->uh_visual = curbuf->b_visual; 603 604 curbuf->b_u_newhead = uhp; 605 if (curbuf->b_u_oldhead == NULL) 606 curbuf->b_u_oldhead = uhp; 607 ++curbuf->b_u_numhead; 608 } 609 else 610 { 611 if (get_undolevel() < 0) // no undo at all 612 return OK; 613 614 /* 615 * When saving a single line, and it has been saved just before, it 616 * doesn't make sense saving it again. Saves a lot of memory when 617 * making lots of changes inside the same line. 618 * This is only possible if the previous change didn't increase or 619 * decrease the number of lines. 620 * Check the ten last changes. More doesn't make sense and takes too 621 * long. 622 */ 623 if (size == 1) 624 { 625 uep = u_get_headentry(); 626 prev_uep = NULL; 627 for (i = 0; i < 10; ++i) 628 { 629 if (uep == NULL) 630 break; 631 632 // If lines have been inserted/deleted we give up. 633 // Also when the line was included in a multi-line save. 634 if ((curbuf->b_u_newhead->uh_getbot_entry != uep 635 ? (uep->ue_top + uep->ue_size + 1 636 != (uep->ue_bot == 0 637 ? curbuf->b_ml.ml_line_count + 1 638 : uep->ue_bot)) 639 : uep->ue_lcount != curbuf->b_ml.ml_line_count) 640 || (uep->ue_size > 1 641 && top >= uep->ue_top 642 && top + 2 <= uep->ue_top + uep->ue_size + 1)) 643 break; 644 645 // If it's the same line we can skip saving it again. 646 if (uep->ue_size == 1 && uep->ue_top == top) 647 { 648 if (i > 0) 649 { 650 // It's not the last entry: get ue_bot for the last 651 // entry now. Following deleted/inserted lines go to 652 // the re-used entry. 653 u_getbot(); 654 curbuf->b_u_synced = FALSE; 655 656 // Move the found entry to become the last entry. The 657 // order of undo/redo doesn't matter for the entries 658 // we move it over, since they don't change the line 659 // count and don't include this line. It does matter 660 // for the found entry if the line count is changed by 661 // the executed command. 662 prev_uep->ue_next = uep->ue_next; 663 uep->ue_next = curbuf->b_u_newhead->uh_entry; 664 curbuf->b_u_newhead->uh_entry = uep; 665 } 666 667 // The executed command may change the line count. 668 if (newbot != 0) 669 uep->ue_bot = newbot; 670 else if (bot > curbuf->b_ml.ml_line_count) 671 uep->ue_bot = 0; 672 else 673 { 674 uep->ue_lcount = curbuf->b_ml.ml_line_count; 675 curbuf->b_u_newhead->uh_getbot_entry = uep; 676 } 677 return OK; 678 } 679 prev_uep = uep; 680 uep = uep->ue_next; 681 } 682 } 683 684 // find line number for ue_bot for previous u_save() 685 u_getbot(); 686 } 687 688 #if !defined(UNIX) && !defined(MSWIN) 689 /* 690 * With Amiga we can't handle big undo's, because 691 * then u_alloc_line would have to allocate a block larger than 32K 692 */ 693 if (size >= 8000) 694 goto nomem; 695 #endif 696 697 /* 698 * add lines in front of entry list 699 */ 700 uep = U_ALLOC_LINE(sizeof(u_entry_T)); 701 if (uep == NULL) 702 goto nomem; 703 CLEAR_POINTER(uep); 704 #ifdef U_DEBUG 705 uep->ue_magic = UE_MAGIC; 706 #endif 707 708 uep->ue_size = size; 709 uep->ue_top = top; 710 if (newbot != 0) 711 uep->ue_bot = newbot; 712 /* 713 * Use 0 for ue_bot if bot is below last line. 714 * Otherwise we have to compute ue_bot later. 715 */ 716 else if (bot > curbuf->b_ml.ml_line_count) 717 uep->ue_bot = 0; 718 else 719 { 720 uep->ue_lcount = curbuf->b_ml.ml_line_count; 721 curbuf->b_u_newhead->uh_getbot_entry = uep; 722 } 723 724 if (size > 0) 725 { 726 if ((uep->ue_array = U_ALLOC_LINE(sizeof(undoline_T) * size)) == NULL) 727 { 728 u_freeentry(uep, 0L); 729 goto nomem; 730 } 731 for (i = 0, lnum = top + 1; i < size; ++i) 732 { 733 fast_breakcheck(); 734 if (got_int) 735 { 736 u_freeentry(uep, i); 737 return FAIL; 738 } 739 if (u_save_line(&uep->ue_array[i], lnum++) == FAIL) 740 { 741 u_freeentry(uep, i); 742 goto nomem; 743 } 744 } 745 } 746 else 747 uep->ue_array = NULL; 748 uep->ue_next = curbuf->b_u_newhead->uh_entry; 749 curbuf->b_u_newhead->uh_entry = uep; 750 curbuf->b_u_synced = FALSE; 751 undo_undoes = FALSE; 752 753 #ifdef U_DEBUG 754 u_check(FALSE); 755 #endif 756 return OK; 757 758 nomem: 759 msg_silent = 0; // must display the prompt 760 if (ask_yesno((char_u *)_("No undo possible; continue anyway"), TRUE) 761 == 'y') 762 { 763 undo_off = TRUE; // will be reset when character typed 764 return OK; 765 } 766 do_outofmem_msg((long_u)0); 767 return FAIL; 768 } 769 770 #if defined(FEAT_PERSISTENT_UNDO) || defined(PROTO) 771 772 # define UF_START_MAGIC "Vim\237UnDo\345" // magic at start of undofile 773 # define UF_START_MAGIC_LEN 9 774 # define UF_HEADER_MAGIC 0x5fd0 // magic at start of header 775 # define UF_HEADER_END_MAGIC 0xe7aa // magic after last header 776 # define UF_ENTRY_MAGIC 0xf518 // magic at start of entry 777 # define UF_ENTRY_END_MAGIC 0x3581 // magic after last entry 778 # define UF_VERSION 2 // 2-byte undofile version number 779 # define UF_VERSION_CRYPT 0x8002 // idem, encrypted 780 781 // extra fields for header 782 # define UF_LAST_SAVE_NR 1 783 784 // extra fields for uhp 785 # define UHP_SAVE_NR 1 786 787 static char_u e_not_open[] = N_("E828: Cannot open undo file for writing: %s"); 788 789 /* 790 * Compute the hash for the current buffer text into hash[UNDO_HASH_SIZE]. 791 */ 792 void 793 u_compute_hash(char_u *hash) 794 { 795 context_sha256_T ctx; 796 linenr_T lnum; 797 char_u *p; 798 799 sha256_start(&ctx); 800 for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) 801 { 802 p = ml_get(lnum); 803 sha256_update(&ctx, p, (UINT32_T)(STRLEN(p) + 1)); 804 } 805 sha256_finish(&ctx, hash); 806 } 807 808 /* 809 * Return an allocated string of the full path of the target undofile. 810 * When "reading" is TRUE find the file to read, go over all directories in 811 * 'undodir'. 812 * When "reading" is FALSE use the first name where the directory exists. 813 * Returns NULL when there is no place to write or no file to read. 814 */ 815 static char_u * 816 u_get_undo_file_name(char_u *buf_ffname, int reading) 817 { 818 char_u *dirp; 819 char_u dir_name[IOSIZE + 1]; 820 char_u *munged_name = NULL; 821 char_u *undo_file_name = NULL; 822 int dir_len; 823 char_u *p; 824 stat_T st; 825 char_u *ffname = buf_ffname; 826 #ifdef HAVE_READLINK 827 char_u fname_buf[MAXPATHL]; 828 #endif 829 830 if (ffname == NULL) 831 return NULL; 832 833 #ifdef HAVE_READLINK 834 // Expand symlink in the file name, so that we put the undo file with the 835 // actual file instead of with the symlink. 836 if (resolve_symlink(ffname, fname_buf) == OK) 837 ffname = fname_buf; 838 #endif 839 840 // Loop over 'undodir'. When reading find the first file that exists. 841 // When not reading use the first directory that exists or ".". 842 dirp = p_udir; 843 while (*dirp != NUL) 844 { 845 dir_len = copy_option_part(&dirp, dir_name, IOSIZE, ","); 846 if (dir_len == 1 && dir_name[0] == '.') 847 { 848 // Use same directory as the ffname, 849 // "dir/name" -> "dir/.name.un~" 850 undo_file_name = vim_strnsave(ffname, (int)(STRLEN(ffname) + 5)); 851 if (undo_file_name == NULL) 852 break; 853 p = gettail(undo_file_name); 854 #ifdef VMS 855 // VMS can not handle more than one dot in the filenames 856 // use "dir/name" -> "dir/_un_name" - add _un_ 857 // at the beginning to keep the extension 858 mch_memmove(p + 4, p, STRLEN(p) + 1); 859 mch_memmove(p, "_un_", 4); 860 861 #else 862 // Use same directory as the ffname, 863 // "dir/name" -> "dir/.name.un~" 864 mch_memmove(p + 1, p, STRLEN(p) + 1); 865 *p = '.'; 866 STRCAT(p, ".un~"); 867 #endif 868 } 869 else 870 { 871 dir_name[dir_len] = NUL; 872 if (mch_isdir(dir_name)) 873 { 874 if (munged_name == NULL) 875 { 876 munged_name = vim_strsave(ffname); 877 if (munged_name == NULL) 878 return NULL; 879 for (p = munged_name; *p != NUL; MB_PTR_ADV(p)) 880 if (vim_ispathsep(*p)) 881 *p = '%'; 882 } 883 undo_file_name = concat_fnames(dir_name, munged_name, TRUE); 884 } 885 } 886 887 // When reading check if the file exists. 888 if (undo_file_name != NULL && (!reading 889 || mch_stat((char *)undo_file_name, &st) >= 0)) 890 break; 891 VIM_CLEAR(undo_file_name); 892 } 893 894 vim_free(munged_name); 895 return undo_file_name; 896 } 897 898 static void 899 corruption_error(char *mesg, char_u *file_name) 900 { 901 semsg(_("E825: Corrupted undo file (%s): %s"), mesg, file_name); 902 } 903 904 static void 905 u_free_uhp(u_header_T *uhp) 906 { 907 u_entry_T *nuep; 908 u_entry_T *uep; 909 910 uep = uhp->uh_entry; 911 while (uep != NULL) 912 { 913 nuep = uep->ue_next; 914 u_freeentry(uep, uep->ue_size); 915 uep = nuep; 916 } 917 vim_free(uhp); 918 } 919 920 /* 921 * Write a sequence of bytes to the undo file. 922 * Buffers and encrypts as needed. 923 * Returns OK or FAIL. 924 */ 925 static int 926 undo_write(bufinfo_T *bi, char_u *ptr, size_t len) 927 { 928 #ifdef FEAT_CRYPT 929 if (bi->bi_buffer != NULL) 930 { 931 size_t len_todo = len; 932 char_u *p = ptr; 933 934 while (bi->bi_used + len_todo >= CRYPT_BUF_SIZE) 935 { 936 size_t n = CRYPT_BUF_SIZE - bi->bi_used; 937 938 mch_memmove(bi->bi_buffer + bi->bi_used, p, n); 939 len_todo -= n; 940 p += n; 941 bi->bi_used = CRYPT_BUF_SIZE; 942 if (undo_flush(bi) == FAIL) 943 return FAIL; 944 } 945 if (len_todo > 0) 946 { 947 mch_memmove(bi->bi_buffer + bi->bi_used, p, len_todo); 948 bi->bi_used += len_todo; 949 } 950 return OK; 951 } 952 #endif 953 if (fwrite(ptr, len, (size_t)1, bi->bi_fp) != 1) 954 return FAIL; 955 return OK; 956 } 957 958 #ifdef FEAT_CRYPT 959 static int 960 undo_flush(bufinfo_T *bi) 961 { 962 if (bi->bi_buffer != NULL && bi->bi_state != NULL && bi->bi_used > 0) 963 { 964 crypt_encode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_used); 965 if (fwrite(bi->bi_buffer, bi->bi_used, (size_t)1, bi->bi_fp) != 1) 966 return FAIL; 967 bi->bi_used = 0; 968 } 969 return OK; 970 } 971 #endif 972 973 /* 974 * Write "ptr[len]" and crypt the bytes when needed. 975 * Returns OK or FAIL. 976 */ 977 static int 978 fwrite_crypt(bufinfo_T *bi, char_u *ptr, size_t len) 979 { 980 #ifdef FEAT_CRYPT 981 char_u *copy; 982 char_u small_buf[100]; 983 size_t i; 984 985 if (bi->bi_state != NULL && bi->bi_buffer == NULL) 986 { 987 // crypting every piece of text separately 988 if (len < 100) 989 copy = small_buf; // no malloc()/free() for short strings 990 else 991 { 992 copy = lalloc(len, FALSE); 993 if (copy == NULL) 994 return 0; 995 } 996 crypt_encode(bi->bi_state, ptr, len, copy); 997 i = fwrite(copy, len, (size_t)1, bi->bi_fp); 998 if (copy != small_buf) 999 vim_free(copy); 1000 return i == 1 ? OK : FAIL; 1001 } 1002 #endif 1003 return undo_write(bi, ptr, len); 1004 } 1005 1006 /* 1007 * Write a number, MSB first, in "len" bytes. 1008 * Must match with undo_read_?c() functions. 1009 * Returns OK or FAIL. 1010 */ 1011 static int 1012 undo_write_bytes(bufinfo_T *bi, long_u nr, int len) 1013 { 1014 char_u buf[8]; 1015 int i; 1016 int bufi = 0; 1017 1018 for (i = len - 1; i >= 0; --i) 1019 buf[bufi++] = (char_u)(nr >> (i * 8)); 1020 return undo_write(bi, buf, (size_t)len); 1021 } 1022 1023 /* 1024 * Write the pointer to an undo header. Instead of writing the pointer itself 1025 * we use the sequence number of the header. This is converted back to 1026 * pointers when reading. */ 1027 static void 1028 put_header_ptr(bufinfo_T *bi, u_header_T *uhp) 1029 { 1030 undo_write_bytes(bi, (long_u)(uhp != NULL ? uhp->uh_seq : 0), 4); 1031 } 1032 1033 static int 1034 undo_read_4c(bufinfo_T *bi) 1035 { 1036 #ifdef FEAT_CRYPT 1037 if (bi->bi_buffer != NULL) 1038 { 1039 char_u buf[4]; 1040 int n; 1041 1042 undo_read(bi, buf, (size_t)4); 1043 n = ((unsigned)buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3]; 1044 return n; 1045 } 1046 #endif 1047 return get4c(bi->bi_fp); 1048 } 1049 1050 static int 1051 undo_read_2c(bufinfo_T *bi) 1052 { 1053 #ifdef FEAT_CRYPT 1054 if (bi->bi_buffer != NULL) 1055 { 1056 char_u buf[2]; 1057 int n; 1058 1059 undo_read(bi, buf, (size_t)2); 1060 n = (buf[0] << 8) + buf[1]; 1061 return n; 1062 } 1063 #endif 1064 return get2c(bi->bi_fp); 1065 } 1066 1067 static int 1068 undo_read_byte(bufinfo_T *bi) 1069 { 1070 #ifdef FEAT_CRYPT 1071 if (bi->bi_buffer != NULL) 1072 { 1073 char_u buf[1]; 1074 1075 undo_read(bi, buf, (size_t)1); 1076 return buf[0]; 1077 } 1078 #endif 1079 return getc(bi->bi_fp); 1080 } 1081 1082 static time_t 1083 undo_read_time(bufinfo_T *bi) 1084 { 1085 #ifdef FEAT_CRYPT 1086 if (bi->bi_buffer != NULL) 1087 { 1088 char_u buf[8]; 1089 time_t n = 0; 1090 int i; 1091 1092 undo_read(bi, buf, (size_t)8); 1093 for (i = 0; i < 8; ++i) 1094 n = (n << 8) + buf[i]; 1095 return n; 1096 } 1097 #endif 1098 return get8ctime(bi->bi_fp); 1099 } 1100 1101 /* 1102 * Read "buffer[size]" from the undo file. 1103 * Return OK or FAIL. 1104 */ 1105 static int 1106 undo_read(bufinfo_T *bi, char_u *buffer, size_t size) 1107 { 1108 int retval = OK; 1109 1110 #ifdef FEAT_CRYPT 1111 if (bi->bi_buffer != NULL) 1112 { 1113 int size_todo = (int)size; 1114 char_u *p = buffer; 1115 1116 while (size_todo > 0) 1117 { 1118 size_t n; 1119 1120 if (bi->bi_used >= bi->bi_avail) 1121 { 1122 n = fread(bi->bi_buffer, 1, (size_t)CRYPT_BUF_SIZE, bi->bi_fp); 1123 if (n == 0) 1124 { 1125 retval = FAIL; 1126 break; 1127 } 1128 bi->bi_avail = n; 1129 bi->bi_used = 0; 1130 crypt_decode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_avail); 1131 } 1132 n = size_todo; 1133 if (n > bi->bi_avail - bi->bi_used) 1134 n = bi->bi_avail - bi->bi_used; 1135 mch_memmove(p, bi->bi_buffer + bi->bi_used, n); 1136 bi->bi_used += n; 1137 size_todo -= (int)n; 1138 p += n; 1139 } 1140 } 1141 else 1142 #endif 1143 if (fread(buffer, (size_t)size, 1, bi->bi_fp) != 1) 1144 retval = FAIL; 1145 1146 if (retval == FAIL) 1147 // Error may be checked for only later. Fill with zeros, 1148 // so that the reader won't use garbage. 1149 vim_memset(buffer, 0, size); 1150 return retval; 1151 } 1152 1153 /* 1154 * Read a string of length "len" from "bi->bi_fd". 1155 * "len" can be zero to allocate an empty line. 1156 * Decrypt the bytes if needed. 1157 * Append a NUL. 1158 * Returns a pointer to allocated memory or NULL for failure. 1159 */ 1160 static char_u * 1161 read_string_decrypt(bufinfo_T *bi, int len) 1162 { 1163 char_u *ptr = alloc(len + 1); 1164 1165 if (ptr != NULL) 1166 { 1167 if (len > 0 && undo_read(bi, ptr, len) == FAIL) 1168 { 1169 vim_free(ptr); 1170 return NULL; 1171 } 1172 // In case there are text properties there already is a NUL, but 1173 // checking for that is more expensive than just adding a dummy byte. 1174 ptr[len] = NUL; 1175 #ifdef FEAT_CRYPT 1176 if (bi->bi_state != NULL && bi->bi_buffer == NULL) 1177 crypt_decode_inplace(bi->bi_state, ptr, len); 1178 #endif 1179 } 1180 return ptr; 1181 } 1182 1183 /* 1184 * Writes the (not encrypted) header and initializes encryption if needed. 1185 */ 1186 static int 1187 serialize_header(bufinfo_T *bi, char_u *hash) 1188 { 1189 long len; 1190 buf_T *buf = bi->bi_buf; 1191 FILE *fp = bi->bi_fp; 1192 char_u time_buf[8]; 1193 1194 // Start writing, first the magic marker and undo info version. 1195 if (fwrite(UF_START_MAGIC, (size_t)UF_START_MAGIC_LEN, (size_t)1, fp) != 1) 1196 return FAIL; 1197 1198 // If the buffer is encrypted then all text bytes following will be 1199 // encrypted. Numbers and other info is not crypted. 1200 #ifdef FEAT_CRYPT 1201 if (*buf->b_p_key != NUL) 1202 { 1203 char_u *header; 1204 int header_len; 1205 1206 undo_write_bytes(bi, (long_u)UF_VERSION_CRYPT, 2); 1207 bi->bi_state = crypt_create_for_writing(crypt_get_method_nr(buf), 1208 buf->b_p_key, &header, &header_len); 1209 if (bi->bi_state == NULL) 1210 return FAIL; 1211 len = (long)fwrite(header, (size_t)header_len, (size_t)1, fp); 1212 vim_free(header); 1213 if (len != 1) 1214 { 1215 crypt_free_state(bi->bi_state); 1216 bi->bi_state = NULL; 1217 return FAIL; 1218 } 1219 1220 if (crypt_whole_undofile(crypt_get_method_nr(buf))) 1221 { 1222 bi->bi_buffer = alloc(CRYPT_BUF_SIZE); 1223 if (bi->bi_buffer == NULL) 1224 { 1225 crypt_free_state(bi->bi_state); 1226 bi->bi_state = NULL; 1227 return FAIL; 1228 } 1229 bi->bi_used = 0; 1230 } 1231 } 1232 else 1233 #endif 1234 undo_write_bytes(bi, (long_u)UF_VERSION, 2); 1235 1236 1237 // Write a hash of the buffer text, so that we can verify it is still the 1238 // same when reading the buffer text. 1239 if (undo_write(bi, hash, (size_t)UNDO_HASH_SIZE) == FAIL) 1240 return FAIL; 1241 1242 // buffer-specific data 1243 undo_write_bytes(bi, (long_u)buf->b_ml.ml_line_count, 4); 1244 len = buf->b_u_line_ptr.ul_line == NULL 1245 ? 0L : (long)STRLEN(buf->b_u_line_ptr.ul_line); 1246 undo_write_bytes(bi, (long_u)len, 4); 1247 if (len > 0 && fwrite_crypt(bi, buf->b_u_line_ptr.ul_line, (size_t)len) 1248 == FAIL) 1249 return FAIL; 1250 undo_write_bytes(bi, (long_u)buf->b_u_line_lnum, 4); 1251 undo_write_bytes(bi, (long_u)buf->b_u_line_colnr, 4); 1252 1253 // Undo structures header data 1254 put_header_ptr(bi, buf->b_u_oldhead); 1255 put_header_ptr(bi, buf->b_u_newhead); 1256 put_header_ptr(bi, buf->b_u_curhead); 1257 1258 undo_write_bytes(bi, (long_u)buf->b_u_numhead, 4); 1259 undo_write_bytes(bi, (long_u)buf->b_u_seq_last, 4); 1260 undo_write_bytes(bi, (long_u)buf->b_u_seq_cur, 4); 1261 time_to_bytes(buf->b_u_time_cur, time_buf); 1262 undo_write(bi, time_buf, 8); 1263 1264 // Optional fields. 1265 undo_write_bytes(bi, 4, 1); 1266 undo_write_bytes(bi, UF_LAST_SAVE_NR, 1); 1267 undo_write_bytes(bi, (long_u)buf->b_u_save_nr_last, 4); 1268 1269 undo_write_bytes(bi, 0, 1); // end marker 1270 1271 return OK; 1272 } 1273 1274 static int 1275 serialize_uhp(bufinfo_T *bi, u_header_T *uhp) 1276 { 1277 int i; 1278 u_entry_T *uep; 1279 char_u time_buf[8]; 1280 1281 if (undo_write_bytes(bi, (long_u)UF_HEADER_MAGIC, 2) == FAIL) 1282 return FAIL; 1283 1284 put_header_ptr(bi, uhp->uh_next.ptr); 1285 put_header_ptr(bi, uhp->uh_prev.ptr); 1286 put_header_ptr(bi, uhp->uh_alt_next.ptr); 1287 put_header_ptr(bi, uhp->uh_alt_prev.ptr); 1288 undo_write_bytes(bi, uhp->uh_seq, 4); 1289 serialize_pos(bi, uhp->uh_cursor); 1290 undo_write_bytes(bi, (long_u)uhp->uh_cursor_vcol, 4); 1291 undo_write_bytes(bi, (long_u)uhp->uh_flags, 2); 1292 // Assume NMARKS will stay the same. 1293 for (i = 0; i < NMARKS; ++i) 1294 serialize_pos(bi, uhp->uh_namedm[i]); 1295 serialize_visualinfo(bi, &uhp->uh_visual); 1296 time_to_bytes(uhp->uh_time, time_buf); 1297 undo_write(bi, time_buf, 8); 1298 1299 // Optional fields. 1300 undo_write_bytes(bi, 4, 1); 1301 undo_write_bytes(bi, UHP_SAVE_NR, 1); 1302 undo_write_bytes(bi, (long_u)uhp->uh_save_nr, 4); 1303 1304 undo_write_bytes(bi, 0, 1); // end marker 1305 1306 // Write all the entries. 1307 for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next) 1308 { 1309 undo_write_bytes(bi, (long_u)UF_ENTRY_MAGIC, 2); 1310 if (serialize_uep(bi, uep) == FAIL) 1311 return FAIL; 1312 } 1313 undo_write_bytes(bi, (long_u)UF_ENTRY_END_MAGIC, 2); 1314 return OK; 1315 } 1316 1317 static u_header_T * 1318 unserialize_uhp(bufinfo_T *bi, char_u *file_name) 1319 { 1320 u_header_T *uhp; 1321 int i; 1322 u_entry_T *uep, *last_uep; 1323 int c; 1324 int error; 1325 1326 uhp = U_ALLOC_LINE(sizeof(u_header_T)); 1327 if (uhp == NULL) 1328 return NULL; 1329 CLEAR_POINTER(uhp); 1330 #ifdef U_DEBUG 1331 uhp->uh_magic = UH_MAGIC; 1332 #endif 1333 uhp->uh_next.seq = undo_read_4c(bi); 1334 uhp->uh_prev.seq = undo_read_4c(bi); 1335 uhp->uh_alt_next.seq = undo_read_4c(bi); 1336 uhp->uh_alt_prev.seq = undo_read_4c(bi); 1337 uhp->uh_seq = undo_read_4c(bi); 1338 if (uhp->uh_seq <= 0) 1339 { 1340 corruption_error("uh_seq", file_name); 1341 vim_free(uhp); 1342 return NULL; 1343 } 1344 unserialize_pos(bi, &uhp->uh_cursor); 1345 uhp->uh_cursor_vcol = undo_read_4c(bi); 1346 uhp->uh_flags = undo_read_2c(bi); 1347 for (i = 0; i < NMARKS; ++i) 1348 unserialize_pos(bi, &uhp->uh_namedm[i]); 1349 unserialize_visualinfo(bi, &uhp->uh_visual); 1350 uhp->uh_time = undo_read_time(bi); 1351 1352 // Optional fields. 1353 for (;;) 1354 { 1355 int len = undo_read_byte(bi); 1356 int what; 1357 1358 if (len == EOF) 1359 { 1360 corruption_error("truncated", file_name); 1361 u_free_uhp(uhp); 1362 return NULL; 1363 } 1364 if (len == 0) 1365 break; 1366 what = undo_read_byte(bi); 1367 switch (what) 1368 { 1369 case UHP_SAVE_NR: 1370 uhp->uh_save_nr = undo_read_4c(bi); 1371 break; 1372 default: 1373 // field not supported, skip 1374 while (--len >= 0) 1375 (void)undo_read_byte(bi); 1376 } 1377 } 1378 1379 // Unserialize the uep list. 1380 last_uep = NULL; 1381 while ((c = undo_read_2c(bi)) == UF_ENTRY_MAGIC) 1382 { 1383 error = FALSE; 1384 uep = unserialize_uep(bi, &error, file_name); 1385 if (last_uep == NULL) 1386 uhp->uh_entry = uep; 1387 else 1388 last_uep->ue_next = uep; 1389 last_uep = uep; 1390 if (uep == NULL || error) 1391 { 1392 u_free_uhp(uhp); 1393 return NULL; 1394 } 1395 } 1396 if (c != UF_ENTRY_END_MAGIC) 1397 { 1398 corruption_error("entry end", file_name); 1399 u_free_uhp(uhp); 1400 return NULL; 1401 } 1402 1403 return uhp; 1404 } 1405 1406 /* 1407 * Serialize "uep". 1408 */ 1409 static int 1410 serialize_uep( 1411 bufinfo_T *bi, 1412 u_entry_T *uep) 1413 { 1414 int i; 1415 size_t len; 1416 1417 undo_write_bytes(bi, (long_u)uep->ue_top, 4); 1418 undo_write_bytes(bi, (long_u)uep->ue_bot, 4); 1419 undo_write_bytes(bi, (long_u)uep->ue_lcount, 4); 1420 undo_write_bytes(bi, (long_u)uep->ue_size, 4); 1421 for (i = 0; i < uep->ue_size; ++i) 1422 { 1423 // Text is written without the text properties, since we cannot restore 1424 // the text property types. 1425 len = STRLEN(uep->ue_array[i].ul_line); 1426 if (undo_write_bytes(bi, (long_u)len, 4) == FAIL) 1427 return FAIL; 1428 if (len > 0 && fwrite_crypt(bi, uep->ue_array[i].ul_line, len) == FAIL) 1429 return FAIL; 1430 } 1431 return OK; 1432 } 1433 1434 static u_entry_T * 1435 unserialize_uep(bufinfo_T *bi, int *error, char_u *file_name) 1436 { 1437 int i; 1438 u_entry_T *uep; 1439 undoline_T *array = NULL; 1440 char_u *line; 1441 int line_len; 1442 1443 uep = U_ALLOC_LINE(sizeof(u_entry_T)); 1444 if (uep == NULL) 1445 return NULL; 1446 CLEAR_POINTER(uep); 1447 #ifdef U_DEBUG 1448 uep->ue_magic = UE_MAGIC; 1449 #endif 1450 uep->ue_top = undo_read_4c(bi); 1451 uep->ue_bot = undo_read_4c(bi); 1452 uep->ue_lcount = undo_read_4c(bi); 1453 uep->ue_size = undo_read_4c(bi); 1454 if (uep->ue_size > 0) 1455 { 1456 if (uep->ue_size < LONG_MAX / (int)sizeof(char_u *)) 1457 array = U_ALLOC_LINE(sizeof(undoline_T) * uep->ue_size); 1458 if (array == NULL) 1459 { 1460 *error = TRUE; 1461 return uep; 1462 } 1463 vim_memset(array, 0, sizeof(undoline_T) * uep->ue_size); 1464 } 1465 uep->ue_array = array; 1466 1467 for (i = 0; i < uep->ue_size; ++i) 1468 { 1469 line_len = undo_read_4c(bi); 1470 if (line_len >= 0) 1471 line = read_string_decrypt(bi, line_len); 1472 else 1473 { 1474 line = NULL; 1475 corruption_error("line length", file_name); 1476 } 1477 if (line == NULL) 1478 { 1479 *error = TRUE; 1480 return uep; 1481 } 1482 array[i].ul_line = line; 1483 array[i].ul_len = line_len + 1; 1484 } 1485 return uep; 1486 } 1487 1488 /* 1489 * Serialize "pos". 1490 */ 1491 static void 1492 serialize_pos(bufinfo_T *bi, pos_T pos) 1493 { 1494 undo_write_bytes(bi, (long_u)pos.lnum, 4); 1495 undo_write_bytes(bi, (long_u)pos.col, 4); 1496 undo_write_bytes(bi, (long_u)pos.coladd, 4); 1497 } 1498 1499 /* 1500 * Unserialize the pos_T at the current position. 1501 */ 1502 static void 1503 unserialize_pos(bufinfo_T *bi, pos_T *pos) 1504 { 1505 pos->lnum = undo_read_4c(bi); 1506 if (pos->lnum < 0) 1507 pos->lnum = 0; 1508 pos->col = undo_read_4c(bi); 1509 if (pos->col < 0) 1510 pos->col = 0; 1511 pos->coladd = undo_read_4c(bi); 1512 if (pos->coladd < 0) 1513 pos->coladd = 0; 1514 } 1515 1516 /* 1517 * Serialize "info". 1518 */ 1519 static void 1520 serialize_visualinfo(bufinfo_T *bi, visualinfo_T *info) 1521 { 1522 serialize_pos(bi, info->vi_start); 1523 serialize_pos(bi, info->vi_end); 1524 undo_write_bytes(bi, (long_u)info->vi_mode, 4); 1525 undo_write_bytes(bi, (long_u)info->vi_curswant, 4); 1526 } 1527 1528 /* 1529 * Unserialize the visualinfo_T at the current position. 1530 */ 1531 static void 1532 unserialize_visualinfo(bufinfo_T *bi, visualinfo_T *info) 1533 { 1534 unserialize_pos(bi, &info->vi_start); 1535 unserialize_pos(bi, &info->vi_end); 1536 info->vi_mode = undo_read_4c(bi); 1537 info->vi_curswant = undo_read_4c(bi); 1538 } 1539 1540 /* 1541 * Write the undo tree in an undo file. 1542 * When "name" is not NULL, use it as the name of the undo file. 1543 * Otherwise use buf->b_ffname to generate the undo file name. 1544 * "buf" must never be null, buf->b_ffname is used to obtain the original file 1545 * permissions. 1546 * "forceit" is TRUE for ":wundo!", FALSE otherwise. 1547 * "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text. 1548 */ 1549 void 1550 u_write_undo( 1551 char_u *name, 1552 int forceit, 1553 buf_T *buf, 1554 char_u *hash) 1555 { 1556 u_header_T *uhp; 1557 char_u *file_name; 1558 int mark; 1559 #ifdef U_DEBUG 1560 int headers_written = 0; 1561 #endif 1562 int fd; 1563 FILE *fp = NULL; 1564 int perm; 1565 int write_ok = FALSE; 1566 #ifdef UNIX 1567 int st_old_valid = FALSE; 1568 stat_T st_old; 1569 stat_T st_new; 1570 #endif 1571 bufinfo_T bi; 1572 1573 CLEAR_FIELD(bi); 1574 1575 if (name == NULL) 1576 { 1577 file_name = u_get_undo_file_name(buf->b_ffname, FALSE); 1578 if (file_name == NULL) 1579 { 1580 if (p_verbose > 0) 1581 { 1582 verbose_enter(); 1583 smsg( 1584 _("Cannot write undo file in any directory in 'undodir'")); 1585 verbose_leave(); 1586 } 1587 return; 1588 } 1589 } 1590 else 1591 file_name = name; 1592 1593 /* 1594 * Decide about the permission to use for the undo file. If the buffer 1595 * has a name use the permission of the original file. Otherwise only 1596 * allow the user to access the undo file. 1597 */ 1598 perm = 0600; 1599 if (buf->b_ffname != NULL) 1600 { 1601 #ifdef UNIX 1602 if (mch_stat((char *)buf->b_ffname, &st_old) >= 0) 1603 { 1604 perm = st_old.st_mode; 1605 st_old_valid = TRUE; 1606 } 1607 #else 1608 perm = mch_getperm(buf->b_ffname); 1609 if (perm < 0) 1610 perm = 0600; 1611 #endif 1612 } 1613 1614 // strip any s-bit and executable bit 1615 perm = perm & 0666; 1616 1617 // If the undo file already exists, verify that it actually is an undo 1618 // file, and delete it. 1619 if (mch_getperm(file_name) >= 0) 1620 { 1621 if (name == NULL || !forceit) 1622 { 1623 // Check we can read it and it's an undo file. 1624 fd = mch_open((char *)file_name, O_RDONLY|O_EXTRA, 0); 1625 if (fd < 0) 1626 { 1627 if (name != NULL || p_verbose > 0) 1628 { 1629 if (name == NULL) 1630 verbose_enter(); 1631 smsg( 1632 _("Will not overwrite with undo file, cannot read: %s"), 1633 file_name); 1634 if (name == NULL) 1635 verbose_leave(); 1636 } 1637 goto theend; 1638 } 1639 else 1640 { 1641 char_u mbuf[UF_START_MAGIC_LEN]; 1642 int len; 1643 1644 len = read_eintr(fd, mbuf, UF_START_MAGIC_LEN); 1645 close(fd); 1646 if (len < UF_START_MAGIC_LEN 1647 || memcmp(mbuf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0) 1648 { 1649 if (name != NULL || p_verbose > 0) 1650 { 1651 if (name == NULL) 1652 verbose_enter(); 1653 smsg( 1654 _("Will not overwrite, this is not an undo file: %s"), 1655 file_name); 1656 if (name == NULL) 1657 verbose_leave(); 1658 } 1659 goto theend; 1660 } 1661 } 1662 } 1663 mch_remove(file_name); 1664 } 1665 1666 // If there is no undo information at all, quit here after deleting any 1667 // existing undo file. 1668 if (buf->b_u_numhead == 0 && buf->b_u_line_ptr.ul_line == NULL) 1669 { 1670 if (p_verbose > 0) 1671 verb_msg(_("Skipping undo file write, nothing to undo")); 1672 goto theend; 1673 } 1674 1675 fd = mch_open((char *)file_name, 1676 O_CREAT|O_EXTRA|O_WRONLY|O_EXCL|O_NOFOLLOW, perm); 1677 if (fd < 0) 1678 { 1679 semsg(_(e_not_open), file_name); 1680 goto theend; 1681 } 1682 (void)mch_setperm(file_name, perm); 1683 if (p_verbose > 0) 1684 { 1685 verbose_enter(); 1686 smsg(_("Writing undo file: %s"), file_name); 1687 verbose_leave(); 1688 } 1689 1690 #ifdef U_DEBUG 1691 // Check there is no problem in undo info before writing. 1692 u_check(FALSE); 1693 #endif 1694 1695 #ifdef UNIX 1696 /* 1697 * Try to set the group of the undo file same as the original file. If 1698 * this fails, set the protection bits for the group same as the 1699 * protection bits for others. 1700 */ 1701 if (st_old_valid 1702 && mch_stat((char *)file_name, &st_new) >= 0 1703 && st_new.st_gid != st_old.st_gid 1704 # ifdef HAVE_FCHOWN // sequent-ptx lacks fchown() 1705 && fchown(fd, (uid_t)-1, st_old.st_gid) != 0 1706 # endif 1707 ) 1708 mch_setperm(file_name, (perm & 0707) | ((perm & 07) << 3)); 1709 # if defined(HAVE_SELINUX) || defined(HAVE_SMACK) 1710 if (buf->b_ffname != NULL) 1711 mch_copy_sec(buf->b_ffname, file_name); 1712 # endif 1713 #endif 1714 1715 fp = fdopen(fd, "w"); 1716 if (fp == NULL) 1717 { 1718 semsg(_(e_not_open), file_name); 1719 close(fd); 1720 mch_remove(file_name); 1721 goto theend; 1722 } 1723 1724 // Undo must be synced. 1725 u_sync(TRUE); 1726 1727 /* 1728 * Write the header. Initializes encryption, if enabled. 1729 */ 1730 bi.bi_buf = buf; 1731 bi.bi_fp = fp; 1732 if (serialize_header(&bi, hash) == FAIL) 1733 goto write_error; 1734 1735 /* 1736 * Iteratively serialize UHPs and their UEPs from the top down. 1737 */ 1738 mark = ++lastmark; 1739 uhp = buf->b_u_oldhead; 1740 while (uhp != NULL) 1741 { 1742 // Serialize current UHP if we haven't seen it 1743 if (uhp->uh_walk != mark) 1744 { 1745 uhp->uh_walk = mark; 1746 #ifdef U_DEBUG 1747 ++headers_written; 1748 #endif 1749 if (serialize_uhp(&bi, uhp) == FAIL) 1750 goto write_error; 1751 } 1752 1753 // Now walk through the tree - algorithm from undo_time(). 1754 if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != mark) 1755 uhp = uhp->uh_prev.ptr; 1756 else if (uhp->uh_alt_next.ptr != NULL 1757 && uhp->uh_alt_next.ptr->uh_walk != mark) 1758 uhp = uhp->uh_alt_next.ptr; 1759 else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL 1760 && uhp->uh_next.ptr->uh_walk != mark) 1761 uhp = uhp->uh_next.ptr; 1762 else if (uhp->uh_alt_prev.ptr != NULL) 1763 uhp = uhp->uh_alt_prev.ptr; 1764 else 1765 uhp = uhp->uh_next.ptr; 1766 } 1767 1768 if (undo_write_bytes(&bi, (long_u)UF_HEADER_END_MAGIC, 2) == OK) 1769 write_ok = TRUE; 1770 #ifdef U_DEBUG 1771 if (headers_written != buf->b_u_numhead) 1772 { 1773 semsg("Written %ld headers, ...", headers_written); 1774 semsg("... but numhead is %ld", buf->b_u_numhead); 1775 } 1776 #endif 1777 1778 #ifdef FEAT_CRYPT 1779 if (bi.bi_state != NULL && undo_flush(&bi) == FAIL) 1780 write_ok = FALSE; 1781 #endif 1782 1783 write_error: 1784 fclose(fp); 1785 if (!write_ok) 1786 semsg(_("E829: write error in undo file: %s"), file_name); 1787 1788 #if defined(MSWIN) 1789 // Copy file attributes; for systems where this can only be done after 1790 // closing the file. 1791 if (buf->b_ffname != NULL) 1792 (void)mch_copy_file_attribute(buf->b_ffname, file_name); 1793 #endif 1794 #ifdef HAVE_ACL 1795 if (buf->b_ffname != NULL) 1796 { 1797 vim_acl_T acl; 1798 1799 // For systems that support ACL: get the ACL from the original file. 1800 acl = mch_get_acl(buf->b_ffname); 1801 mch_set_acl(file_name, acl); 1802 mch_free_acl(acl); 1803 } 1804 #endif 1805 1806 theend: 1807 #ifdef FEAT_CRYPT 1808 if (bi.bi_state != NULL) 1809 crypt_free_state(bi.bi_state); 1810 vim_free(bi.bi_buffer); 1811 #endif 1812 if (file_name != name) 1813 vim_free(file_name); 1814 } 1815 1816 /* 1817 * Load the undo tree from an undo file. 1818 * If "name" is not NULL use it as the undo file name. This also means being 1819 * a bit more verbose. 1820 * Otherwise use curbuf->b_ffname to generate the undo file name. 1821 * "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text. 1822 */ 1823 void 1824 u_read_undo(char_u *name, char_u *hash, char_u *orig_name UNUSED) 1825 { 1826 char_u *file_name; 1827 FILE *fp; 1828 long version, str_len; 1829 undoline_T line_ptr; 1830 linenr_T line_lnum; 1831 colnr_T line_colnr; 1832 linenr_T line_count; 1833 long num_head = 0; 1834 long old_header_seq, new_header_seq, cur_header_seq; 1835 long seq_last, seq_cur; 1836 long last_save_nr = 0; 1837 short old_idx = -1, new_idx = -1, cur_idx = -1; 1838 long num_read_uhps = 0; 1839 time_t seq_time; 1840 int i, j; 1841 int c; 1842 u_header_T *uhp; 1843 u_header_T **uhp_table = NULL; 1844 char_u read_hash[UNDO_HASH_SIZE]; 1845 char_u magic_buf[UF_START_MAGIC_LEN]; 1846 #ifdef U_DEBUG 1847 int *uhp_table_used; 1848 #endif 1849 #ifdef UNIX 1850 stat_T st_orig; 1851 stat_T st_undo; 1852 #endif 1853 bufinfo_T bi; 1854 1855 CLEAR_FIELD(bi); 1856 line_ptr.ul_len = 0; 1857 line_ptr.ul_line = NULL; 1858 1859 if (name == NULL) 1860 { 1861 file_name = u_get_undo_file_name(curbuf->b_ffname, TRUE); 1862 if (file_name == NULL) 1863 return; 1864 1865 #ifdef UNIX 1866 // For safety we only read an undo file if the owner is equal to the 1867 // owner of the text file or equal to the current user. 1868 if (mch_stat((char *)orig_name, &st_orig) >= 0 1869 && mch_stat((char *)file_name, &st_undo) >= 0 1870 && st_orig.st_uid != st_undo.st_uid 1871 && st_undo.st_uid != getuid()) 1872 { 1873 if (p_verbose > 0) 1874 { 1875 verbose_enter(); 1876 smsg(_("Not reading undo file, owner differs: %s"), 1877 file_name); 1878 verbose_leave(); 1879 } 1880 return; 1881 } 1882 #endif 1883 } 1884 else 1885 file_name = name; 1886 1887 if (p_verbose > 0) 1888 { 1889 verbose_enter(); 1890 smsg(_("Reading undo file: %s"), file_name); 1891 verbose_leave(); 1892 } 1893 1894 fp = mch_fopen((char *)file_name, "r"); 1895 if (fp == NULL) 1896 { 1897 if (name != NULL || p_verbose > 0) 1898 semsg(_("E822: Cannot open undo file for reading: %s"), file_name); 1899 goto error; 1900 } 1901 bi.bi_buf = curbuf; 1902 bi.bi_fp = fp; 1903 1904 /* 1905 * Read the undo file header. 1906 */ 1907 if (fread(magic_buf, UF_START_MAGIC_LEN, 1, fp) != 1 1908 || memcmp(magic_buf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0) 1909 { 1910 semsg(_("E823: Not an undo file: %s"), file_name); 1911 goto error; 1912 } 1913 version = get2c(fp); 1914 if (version == UF_VERSION_CRYPT) 1915 { 1916 #ifdef FEAT_CRYPT 1917 if (*curbuf->b_p_key == NUL) 1918 { 1919 semsg(_("E832: Non-encrypted file has encrypted undo file: %s"), 1920 file_name); 1921 goto error; 1922 } 1923 bi.bi_state = crypt_create_from_file(fp, curbuf->b_p_key); 1924 if (bi.bi_state == NULL) 1925 { 1926 semsg(_("E826: Undo file decryption failed: %s"), file_name); 1927 goto error; 1928 } 1929 if (crypt_whole_undofile(bi.bi_state->method_nr)) 1930 { 1931 bi.bi_buffer = alloc(CRYPT_BUF_SIZE); 1932 if (bi.bi_buffer == NULL) 1933 { 1934 crypt_free_state(bi.bi_state); 1935 bi.bi_state = NULL; 1936 goto error; 1937 } 1938 bi.bi_avail = 0; 1939 bi.bi_used = 0; 1940 } 1941 #else 1942 semsg(_("E827: Undo file is encrypted: %s"), file_name); 1943 goto error; 1944 #endif 1945 } 1946 else if (version != UF_VERSION) 1947 { 1948 semsg(_("E824: Incompatible undo file: %s"), file_name); 1949 goto error; 1950 } 1951 1952 if (undo_read(&bi, read_hash, (size_t)UNDO_HASH_SIZE) == FAIL) 1953 { 1954 corruption_error("hash", file_name); 1955 goto error; 1956 } 1957 line_count = (linenr_T)undo_read_4c(&bi); 1958 if (memcmp(hash, read_hash, UNDO_HASH_SIZE) != 0 1959 || line_count != curbuf->b_ml.ml_line_count) 1960 { 1961 if (p_verbose > 0 || name != NULL) 1962 { 1963 if (name == NULL) 1964 verbose_enter(); 1965 give_warning((char_u *) 1966 _("File contents changed, cannot use undo info"), TRUE); 1967 if (name == NULL) 1968 verbose_leave(); 1969 } 1970 goto error; 1971 } 1972 1973 // Read undo data for "U" command. 1974 str_len = undo_read_4c(&bi); 1975 if (str_len < 0) 1976 goto error; 1977 if (str_len > 0) 1978 { 1979 line_ptr.ul_line = read_string_decrypt(&bi, str_len); 1980 line_ptr.ul_len = str_len + 1; 1981 } 1982 line_lnum = (linenr_T)undo_read_4c(&bi); 1983 line_colnr = (colnr_T)undo_read_4c(&bi); 1984 if (line_lnum < 0 || line_colnr < 0) 1985 { 1986 corruption_error("line lnum/col", file_name); 1987 goto error; 1988 } 1989 1990 // Begin general undo data 1991 old_header_seq = undo_read_4c(&bi); 1992 new_header_seq = undo_read_4c(&bi); 1993 cur_header_seq = undo_read_4c(&bi); 1994 num_head = undo_read_4c(&bi); 1995 seq_last = undo_read_4c(&bi); 1996 seq_cur = undo_read_4c(&bi); 1997 seq_time = undo_read_time(&bi); 1998 1999 // Optional header fields. 2000 for (;;) 2001 { 2002 int len = undo_read_byte(&bi); 2003 int what; 2004 2005 if (len == 0 || len == EOF) 2006 break; 2007 what = undo_read_byte(&bi); 2008 switch (what) 2009 { 2010 case UF_LAST_SAVE_NR: 2011 last_save_nr = undo_read_4c(&bi); 2012 break; 2013 default: 2014 // field not supported, skip 2015 while (--len >= 0) 2016 (void)undo_read_byte(&bi); 2017 } 2018 } 2019 2020 // uhp_table will store the freshly created undo headers we allocate 2021 // until we insert them into curbuf. The table remains sorted by the 2022 // sequence numbers of the headers. 2023 // When there are no headers uhp_table is NULL. 2024 if (num_head > 0) 2025 { 2026 if (num_head < LONG_MAX / (long)sizeof(u_header_T *)) 2027 uhp_table = U_ALLOC_LINE(num_head * sizeof(u_header_T *)); 2028 if (uhp_table == NULL) 2029 goto error; 2030 } 2031 2032 while ((c = undo_read_2c(&bi)) == UF_HEADER_MAGIC) 2033 { 2034 if (num_read_uhps >= num_head) 2035 { 2036 corruption_error("num_head too small", file_name); 2037 goto error; 2038 } 2039 2040 uhp = unserialize_uhp(&bi, file_name); 2041 if (uhp == NULL) 2042 goto error; 2043 uhp_table[num_read_uhps++] = uhp; 2044 } 2045 2046 if (num_read_uhps != num_head) 2047 { 2048 corruption_error("num_head", file_name); 2049 goto error; 2050 } 2051 if (c != UF_HEADER_END_MAGIC) 2052 { 2053 corruption_error("end marker", file_name); 2054 goto error; 2055 } 2056 2057 #ifdef U_DEBUG 2058 uhp_table_used = alloc_clear(sizeof(int) * num_head + 1); 2059 # define SET_FLAG(j) ++uhp_table_used[j] 2060 #else 2061 # define SET_FLAG(j) 2062 #endif 2063 2064 // We have put all of the headers into a table. Now we iterate through the 2065 // table and swizzle each sequence number we have stored in uh_*_seq into 2066 // a pointer corresponding to the header with that sequence number. 2067 for (i = 0; i < num_head; i++) 2068 { 2069 uhp = uhp_table[i]; 2070 if (uhp == NULL) 2071 continue; 2072 for (j = 0; j < num_head; j++) 2073 if (uhp_table[j] != NULL && i != j 2074 && uhp_table[i]->uh_seq == uhp_table[j]->uh_seq) 2075 { 2076 corruption_error("duplicate uh_seq", file_name); 2077 goto error; 2078 } 2079 for (j = 0; j < num_head; j++) 2080 if (uhp_table[j] != NULL 2081 && uhp_table[j]->uh_seq == uhp->uh_next.seq) 2082 { 2083 uhp->uh_next.ptr = uhp_table[j]; 2084 SET_FLAG(j); 2085 break; 2086 } 2087 for (j = 0; j < num_head; j++) 2088 if (uhp_table[j] != NULL 2089 && uhp_table[j]->uh_seq == uhp->uh_prev.seq) 2090 { 2091 uhp->uh_prev.ptr = uhp_table[j]; 2092 SET_FLAG(j); 2093 break; 2094 } 2095 for (j = 0; j < num_head; j++) 2096 if (uhp_table[j] != NULL 2097 && uhp_table[j]->uh_seq == uhp->uh_alt_next.seq) 2098 { 2099 uhp->uh_alt_next.ptr = uhp_table[j]; 2100 SET_FLAG(j); 2101 break; 2102 } 2103 for (j = 0; j < num_head; j++) 2104 if (uhp_table[j] != NULL 2105 && uhp_table[j]->uh_seq == uhp->uh_alt_prev.seq) 2106 { 2107 uhp->uh_alt_prev.ptr = uhp_table[j]; 2108 SET_FLAG(j); 2109 break; 2110 } 2111 if (old_header_seq > 0 && old_idx < 0 && uhp->uh_seq == old_header_seq) 2112 { 2113 old_idx = i; 2114 SET_FLAG(i); 2115 } 2116 if (new_header_seq > 0 && new_idx < 0 && uhp->uh_seq == new_header_seq) 2117 { 2118 new_idx = i; 2119 SET_FLAG(i); 2120 } 2121 if (cur_header_seq > 0 && cur_idx < 0 && uhp->uh_seq == cur_header_seq) 2122 { 2123 cur_idx = i; 2124 SET_FLAG(i); 2125 } 2126 } 2127 2128 // Now that we have read the undo info successfully, free the current undo 2129 // info and use the info from the file. 2130 u_blockfree(curbuf); 2131 curbuf->b_u_oldhead = old_idx < 0 ? NULL : uhp_table[old_idx]; 2132 curbuf->b_u_newhead = new_idx < 0 ? NULL : uhp_table[new_idx]; 2133 curbuf->b_u_curhead = cur_idx < 0 ? NULL : uhp_table[cur_idx]; 2134 curbuf->b_u_line_ptr = line_ptr; 2135 curbuf->b_u_line_lnum = line_lnum; 2136 curbuf->b_u_line_colnr = line_colnr; 2137 curbuf->b_u_numhead = num_head; 2138 curbuf->b_u_seq_last = seq_last; 2139 curbuf->b_u_seq_cur = seq_cur; 2140 curbuf->b_u_time_cur = seq_time; 2141 curbuf->b_u_save_nr_last = last_save_nr; 2142 curbuf->b_u_save_nr_cur = last_save_nr; 2143 2144 curbuf->b_u_synced = TRUE; 2145 vim_free(uhp_table); 2146 2147 #ifdef U_DEBUG 2148 for (i = 0; i < num_head; ++i) 2149 if (uhp_table_used[i] == 0) 2150 semsg("uhp_table entry %ld not used, leaking memory", i); 2151 vim_free(uhp_table_used); 2152 u_check(TRUE); 2153 #endif 2154 2155 if (name != NULL) 2156 smsg(_("Finished reading undo file %s"), file_name); 2157 goto theend; 2158 2159 error: 2160 vim_free(line_ptr.ul_line); 2161 if (uhp_table != NULL) 2162 { 2163 for (i = 0; i < num_read_uhps; i++) 2164 if (uhp_table[i] != NULL) 2165 u_free_uhp(uhp_table[i]); 2166 vim_free(uhp_table); 2167 } 2168 2169 theend: 2170 #ifdef FEAT_CRYPT 2171 if (bi.bi_state != NULL) 2172 crypt_free_state(bi.bi_state); 2173 vim_free(bi.bi_buffer); 2174 #endif 2175 if (fp != NULL) 2176 fclose(fp); 2177 if (file_name != name) 2178 vim_free(file_name); 2179 return; 2180 } 2181 2182 #endif // FEAT_PERSISTENT_UNDO 2183 2184 2185 /* 2186 * If 'cpoptions' contains 'u': Undo the previous undo or redo (vi compatible). 2187 * If 'cpoptions' does not contain 'u': Always undo. 2188 */ 2189 void 2190 u_undo(int count) 2191 { 2192 /* 2193 * If we get an undo command while executing a macro, we behave like the 2194 * original vi. If this happens twice in one macro the result will not 2195 * be compatible. 2196 */ 2197 if (curbuf->b_u_synced == FALSE) 2198 { 2199 u_sync(TRUE); 2200 count = 1; 2201 } 2202 2203 if (vim_strchr(p_cpo, CPO_UNDO) == NULL) 2204 undo_undoes = TRUE; 2205 else 2206 undo_undoes = !undo_undoes; 2207 u_doit(count); 2208 } 2209 2210 /* 2211 * If 'cpoptions' contains 'u': Repeat the previous undo or redo. 2212 * If 'cpoptions' does not contain 'u': Always redo. 2213 */ 2214 void 2215 u_redo(int count) 2216 { 2217 if (vim_strchr(p_cpo, CPO_UNDO) == NULL) 2218 undo_undoes = FALSE; 2219 u_doit(count); 2220 } 2221 2222 /* 2223 * Undo or redo, depending on 'undo_undoes', 'count' times. 2224 */ 2225 static void 2226 u_doit(int startcount) 2227 { 2228 int count = startcount; 2229 2230 if (!undo_allowed()) 2231 return; 2232 2233 u_newcount = 0; 2234 u_oldcount = 0; 2235 if (curbuf->b_ml.ml_flags & ML_EMPTY) 2236 u_oldcount = -1; 2237 while (count--) 2238 { 2239 // Do the change warning now, so that it triggers FileChangedRO when 2240 // needed. This may cause the file to be reloaded, that must happen 2241 // before we do anything, because it may change curbuf->b_u_curhead 2242 // and more. 2243 change_warning(0); 2244 2245 if (undo_undoes) 2246 { 2247 if (curbuf->b_u_curhead == NULL) // first undo 2248 curbuf->b_u_curhead = curbuf->b_u_newhead; 2249 else if (get_undolevel() > 0) // multi level undo 2250 // get next undo 2251 curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next.ptr; 2252 // nothing to undo 2253 if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL) 2254 { 2255 // stick curbuf->b_u_curhead at end 2256 curbuf->b_u_curhead = curbuf->b_u_oldhead; 2257 beep_flush(); 2258 if (count == startcount - 1) 2259 { 2260 msg(_("Already at oldest change")); 2261 return; 2262 } 2263 break; 2264 } 2265 2266 u_undoredo(TRUE); 2267 } 2268 else 2269 { 2270 if (curbuf->b_u_curhead == NULL || get_undolevel() <= 0) 2271 { 2272 beep_flush(); // nothing to redo 2273 if (count == startcount - 1) 2274 { 2275 msg(_("Already at newest change")); 2276 return; 2277 } 2278 break; 2279 } 2280 2281 u_undoredo(FALSE); 2282 2283 // Advance for next redo. Set "newhead" when at the end of the 2284 // redoable changes. 2285 if (curbuf->b_u_curhead->uh_prev.ptr == NULL) 2286 curbuf->b_u_newhead = curbuf->b_u_curhead; 2287 curbuf->b_u_curhead = curbuf->b_u_curhead->uh_prev.ptr; 2288 } 2289 } 2290 u_undo_end(undo_undoes, FALSE); 2291 } 2292 2293 /* 2294 * Undo or redo over the timeline. 2295 * When "step" is negative go back in time, otherwise goes forward in time. 2296 * When "sec" is FALSE make "step" steps, when "sec" is TRUE use "step" as 2297 * seconds. 2298 * When "file" is TRUE use "step" as a number of file writes. 2299 * When "absolute" is TRUE use "step" as the sequence number to jump to. 2300 * "sec" must be FALSE then. 2301 */ 2302 void 2303 undo_time( 2304 long step, 2305 int sec, 2306 int file, 2307 int absolute) 2308 { 2309 long target; 2310 long closest; 2311 long closest_start; 2312 long closest_seq = 0; 2313 long val; 2314 u_header_T *uhp = NULL; 2315 u_header_T *last; 2316 int mark; 2317 int nomark = 0; // shut up compiler 2318 int round; 2319 int dosec = sec; 2320 int dofile = file; 2321 int above = FALSE; 2322 int did_undo = TRUE; 2323 2324 // First make sure the current undoable change is synced. 2325 if (curbuf->b_u_synced == FALSE) 2326 u_sync(TRUE); 2327 2328 u_newcount = 0; 2329 u_oldcount = 0; 2330 if (curbuf->b_ml.ml_flags & ML_EMPTY) 2331 u_oldcount = -1; 2332 2333 // "target" is the node below which we want to be. 2334 // Init "closest" to a value we can't reach. 2335 if (absolute) 2336 { 2337 target = step; 2338 closest = -1; 2339 } 2340 else 2341 { 2342 if (dosec) 2343 target = (long)(curbuf->b_u_time_cur) + step; 2344 else if (dofile) 2345 { 2346 if (step < 0) 2347 { 2348 // Going back to a previous write. If there were changes after 2349 // the last write, count that as moving one file-write, so 2350 // that ":earlier 1f" undoes all changes since the last save. 2351 uhp = curbuf->b_u_curhead; 2352 if (uhp != NULL) 2353 uhp = uhp->uh_next.ptr; 2354 else 2355 uhp = curbuf->b_u_newhead; 2356 if (uhp != NULL && uhp->uh_save_nr != 0) 2357 // "uh_save_nr" was set in the last block, that means 2358 // there were no changes since the last write 2359 target = curbuf->b_u_save_nr_cur + step; 2360 else 2361 // count the changes since the last write as one step 2362 target = curbuf->b_u_save_nr_cur + step + 1; 2363 if (target <= 0) 2364 // Go to before first write: before the oldest change. Use 2365 // the sequence number for that. 2366 dofile = FALSE; 2367 } 2368 else 2369 { 2370 // Moving forward to a newer write. 2371 target = curbuf->b_u_save_nr_cur + step; 2372 if (target > curbuf->b_u_save_nr_last) 2373 { 2374 // Go to after last write: after the latest change. Use 2375 // the sequence number for that. 2376 target = curbuf->b_u_seq_last + 1; 2377 dofile = FALSE; 2378 } 2379 } 2380 } 2381 else 2382 target = curbuf->b_u_seq_cur + step; 2383 if (step < 0) 2384 { 2385 if (target < 0) 2386 target = 0; 2387 closest = -1; 2388 } 2389 else 2390 { 2391 if (dosec) 2392 closest = (long)(vim_time() + 1); 2393 else if (dofile) 2394 closest = curbuf->b_u_save_nr_last + 2; 2395 else 2396 closest = curbuf->b_u_seq_last + 2; 2397 if (target >= closest) 2398 target = closest - 1; 2399 } 2400 } 2401 closest_start = closest; 2402 closest_seq = curbuf->b_u_seq_cur; 2403 2404 // When "target" is 0; Back to origin. 2405 if (target == 0) 2406 { 2407 mark = lastmark; // avoid that GCC complains 2408 goto target_zero; 2409 } 2410 2411 /* 2412 * May do this twice: 2413 * 1. Search for "target", update "closest" to the best match found. 2414 * 2. If "target" not found search for "closest". 2415 * 2416 * When using the closest time we use the sequence number in the second 2417 * round, because there may be several entries with the same time. 2418 */ 2419 for (round = 1; round <= 2; ++round) 2420 { 2421 // Find the path from the current state to where we want to go. The 2422 // desired state can be anywhere in the undo tree, need to go all over 2423 // it. We put "nomark" in uh_walk where we have been without success, 2424 // "mark" where it could possibly be. 2425 mark = ++lastmark; 2426 nomark = ++lastmark; 2427 2428 if (curbuf->b_u_curhead == NULL) // at leaf of the tree 2429 uhp = curbuf->b_u_newhead; 2430 else 2431 uhp = curbuf->b_u_curhead; 2432 2433 while (uhp != NULL) 2434 { 2435 uhp->uh_walk = mark; 2436 if (dosec) 2437 val = (long)(uhp->uh_time); 2438 else if (dofile) 2439 val = uhp->uh_save_nr; 2440 else 2441 val = uhp->uh_seq; 2442 2443 if (round == 1 && !(dofile && val == 0)) 2444 { 2445 // Remember the header that is closest to the target. 2446 // It must be at least in the right direction (checked with 2447 // "b_u_seq_cur"). When the timestamp is equal find the 2448 // highest/lowest sequence number. 2449 if ((step < 0 ? uhp->uh_seq <= curbuf->b_u_seq_cur 2450 : uhp->uh_seq > curbuf->b_u_seq_cur) 2451 && ((dosec && val == closest) 2452 ? (step < 0 2453 ? uhp->uh_seq < closest_seq 2454 : uhp->uh_seq > closest_seq) 2455 : closest == closest_start 2456 || (val > target 2457 ? (closest > target 2458 ? val - target <= closest - target 2459 : val - target <= target - closest) 2460 : (closest > target 2461 ? target - val <= closest - target 2462 : target - val <= target - closest)))) 2463 { 2464 closest = val; 2465 closest_seq = uhp->uh_seq; 2466 } 2467 } 2468 2469 // Quit searching when we found a match. But when searching for a 2470 // time we need to continue looking for the best uh_seq. 2471 if (target == val && !dosec) 2472 { 2473 target = uhp->uh_seq; 2474 break; 2475 } 2476 2477 // go down in the tree if we haven't been there 2478 if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark 2479 && uhp->uh_prev.ptr->uh_walk != mark) 2480 uhp = uhp->uh_prev.ptr; 2481 2482 // go to alternate branch if we haven't been there 2483 else if (uhp->uh_alt_next.ptr != NULL 2484 && uhp->uh_alt_next.ptr->uh_walk != nomark 2485 && uhp->uh_alt_next.ptr->uh_walk != mark) 2486 uhp = uhp->uh_alt_next.ptr; 2487 2488 // go up in the tree if we haven't been there and we are at the 2489 // start of alternate branches 2490 else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL 2491 && uhp->uh_next.ptr->uh_walk != nomark 2492 && uhp->uh_next.ptr->uh_walk != mark) 2493 { 2494 // If still at the start we don't go through this change. 2495 if (uhp == curbuf->b_u_curhead) 2496 uhp->uh_walk = nomark; 2497 uhp = uhp->uh_next.ptr; 2498 } 2499 2500 else 2501 { 2502 // need to backtrack; mark this node as useless 2503 uhp->uh_walk = nomark; 2504 if (uhp->uh_alt_prev.ptr != NULL) 2505 uhp = uhp->uh_alt_prev.ptr; 2506 else 2507 uhp = uhp->uh_next.ptr; 2508 } 2509 } 2510 2511 if (uhp != NULL) // found it 2512 break; 2513 2514 if (absolute) 2515 { 2516 semsg(_("E830: Undo number %ld not found"), step); 2517 return; 2518 } 2519 2520 if (closest == closest_start) 2521 { 2522 if (step < 0) 2523 msg(_("Already at oldest change")); 2524 else 2525 msg(_("Already at newest change")); 2526 return; 2527 } 2528 2529 target = closest_seq; 2530 dosec = FALSE; 2531 dofile = FALSE; 2532 if (step < 0) 2533 above = TRUE; // stop above the header 2534 } 2535 2536 target_zero: 2537 // If we found it: Follow the path to go to where we want to be. 2538 if (uhp != NULL || target == 0) 2539 { 2540 /* 2541 * First go up the tree as much as needed. 2542 */ 2543 while (!got_int) 2544 { 2545 // Do the change warning now, for the same reason as above. 2546 change_warning(0); 2547 2548 uhp = curbuf->b_u_curhead; 2549 if (uhp == NULL) 2550 uhp = curbuf->b_u_newhead; 2551 else 2552 uhp = uhp->uh_next.ptr; 2553 if (uhp == NULL || (target > 0 && uhp->uh_walk != mark) 2554 || (uhp->uh_seq == target && !above)) 2555 break; 2556 curbuf->b_u_curhead = uhp; 2557 u_undoredo(TRUE); 2558 if (target > 0) 2559 uhp->uh_walk = nomark; // don't go back down here 2560 } 2561 2562 // When back to origin, redo is not needed. 2563 if (target > 0) 2564 { 2565 /* 2566 * And now go down the tree (redo), branching off where needed. 2567 */ 2568 while (!got_int) 2569 { 2570 // Do the change warning now, for the same reason as above. 2571 change_warning(0); 2572 2573 uhp = curbuf->b_u_curhead; 2574 if (uhp == NULL) 2575 break; 2576 2577 // Go back to the first branch with a mark. 2578 while (uhp->uh_alt_prev.ptr != NULL 2579 && uhp->uh_alt_prev.ptr->uh_walk == mark) 2580 uhp = uhp->uh_alt_prev.ptr; 2581 2582 // Find the last branch with a mark, that's the one. 2583 last = uhp; 2584 while (last->uh_alt_next.ptr != NULL 2585 && last->uh_alt_next.ptr->uh_walk == mark) 2586 last = last->uh_alt_next.ptr; 2587 if (last != uhp) 2588 { 2589 // Make the used branch the first entry in the list of 2590 // alternatives to make "u" and CTRL-R take this branch. 2591 while (uhp->uh_alt_prev.ptr != NULL) 2592 uhp = uhp->uh_alt_prev.ptr; 2593 if (last->uh_alt_next.ptr != NULL) 2594 last->uh_alt_next.ptr->uh_alt_prev.ptr = 2595 last->uh_alt_prev.ptr; 2596 last->uh_alt_prev.ptr->uh_alt_next.ptr = 2597 last->uh_alt_next.ptr; 2598 last->uh_alt_prev.ptr = NULL; 2599 last->uh_alt_next.ptr = uhp; 2600 uhp->uh_alt_prev.ptr = last; 2601 2602 if (curbuf->b_u_oldhead == uhp) 2603 curbuf->b_u_oldhead = last; 2604 uhp = last; 2605 if (uhp->uh_next.ptr != NULL) 2606 uhp->uh_next.ptr->uh_prev.ptr = uhp; 2607 } 2608 curbuf->b_u_curhead = uhp; 2609 2610 if (uhp->uh_walk != mark) 2611 break; // must have reached the target 2612 2613 // Stop when going backwards in time and didn't find the exact 2614 // header we were looking for. 2615 if (uhp->uh_seq == target && above) 2616 { 2617 curbuf->b_u_seq_cur = target - 1; 2618 break; 2619 } 2620 2621 u_undoredo(FALSE); 2622 2623 // Advance "curhead" to below the header we last used. If it 2624 // becomes NULL then we need to set "newhead" to this leaf. 2625 if (uhp->uh_prev.ptr == NULL) 2626 curbuf->b_u_newhead = uhp; 2627 curbuf->b_u_curhead = uhp->uh_prev.ptr; 2628 did_undo = FALSE; 2629 2630 if (uhp->uh_seq == target) // found it! 2631 break; 2632 2633 uhp = uhp->uh_prev.ptr; 2634 if (uhp == NULL || uhp->uh_walk != mark) 2635 { 2636 // Need to redo more but can't find it... 2637 internal_error("undo_time()"); 2638 break; 2639 } 2640 } 2641 } 2642 } 2643 u_undo_end(did_undo, absolute); 2644 } 2645 2646 /* 2647 * u_undoredo: common code for undo and redo 2648 * 2649 * The lines in the file are replaced by the lines in the entry list at 2650 * curbuf->b_u_curhead. The replaced lines in the file are saved in the entry 2651 * list for the next undo/redo. 2652 * 2653 * When "undo" is TRUE we go up in the tree, when FALSE we go down. 2654 */ 2655 static void 2656 u_undoredo(int undo) 2657 { 2658 undoline_T *newarray = NULL; 2659 linenr_T oldsize; 2660 linenr_T newsize; 2661 linenr_T top, bot; 2662 linenr_T lnum; 2663 linenr_T newlnum = MAXLNUM; 2664 pos_T new_curpos = curwin->w_cursor; 2665 long i; 2666 u_entry_T *uep, *nuep; 2667 u_entry_T *newlist = NULL; 2668 int old_flags; 2669 int new_flags; 2670 pos_T namedm[NMARKS]; 2671 visualinfo_T visualinfo; 2672 int empty_buffer; // buffer became empty 2673 u_header_T *curhead = curbuf->b_u_curhead; 2674 2675 // Don't want autocommands using the undo structures here, they are 2676 // invalid till the end. 2677 block_autocmds(); 2678 2679 #ifdef U_DEBUG 2680 u_check(FALSE); 2681 #endif 2682 old_flags = curhead->uh_flags; 2683 new_flags = (curbuf->b_changed ? UH_CHANGED : 0) + 2684 ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0); 2685 setpcmark(); 2686 2687 /* 2688 * save marks before undo/redo 2689 */ 2690 mch_memmove(namedm, curbuf->b_namedm, sizeof(pos_T) * NMARKS); 2691 visualinfo = curbuf->b_visual; 2692 curbuf->b_op_start.lnum = curbuf->b_ml.ml_line_count; 2693 curbuf->b_op_start.col = 0; 2694 curbuf->b_op_end.lnum = 0; 2695 curbuf->b_op_end.col = 0; 2696 2697 for (uep = curhead->uh_entry; uep != NULL; uep = nuep) 2698 { 2699 top = uep->ue_top; 2700 bot = uep->ue_bot; 2701 if (bot == 0) 2702 bot = curbuf->b_ml.ml_line_count + 1; 2703 if (top > curbuf->b_ml.ml_line_count || top >= bot 2704 || bot > curbuf->b_ml.ml_line_count + 1) 2705 { 2706 unblock_autocmds(); 2707 iemsg(_("E438: u_undo: line numbers wrong")); 2708 changed(); // don't want UNCHANGED now 2709 return; 2710 } 2711 2712 oldsize = bot - top - 1; // number of lines before undo 2713 newsize = uep->ue_size; // number of lines after undo 2714 2715 // Decide about the cursor position, depending on what text changed. 2716 // Don't set it yet, it may be invalid if lines are going to be added. 2717 if (top < newlnum) 2718 { 2719 // If the saved cursor is somewhere in this undo block, move it to 2720 // the remembered position. Makes "gwap" put the cursor back 2721 // where it was. 2722 lnum = curhead->uh_cursor.lnum; 2723 if (lnum >= top && lnum <= top + newsize + 1) 2724 { 2725 new_curpos = curhead->uh_cursor; 2726 newlnum = new_curpos.lnum - 1; 2727 } 2728 else 2729 { 2730 // Use the first line that actually changed. Avoids that 2731 // undoing auto-formatting puts the cursor in the previous 2732 // line. 2733 for (i = 0; i < newsize && i < oldsize; ++i) 2734 { 2735 char_u *p = ml_get(top + 1 + i); 2736 2737 if (curbuf->b_ml.ml_line_len != uep->ue_array[i].ul_len 2738 || memcmp(uep->ue_array[i].ul_line, p, 2739 curbuf->b_ml.ml_line_len) != 0) 2740 break; 2741 } 2742 if (i == newsize && newlnum == MAXLNUM && uep->ue_next == NULL) 2743 { 2744 newlnum = top; 2745 new_curpos.lnum = newlnum + 1; 2746 } 2747 else if (i < newsize) 2748 { 2749 newlnum = top + i; 2750 new_curpos.lnum = newlnum + 1; 2751 } 2752 } 2753 } 2754 2755 empty_buffer = FALSE; 2756 2757 /* 2758 * Delete the lines between top and bot and save them in newarray. 2759 */ 2760 if (oldsize > 0) 2761 { 2762 if ((newarray = U_ALLOC_LINE(sizeof(undoline_T) * oldsize)) == NULL) 2763 { 2764 do_outofmem_msg((long_u)(sizeof(undoline_T) * oldsize)); 2765 2766 // We have messed up the entry list, repair is impossible. 2767 // we have to free the rest of the list. 2768 while (uep != NULL) 2769 { 2770 nuep = uep->ue_next; 2771 u_freeentry(uep, uep->ue_size); 2772 uep = nuep; 2773 } 2774 break; 2775 } 2776 // delete backwards, it goes faster in most cases 2777 for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum) 2778 { 2779 // what can we do when we run out of memory? 2780 if (u_save_line(&newarray[i], lnum) == FAIL) 2781 do_outofmem_msg((long_u)0); 2782 // remember we deleted the last line in the buffer, and a 2783 // dummy empty line will be inserted 2784 if (curbuf->b_ml.ml_line_count == 1) 2785 empty_buffer = TRUE; 2786 ml_delete_flags(lnum, ML_DEL_UNDO); 2787 } 2788 } 2789 else 2790 newarray = NULL; 2791 2792 // make sure the cursor is on a valid line after the deletions 2793 check_cursor_lnum(); 2794 2795 /* 2796 * Insert the lines in u_array between top and bot. 2797 */ 2798 if (newsize) 2799 { 2800 for (lnum = top, i = 0; i < newsize; ++i, ++lnum) 2801 { 2802 // If the file is empty, there is an empty line 1 that we 2803 // should get rid of, by replacing it with the new line. 2804 if (empty_buffer && lnum == 0) 2805 ml_replace_len((linenr_T)1, uep->ue_array[i].ul_line, 2806 uep->ue_array[i].ul_len, TRUE, TRUE); 2807 else 2808 ml_append_flags(lnum, uep->ue_array[i].ul_line, 2809 (colnr_T)uep->ue_array[i].ul_len, ML_APPEND_UNDO); 2810 vim_free(uep->ue_array[i].ul_line); 2811 } 2812 vim_free((char_u *)uep->ue_array); 2813 } 2814 2815 // adjust marks 2816 if (oldsize != newsize) 2817 { 2818 mark_adjust(top + 1, top + oldsize, (long)MAXLNUM, 2819 (long)newsize - (long)oldsize); 2820 if (curbuf->b_op_start.lnum > top + oldsize) 2821 curbuf->b_op_start.lnum += newsize - oldsize; 2822 if (curbuf->b_op_end.lnum > top + oldsize) 2823 curbuf->b_op_end.lnum += newsize - oldsize; 2824 } 2825 2826 changed_lines(top + 1, 0, bot, newsize - oldsize); 2827 2828 // set '[ and '] mark 2829 if (top + 1 < curbuf->b_op_start.lnum) 2830 curbuf->b_op_start.lnum = top + 1; 2831 if (newsize == 0 && top + 1 > curbuf->b_op_end.lnum) 2832 curbuf->b_op_end.lnum = top + 1; 2833 else if (top + newsize > curbuf->b_op_end.lnum) 2834 curbuf->b_op_end.lnum = top + newsize; 2835 2836 u_newcount += newsize; 2837 u_oldcount += oldsize; 2838 uep->ue_size = oldsize; 2839 uep->ue_array = newarray; 2840 uep->ue_bot = top + newsize + 1; 2841 2842 /* 2843 * insert this entry in front of the new entry list 2844 */ 2845 nuep = uep->ue_next; 2846 uep->ue_next = newlist; 2847 newlist = uep; 2848 } 2849 2850 // Set the cursor to the desired position. Check that the line is valid. 2851 curwin->w_cursor = new_curpos; 2852 check_cursor_lnum(); 2853 2854 curhead->uh_entry = newlist; 2855 curhead->uh_flags = new_flags; 2856 if ((old_flags & UH_EMPTYBUF) && BUFEMPTY()) 2857 curbuf->b_ml.ml_flags |= ML_EMPTY; 2858 if (old_flags & UH_CHANGED) 2859 changed(); 2860 else 2861 #ifdef FEAT_NETBEANS_INTG 2862 // per netbeans undo rules, keep it as modified 2863 if (!isNetbeansModified(curbuf)) 2864 #endif 2865 unchanged(curbuf, FALSE, TRUE); 2866 2867 /* 2868 * restore marks from before undo/redo 2869 */ 2870 for (i = 0; i < NMARKS; ++i) 2871 { 2872 if (curhead->uh_namedm[i].lnum != 0) 2873 curbuf->b_namedm[i] = curhead->uh_namedm[i]; 2874 if (namedm[i].lnum != 0) 2875 curhead->uh_namedm[i] = namedm[i]; 2876 else 2877 curhead->uh_namedm[i].lnum = 0; 2878 } 2879 if (curhead->uh_visual.vi_start.lnum != 0) 2880 { 2881 curbuf->b_visual = curhead->uh_visual; 2882 curhead->uh_visual = visualinfo; 2883 } 2884 2885 /* 2886 * If the cursor is only off by one line, put it at the same position as 2887 * before starting the change (for the "o" command). 2888 * Otherwise the cursor should go to the first undone line. 2889 */ 2890 if (curhead->uh_cursor.lnum + 1 == curwin->w_cursor.lnum 2891 && curwin->w_cursor.lnum > 1) 2892 --curwin->w_cursor.lnum; 2893 if (curwin->w_cursor.lnum <= curbuf->b_ml.ml_line_count) 2894 { 2895 if (curhead->uh_cursor.lnum == curwin->w_cursor.lnum) 2896 { 2897 curwin->w_cursor.col = curhead->uh_cursor.col; 2898 if (virtual_active() && curhead->uh_cursor_vcol >= 0) 2899 coladvance((colnr_T)curhead->uh_cursor_vcol); 2900 else 2901 curwin->w_cursor.coladd = 0; 2902 } 2903 else 2904 beginline(BL_SOL | BL_FIX); 2905 } 2906 else 2907 { 2908 // We get here with the current cursor line being past the end (eg 2909 // after adding lines at the end of the file, and then undoing it). 2910 // check_cursor() will move the cursor to the last line. Move it to 2911 // the first column here. 2912 curwin->w_cursor.col = 0; 2913 curwin->w_cursor.coladd = 0; 2914 } 2915 2916 // Make sure the cursor is on an existing line and column. 2917 check_cursor(); 2918 2919 // Remember where we are for "g-" and ":earlier 10s". 2920 curbuf->b_u_seq_cur = curhead->uh_seq; 2921 if (undo) 2922 { 2923 // We are below the previous undo. However, to make ":earlier 1s" 2924 // work we compute this as being just above the just undone change. 2925 if (curhead->uh_next.ptr != NULL) 2926 curbuf->b_u_seq_cur = curhead->uh_next.ptr->uh_seq; 2927 else 2928 curbuf->b_u_seq_cur = 0; 2929 } 2930 2931 // Remember where we are for ":earlier 1f" and ":later 1f". 2932 if (curhead->uh_save_nr != 0) 2933 { 2934 if (undo) 2935 curbuf->b_u_save_nr_cur = curhead->uh_save_nr - 1; 2936 else 2937 curbuf->b_u_save_nr_cur = curhead->uh_save_nr; 2938 } 2939 2940 // The timestamp can be the same for multiple changes, just use the one of 2941 // the undone/redone change. 2942 curbuf->b_u_time_cur = curhead->uh_time; 2943 2944 unblock_autocmds(); 2945 #ifdef U_DEBUG 2946 u_check(FALSE); 2947 #endif 2948 } 2949 2950 /* 2951 * If we deleted or added lines, report the number of less/more lines. 2952 * Otherwise, report the number of changes (this may be incorrect 2953 * in some cases, but it's better than nothing). 2954 */ 2955 static void 2956 u_undo_end( 2957 int did_undo, // just did an undo 2958 int absolute) // used ":undo N" 2959 { 2960 char *msgstr; 2961 u_header_T *uhp; 2962 char_u msgbuf[80]; 2963 2964 #ifdef FEAT_FOLDING 2965 if ((fdo_flags & FDO_UNDO) && KeyTyped) 2966 foldOpenCursor(); 2967 #endif 2968 2969 if (global_busy // no messages now, wait until global is finished 2970 || !messaging()) // 'lazyredraw' set, don't do messages now 2971 return; 2972 2973 if (curbuf->b_ml.ml_flags & ML_EMPTY) 2974 --u_newcount; 2975 2976 u_oldcount -= u_newcount; 2977 if (u_oldcount == -1) 2978 msgstr = N_("more line"); 2979 else if (u_oldcount < 0) 2980 msgstr = N_("more lines"); 2981 else if (u_oldcount == 1) 2982 msgstr = N_("line less"); 2983 else if (u_oldcount > 1) 2984 msgstr = N_("fewer lines"); 2985 else 2986 { 2987 u_oldcount = u_newcount; 2988 if (u_newcount == 1) 2989 msgstr = N_("change"); 2990 else 2991 msgstr = N_("changes"); 2992 } 2993 2994 if (curbuf->b_u_curhead != NULL) 2995 { 2996 // For ":undo N" we prefer a "after #N" message. 2997 if (absolute && curbuf->b_u_curhead->uh_next.ptr != NULL) 2998 { 2999 uhp = curbuf->b_u_curhead->uh_next.ptr; 3000 did_undo = FALSE; 3001 } 3002 else if (did_undo) 3003 uhp = curbuf->b_u_curhead; 3004 else 3005 uhp = curbuf->b_u_curhead->uh_next.ptr; 3006 } 3007 else 3008 uhp = curbuf->b_u_newhead; 3009 3010 if (uhp == NULL) 3011 *msgbuf = NUL; 3012 else 3013 add_time(msgbuf, sizeof(msgbuf), uhp->uh_time); 3014 3015 #ifdef FEAT_CONCEAL 3016 { 3017 win_T *wp; 3018 3019 FOR_ALL_WINDOWS(wp) 3020 { 3021 if (wp->w_buffer == curbuf && wp->w_p_cole > 0) 3022 redraw_win_later(wp, NOT_VALID); 3023 } 3024 } 3025 #endif 3026 3027 smsg_attr_keep(0, _("%ld %s; %s #%ld %s"), 3028 u_oldcount < 0 ? -u_oldcount : u_oldcount, 3029 _(msgstr), 3030 did_undo ? _("before") : _("after"), 3031 uhp == NULL ? 0L : uhp->uh_seq, 3032 msgbuf); 3033 } 3034 3035 /* 3036 * u_sync: stop adding to the current entry list 3037 */ 3038 void 3039 u_sync( 3040 int force) // Also sync when no_u_sync is set. 3041 { 3042 // Skip it when already synced or syncing is disabled. 3043 if (curbuf->b_u_synced || (!force && no_u_sync > 0)) 3044 return; 3045 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) 3046 if (p_imst == IM_ON_THE_SPOT && im_is_preediting()) 3047 return; // XIM is busy, don't break an undo sequence 3048 #endif 3049 if (get_undolevel() < 0) 3050 curbuf->b_u_synced = TRUE; // no entries, nothing to do 3051 else 3052 { 3053 u_getbot(); // compute ue_bot of previous u_save 3054 curbuf->b_u_curhead = NULL; 3055 } 3056 } 3057 3058 /* 3059 * ":undolist": List the leafs of the undo tree 3060 */ 3061 void 3062 ex_undolist(exarg_T *eap UNUSED) 3063 { 3064 garray_T ga; 3065 u_header_T *uhp; 3066 int mark; 3067 int nomark; 3068 int changes = 1; 3069 int i; 3070 3071 /* 3072 * 1: walk the tree to find all leafs, put the info in "ga". 3073 * 2: sort the lines 3074 * 3: display the list 3075 */ 3076 mark = ++lastmark; 3077 nomark = ++lastmark; 3078 ga_init2(&ga, (int)sizeof(char *), 20); 3079 3080 uhp = curbuf->b_u_oldhead; 3081 while (uhp != NULL) 3082 { 3083 if (uhp->uh_prev.ptr == NULL && uhp->uh_walk != nomark 3084 && uhp->uh_walk != mark) 3085 { 3086 if (ga_grow(&ga, 1) == FAIL) 3087 break; 3088 vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7d ", 3089 uhp->uh_seq, changes); 3090 add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff), 3091 uhp->uh_time); 3092 if (uhp->uh_save_nr > 0) 3093 { 3094 while (STRLEN(IObuff) < 33) 3095 STRCAT(IObuff, " "); 3096 vim_snprintf_add((char *)IObuff, IOSIZE, 3097 " %3ld", uhp->uh_save_nr); 3098 } 3099 ((char_u **)(ga.ga_data))[ga.ga_len++] = vim_strsave(IObuff); 3100 } 3101 3102 uhp->uh_walk = mark; 3103 3104 // go down in the tree if we haven't been there 3105 if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark 3106 && uhp->uh_prev.ptr->uh_walk != mark) 3107 { 3108 uhp = uhp->uh_prev.ptr; 3109 ++changes; 3110 } 3111 3112 // go to alternate branch if we haven't been there 3113 else if (uhp->uh_alt_next.ptr != NULL 3114 && uhp->uh_alt_next.ptr->uh_walk != nomark 3115 && uhp->uh_alt_next.ptr->uh_walk != mark) 3116 uhp = uhp->uh_alt_next.ptr; 3117 3118 // go up in the tree if we haven't been there and we are at the 3119 // start of alternate branches 3120 else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL 3121 && uhp->uh_next.ptr->uh_walk != nomark 3122 && uhp->uh_next.ptr->uh_walk != mark) 3123 { 3124 uhp = uhp->uh_next.ptr; 3125 --changes; 3126 } 3127 3128 else 3129 { 3130 // need to backtrack; mark this node as done 3131 uhp->uh_walk = nomark; 3132 if (uhp->uh_alt_prev.ptr != NULL) 3133 uhp = uhp->uh_alt_prev.ptr; 3134 else 3135 { 3136 uhp = uhp->uh_next.ptr; 3137 --changes; 3138 } 3139 } 3140 } 3141 3142 if (ga.ga_len == 0) 3143 msg(_("Nothing to undo")); 3144 else 3145 { 3146 sort_strings((char_u **)ga.ga_data, ga.ga_len); 3147 3148 msg_start(); 3149 msg_puts_attr(_("number changes when saved"), 3150 HL_ATTR(HLF_T)); 3151 for (i = 0; i < ga.ga_len && !got_int; ++i) 3152 { 3153 msg_putchar('\n'); 3154 if (got_int) 3155 break; 3156 msg_puts(((char **)ga.ga_data)[i]); 3157 } 3158 msg_end(); 3159 3160 ga_clear_strings(&ga); 3161 } 3162 } 3163 3164 /* 3165 * ":undojoin": continue adding to the last entry list 3166 */ 3167 void 3168 ex_undojoin(exarg_T *eap UNUSED) 3169 { 3170 if (curbuf->b_u_newhead == NULL) 3171 return; // nothing changed before 3172 if (curbuf->b_u_curhead != NULL) 3173 { 3174 emsg(_("E790: undojoin is not allowed after undo")); 3175 return; 3176 } 3177 if (!curbuf->b_u_synced) 3178 return; // already unsynced 3179 if (get_undolevel() < 0) 3180 return; // no entries, nothing to do 3181 else 3182 // Append next change to the last entry 3183 curbuf->b_u_synced = FALSE; 3184 } 3185 3186 /* 3187 * Called after writing or reloading the file and setting b_changed to FALSE. 3188 * Now an undo means that the buffer is modified. 3189 */ 3190 void 3191 u_unchanged(buf_T *buf) 3192 { 3193 u_unch_branch(buf->b_u_oldhead); 3194 buf->b_did_warn = FALSE; 3195 } 3196 3197 /* 3198 * After reloading a buffer which was saved for 'undoreload': Find the first 3199 * line that was changed and set the cursor there. 3200 */ 3201 void 3202 u_find_first_changed(void) 3203 { 3204 u_header_T *uhp = curbuf->b_u_newhead; 3205 u_entry_T *uep; 3206 linenr_T lnum; 3207 3208 if (curbuf->b_u_curhead != NULL || uhp == NULL) 3209 return; // undid something in an autocmd? 3210 3211 // Check that the last undo block was for the whole file. 3212 uep = uhp->uh_entry; 3213 if (uep->ue_top != 0 || uep->ue_bot != 0) 3214 return; 3215 3216 for (lnum = 1; lnum < curbuf->b_ml.ml_line_count 3217 && lnum <= uep->ue_size; ++lnum) 3218 { 3219 char_u *p = ml_get_buf(curbuf, lnum, FALSE); 3220 3221 if (uep->ue_array[lnum - 1].ul_len != curbuf->b_ml.ml_line_len 3222 || memcmp(p, uep->ue_array[lnum - 1].ul_line, uep->ue_array[lnum - 1].ul_len) != 0) 3223 { 3224 CLEAR_POS(&(uhp->uh_cursor)); 3225 uhp->uh_cursor.lnum = lnum; 3226 return; 3227 } 3228 } 3229 if (curbuf->b_ml.ml_line_count != uep->ue_size) 3230 { 3231 // lines added or deleted at the end, put the cursor there 3232 CLEAR_POS(&(uhp->uh_cursor)); 3233 uhp->uh_cursor.lnum = lnum; 3234 } 3235 } 3236 3237 /* 3238 * Increase the write count, store it in the last undo header, what would be 3239 * used for "u". 3240 */ 3241 void 3242 u_update_save_nr(buf_T *buf) 3243 { 3244 u_header_T *uhp; 3245 3246 ++buf->b_u_save_nr_last; 3247 buf->b_u_save_nr_cur = buf->b_u_save_nr_last; 3248 uhp = buf->b_u_curhead; 3249 if (uhp != NULL) 3250 uhp = uhp->uh_next.ptr; 3251 else 3252 uhp = buf->b_u_newhead; 3253 if (uhp != NULL) 3254 uhp->uh_save_nr = buf->b_u_save_nr_last; 3255 } 3256 3257 static void 3258 u_unch_branch(u_header_T *uhp) 3259 { 3260 u_header_T *uh; 3261 3262 for (uh = uhp; uh != NULL; uh = uh->uh_prev.ptr) 3263 { 3264 uh->uh_flags |= UH_CHANGED; 3265 if (uh->uh_alt_next.ptr != NULL) 3266 u_unch_branch(uh->uh_alt_next.ptr); // recursive 3267 } 3268 } 3269 3270 /* 3271 * Get pointer to last added entry. 3272 * If it's not valid, give an error message and return NULL. 3273 */ 3274 static u_entry_T * 3275 u_get_headentry(void) 3276 { 3277 if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL) 3278 { 3279 iemsg(_("E439: undo list corrupt")); 3280 return NULL; 3281 } 3282 return curbuf->b_u_newhead->uh_entry; 3283 } 3284 3285 /* 3286 * u_getbot(): compute the line number of the previous u_save 3287 * It is called only when b_u_synced is FALSE. 3288 */ 3289 static void 3290 u_getbot(void) 3291 { 3292 u_entry_T *uep; 3293 linenr_T extra; 3294 3295 uep = u_get_headentry(); // check for corrupt undo list 3296 if (uep == NULL) 3297 return; 3298 3299 uep = curbuf->b_u_newhead->uh_getbot_entry; 3300 if (uep != NULL) 3301 { 3302 /* 3303 * the new ue_bot is computed from the number of lines that has been 3304 * inserted (0 - deleted) since calling u_save. This is equal to the 3305 * old line count subtracted from the current line count. 3306 */ 3307 extra = curbuf->b_ml.ml_line_count - uep->ue_lcount; 3308 uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra; 3309 if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count) 3310 { 3311 iemsg(_("E440: undo line missing")); 3312 uep->ue_bot = uep->ue_top + 1; // assume all lines deleted, will 3313 // get all the old lines back 3314 // without deleting the current 3315 // ones 3316 } 3317 3318 curbuf->b_u_newhead->uh_getbot_entry = NULL; 3319 } 3320 3321 curbuf->b_u_synced = TRUE; 3322 } 3323 3324 /* 3325 * Free one header "uhp" and its entry list and adjust the pointers. 3326 */ 3327 static void 3328 u_freeheader( 3329 buf_T *buf, 3330 u_header_T *uhp, 3331 u_header_T **uhpp) // if not NULL reset when freeing this header 3332 { 3333 u_header_T *uhap; 3334 3335 // When there is an alternate redo list free that branch completely, 3336 // because we can never go there. 3337 if (uhp->uh_alt_next.ptr != NULL) 3338 u_freebranch(buf, uhp->uh_alt_next.ptr, uhpp); 3339 3340 if (uhp->uh_alt_prev.ptr != NULL) 3341 uhp->uh_alt_prev.ptr->uh_alt_next.ptr = NULL; 3342 3343 // Update the links in the list to remove the header. 3344 if (uhp->uh_next.ptr == NULL) 3345 buf->b_u_oldhead = uhp->uh_prev.ptr; 3346 else 3347 uhp->uh_next.ptr->uh_prev.ptr = uhp->uh_prev.ptr; 3348 3349 if (uhp->uh_prev.ptr == NULL) 3350 buf->b_u_newhead = uhp->uh_next.ptr; 3351 else 3352 for (uhap = uhp->uh_prev.ptr; uhap != NULL; 3353 uhap = uhap->uh_alt_next.ptr) 3354 uhap->uh_next.ptr = uhp->uh_next.ptr; 3355 3356 u_freeentries(buf, uhp, uhpp); 3357 } 3358 3359 /* 3360 * Free an alternate branch and any following alternate branches. 3361 */ 3362 static void 3363 u_freebranch( 3364 buf_T *buf, 3365 u_header_T *uhp, 3366 u_header_T **uhpp) // if not NULL reset when freeing this header 3367 { 3368 u_header_T *tofree, *next; 3369 3370 // If this is the top branch we may need to use u_freeheader() to update 3371 // all the pointers. 3372 if (uhp == buf->b_u_oldhead) 3373 { 3374 while (buf->b_u_oldhead != NULL) 3375 u_freeheader(buf, buf->b_u_oldhead, uhpp); 3376 return; 3377 } 3378 3379 if (uhp->uh_alt_prev.ptr != NULL) 3380 uhp->uh_alt_prev.ptr->uh_alt_next.ptr = NULL; 3381 3382 next = uhp; 3383 while (next != NULL) 3384 { 3385 tofree = next; 3386 if (tofree->uh_alt_next.ptr != NULL) 3387 u_freebranch(buf, tofree->uh_alt_next.ptr, uhpp); // recursive 3388 next = tofree->uh_prev.ptr; 3389 u_freeentries(buf, tofree, uhpp); 3390 } 3391 } 3392 3393 /* 3394 * Free all the undo entries for one header and the header itself. 3395 * This means that "uhp" is invalid when returning. 3396 */ 3397 static void 3398 u_freeentries( 3399 buf_T *buf, 3400 u_header_T *uhp, 3401 u_header_T **uhpp) // if not NULL reset when freeing this header 3402 { 3403 u_entry_T *uep, *nuep; 3404 3405 // Check for pointers to the header that become invalid now. 3406 if (buf->b_u_curhead == uhp) 3407 buf->b_u_curhead = NULL; 3408 if (buf->b_u_newhead == uhp) 3409 buf->b_u_newhead = NULL; // freeing the newest entry 3410 if (uhpp != NULL && uhp == *uhpp) 3411 *uhpp = NULL; 3412 3413 for (uep = uhp->uh_entry; uep != NULL; uep = nuep) 3414 { 3415 nuep = uep->ue_next; 3416 u_freeentry(uep, uep->ue_size); 3417 } 3418 3419 #ifdef U_DEBUG 3420 uhp->uh_magic = 0; 3421 #endif 3422 vim_free((char_u *)uhp); 3423 --buf->b_u_numhead; 3424 } 3425 3426 /* 3427 * free entry 'uep' and 'n' lines in uep->ue_array[] 3428 */ 3429 static void 3430 u_freeentry(u_entry_T *uep, long n) 3431 { 3432 while (n > 0) 3433 vim_free(uep->ue_array[--n].ul_line); 3434 vim_free((char_u *)uep->ue_array); 3435 #ifdef U_DEBUG 3436 uep->ue_magic = 0; 3437 #endif 3438 vim_free((char_u *)uep); 3439 } 3440 3441 /* 3442 * invalidate the undo buffer; called when storage has already been released 3443 */ 3444 void 3445 u_clearall(buf_T *buf) 3446 { 3447 buf->b_u_newhead = buf->b_u_oldhead = buf->b_u_curhead = NULL; 3448 buf->b_u_synced = TRUE; 3449 buf->b_u_numhead = 0; 3450 buf->b_u_line_ptr.ul_line = NULL; 3451 buf->b_u_line_ptr.ul_len = 0; 3452 buf->b_u_line_lnum = 0; 3453 } 3454 3455 /* 3456 * Save the line "lnum" for the "U" command. 3457 */ 3458 static void 3459 u_saveline(linenr_T lnum) 3460 { 3461 if (lnum == curbuf->b_u_line_lnum) // line is already saved 3462 return; 3463 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) // should never happen 3464 return; 3465 u_clearline(); 3466 curbuf->b_u_line_lnum = lnum; 3467 if (curwin->w_cursor.lnum == lnum) 3468 curbuf->b_u_line_colnr = curwin->w_cursor.col; 3469 else 3470 curbuf->b_u_line_colnr = 0; 3471 if (u_save_line(&curbuf->b_u_line_ptr, lnum) == FAIL) 3472 do_outofmem_msg((long_u)0); 3473 } 3474 3475 /* 3476 * clear the line saved for the "U" command 3477 * (this is used externally for crossing a line while in insert mode) 3478 */ 3479 void 3480 u_clearline(void) 3481 { 3482 if (curbuf->b_u_line_ptr.ul_line != NULL) 3483 { 3484 VIM_CLEAR(curbuf->b_u_line_ptr.ul_line); 3485 curbuf->b_u_line_ptr.ul_len = 0; 3486 curbuf->b_u_line_lnum = 0; 3487 } 3488 } 3489 3490 /* 3491 * Implementation of the "U" command. 3492 * Differentiation from vi: "U" can be undone with the next "U". 3493 * We also allow the cursor to be in another line. 3494 * Careful: may trigger autocommands that reload the buffer. 3495 */ 3496 void 3497 u_undoline(void) 3498 { 3499 colnr_T t; 3500 undoline_T oldp; 3501 3502 if (undo_off) 3503 return; 3504 3505 if (curbuf->b_u_line_ptr.ul_line == NULL 3506 || curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count) 3507 { 3508 beep_flush(); 3509 return; 3510 } 3511 3512 // first save the line for the 'u' command 3513 if (u_savecommon(curbuf->b_u_line_lnum - 1, 3514 curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL) 3515 return; 3516 if (u_save_line(&oldp, curbuf->b_u_line_lnum) == FAIL) 3517 { 3518 do_outofmem_msg((long_u)0); 3519 return; 3520 } 3521 ml_replace_len(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr.ul_line, curbuf->b_u_line_ptr.ul_len, TRUE, FALSE); 3522 changed_bytes(curbuf->b_u_line_lnum, 0); 3523 curbuf->b_u_line_ptr = oldp; 3524 3525 t = curbuf->b_u_line_colnr; 3526 if (curwin->w_cursor.lnum == curbuf->b_u_line_lnum) 3527 curbuf->b_u_line_colnr = curwin->w_cursor.col; 3528 curwin->w_cursor.col = t; 3529 curwin->w_cursor.lnum = curbuf->b_u_line_lnum; 3530 check_cursor_col(); 3531 } 3532 3533 /* 3534 * Free all allocated memory blocks for the buffer 'buf'. 3535 */ 3536 void 3537 u_blockfree(buf_T *buf) 3538 { 3539 while (buf->b_u_oldhead != NULL) 3540 u_freeheader(buf, buf->b_u_oldhead, NULL); 3541 vim_free(buf->b_u_line_ptr.ul_line); 3542 } 3543 3544 /* 3545 * Check if the 'modified' flag is set, or 'ff' has changed (only need to 3546 * check the first character, because it can only be "dos", "unix" or "mac"). 3547 * "nofile" and "scratch" type buffers are considered to always be unchanged. 3548 * Also considers a buffer changed when a terminal window contains a running 3549 * job. 3550 */ 3551 int 3552 bufIsChanged(buf_T *buf) 3553 { 3554 #ifdef FEAT_TERMINAL 3555 if (term_job_running(buf->b_term)) 3556 return TRUE; 3557 #endif 3558 return bufIsChangedNotTerm(buf); 3559 } 3560 3561 /* 3562 * Return TRUE if any buffer has changes. Also buffers that are not written. 3563 */ 3564 int 3565 anyBufIsChanged(void) 3566 { 3567 buf_T *buf; 3568 3569 FOR_ALL_BUFFERS(buf) 3570 if (bufIsChanged(buf)) 3571 return TRUE; 3572 return FALSE; 3573 } 3574 3575 /* 3576 * Like bufIsChanged() but ignoring a terminal window. 3577 */ 3578 int 3579 bufIsChangedNotTerm(buf_T *buf) 3580 { 3581 // In a "prompt" buffer we do respect 'modified', so that we can control 3582 // closing the window by setting or resetting that option. 3583 return (!bt_dontwrite(buf) || bt_prompt(buf)) 3584 && (buf->b_changed || file_ff_differs(buf, TRUE)); 3585 } 3586 3587 int 3588 curbufIsChanged(void) 3589 { 3590 return bufIsChanged(curbuf); 3591 } 3592 3593 #if defined(FEAT_EVAL) || defined(PROTO) 3594 3595 /* 3596 * For undotree(): Append the list of undo blocks at "first_uhp" to "list". 3597 * Recursive. 3598 */ 3599 static void 3600 u_eval_tree(u_header_T *first_uhp, list_T *list) 3601 { 3602 u_header_T *uhp = first_uhp; 3603 dict_T *dict; 3604 3605 while (uhp != NULL) 3606 { 3607 dict = dict_alloc(); 3608 if (dict == NULL) 3609 return; 3610 dict_add_number(dict, "seq", uhp->uh_seq); 3611 dict_add_number(dict, "time", (long)uhp->uh_time); 3612 if (uhp == curbuf->b_u_newhead) 3613 dict_add_number(dict, "newhead", 1); 3614 if (uhp == curbuf->b_u_curhead) 3615 dict_add_number(dict, "curhead", 1); 3616 if (uhp->uh_save_nr > 0) 3617 dict_add_number(dict, "save", uhp->uh_save_nr); 3618 3619 if (uhp->uh_alt_next.ptr != NULL) 3620 { 3621 list_T *alt_list = list_alloc(); 3622 3623 if (alt_list != NULL) 3624 { 3625 // Recursive call to add alternate undo tree. 3626 u_eval_tree(uhp->uh_alt_next.ptr, alt_list); 3627 dict_add_list(dict, "alt", alt_list); 3628 } 3629 } 3630 3631 list_append_dict(list, dict); 3632 uhp = uhp->uh_prev.ptr; 3633 } 3634 } 3635 3636 /* 3637 * "undofile(name)" function 3638 */ 3639 void 3640 f_undofile(typval_T *argvars UNUSED, typval_T *rettv) 3641 { 3642 rettv->v_type = VAR_STRING; 3643 #ifdef FEAT_PERSISTENT_UNDO 3644 { 3645 char_u *fname = tv_get_string(&argvars[0]); 3646 3647 if (*fname == NUL) 3648 { 3649 // If there is no file name there will be no undo file. 3650 rettv->vval.v_string = NULL; 3651 } 3652 else 3653 { 3654 char_u *ffname = FullName_save(fname, TRUE); 3655 3656 if (ffname != NULL) 3657 rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE); 3658 vim_free(ffname); 3659 } 3660 } 3661 #else 3662 rettv->vval.v_string = NULL; 3663 #endif 3664 } 3665 3666 /* 3667 * "undotree()" function 3668 */ 3669 void 3670 f_undotree(typval_T *argvars UNUSED, typval_T *rettv) 3671 { 3672 if (rettv_dict_alloc(rettv) == OK) 3673 { 3674 dict_T *dict = rettv->vval.v_dict; 3675 list_T *list; 3676 3677 dict_add_number(dict, "synced", (long)curbuf->b_u_synced); 3678 dict_add_number(dict, "seq_last", curbuf->b_u_seq_last); 3679 dict_add_number(dict, "save_last", (long)curbuf->b_u_save_nr_last); 3680 dict_add_number(dict, "seq_cur", curbuf->b_u_seq_cur); 3681 dict_add_number(dict, "time_cur", (long)curbuf->b_u_time_cur); 3682 dict_add_number(dict, "save_cur", (long)curbuf->b_u_save_nr_cur); 3683 3684 list = list_alloc(); 3685 if (list != NULL) 3686 { 3687 u_eval_tree(curbuf->b_u_oldhead, list); 3688 dict_add_list(dict, "entries", list); 3689 } 3690 } 3691 } 3692 3693 #endif 3694