Mercurial > vim
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 } |