/* undo handling for GNU Emacs.
- Copyright (C) 1990, 1993-1994, 2000-2011 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1993-1994, 2000-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include <setjmp.h>
#include "lisp.h"
+#include "character.h"
#include "buffer.h"
#include "commands.h"
#include "window.h"
/* Position of point last time we inserted a boundary. */
static struct buffer *last_boundary_buffer;
-static EMACS_INT last_boundary_position;
+static ptrdiff_t last_boundary_position;
Lisp_Object Qinhibit_read_only;
undo record that will be added just after this command terminates. */
static void
-record_point (EMACS_INT pt)
+record_point (ptrdiff_t pt)
{
int at_boundary;
because we don't need to record the contents.) */
void
-record_insert (EMACS_INT beg, EMACS_INT length)
+record_insert (ptrdiff_t beg, ptrdiff_t length)
{
Lisp_Object lbeg, lend;
of the characters in STRING, at location BEG. */
void
-record_delete (EMACS_INT beg, Lisp_Object string)
+record_delete (ptrdiff_t beg, Lisp_Object string)
{
Lisp_Object sbeg;
won't be inverted automatically by undoing the buffer modification. */
void
-record_marker_adjustment (Lisp_Object marker, EMACS_INT adjustment)
+record_marker_adjustment (Lisp_Object marker, ptrdiff_t adjustment)
{
if (EQ (BVAR (current_buffer, undo_list), Qt))
return;
The replacement must not change the number of characters. */
void
-record_change (EMACS_INT beg, EMACS_INT length)
+record_change (ptrdiff_t beg, ptrdiff_t length)
{
record_delete (beg, make_buffer_string (beg, beg + length, 1));
record_insert (beg, length);
base_buffer = base_buffer->base_buffer;
BVAR (current_buffer, undo_list) =
- Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)),
+ Fcons (Fcons (Qt, make_lisp_time (base_buffer->modtime)),
BVAR (current_buffer, undo_list));
}
for LENGTH characters starting at position BEG in BUFFER. */
void
-record_property_change (EMACS_INT beg, EMACS_INT length,
+record_property_change (ptrdiff_t beg, ptrdiff_t length,
Lisp_Object prop, Lisp_Object value,
Lisp_Object buffer)
{
{
Lisp_Object list;
Lisp_Object prev, next, last_boundary;
- int size_so_far = 0;
+ EMACS_INT size_so_far = 0;
/* Make sure that calling undo-outer-limit-function
won't cause another GC. */
- int count = inhibit_garbage_collection ();
+ ptrdiff_t count = inhibit_garbage_collection ();
/* Make the buffer current to get its local values of variables such
as undo_limit. Also so that Vundo_outer_limit_function can
unbind_to (count, Qnil);
}
+
+static _Noreturn void
+user_error (const char *msg)
+{
+ xsignal1 (Quser_error, build_string (msg));
+}
+
\f
DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0,
doc: /* Undo N records from the front of the list LIST.
{
struct gcpro gcpro1, gcpro2;
Lisp_Object next;
- int count = SPECPDL_INDEX ();
- register int arg;
+ ptrdiff_t count = SPECPDL_INDEX ();
+ register EMACS_INT arg;
Lisp_Object oldlist;
int did_apply = 0;
cdr = XCDR (next);
if (EQ (car, Qt))
{
- /* Element (t high . low) records previous modtime. */
+ /* Element (t . TIME) records previous modtime.
+ Preserve any flag of NONEXISTENT_MODTIME_NSECS or
+ UNKNOWN_MODTIME_NSECS. */
struct buffer *base_buffer = current_buffer;
- time_t mod_time;
- CONS_TO_INTEGER (cdr, time_t, mod_time);
+ EMACS_TIME mod_time;
+
+ if (CONSP (cdr)
+ && CONSP (XCDR (cdr))
+ && CONSP (XCDR (XCDR (cdr)))
+ && CONSP (XCDR (XCDR (XCDR (cdr))))
+ && INTEGERP (XCAR (XCDR (XCDR (XCDR (cdr)))))
+ && XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) < 0)
+ EMACS_SET_SECS_NSECS
+ (mod_time, 0,
+ XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) / 1000);
+ else
+ mod_time = lisp_time_argument (cdr, 0);
if (current_buffer->base_buffer)
base_buffer = current_buffer->base_buffer;
/* If this records an obsolete save
(not matching the actual disk file)
then don't mark unmodified. */
- if (mod_time != base_buffer->modtime)
+ if (EMACS_TIME_NE (mod_time, base_buffer->modtime))
continue;
#ifdef CLASH_DETECTION
Funlock_buffer ();
end = Fcdr (cdr);
if (XINT (beg) < BEGV || XINT (end) > ZV)
- error ("Changes to be undone are outside visible portion of buffer");
+ user_error ("Changes to be undone are outside visible portion of buffer");
Fput_text_property (beg, end, prop, val, Qnil);
}
else if (INTEGERP (car) && INTEGERP (cdr))
if (XINT (car) < BEGV
|| XINT (cdr) > ZV)
- error ("Changes to be undone are outside visible portion of buffer");
+ user_error ("Changes to be undone are outside visible portion of buffer");
/* Set point first thing, so that undoing this undo
does not send point back to where it is now. */
Fgoto_char (car);
if (pos < 0)
{
if (-pos < BEGV || -pos > ZV)
- error ("Changes to be undone are outside visible portion of buffer");
+ user_error ("Changes to be undone are outside visible portion of buffer");
SET_PT (-pos);
Finsert (1, &membuf);
}
else
{
if (pos < BEGV || pos > ZV)
- error ("Changes to be undone are outside visible portion of buffer");
+ user_error ("Changes to be undone are outside visible portion of buffer");
SET_PT (pos);
/* Now that we record marker adjustments
void
syms_of_undo (void)
{
- Qinhibit_read_only = intern_c_string ("inhibit-read-only");
- staticpro (&Qinhibit_read_only);
-
- Qapply = intern_c_string ("apply");
- staticpro (&Qapply);
+ DEFSYM (Qinhibit_read_only, "inhibit-read-only");
+ DEFSYM (Qapply, "apply");
pending_boundary = Qnil;
staticpro (&pending_boundary);