mirror of
https://github.com/vim/vim.git
synced 2025-07-04 23:07:33 -04:00
Added ":earlier 1f" and ":later 1f".
This commit is contained in:
parent
a800b42975
commit
730cde924c
@ -5797,6 +5797,8 @@ undotree() *undotree()*
|
|||||||
something readable.
|
something readable.
|
||||||
"save_last" Number of the last file write. Zero when no
|
"save_last" Number of the last file write. Zero when no
|
||||||
write yet.
|
write yet.
|
||||||
|
"save_cur" Number of the current position in the undo
|
||||||
|
tree.
|
||||||
"synced" Non-zero when the last undo block was synced.
|
"synced" Non-zero when the last undo block was synced.
|
||||||
This happens when waiting from input from the
|
This happens when waiting from input from the
|
||||||
user. See |undo-blocks|.
|
user. See |undo-blocks|.
|
||||||
|
@ -145,6 +145,16 @@ g- Go to older text state. With a count repeat that many
|
|||||||
:earlier {N}s Go to older text state about {N} seconds before.
|
:earlier {N}s Go to older text state about {N} seconds before.
|
||||||
:earlier {N}m Go to older text state about {N} minutes before.
|
:earlier {N}m Go to older text state about {N} minutes before.
|
||||||
:earlier {N}h Go to older text state about {N} hours before.
|
:earlier {N}h Go to older text state about {N} hours before.
|
||||||
|
:earlier {N}d Go to older text state about {N} days before.
|
||||||
|
|
||||||
|
:earlier {N}f Go to older text state {N} file writes before.
|
||||||
|
When changes were made since the laste write
|
||||||
|
":earlier 1f" will revert the text to the state when
|
||||||
|
it was written. Otherwise it will go to the write
|
||||||
|
before that.
|
||||||
|
When at the state of the first file write, or when
|
||||||
|
the file was not written, ":earlier 1f" will go to
|
||||||
|
before the first change.
|
||||||
|
|
||||||
*g+*
|
*g+*
|
||||||
g+ Go to newer text state. With a count repeat that many
|
g+ Go to newer text state. With a count repeat that many
|
||||||
@ -154,6 +164,11 @@ g+ Go to newer text state. With a count repeat that many
|
|||||||
:later {N}s Go to newer text state about {N} seconds later.
|
:later {N}s Go to newer text state about {N} seconds later.
|
||||||
:later {N}m Go to newer text state about {N} minutes later.
|
:later {N}m Go to newer text state about {N} minutes later.
|
||||||
:later {N}h Go to newer text state about {N} hours later.
|
:later {N}h Go to newer text state about {N} hours later.
|
||||||
|
:later {N}d Go to newer text state about {N} days later.
|
||||||
|
|
||||||
|
:later {N}f Go to newer text state {N} file writes later.
|
||||||
|
When at the state of the last file write, ":later 1f"
|
||||||
|
will go to the newest text state.
|
||||||
|
|
||||||
|
|
||||||
Note that text states will become unreachable when undo information is cleared
|
Note that text states will become unreachable when undo information is cleared
|
||||||
|
@ -302,7 +302,7 @@ edited. Typing this command twice cancels the preceding "U".
|
|||||||
|
|
||||||
The "U" command is a change by itself, which the "u" command undoes and CTRL-R
|
The "U" command is a change by itself, which the "u" command undoes and CTRL-R
|
||||||
redoes. This might be a bit confusing. Don't worry, with "u" and CTRL-R you
|
redoes. This might be a bit confusing. Don't worry, with "u" and CTRL-R you
|
||||||
can go to any of the situations you had. More about that in section |32.1|.
|
can go to any of the situations you had. More about that in section |32.2|.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
*02.6* Other editing commands
|
*02.6* Other editing commands
|
||||||
|
@ -9,16 +9,40 @@ Vim provides multi-level undo. If you undo a few changes and then make a new
|
|||||||
change you create a branch in the undo tree. This text is about moving
|
change you create a branch in the undo tree. This text is about moving
|
||||||
through the branches.
|
through the branches.
|
||||||
|
|
||||||
|32.1| Numbering changes
|
|32.1| Undo up to a file write
|
||||||
|32.2| Jumping around the tree
|
|32.2| Numbering changes
|
||||||
|32.3| Time travelling
|
|32.3| Jumping around the tree
|
||||||
|
|32.4| Time travelling
|
||||||
|
|
||||||
Next chapter: |usr_40.txt| Make new commands
|
Next chapter: |usr_40.txt| Make new commands
|
||||||
Previous chapter: |usr_31.txt| Exploiting the GUI
|
Previous chapter: |usr_31.txt| Exploiting the GUI
|
||||||
Table of contents: |usr_toc.txt|
|
Table of contents: |usr_toc.txt|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
*32.1* Numbering changes
|
*32.1* Undo up to a file write
|
||||||
|
|
||||||
|
Sometimes you make several changes, and then discover you want to go back to
|
||||||
|
when you have last written the file. You can do that with this command: >
|
||||||
|
|
||||||
|
:earlier 1f
|
||||||
|
|
||||||
|
The "f" stands for "file" here.
|
||||||
|
|
||||||
|
You can repeat this command to go further back in the past. Or use a count
|
||||||
|
diferent from 1 to go back faster.
|
||||||
|
|
||||||
|
If you go back too far, go forward again with: >
|
||||||
|
|
||||||
|
:later 1f
|
||||||
|
|
||||||
|
Note that these commands really work in time sequence. This matters if you
|
||||||
|
made changes after undoing some changes. It's explained in the next section.
|
||||||
|
|
||||||
|
Also note that we are talking about text writes here. For writing the undo
|
||||||
|
information in a file see |undo-persistence|.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
*32.2* Numbering changes
|
||||||
|
|
||||||
In section |02.5| we only discussed one line of undo/redo. But it is also
|
In section |02.5| we only discussed one line of undo/redo. But it is also
|
||||||
possible to branch off. This happens when you undo a few changes and then
|
possible to branch off. This happens when you undo a few changes and then
|
||||||
@ -66,7 +90,7 @@ it. But sometimes by the number of one of the changes below it, especially
|
|||||||
when moving up in the tree, so that you know which change was just undone.
|
when moving up in the tree, so that you know which change was just undone.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
*32.2* Jumping around the tree
|
*32.3* Jumping around the tree
|
||||||
|
|
||||||
So how do you get to "one two" now? You can use this command: >
|
So how do you get to "one two" now? You can use this command: >
|
||||||
|
|
||||||
@ -114,7 +138,7 @@ Using |:undo| is useful if you know what change you want to jump to. |g-| and
|
|||||||
You can type a count before |g-| and |g+| to repeat them.
|
You can type a count before |g-| and |g+| to repeat them.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
*32.3* Time travelling
|
*32.4* Time travelling
|
||||||
|
|
||||||
When you have been working on text for a while the tree grows to become big.
|
When you have been working on text for a while the tree grows to become big.
|
||||||
Then you may want to go to the text of some minutes ago.
|
Then you may want to go to the text of some minutes ago.
|
||||||
@ -133,10 +157,10 @@ seconds with this command: >
|
|||||||
:earlier 10s
|
:earlier 10s
|
||||||
|
|
||||||
Depending on how much time you took for the changes you end up at a certain
|
Depending on how much time you took for the changes you end up at a certain
|
||||||
position in the tree. The |:earlier| command argument can be "m" for minutes
|
position in the tree. The |:earlier| command argument can be "m" for minutes,
|
||||||
and "h" for hours. To go all the way back use a big number: >
|
"h" for hours and "d" for days. To go all the way back use a big number: >
|
||||||
|
|
||||||
:earlier 10h
|
:earlier 100d
|
||||||
|
|
||||||
To travel forward in time again use the |:later| command: >
|
To travel forward in time again use the |:later| command: >
|
||||||
|
|
||||||
@ -144,6 +168,11 @@ To travel forward in time again use the |:later| command: >
|
|||||||
|
|
||||||
The arguments are "s", "m" and "h", just like with |:earlier|.
|
The arguments are "s", "m" and "h", just like with |:earlier|.
|
||||||
|
|
||||||
|
If you want even more details, or want to manipulate the information, you can
|
||||||
|
use the |undotree()| function. To see what it returns: >
|
||||||
|
|
||||||
|
:echo undotree()
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
Next chapter: |usr_40.txt| Make new commands
|
Next chapter: |usr_40.txt| Make new commands
|
||||||
|
@ -273,9 +273,10 @@ Subjects that can be read independently.
|
|||||||
|31.5| Various
|
|31.5| Various
|
||||||
|
|
||||||
|usr_32.txt| The undo tree
|
|usr_32.txt| The undo tree
|
||||||
|32.1| Numbering changes
|
|32.1| Undo up to a file write
|
||||||
|32.2| Jumping around the tree
|
|32.2| Numbering changes
|
||||||
|32.3| Time travelling
|
|32.3| Jumping around the tree
|
||||||
|
|32.4| Time travelling
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Tuning Vim ~
|
Tuning Vim ~
|
||||||
|
@ -17735,12 +17735,13 @@ f_undotree(argvars, rettv)
|
|||||||
dict_T *dict = rettv->vval.v_dict;
|
dict_T *dict = rettv->vval.v_dict;
|
||||||
list_T *list;
|
list_T *list;
|
||||||
|
|
||||||
|
dict_add_nr_str(dict, "synced", (long)curbuf->b_u_synced, NULL);
|
||||||
dict_add_nr_str(dict, "seq_last", curbuf->b_u_seq_last, NULL);
|
dict_add_nr_str(dict, "seq_last", curbuf->b_u_seq_last, NULL);
|
||||||
|
dict_add_nr_str(dict, "save_last",
|
||||||
|
(long)curbuf->b_u_save_nr_last, NULL);
|
||||||
dict_add_nr_str(dict, "seq_cur", curbuf->b_u_seq_cur, NULL);
|
dict_add_nr_str(dict, "seq_cur", curbuf->b_u_seq_cur, NULL);
|
||||||
dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL);
|
dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL);
|
||||||
dict_add_nr_str(dict, "save_last",
|
dict_add_nr_str(dict, "save_cur", (long)curbuf->b_u_save_nr_cur, NULL);
|
||||||
(long)curbuf->b_u_last_save_nr, NULL);
|
|
||||||
dict_add_nr_str(dict, "synced", (long)curbuf->b_u_synced, NULL);
|
|
||||||
|
|
||||||
list = list_alloc();
|
list = list_alloc();
|
||||||
if (list != NULL)
|
if (list != NULL)
|
||||||
|
@ -8461,7 +8461,7 @@ ex_undo(eap)
|
|||||||
exarg_T *eap UNUSED;
|
exarg_T *eap UNUSED;
|
||||||
{
|
{
|
||||||
if (eap->addr_count == 1) /* :undo 123 */
|
if (eap->addr_count == 1) /* :undo 123 */
|
||||||
undo_time(eap->line2, FALSE, TRUE);
|
undo_time(eap->line2, FALSE, FALSE, TRUE);
|
||||||
else
|
else
|
||||||
u_undo(1);
|
u_undo(1);
|
||||||
}
|
}
|
||||||
@ -8507,6 +8507,7 @@ ex_later(eap)
|
|||||||
{
|
{
|
||||||
long count = 0;
|
long count = 0;
|
||||||
int sec = FALSE;
|
int sec = FALSE;
|
||||||
|
int file = FALSE;
|
||||||
char_u *p = eap->arg;
|
char_u *p = eap->arg;
|
||||||
|
|
||||||
if (*p == NUL)
|
if (*p == NUL)
|
||||||
@ -8519,13 +8520,16 @@ ex_later(eap)
|
|||||||
case 's': ++p; sec = TRUE; break;
|
case 's': ++p; sec = TRUE; break;
|
||||||
case 'm': ++p; sec = TRUE; count *= 60; break;
|
case 'm': ++p; sec = TRUE; count *= 60; break;
|
||||||
case 'h': ++p; sec = TRUE; count *= 60 * 60; break;
|
case 'h': ++p; sec = TRUE; count *= 60 * 60; break;
|
||||||
|
case 'd': ++p; sec = TRUE; count *= 24 * 60 * 60; break;
|
||||||
|
case 'f': ++p; file = TRUE; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*p != NUL)
|
if (*p != NUL)
|
||||||
EMSG2(_(e_invarg2), eap->arg);
|
EMSG2(_(e_invarg2), eap->arg);
|
||||||
else
|
else
|
||||||
undo_time(eap->cmdidx == CMD_earlier ? -count : count, sec, FALSE);
|
undo_time(eap->cmdidx == CMD_earlier ? -count : count,
|
||||||
|
sec, file, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4879,6 +4879,7 @@ restore_backup:
|
|||||||
{
|
{
|
||||||
unchanged(buf, TRUE);
|
unchanged(buf, TRUE);
|
||||||
u_unchanged(buf);
|
u_unchanged(buf);
|
||||||
|
u_update_save_nr(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8294,7 +8294,7 @@ nv_g_cmd(cap)
|
|||||||
case '-': /* "g+" and "g-": undo or redo along the timeline */
|
case '-': /* "g+" and "g-": undo or redo along the timeline */
|
||||||
if (!checkclearopq(oap))
|
if (!checkclearopq(oap))
|
||||||
undo_time(cap->nchar == '-' ? -cap->count1 : cap->count1,
|
undo_time(cap->nchar == '-' ? -cap->count1 : cap->count1,
|
||||||
FALSE, FALSE);
|
FALSE, FALSE, FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -12,11 +12,12 @@ void u_write_undo __ARGS((char_u *name, int forceit, buf_T *buf, char_u *hash));
|
|||||||
void u_read_undo __ARGS((char_u *name, char_u *hash, char_u *orig_name));
|
void u_read_undo __ARGS((char_u *name, char_u *hash, char_u *orig_name));
|
||||||
void u_undo __ARGS((int count));
|
void u_undo __ARGS((int count));
|
||||||
void u_redo __ARGS((int count));
|
void u_redo __ARGS((int count));
|
||||||
void undo_time __ARGS((long step, int sec, int absolute));
|
void undo_time __ARGS((long step, int sec, int file, int absolute));
|
||||||
void u_sync __ARGS((int force));
|
void u_sync __ARGS((int force));
|
||||||
void ex_undolist __ARGS((exarg_T *eap));
|
void ex_undolist __ARGS((exarg_T *eap));
|
||||||
void ex_undojoin __ARGS((exarg_T *eap));
|
void ex_undojoin __ARGS((exarg_T *eap));
|
||||||
void u_unchanged __ARGS((buf_T *buf));
|
void u_unchanged __ARGS((buf_T *buf));
|
||||||
|
void u_update_save_nr __ARGS((buf_T *buf));
|
||||||
void u_clearall __ARGS((buf_T *buf));
|
void u_clearall __ARGS((buf_T *buf));
|
||||||
void u_saveline __ARGS((linenr_T lnum));
|
void u_saveline __ARGS((linenr_T lnum));
|
||||||
void u_clearline __ARGS((void));
|
void u_clearline __ARGS((void));
|
||||||
|
@ -327,7 +327,8 @@ struct u_header
|
|||||||
visualinfo_T uh_visual; /* Visual areas before undo/after redo */
|
visualinfo_T uh_visual; /* Visual areas before undo/after redo */
|
||||||
#endif
|
#endif
|
||||||
time_t uh_time; /* timestamp when the change was made */
|
time_t uh_time; /* timestamp when the change was made */
|
||||||
long_u uh_save_nr; /* counter for last time saved */
|
long uh_save_nr; /* set when the file was saved after the
|
||||||
|
changes in this block */
|
||||||
#ifdef U_DEBUG
|
#ifdef U_DEBUG
|
||||||
int uh_magic; /* magic number to check allocation */
|
int uh_magic; /* magic number to check allocation */
|
||||||
#endif
|
#endif
|
||||||
@ -1371,9 +1372,10 @@ struct file_buffer
|
|||||||
int b_u_numhead; /* current number of headers */
|
int b_u_numhead; /* current number of headers */
|
||||||
int b_u_synced; /* entry lists are synced */
|
int b_u_synced; /* entry lists are synced */
|
||||||
long b_u_seq_last; /* last used undo sequence number */
|
long b_u_seq_last; /* last used undo sequence number */
|
||||||
|
long b_u_save_nr_last; /* counter for last file write */
|
||||||
long b_u_seq_cur; /* hu_seq of header below which we are now */
|
long b_u_seq_cur; /* hu_seq of header below which we are now */
|
||||||
time_t b_u_time_cur; /* uh_time of header below which we are now */
|
time_t b_u_time_cur; /* uh_time of header below which we are now */
|
||||||
long_u b_u_last_save_nr; /* counter for last file write */
|
long b_u_save_nr_cur; /* file write nr after which we are now */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* variables for "U" command in undo.c
|
* variables for "U" command in undo.c
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
Tests for undo tree.
|
Tests for undo tree.
|
||||||
Since this script is sourced we need to explicitly break changes up in
|
Since this script is sourced we need to explicitly break changes up in
|
||||||
undo-able pieces. Do that by setting 'undolevels'.
|
undo-able pieces. Do that by setting 'undolevels'.
|
||||||
|
Also tests :earlier and :later.
|
||||||
|
|
||||||
STARTTEST
|
STARTTEST
|
||||||
:" Delete three characters and undo
|
:" Delete three characters and undo
|
||||||
@ -50,6 +51,35 @@ obbbbu:.w >>test.out
|
|||||||
obbbb:set ul=100
|
obbbb:set ul=100
|
||||||
:undojoin
|
:undojoin
|
||||||
occccu:.w >>test.out
|
occccu:.w >>test.out
|
||||||
|
:e! Xtest
|
||||||
|
ione one one:set ul=100
|
||||||
|
:w!
|
||||||
|
otwo:set ul=100
|
||||||
|
otwo:set ul=100
|
||||||
|
:w
|
||||||
|
othree:earlier 1f
|
||||||
|
:" expect "one one one\ntwo\ntwo"
|
||||||
|
:%yank a
|
||||||
|
:earlier 1f
|
||||||
|
:" expect "one one one"
|
||||||
|
:%yank b
|
||||||
|
:earlier 1f
|
||||||
|
:" expect empty line
|
||||||
|
:%yank c
|
||||||
|
:later 1f
|
||||||
|
:" expect "one one one"
|
||||||
|
:%yank d
|
||||||
|
:later 1f
|
||||||
|
:" expect "one one one\ntwo\ntwo"
|
||||||
|
:%yank e
|
||||||
|
:later 1f
|
||||||
|
:" expect "one one one\ntwo\ntwo\nthree"
|
||||||
|
ggO---:0put e
|
||||||
|
ggO---:0put d
|
||||||
|
ggO---:0put c
|
||||||
|
ggO---:0put b
|
||||||
|
ggO---:0put a
|
||||||
|
ggO---:w >>test.out
|
||||||
:qa!
|
:qa!
|
||||||
ENDTEST
|
ENDTEST
|
||||||
|
|
||||||
|
@ -22,3 +22,22 @@
|
|||||||
123456abc
|
123456abc
|
||||||
aaaa
|
aaaa
|
||||||
aaaa
|
aaaa
|
||||||
|
---
|
||||||
|
one one one
|
||||||
|
two
|
||||||
|
two
|
||||||
|
---
|
||||||
|
one one one
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
one one one
|
||||||
|
---
|
||||||
|
one one one
|
||||||
|
two
|
||||||
|
two
|
||||||
|
---
|
||||||
|
one one one
|
||||||
|
two
|
||||||
|
two
|
||||||
|
three
|
||||||
|
107
src/undo.c
107
src/undo.c
@ -119,6 +119,7 @@ static void put_header_ptr __ARGS((FILE *fp, u_header_T *uhp));
|
|||||||
#define U_ALLOC_LINE(size) lalloc((long_u)(size), FALSE)
|
#define U_ALLOC_LINE(size) lalloc((long_u)(size), FALSE)
|
||||||
static char_u *u_save_line __ARGS((linenr_T));
|
static char_u *u_save_line __ARGS((linenr_T));
|
||||||
|
|
||||||
|
/* used in undo_end() to report number of added and deleted lines */
|
||||||
static long u_newcount, u_oldcount;
|
static long u_newcount, u_oldcount;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -932,7 +933,7 @@ serialize_header(fp, buf, hash)
|
|||||||
/* Optional fields. */
|
/* Optional fields. */
|
||||||
putc(4, fp);
|
putc(4, fp);
|
||||||
putc(UF_LAST_SAVE_NR, fp);
|
putc(UF_LAST_SAVE_NR, fp);
|
||||||
put_bytes(fp, (long_u)buf->b_u_last_save_nr, 4);
|
put_bytes(fp, (long_u)buf->b_u_save_nr_last, 4);
|
||||||
|
|
||||||
putc(0, fp); /* end marker */
|
putc(0, fp); /* end marker */
|
||||||
|
|
||||||
@ -1444,17 +1445,6 @@ u_write_undo(name, forceit, buf, hash)
|
|||||||
/* Undo must be synced. */
|
/* Undo must be synced. */
|
||||||
u_sync(TRUE);
|
u_sync(TRUE);
|
||||||
|
|
||||||
/* Increase the write count, store it in the last undo header, what would
|
|
||||||
* be used for "u". */
|
|
||||||
++buf->b_u_last_save_nr;
|
|
||||||
uhp = buf->b_u_curhead;
|
|
||||||
if (uhp != NULL)
|
|
||||||
uhp = uhp->uh_next.ptr;
|
|
||||||
else
|
|
||||||
uhp = buf->b_u_newhead;
|
|
||||||
if (uhp != NULL)
|
|
||||||
uhp->uh_save_nr = buf->b_u_last_save_nr;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the header.
|
* Write the header.
|
||||||
*/
|
*/
|
||||||
@ -1849,7 +1839,7 @@ u_read_undo(name, hash, orig_name)
|
|||||||
curbuf->b_u_seq_last = seq_last;
|
curbuf->b_u_seq_last = seq_last;
|
||||||
curbuf->b_u_seq_cur = seq_cur;
|
curbuf->b_u_seq_cur = seq_cur;
|
||||||
curbuf->b_u_time_cur = seq_time;
|
curbuf->b_u_time_cur = seq_time;
|
||||||
curbuf->b_u_last_save_nr = last_save_nr;
|
curbuf->b_u_save_nr_last = last_save_nr;
|
||||||
|
|
||||||
curbuf->b_u_synced = TRUE;
|
curbuf->b_u_synced = TRUE;
|
||||||
vim_free(uhp_table);
|
vim_free(uhp_table);
|
||||||
@ -2001,13 +1991,15 @@ u_doit(startcount)
|
|||||||
* When "step" is negative go back in time, otherwise goes forward in time.
|
* When "step" is negative go back in time, otherwise goes forward in time.
|
||||||
* When "sec" is FALSE make "step" steps, when "sec" is TRUE use "step" as
|
* When "sec" is FALSE make "step" steps, when "sec" is TRUE use "step" as
|
||||||
* seconds.
|
* seconds.
|
||||||
|
* When "file" is TRUE use "step" as a number of file writes.
|
||||||
* When "absolute" is TRUE use "step" as the sequence number to jump to.
|
* When "absolute" is TRUE use "step" as the sequence number to jump to.
|
||||||
* "sec" must be FALSE then.
|
* "sec" must be FALSE then.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
undo_time(step, sec, absolute)
|
undo_time(step, sec, file, absolute)
|
||||||
long step;
|
long step;
|
||||||
int sec;
|
int sec;
|
||||||
|
int file;
|
||||||
int absolute;
|
int absolute;
|
||||||
{
|
{
|
||||||
long target;
|
long target;
|
||||||
@ -2021,6 +2013,7 @@ undo_time(step, sec, absolute)
|
|||||||
int nomark;
|
int nomark;
|
||||||
int round;
|
int round;
|
||||||
int dosec = sec;
|
int dosec = sec;
|
||||||
|
int dofile = file;
|
||||||
int above = FALSE;
|
int above = FALSE;
|
||||||
int did_undo = TRUE;
|
int did_undo = TRUE;
|
||||||
|
|
||||||
@ -2044,8 +2037,45 @@ undo_time(step, sec, absolute)
|
|||||||
{
|
{
|
||||||
/* When doing computations with time_t subtract starttime, because
|
/* When doing computations with time_t subtract starttime, because
|
||||||
* time_t converted to a long may result in a wrong number. */
|
* time_t converted to a long may result in a wrong number. */
|
||||||
if (sec)
|
if (dosec)
|
||||||
target = (long)(curbuf->b_u_time_cur - starttime) + step;
|
target = (long)(curbuf->b_u_time_cur - starttime) + step;
|
||||||
|
else if (dofile)
|
||||||
|
{
|
||||||
|
if (step < 0)
|
||||||
|
{
|
||||||
|
/* Going back to a previous write. If there were changes after
|
||||||
|
* the last write, count that as moving one file-write, so
|
||||||
|
* that ":earlier 1f" undoes all changes since the last save. */
|
||||||
|
uhp = curbuf->b_u_curhead;
|
||||||
|
if (uhp != NULL)
|
||||||
|
uhp = uhp->uh_next.ptr;
|
||||||
|
else
|
||||||
|
uhp = curbuf->b_u_newhead;
|
||||||
|
if (uhp != NULL && uhp->uh_save_nr != 0)
|
||||||
|
/* "uh_save_nr" was set in the last block, that means
|
||||||
|
* there were no changes since the last write */
|
||||||
|
target = curbuf->b_u_save_nr_cur + step;
|
||||||
|
else
|
||||||
|
/* count the changes since the last write as one step */
|
||||||
|
target = curbuf->b_u_save_nr_cur + step + 1;
|
||||||
|
if (target <= 0)
|
||||||
|
/* Go to before first write: before the oldest change. Use
|
||||||
|
* the sequence number for that. */
|
||||||
|
dofile = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Moving forward to a newer write. */
|
||||||
|
target = curbuf->b_u_save_nr_cur + step;
|
||||||
|
if (target > curbuf->b_u_save_nr_last)
|
||||||
|
{
|
||||||
|
/* Go to after last write: after the latest change. Use
|
||||||
|
* the sequence number for that. */
|
||||||
|
target = curbuf->b_u_seq_last + 1;
|
||||||
|
dofile = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
target = curbuf->b_u_seq_cur + step;
|
target = curbuf->b_u_seq_cur + step;
|
||||||
if (step < 0)
|
if (step < 0)
|
||||||
@ -2056,8 +2086,10 @@ undo_time(step, sec, absolute)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (sec)
|
if (dosec)
|
||||||
closest = (long)(time(NULL) - starttime + 1);
|
closest = (long)(time(NULL) - starttime + 1);
|
||||||
|
else if (dofile)
|
||||||
|
closest = curbuf->b_u_save_nr_last + 2;
|
||||||
else
|
else
|
||||||
closest = curbuf->b_u_seq_last + 2;
|
closest = curbuf->b_u_seq_last + 2;
|
||||||
if (target >= closest)
|
if (target >= closest)
|
||||||
@ -2092,9 +2124,14 @@ undo_time(step, sec, absolute)
|
|||||||
while (uhp != NULL)
|
while (uhp != NULL)
|
||||||
{
|
{
|
||||||
uhp->uh_walk = mark;
|
uhp->uh_walk = mark;
|
||||||
val = (long)(dosec ? (uhp->uh_time - starttime) : uhp->uh_seq);
|
if (dosec)
|
||||||
|
val = (long)(uhp->uh_time - starttime);
|
||||||
|
else if (dofile)
|
||||||
|
val = uhp->uh_save_nr;
|
||||||
|
else
|
||||||
|
val = uhp->uh_seq;
|
||||||
|
|
||||||
if (round == 1)
|
if (round == 1 && !(dofile && val == 0))
|
||||||
{
|
{
|
||||||
/* Remember the header that is closest to the target.
|
/* Remember the header that is closest to the target.
|
||||||
* It must be at least in the right direction (checked with
|
* It must be at least in the right direction (checked with
|
||||||
@ -2123,7 +2160,10 @@ undo_time(step, sec, absolute)
|
|||||||
/* Quit searching when we found a match. But when searching for a
|
/* Quit searching when we found a match. But when searching for a
|
||||||
* time we need to continue looking for the best uh_seq. */
|
* time we need to continue looking for the best uh_seq. */
|
||||||
if (target == val && !dosec)
|
if (target == val && !dosec)
|
||||||
|
{
|
||||||
|
target = uhp->uh_seq;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* go down in the tree if we haven't been there */
|
/* go down in the tree if we haven't been there */
|
||||||
if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark
|
if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark
|
||||||
@ -2179,6 +2219,7 @@ undo_time(step, sec, absolute)
|
|||||||
|
|
||||||
target = closest_seq;
|
target = closest_seq;
|
||||||
dosec = FALSE;
|
dosec = FALSE;
|
||||||
|
dofile = FALSE;
|
||||||
if (step < 0)
|
if (step < 0)
|
||||||
above = TRUE; /* stop above the header */
|
above = TRUE; /* stop above the header */
|
||||||
}
|
}
|
||||||
@ -2539,6 +2580,15 @@ u_undoredo(undo)
|
|||||||
* work we compute this as being just above the just undone change. */
|
* work we compute this as being just above the just undone change. */
|
||||||
--curbuf->b_u_seq_cur;
|
--curbuf->b_u_seq_cur;
|
||||||
|
|
||||||
|
/* Remember where we are for ":earlier 1f" and ":later 1f". */
|
||||||
|
if (curhead->uh_save_nr != 0)
|
||||||
|
{
|
||||||
|
if (undo)
|
||||||
|
curbuf->b_u_save_nr_cur = curhead->uh_save_nr - 1;
|
||||||
|
else
|
||||||
|
curbuf->b_u_save_nr_cur = curhead->uh_save_nr;
|
||||||
|
}
|
||||||
|
|
||||||
/* The timestamp can be the same for multiple changes, just use the one of
|
/* The timestamp can be the same for multiple changes, just use the one of
|
||||||
* the undone/redone change. */
|
* the undone/redone change. */
|
||||||
curbuf->b_u_time_cur = curhead->uh_time;
|
curbuf->b_u_time_cur = curhead->uh_time;
|
||||||
@ -2811,6 +2861,27 @@ u_unchanged(buf)
|
|||||||
buf->b_did_warn = FALSE;
|
buf->b_did_warn = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Increase the write count, store it in the last undo header, what would be
|
||||||
|
* used for "u".
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
u_update_save_nr(buf)
|
||||||
|
buf_T *buf;
|
||||||
|
{
|
||||||
|
u_header_T *uhp;
|
||||||
|
|
||||||
|
++buf->b_u_save_nr_last;
|
||||||
|
buf->b_u_save_nr_cur = buf->b_u_save_nr_last;
|
||||||
|
uhp = buf->b_u_curhead;
|
||||||
|
if (uhp != NULL)
|
||||||
|
uhp = uhp->uh_next.ptr;
|
||||||
|
else
|
||||||
|
uhp = buf->b_u_newhead;
|
||||||
|
if (uhp != NULL)
|
||||||
|
uhp->uh_save_nr = buf->b_u_save_nr_last;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
u_unch_branch(uhp)
|
u_unch_branch(uhp)
|
||||||
u_header_T *uhp;
|
u_header_T *uhp;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user