Timestamp fixes for undo.
* doc/lispref/text.texi (Undo): Document (t . 0) and (t . -1) in buffer-undo-list. * etc/NEWS: Changes to visited-file-modtime, set-visited-file-modtime. * lisp/files.el (clear-visited-file-modtime): Move here from fileio.c. * src/atimer.c (schedule_atimer): * src/fileio.c (Ffile_newer_than_file_p): Minor cleanup: use EMACS_TIME_LT so that we can remove EMACS_TIME_GT. * src/buffer.c (buffer-undo-list): Document (t . 0) and (t . -1). * src/fileio.c (Fclear_visited_file_modtime): Move to lisp/files.el. (syms_of_fileio): Remove Sclear_visited_file_name. (Fvisited_file_modtime): Return -1, not (-1 ...), when the visited file doesn't exist; this avoids an ambiguity with negative timestamps. (Fset_visited_file_modtime): Accept -1 and 0 as time-list arg. * src/systime.h (make_emacs_time, invalid_emacs_time): Don't assume struct timespec layout; POSIX doesn't guarantee it. (EMACS_TIME_NE, EMACS_TIME_GT, EMACS_TIME_GE): Remove. * src/undo.c (record_first_change): Push (visited-file-modtime) onto undo list rather than reimplementing it by hand, incorrectly. Fixes: debbugs:14824
This commit is contained in:
parent
56973319b5
commit
954b166e90
12 changed files with 86 additions and 53 deletions
|
@ -1,3 +1,8 @@
|
|||
2013-07-10 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Timestamp fixes for undo (Bug#14824).
|
||||
* text.texi (Undo): Document (t . 0) and (t . -1) in buffer-undo-list.
|
||||
|
||||
2013-07-06 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* nonascii.texi (Text Representations): Document that
|
||||
|
|
|
@ -1250,14 +1250,18 @@ reinsert it is @code{(abs @var{position})}. If @var{position} is
|
|||
positive, point was at the beginning of the deleted text, otherwise it
|
||||
was at the end.
|
||||
|
||||
@item (t @var{sec-high} @var{sec-low} @var{microsec} @var{picosec})
|
||||
@item (t . @var{time-flag})
|
||||
This kind of element indicates that an unmodified buffer became
|
||||
modified. The list @code{(@var{sec-high} @var{sec-low} @var{microsec}
|
||||
modified. A @var{time-flag} of the form
|
||||
@code{(@var{sec-high} @var{sec-low} @var{microsec}
|
||||
@var{picosec})} represents the visited file's modification time as of
|
||||
when it was previously visited or saved, using the same format as
|
||||
@code{current-time}; see @ref{Time of Day}. @code{primitive-undo} uses those
|
||||
@code{current-time}; see @ref{Time of Day}.
|
||||
A @var{time-flag} of 0 means the buffer does not correspond to any file;
|
||||
@minus{}1 means the visited file previously did not exist.
|
||||
@code{primitive-undo} uses these
|
||||
values to determine whether to mark the buffer as unmodified once again;
|
||||
it does so only if the file's modification time matches those numbers.
|
||||
it does so only if the file's status matches that of @var{time-flag}.
|
||||
|
||||
@item (nil @var{property} @var{value} @var{beg} . @var{end})
|
||||
This kind of element records a change in a text property.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2013-07-10 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Timestamp fixes for undo (Bug#14824).
|
||||
* NEWS: Changes to visited-file-modtime, set-visited-file-modtime.
|
||||
|
||||
2013-07-08 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* NEWS: NS can be build with ImageMagick.
|
||||
|
|
6
etc/NEWS
6
etc/NEWS
|
@ -537,6 +537,9 @@ alist of extended attributes as returned by the new function
|
|||
`file-extended-attributes'. The attributes can be applied to another
|
||||
file using `set-file-extended-attributes'.
|
||||
|
||||
** `visited-file-modtime' now returns -1 for nonexistent files.
|
||||
Formerly it returned a list (-1 LOW USEC PSEC), but this was ambiguous
|
||||
in the presence of files with negative time stamps.
|
||||
|
||||
* Lisp Changes in Emacs 24.4
|
||||
|
||||
|
@ -613,6 +616,9 @@ Emacs uses `image-default-frame-delay'.
|
|||
*** New functions `image-current-frame' and `image-show-frame' for getting
|
||||
and setting the current frame of a multi-frame image.
|
||||
|
||||
** The function `set-visited-file-modtime' now accepts a 0 or -1 argument
|
||||
with the same interpretation as the returned value of `visited-file-modtime'.
|
||||
|
||||
** time-to-seconds is not obsolete any more.
|
||||
** New function special-form-p.
|
||||
** Docstrings can be made dynamic by adding a `dynamic-docstring-function'
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2013-07-10 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Timestamp fixes for undo (Bug#14824).
|
||||
* files.el (clear-visited-file-modtime): Move here from fileio.c.
|
||||
|
||||
2013-07-10 Leo Liu <sdl.web@gmail.com>
|
||||
|
||||
* files.el (require-final-newline): Allow safe local value.
|
||||
|
|
|
@ -4918,6 +4918,11 @@ change the additional actions you can take on files."
|
|||
(length autosaved-buffers)
|
||||
(mapconcat 'identity autosaved-buffers ", "))))))))
|
||||
|
||||
(defun clear-visited-file-modtime ()
|
||||
"Clear out records of last mod time of visited file.
|
||||
Next attempt to save will certainly not complain of a discrepancy."
|
||||
(set-visited-file-modtime 0))
|
||||
|
||||
(defun not-modified (&optional arg)
|
||||
"Mark current buffer as unmodified, not needing to be saved.
|
||||
With prefix ARG, mark buffer as modified, so \\[save-buffer] will save.
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
2013-07-10 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Timestamp fixes for undo (Bug#14824).
|
||||
* atimer.c (schedule_atimer):
|
||||
* fileio.c (Ffile_newer_than_file_p):
|
||||
Minor cleanup: use EMACS_TIME_LT so that we can remove EMACS_TIME_GT.
|
||||
* buffer.c (buffer-undo-list): Document (t . 0) and (t . -1).
|
||||
* fileio.c (Fclear_visited_file_modtime): Move to lisp/files.el.
|
||||
(syms_of_fileio): Remove Sclear_visited_file_name.
|
||||
(Fvisited_file_modtime): Return -1, not (-1 ...), when the visited
|
||||
file doesn't exist; this avoids an ambiguity with negative timestamps.
|
||||
(Fset_visited_file_modtime): Accept -1 and 0 as time-list arg.
|
||||
* systime.h (make_emacs_time, invalid_emacs_time):
|
||||
Don't assume struct timespec layout; POSIX doesn't guarantee it.
|
||||
(EMACS_TIME_NE, EMACS_TIME_GT, EMACS_TIME_GE): Remove.
|
||||
* undo.c (record_first_change): Push (visited-file-modtime) onto
|
||||
undo list rather than reimplementing it by hand, incorrectly.
|
||||
|
||||
2013-07-09 Ken Brown <kbrown@cornell.edu>
|
||||
|
||||
* sheap.c (STATIC_HEAP_SIZE) [__x86_64__]: Increase to 18MB.
|
||||
|
|
|
@ -336,7 +336,7 @@ schedule_atimer (struct atimer *t)
|
|||
struct atimer *a = atimers, *prev = NULL;
|
||||
|
||||
/* Look for the first atimer that is ripe after T. */
|
||||
while (a && EMACS_TIME_GT (t->expiration, a->expiration))
|
||||
while (a && EMACS_TIME_LT (a->expiration, t->expiration))
|
||||
prev = a, a = a->next;
|
||||
|
||||
/* Insert T in front of the atimer found, if any. */
|
||||
|
|
|
@ -6095,6 +6095,11 @@ and is the visited file's modification time, as of that time. If the
|
|||
modification time of the most recent save is different, this entry is
|
||||
obsolete.
|
||||
|
||||
An entry (t . 0) means means the buffer was previously unmodified but
|
||||
its time stamp was unknown because it was not associated with a file.
|
||||
An entry (t . -1) is similar, except that it means the buffer's visited
|
||||
file did not exist.
|
||||
|
||||
An entry (nil PROPERTY VALUE BEG . END) indicates that a text property
|
||||
was modified between BEG and END. PROPERTY is the property name,
|
||||
and VALUE is the old value.
|
||||
|
|
46
src/fileio.c
46
src/fileio.c
|
@ -3345,7 +3345,7 @@ otherwise, if FILE2 does not exist, the answer is t. */)
|
|||
if (stat (SSDATA (absname2), &st2) < 0)
|
||||
return Qt;
|
||||
|
||||
return (EMACS_TIME_GT (get_stat_mtime (&st1), get_stat_mtime (&st2))
|
||||
return (EMACS_TIME_LT (get_stat_mtime (&st2), get_stat_mtime (&st1))
|
||||
? Qt : Qnil);
|
||||
}
|
||||
|
||||
|
@ -5375,36 +5375,19 @@ See Info node `(elisp)Modification Time' for more details. */)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
|
||||
Sclear_visited_file_modtime, 0, 0, 0,
|
||||
doc: /* Clear out records of last mod time of visited file.
|
||||
Next attempt to save will certainly not complain of a discrepancy. */)
|
||||
(void)
|
||||
{
|
||||
current_buffer->modtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS);
|
||||
current_buffer->modtime_size = -1;
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("visited-file-modtime", Fvisited_file_modtime,
|
||||
Svisited_file_modtime, 0, 0, 0,
|
||||
doc: /* Return the current buffer's recorded visited file modification time.
|
||||
The value is a list of the form (HIGH LOW USEC PSEC), like the time values that
|
||||
`file-attributes' returns. If the current buffer has no recorded file
|
||||
modification time, this function returns 0. If the visited file
|
||||
doesn't exist, HIGH will be -1.
|
||||
doesn't exist, return -1.
|
||||
See Info node `(elisp)Modification Time' for more details. */)
|
||||
(void)
|
||||
{
|
||||
if (EMACS_NSECS (current_buffer->modtime) < 0)
|
||||
{
|
||||
if (EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS)
|
||||
{
|
||||
/* make_lisp_time won't work here if time_t is unsigned. */
|
||||
return list4i (-1, 65535, 0, 0);
|
||||
}
|
||||
return make_number (0);
|
||||
}
|
||||
int ns = EMACS_NSECS (current_buffer->modtime);
|
||||
if (ns < 0)
|
||||
return make_number (UNKNOWN_MODTIME_NSECS - ns);
|
||||
return make_lisp_time (current_buffer->modtime);
|
||||
}
|
||||
|
||||
|
@ -5415,12 +5398,22 @@ Useful if the buffer was not read from the file normally
|
|||
or if the file itself has been changed for some known benign reason.
|
||||
An argument specifies the modification time value to use
|
||||
\(instead of that of the visited file), in the form of a list
|
||||
\(HIGH LOW USEC PSEC) as returned by `current-time'. */)
|
||||
(Lisp_Object time_list)
|
||||
\(HIGH LOW USEC PSEC) or an integer flag as returned by
|
||||
`visited-file-modtime'. */)
|
||||
(Lisp_Object time_flag)
|
||||
{
|
||||
if (!NILP (time_list))
|
||||
if (!NILP (time_flag))
|
||||
{
|
||||
current_buffer->modtime = lisp_time_argument (time_list);
|
||||
EMACS_TIME mtime;
|
||||
if (INTEGERP (time_flag))
|
||||
{
|
||||
CHECK_RANGED_INTEGER (time_flag, -1, 0);
|
||||
mtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS - XINT (time_flag));
|
||||
}
|
||||
else
|
||||
mtime = lisp_time_argument (time_flag);
|
||||
|
||||
current_buffer->modtime = mtime;
|
||||
current_buffer->modtime_size = -1;
|
||||
}
|
||||
else
|
||||
|
@ -6121,7 +6114,6 @@ This includes interactive calls to `delete-file' and
|
|||
defsubr (&Swrite_region);
|
||||
defsubr (&Scar_less_than_car);
|
||||
defsubr (&Sverify_visited_file_modtime);
|
||||
defsubr (&Sclear_visited_file_modtime);
|
||||
defsubr (&Svisited_file_modtime);
|
||||
defsubr (&Sset_visited_file_modtime);
|
||||
defsubr (&Sdo_auto_save);
|
||||
|
|
|
@ -67,7 +67,9 @@ SYSTIME_INLINE time_t *emacs_secs_addr (EMACS_TIME *t) { return &t->tv_sec; }
|
|||
SYSTIME_INLINE EMACS_TIME
|
||||
make_emacs_time (time_t s, int ns)
|
||||
{
|
||||
EMACS_TIME r = { s, ns };
|
||||
EMACS_TIME r;
|
||||
r.tv_sec = s;
|
||||
r.tv_nsec = ns;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -75,7 +77,9 @@ make_emacs_time (time_t s, int ns)
|
|||
SYSTIME_INLINE EMACS_TIME
|
||||
invalid_emacs_time (void)
|
||||
{
|
||||
EMACS_TIME r = { 0, -1 };
|
||||
EMACS_TIME r;
|
||||
r.tv_sec = 0;
|
||||
r.tv_nsec = -1;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -166,21 +170,6 @@ EMACS_TIME_EQ (EMACS_TIME t1, EMACS_TIME t2)
|
|||
return timespec_cmp (t1, t2) == 0;
|
||||
}
|
||||
SYSTIME_INLINE int
|
||||
EMACS_TIME_NE (EMACS_TIME t1, EMACS_TIME t2)
|
||||
{
|
||||
return timespec_cmp (t1, t2) != 0;
|
||||
}
|
||||
SYSTIME_INLINE int
|
||||
EMACS_TIME_GT (EMACS_TIME t1, EMACS_TIME t2)
|
||||
{
|
||||
return timespec_cmp (t1, t2) > 0;
|
||||
}
|
||||
SYSTIME_INLINE int
|
||||
EMACS_TIME_GE (EMACS_TIME t1, EMACS_TIME t2)
|
||||
{
|
||||
return timespec_cmp (t1, t2) >= 0;
|
||||
}
|
||||
SYSTIME_INLINE int
|
||||
EMACS_TIME_LT (EMACS_TIME t1, EMACS_TIME t2)
|
||||
{
|
||||
return timespec_cmp (t1, t2) < 0;
|
||||
|
|
|
@ -229,10 +229,9 @@ record_first_change (void)
|
|||
if (base_buffer->base_buffer)
|
||||
base_buffer = base_buffer->base_buffer;
|
||||
|
||||
bset_undo_list
|
||||
(current_buffer,
|
||||
Fcons (Fcons (Qt, make_lisp_time (base_buffer->modtime)),
|
||||
BVAR (current_buffer, undo_list)));
|
||||
bset_undo_list (current_buffer,
|
||||
Fcons (Fcons (Qt, Fvisited_file_modtime ()),
|
||||
BVAR (current_buffer, undo_list)));
|
||||
}
|
||||
|
||||
/* Record a change in property PROP (whose old value was VAL)
|
||||
|
|
Loading…
Add table
Reference in a new issue