Patch 8.0.1441
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)
Files: src/undo.c, src/testdir/test_undo.vim
*** ../vim-8.0.1440/src/undo.c 2017-12-09 19:51:44.633128944 +0100
--- src/undo.c 2018-01-30 22:40:05.496107324 +0100
***************
*** 2272,2278 ****
long closest_start;
long closest_seq = 0;
long val;
! u_header_T *uhp;
u_header_T *last;
int mark;
int nomark;
--- 2272,2278 ----
long closest_start;
long closest_seq = 0;
long val;
! u_header_T *uhp = NULL;
u_header_T *last;
int mark;
int nomark;
***************
*** 2295,2308 ****
* Init "closest" to a value we can't reach. */
if (absolute)
{
! if (step == 0)
! {
! /* target 0 does not exist, got to 1 and above it. */
! target = 1;
! above = TRUE;
! }
! else
! target = step;
closest = -1;
}
else
--- 2295,2301 ----
* Init "closest" to a value we can't reach. */
if (absolute)
{
! target = step;
closest = -1;
}
else
***************
*** 2369,2374 ****
--- 2362,2371 ----
closest_start = closest;
closest_seq = curbuf->b_u_seq_cur;
+ /* When "target" is 0; Back to origin. */
+ if (target == 0)
+ goto found;
+
/*
* May do this twice:
* 1. Search for "target", update "closest" to the best match found.
***************
*** 2494,2501 ****
above = TRUE; /* stop above the header */
}
/* If we found it: Follow the path to go to where we want to be. */
! if (uhp != NULL)
{
/*
* First go up the tree as much as needed.
--- 2491,2499 ----
above = TRUE; /* stop above the header */
}
+ found:
/* If we found it: Follow the path to go to where we want to be. */
! if (uhp != NULL || target == 0)
{
/*
* First go up the tree as much as needed.
***************
*** 2510,2596 ****
uhp = curbuf->b_u_newhead;
else
uhp = uhp->uh_next.ptr;
! if (uhp == NULL || uhp->uh_walk != mark
|| (uhp->uh_seq == target && !above))
break;
curbuf->b_u_curhead = uhp;
u_undoredo(TRUE);
! uhp->uh_walk = nomark; /* don't go back down here */
}
! /*
! * And now go down the tree (redo), branching off where needed.
! */
! while (!got_int)
{
! /* Do the change warning now, for the same reason as above. */
! change_warning(0);
! uhp = curbuf->b_u_curhead;
! if (uhp == NULL)
! break;
! /* Go back to the first branch with a mark. */
! while (uhp->uh_alt_prev.ptr != NULL
&& uhp->uh_alt_prev.ptr->uh_walk == mark)
! uhp = uhp->uh_alt_prev.ptr;
! /* Find the last branch with a mark, that's the one. */
! last = uhp;
! while (last->uh_alt_next.ptr != NULL
&& last->uh_alt_next.ptr->uh_walk == mark)
! last = last->uh_alt_next.ptr;
! if (last != uhp)
! {
! /* Make the used branch the first entry in the list of
! * alternatives to make "u" and CTRL-R take this branch. */
! while (uhp->uh_alt_prev.ptr != NULL)
! uhp = uhp->uh_alt_prev.ptr;
! if (last->uh_alt_next.ptr != NULL)
! last->uh_alt_next.ptr->uh_alt_prev.ptr =
last->uh_alt_prev.ptr;
! last->uh_alt_prev.ptr->uh_alt_next.ptr = last->uh_alt_next.ptr;
! last->uh_alt_prev.ptr = NULL;
! last->uh_alt_next.ptr = uhp;
! uhp->uh_alt_prev.ptr = last;
!
! if (curbuf->b_u_oldhead == uhp)
! curbuf->b_u_oldhead = last;
! uhp = last;
! if (uhp->uh_next.ptr != NULL)
! uhp->uh_next.ptr->uh_prev.ptr = uhp;
! }
! curbuf->b_u_curhead = uhp;
! if (uhp->uh_walk != mark)
! break; /* must have reached the target */
! /* Stop when going backwards in time and didn't find the exact
! * header we were looking for. */
! if (uhp->uh_seq == target && above)
! {
! curbuf->b_u_seq_cur = target - 1;
! break;
! }
! u_undoredo(FALSE);
! /* Advance "curhead" to below the header we last used. If it
! * becomes NULL then we need to set "newhead" to this leaf. */
! if (uhp->uh_prev.ptr == NULL)
! curbuf->b_u_newhead = uhp;
! curbuf->b_u_curhead = uhp->uh_prev.ptr;
! did_undo = FALSE;
! if (uhp->uh_seq == target) /* found it! */
! break;
! uhp = uhp->uh_prev.ptr;
! if (uhp == NULL || uhp->uh_walk != mark)
! {
! /* Need to redo more but can't find it... */
! internal_error("undo_time()");
! break;
}
}
}
--- 2508,2600 ----
uhp = curbuf->b_u_newhead;
else
uhp = uhp->uh_next.ptr;
! if (uhp == NULL || (target > 0 && uhp->uh_walk != mark)
|| (uhp->uh_seq == target && !above))
break;
curbuf->b_u_curhead = uhp;
u_undoredo(TRUE);
! if (target > 0)
! uhp->uh_walk = nomark; /* don't go back down here */
}
! /* When back to origin, redo is not needed. */
! if (target > 0)
{
! /*
! * And now go down the tree (redo), branching off where needed.
! */
! while (!got_int)
! {
! /* Do the change warning now, for the same reason as above. */
! change_warning(0);
! uhp = curbuf->b_u_curhead;
! if (uhp == NULL)
! break;
! /* Go back to the first branch with a mark. */
! while (uhp->uh_alt_prev.ptr != NULL
&& uhp->uh_alt_prev.ptr->uh_walk == mark)
! uhp = uhp->uh_alt_prev.ptr;
! /* Find the last branch with a mark, that's the one. */
! last = uhp;
! while (last->uh_alt_next.ptr != NULL
&& last->uh_alt_next.ptr->uh_walk == mark)
! last = last->uh_alt_next.ptr;
! if (last != uhp)
! {
! /* Make the used branch the first entry in the list of
! * alternatives to make "u" and CTRL-R take this branch. */
! while (uhp->uh_alt_prev.ptr != NULL)
! uhp = uhp->uh_alt_prev.ptr;
! if (last->uh_alt_next.ptr != NULL)
! last->uh_alt_next.ptr->uh_alt_prev.ptr =
last->uh_alt_prev.ptr;
! last->uh_alt_prev.ptr->uh_alt_next.ptr =
! last->uh_alt_next.ptr;
! last->uh_alt_prev.ptr = NULL;
! last->uh_alt_next.ptr = uhp;
! uhp->uh_alt_prev.ptr = last;
!
! if (curbuf->b_u_oldhead == uhp)
! curbuf->b_u_oldhead = last;
! uhp = last;
! if (uhp->uh_next.ptr != NULL)
! uhp->uh_next.ptr->uh_prev.ptr = uhp;
! }
! curbuf->b_u_curhead = uhp;
! if (uhp->uh_walk != mark)
! break; /* must have reached the target */
! /* Stop when going backwards in time and didn't find the exact
! * header we were looking for. */
! if (uhp->uh_seq == target && above)
! {
! curbuf->b_u_seq_cur = target - 1;
! break;
! }
! u_undoredo(FALSE);
! /* Advance "curhead" to below the header we last used. If it
! * becomes NULL then we need to set "newhead" to this leaf. */
! if (uhp->uh_prev.ptr == NULL)
! curbuf->b_u_newhead = uhp;
! curbuf->b_u_curhead = uhp->uh_prev.ptr;
! did_undo = FALSE;
! if (uhp->uh_seq == target) /* found it! */
! break;
! uhp = uhp->uh_prev.ptr;
! if (uhp == NULL || uhp->uh_walk != mark)
! {
! /* Need to redo more but can't find it... */
! internal_error("undo_time()");
! break;
! }
}
}
}
*** ../vim-8.0.1440/src/testdir/test_undo.vim 2018-01-27 21:01:30.242242117
+0100
--- src/testdir/test_undo.vim 2018-01-30 22:38:26.840843392 +0100
***************
*** 359,361 ****
--- 359,405 ----
norm o
quit
endfunc
+
+ func Test_undo_0()
+ new
+ set ul=100
+ normal i1
+ undo
+ normal i2
+ undo
+ normal i3
+
+ undo 0
+ let d = undotree()
+ call assert_equal('', getline(1))
+ call assert_equal(0, d.seq_cur)
+
+ redo
+ let d = undotree()
+ call assert_equal('3', getline(1))
+ call assert_equal(3, d.seq_cur)
+
+ undo 2
+ undo 0
+ let d = undotree()
+ call assert_equal('', getline(1))
+ call assert_equal(0, d.seq_cur)
+
+ redo
+ let d = undotree()
+ call assert_equal('2', getline(1))
+ call assert_equal(2, d.seq_cur)
+
+ undo 1
+ undo 0
+ let d = undotree()
+ call assert_equal('', getline(1))
+ call assert_equal(0, d.seq_cur)
+
+ redo
+ let d = undotree()
+ call assert_equal('1', getline(1))
+ call assert_equal(1, d.seq_cur)
+
+ bwipe!
+ endfunc
*** ../vim-8.0.1440/src/version.c 2018-01-30 22:31:13.755952680 +0100
--- src/version.c 2018-01-30 22:45:47.125513788 +0100
***************
*** 773,774 ****
--- 773,776 ----
{ /* Add new patch number below this line */
+ /**/
+ 1441,
/**/
--
ARTHUR: Right! Knights! Forward!
ARTHUR leads a charge toward the castle. Various shots of them battling on,
despite being hit by a variety of farm animals.
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.