comparison src/undo.c @ 13134:c4b5ad2b3596 v8.0.1441

patch 8.0.1441: using ":undo 0" leaves undo in wrong state commit https://github.com/vim/vim/commit/ce46d934af35d0f774be7f996001db03cf0b894a Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jan 30 22:46:06 2018 +0100 patch 8.0.1441: using ":undo 0" leaves undo in wrong state Problem: Using ":undo 0" leaves undo in wrong state. Solution: Instead of searching for state 1 and go above, just use the start. (Ozaki Kiichi, closes #2595)
author Christian Brabandt <cb@256bit.org>
date Tue, 30 Jan 2018 23:00:06 +0100
parents 8d5b451d7bab
children 0f906f414c69
comparison
equal deleted inserted replaced
13133:31a78144e47f 13134:c4b5ad2b3596
2270 long target; 2270 long target;
2271 long closest; 2271 long closest;
2272 long closest_start; 2272 long closest_start;
2273 long closest_seq = 0; 2273 long closest_seq = 0;
2274 long val; 2274 long val;
2275 u_header_T *uhp; 2275 u_header_T *uhp = NULL;
2276 u_header_T *last; 2276 u_header_T *last;
2277 int mark; 2277 int mark;
2278 int nomark; 2278 int nomark;
2279 int round; 2279 int round;
2280 int dosec = sec; 2280 int dosec = sec;
2293 2293
2294 /* "target" is the node below which we want to be. 2294 /* "target" is the node below which we want to be.
2295 * Init "closest" to a value we can't reach. */ 2295 * Init "closest" to a value we can't reach. */
2296 if (absolute) 2296 if (absolute)
2297 { 2297 {
2298 if (step == 0) 2298 target = step;
2299 {
2300 /* target 0 does not exist, got to 1 and above it. */
2301 target = 1;
2302 above = TRUE;
2303 }
2304 else
2305 target = step;
2306 closest = -1; 2299 closest = -1;
2307 } 2300 }
2308 else 2301 else
2309 { 2302 {
2310 if (dosec) 2303 if (dosec)
2367 } 2360 }
2368 } 2361 }
2369 closest_start = closest; 2362 closest_start = closest;
2370 closest_seq = curbuf->b_u_seq_cur; 2363 closest_seq = curbuf->b_u_seq_cur;
2371 2364
2365 /* When "target" is 0; Back to origin. */
2366 if (target == 0)
2367 goto found;
2368
2372 /* 2369 /*
2373 * May do this twice: 2370 * May do this twice:
2374 * 1. Search for "target", update "closest" to the best match found. 2371 * 1. Search for "target", update "closest" to the best match found.
2375 * 2. If "target" not found search for "closest". 2372 * 2. If "target" not found search for "closest".
2376 * 2373 *
2492 dofile = FALSE; 2489 dofile = FALSE;
2493 if (step < 0) 2490 if (step < 0)
2494 above = TRUE; /* stop above the header */ 2491 above = TRUE; /* stop above the header */
2495 } 2492 }
2496 2493
2494 found:
2497 /* If we found it: Follow the path to go to where we want to be. */ 2495 /* If we found it: Follow the path to go to where we want to be. */
2498 if (uhp != NULL) 2496 if (uhp != NULL || target == 0)
2499 { 2497 {
2500 /* 2498 /*
2501 * First go up the tree as much as needed. 2499 * First go up the tree as much as needed.
2502 */ 2500 */
2503 while (!got_int) 2501 while (!got_int)
2508 uhp = curbuf->b_u_curhead; 2506 uhp = curbuf->b_u_curhead;
2509 if (uhp == NULL) 2507 if (uhp == NULL)
2510 uhp = curbuf->b_u_newhead; 2508 uhp = curbuf->b_u_newhead;
2511 else 2509 else
2512 uhp = uhp->uh_next.ptr; 2510 uhp = uhp->uh_next.ptr;
2513 if (uhp == NULL || uhp->uh_walk != mark 2511 if (uhp == NULL || (target > 0 && uhp->uh_walk != mark)
2514 || (uhp->uh_seq == target && !above)) 2512 || (uhp->uh_seq == target && !above))
2515 break; 2513 break;
2516 curbuf->b_u_curhead = uhp; 2514 curbuf->b_u_curhead = uhp;
2517 u_undoredo(TRUE); 2515 u_undoredo(TRUE);
2518 uhp->uh_walk = nomark; /* don't go back down here */ 2516 if (target > 0)
2519 } 2517 uhp->uh_walk = nomark; /* don't go back down here */
2520 2518 }
2521 /* 2519
2522 * And now go down the tree (redo), branching off where needed. 2520 /* When back to origin, redo is not needed. */
2523 */ 2521 if (target > 0)
2524 while (!got_int) 2522 {
2525 { 2523 /*
2526 /* Do the change warning now, for the same reason as above. */ 2524 * And now go down the tree (redo), branching off where needed.
2527 change_warning(0); 2525 */
2528 2526 while (!got_int)
2529 uhp = curbuf->b_u_curhead; 2527 {
2530 if (uhp == NULL) 2528 /* Do the change warning now, for the same reason as above. */
2531 break; 2529 change_warning(0);
2532 2530
2533 /* Go back to the first branch with a mark. */ 2531 uhp = curbuf->b_u_curhead;
2534 while (uhp->uh_alt_prev.ptr != NULL 2532 if (uhp == NULL)
2533 break;
2534
2535 /* Go back to the first branch with a mark. */
2536 while (uhp->uh_alt_prev.ptr != NULL
2535 && uhp->uh_alt_prev.ptr->uh_walk == mark) 2537 && uhp->uh_alt_prev.ptr->uh_walk == mark)
2536 uhp = uhp->uh_alt_prev.ptr; 2538 uhp = uhp->uh_alt_prev.ptr;
2537 2539
2538 /* Find the last branch with a mark, that's the one. */ 2540 /* Find the last branch with a mark, that's the one. */
2539 last = uhp; 2541 last = uhp;
2540 while (last->uh_alt_next.ptr != NULL 2542 while (last->uh_alt_next.ptr != NULL
2541 && last->uh_alt_next.ptr->uh_walk == mark) 2543 && last->uh_alt_next.ptr->uh_walk == mark)
2542 last = last->uh_alt_next.ptr; 2544 last = last->uh_alt_next.ptr;
2543 if (last != uhp) 2545 if (last != uhp)
2544 { 2546 {
2545 /* Make the used branch the first entry in the list of 2547 /* Make the used branch the first entry in the list of
2546 * alternatives to make "u" and CTRL-R take this branch. */ 2548 * alternatives to make "u" and CTRL-R take this branch. */
2547 while (uhp->uh_alt_prev.ptr != NULL) 2549 while (uhp->uh_alt_prev.ptr != NULL)
2548 uhp = uhp->uh_alt_prev.ptr; 2550 uhp = uhp->uh_alt_prev.ptr;
2549 if (last->uh_alt_next.ptr != NULL) 2551 if (last->uh_alt_next.ptr != NULL)
2550 last->uh_alt_next.ptr->uh_alt_prev.ptr = 2552 last->uh_alt_next.ptr->uh_alt_prev.ptr =
2551 last->uh_alt_prev.ptr; 2553 last->uh_alt_prev.ptr;
2552 last->uh_alt_prev.ptr->uh_alt_next.ptr = last->uh_alt_next.ptr; 2554 last->uh_alt_prev.ptr->uh_alt_next.ptr =
2553 last->uh_alt_prev.ptr = NULL; 2555 last->uh_alt_next.ptr;
2554 last->uh_alt_next.ptr = uhp; 2556 last->uh_alt_prev.ptr = NULL;
2555 uhp->uh_alt_prev.ptr = last; 2557 last->uh_alt_next.ptr = uhp;
2556 2558 uhp->uh_alt_prev.ptr = last;
2557 if (curbuf->b_u_oldhead == uhp) 2559
2558 curbuf->b_u_oldhead = last; 2560 if (curbuf->b_u_oldhead == uhp)
2559 uhp = last; 2561 curbuf->b_u_oldhead = last;
2560 if (uhp->uh_next.ptr != NULL) 2562 uhp = last;
2561 uhp->uh_next.ptr->uh_prev.ptr = uhp; 2563 if (uhp->uh_next.ptr != NULL)
2562 } 2564 uhp->uh_next.ptr->uh_prev.ptr = uhp;
2563 curbuf->b_u_curhead = uhp; 2565 }
2564 2566 curbuf->b_u_curhead = uhp;
2565 if (uhp->uh_walk != mark) 2567
2566 break; /* must have reached the target */ 2568 if (uhp->uh_walk != mark)
2567 2569 break; /* must have reached the target */
2568 /* Stop when going backwards in time and didn't find the exact 2570
2569 * header we were looking for. */ 2571 /* Stop when going backwards in time and didn't find the exact
2570 if (uhp->uh_seq == target && above) 2572 * header we were looking for. */
2571 { 2573 if (uhp->uh_seq == target && above)
2572 curbuf->b_u_seq_cur = target - 1; 2574 {
2573 break; 2575 curbuf->b_u_seq_cur = target - 1;
2574 } 2576 break;
2575 2577 }
2576 u_undoredo(FALSE); 2578
2577 2579 u_undoredo(FALSE);
2578 /* Advance "curhead" to below the header we last used. If it 2580
2579 * becomes NULL then we need to set "newhead" to this leaf. */ 2581 /* Advance "curhead" to below the header we last used. If it
2580 if (uhp->uh_prev.ptr == NULL) 2582 * becomes NULL then we need to set "newhead" to this leaf. */
2581 curbuf->b_u_newhead = uhp; 2583 if (uhp->uh_prev.ptr == NULL)
2582 curbuf->b_u_curhead = uhp->uh_prev.ptr; 2584 curbuf->b_u_newhead = uhp;
2583 did_undo = FALSE; 2585 curbuf->b_u_curhead = uhp->uh_prev.ptr;
2584 2586 did_undo = FALSE;
2585 if (uhp->uh_seq == target) /* found it! */ 2587
2586 break; 2588 if (uhp->uh_seq == target) /* found it! */
2587 2589 break;
2588 uhp = uhp->uh_prev.ptr; 2590
2589 if (uhp == NULL || uhp->uh_walk != mark) 2591 uhp = uhp->uh_prev.ptr;
2590 { 2592 if (uhp == NULL || uhp->uh_walk != mark)
2591 /* Need to redo more but can't find it... */ 2593 {
2592 internal_error("undo_time()"); 2594 /* Need to redo more but can't find it... */
2593 break; 2595 internal_error("undo_time()");
2596 break;
2597 }
2594 } 2598 }
2595 } 2599 }
2596 } 2600 }
2597 u_undo_end(did_undo, absolute); 2601 u_undo_end(did_undo, absolute);
2598 } 2602 }