X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/4c0078d4ab7fa8c234fa8098ec3a9686199edbff..4c31be6153255dfe29a0231253263ea0d9011ac3:/src/undo.c
diff --git a/src/undo.c b/src/undo.c
index 7e999fe512..cfb67ba5bc 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -1,5 +1,5 @@
/* 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.
@@ -20,6 +20,7 @@ along with GNU Emacs. If not, see . */
#include
#include
#include "lisp.h"
+#include "character.h"
#include "buffer.h"
#include "commands.h"
#include "window.h"
@@ -103,8 +104,9 @@ record_point (ptrdiff_t pt)
if (at_boundary
&& current_buffer == last_boundary_buffer
&& last_boundary_position != pt)
- BVAR (current_buffer, undo_list)
- = Fcons (make_number (last_boundary_position), BVAR (current_buffer, undo_list));
+ BSET (current_buffer, undo_list,
+ Fcons (make_number (last_boundary_position),
+ BVAR (current_buffer, undo_list)));
}
/* Record an insertion that just happened or is about to happen,
@@ -140,8 +142,8 @@ record_insert (ptrdiff_t beg, ptrdiff_t length)
XSETFASTINT (lbeg, beg);
XSETINT (lend, beg + length);
- BVAR (current_buffer, undo_list) = Fcons (Fcons (lbeg, lend),
- BVAR (current_buffer, undo_list));
+ BSET (current_buffer, undo_list,
+ Fcons (Fcons (lbeg, lend), BVAR (current_buffer, undo_list)));
}
/* Record that a deletion is about to take place,
@@ -166,8 +168,8 @@ record_delete (ptrdiff_t beg, Lisp_Object string)
record_point (beg);
}
- BVAR (current_buffer, undo_list)
- = Fcons (Fcons (string, sbeg), BVAR (current_buffer, undo_list));
+ BSET (current_buffer, undo_list,
+ Fcons (Fcons (string, sbeg), BVAR (current_buffer, undo_list)));
}
/* Record the fact that MARKER is about to be adjusted by ADJUSTMENT.
@@ -189,9 +191,9 @@ record_marker_adjustment (Lisp_Object marker, ptrdiff_t adjustment)
Fundo_boundary ();
last_undo_buffer = current_buffer;
- BVAR (current_buffer, undo_list)
- = Fcons (Fcons (marker, make_number (adjustment)),
- BVAR (current_buffer, undo_list));
+ BSET (current_buffer, undo_list,
+ Fcons (Fcons (marker, make_number (adjustment)),
+ BVAR (current_buffer, undo_list)));
}
/* Record that a replacement is about to take place,
@@ -224,9 +226,9 @@ record_first_change (void)
if (base_buffer->base_buffer)
base_buffer = base_buffer->base_buffer;
- BVAR (current_buffer, undo_list) =
- Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)),
- BVAR (current_buffer, undo_list));
+ BSET (current_buffer, undo_list,
+ Fcons (Fcons (Qt, make_lisp_time (base_buffer->modtime)),
+ BVAR (current_buffer, undo_list)));
}
/* Record a change in property PROP (whose old value was VAL)
@@ -264,7 +266,8 @@ record_property_change (ptrdiff_t beg, ptrdiff_t length,
XSETINT (lbeg, beg);
XSETINT (lend, beg + length);
entry = Fcons (Qnil, Fcons (prop, Fcons (value, Fcons (lbeg, lend))));
- BVAR (current_buffer, undo_list) = Fcons (entry, BVAR (current_buffer, undo_list));
+ BSET (current_buffer, undo_list,
+ Fcons (entry, BVAR (current_buffer, undo_list)));
current_buffer = obuf;
}
@@ -287,11 +290,11 @@ but another undo command will undo to the previous boundary. */)
/* If we have preallocated the cons cell to use here,
use that one. */
XSETCDR (pending_boundary, BVAR (current_buffer, undo_list));
- BVAR (current_buffer, undo_list) = pending_boundary;
+ BSET (current_buffer, undo_list, pending_boundary);
pending_boundary = Qnil;
}
else
- BVAR (current_buffer, undo_list) = Fcons (Qnil, BVAR (current_buffer, undo_list));
+ BSET (current_buffer, undo_list, Fcons (Qnil, BVAR (current_buffer, undo_list)));
}
last_boundary_position = PT;
last_boundary_buffer = current_buffer;
@@ -432,10 +435,17 @@ truncate_undo_list (struct buffer *b)
XSETCDR (last_boundary, Qnil);
/* There's nothing we decided to keep, so clear it out. */
else
- BVAR (b, undo_list) = Qnil;
+ BSET (b, undo_list, Qnil);
unbind_to (count, Qnil);
}
+
+static _Noreturn void
+user_error (const char *msg)
+{
+ xsignal1 (Quser_error, build_string (msg));
+}
+
DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0,
doc: /* Undo N records from the front of the list LIST.
@@ -497,10 +507,23 @@ Return what remains of the list. */)
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)
+ mod_time =
+ (make_emacs_time
+ (0, XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) / 1000));
+ else
+ mod_time = lisp_time_argument (cdr);
if (current_buffer->base_buffer)
base_buffer = current_buffer->base_buffer;
@@ -508,7 +531,7 @@ Return what remains of the list. */)
/* 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 ();
@@ -528,7 +551,7 @@ Return what remains of the list. */)
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))
@@ -537,7 +560,7 @@ Return what remains of the list. */)
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);
@@ -588,14 +611,14 @@ Return what remains of the list. */)
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
@@ -627,8 +650,8 @@ Return what remains of the list. */)
will work right. */
if (did_apply
&& EQ (oldlist, BVAR (current_buffer, undo_list)))
- BVAR (current_buffer, undo_list)
- = Fcons (list3 (Qapply, Qcdr, Qnil), BVAR (current_buffer, undo_list));
+ BSET (current_buffer, undo_list,
+ Fcons (list3 (Qapply, Qcdr, Qnil), BVAR (current_buffer, undo_list)));
UNGCPRO;
return unbind_to (count, list);