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