mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
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)
This commit is contained in:
@@ -359,3 +359,47 @@ func Test_undo_append()
|
||||
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
|
||||
|
26
src/undo.c
26
src/undo.c
@@ -2272,7 +2272,7 @@ undo_time(
|
||||
long closest_start;
|
||||
long closest_seq = 0;
|
||||
long val;
|
||||
u_header_T *uhp;
|
||||
u_header_T *uhp = NULL;
|
||||
u_header_T *last;
|
||||
int mark;
|
||||
int nomark;
|
||||
@@ -2295,13 +2295,6 @@ undo_time(
|
||||
* 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;
|
||||
}
|
||||
@@ -2369,6 +2362,10 @@ undo_time(
|
||||
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,8 +2491,9 @@ undo_time(
|
||||
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)
|
||||
if (uhp != NULL || target == 0)
|
||||
{
|
||||
/*
|
||||
* First go up the tree as much as needed.
|
||||
@@ -2510,14 +2508,18 @@ undo_time(
|
||||
uhp = curbuf->b_u_newhead;
|
||||
else
|
||||
uhp = uhp->uh_next.ptr;
|
||||
if (uhp == NULL || uhp->uh_walk != mark
|
||||
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.
|
||||
*/
|
||||
@@ -2549,7 +2551,8 @@ undo_time(
|
||||
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->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;
|
||||
@@ -2594,6 +2597,7 @@ undo_time(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
u_undo_end(did_undo, absolute);
|
||||
}
|
||||
|
||||
|
@@ -771,6 +771,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1441,
|
||||
/**/
|
||||
1440,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user