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