X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/8abe0f97764a932f9e15863a93014fefff484ed6..71c44c04bb996abe77db8efd88255fde06532b10:/src/undo.c
diff --git a/src/undo.c b/src/undo.c
index 77590e4ace..2d491a4122 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -1,13 +1,13 @@
/* undo handling for GNU Emacs.
Copyright (C) 1990, 1993, 1994, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Emacs.
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,12 +15,11 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GNU Emacs. If not, see . */
#include
+#include
#include "lisp.h"
#include "buffer.h"
#include "commands.h"
@@ -38,7 +37,12 @@ Lisp_Object Vundo_outer_limit;
Lisp_Object Vundo_outer_limit_function;
/* Last buffer for which undo information was recorded. */
-Lisp_Object last_undo_buffer;
+/* BEWARE: This is not traced by the GC, so never dereference it! */
+struct buffer *last_undo_buffer;
+
+/* Position of point last time we inserted a boundary. */
+struct buffer *last_boundary_buffer;
+EMACS_INT last_boundary_position;
Lisp_Object Qinhibit_read_only;
@@ -63,16 +67,11 @@ int undo_inhibit_record_point;
undo record that will be added just after this command terminates. */
static void
-record_point (pt)
- int pt;
+record_point (int pt)
{
int at_boundary;
- /* Don't record position of pt when undo_inhibit_record_point holds.
- Needed to avoid inserting a position record in buffer-undo-list
- when last_point_position has not been set up correctly by
- command_loop_1, for example, when running a repeat-repeat-char
- event. */
+ /* Don't record position of pt when undo_inhibit_record_point holds. */
if (undo_inhibit_record_point)
return;
@@ -80,10 +79,15 @@ record_point (pt)
if (NILP (pending_boundary))
pending_boundary = Fcons (Qnil, Qnil);
- if (!BUFFERP (last_undo_buffer)
- || current_buffer != XBUFFER (last_undo_buffer))
+ if ((current_buffer != last_undo_buffer)
+ /* Don't call Fundo_boundary for the first change. Otherwise we
+ risk overwriting last_boundary_position in Fundo_boundary with
+ PT of the current buffer and as a consequence not insert an
+ undo boundary because last_boundary_position will equal pt in
+ the test at the end of the present function (Bug#731). */
+ && (MODIFF > SAVE_MODIFF))
Fundo_boundary ();
- XSETBUFFER (last_undo_buffer, current_buffer);
+ last_undo_buffer = current_buffer;
if (CONSP (current_buffer->undo_list))
{
@@ -113,19 +117,10 @@ record_point (pt)
/* If we are just after an undo boundary, and
point wasn't at start of deleted range, record where it was. */
if (at_boundary
- && BUFFERP (last_point_position_buffer)
- /* If we're called from batch mode, this could be nil. */
- && current_buffer == XBUFFER (last_point_position_buffer))
- {
- /* If we have switched windows, use the point value
- from the window we are in. */
- if (! EQ (last_point_position_window, selected_window))
- last_point_position = marker_position (XWINDOW (selected_window)->pointm);
-
- if (last_point_position != pt)
- current_buffer->undo_list
- = Fcons (make_number (last_point_position), current_buffer->undo_list);
- }
+ && current_buffer == last_boundary_buffer
+ && last_boundary_position != pt)
+ current_buffer->undo_list
+ = Fcons (make_number (last_boundary_position), current_buffer->undo_list);
}
/* Record an insertion that just happened or is about to happen,
@@ -134,8 +129,7 @@ record_point (pt)
because we don't need to record the contents.) */
void
-record_insert (beg, length)
- int beg, length;
+record_insert (int beg, int length)
{
Lisp_Object lbeg, lend;
@@ -170,9 +164,7 @@ record_insert (beg, length)
of the characters in STRING, at location BEG. */
void
-record_delete (beg, string)
- int beg;
- Lisp_Object string;
+record_delete (int beg, Lisp_Object string)
{
Lisp_Object sbeg;
@@ -200,9 +192,7 @@ record_delete (beg, string)
won't be inverted automatically by undoing the buffer modification. */
void
-record_marker_adjustment (marker, adjustment)
- Lisp_Object marker;
- int adjustment;
+record_marker_adjustment (Lisp_Object marker, int adjustment)
{
if (EQ (current_buffer->undo_list, Qt))
return;
@@ -211,10 +201,9 @@ record_marker_adjustment (marker, adjustment)
if (NILP (pending_boundary))
pending_boundary = Fcons (Qnil, Qnil);
- if (!BUFFERP (last_undo_buffer)
- || current_buffer != XBUFFER (last_undo_buffer))
+ if (current_buffer != last_undo_buffer)
Fundo_boundary ();
- XSETBUFFER (last_undo_buffer, current_buffer);
+ last_undo_buffer = current_buffer;
current_buffer->undo_list
= Fcons (Fcons (marker, make_number (adjustment)),
@@ -226,8 +215,7 @@ record_marker_adjustment (marker, adjustment)
The replacement must not change the number of characters. */
void
-record_change (beg, length)
- int beg, length;
+record_change (int beg, int length)
{
record_delete (beg, make_buffer_string (beg, beg + length, 1));
record_insert (beg, length);
@@ -238,7 +226,7 @@ record_change (beg, length)
we can tell whether it is obsolete because the file was saved again. */
void
-record_first_change ()
+record_first_change (void)
{
Lisp_Object high, low;
struct buffer *base_buffer = current_buffer;
@@ -246,10 +234,9 @@ record_first_change ()
if (EQ (current_buffer->undo_list, Qt))
return;
- if (!BUFFERP (last_undo_buffer)
- || current_buffer != XBUFFER (last_undo_buffer))
+ if (current_buffer != last_undo_buffer)
Fundo_boundary ();
- XSETBUFFER (last_undo_buffer, current_buffer);
+ last_undo_buffer = current_buffer;
if (base_buffer->base_buffer)
base_buffer = base_buffer->base_buffer;
@@ -263,27 +250,25 @@ record_first_change ()
for LENGTH characters starting at position BEG in BUFFER. */
void
-record_property_change (beg, length, prop, value, buffer)
- int beg, length;
- Lisp_Object prop, value, buffer;
+record_property_change (int beg, int length, Lisp_Object prop, Lisp_Object value, Lisp_Object buffer)
{
Lisp_Object lbeg, lend, entry;
- struct buffer *obuf = current_buffer;
+ struct buffer *obuf = current_buffer, *buf = XBUFFER (buffer);
int boundary = 0;
- if (EQ (XBUFFER (buffer)->undo_list, Qt))
+ if (EQ (buf->undo_list, Qt))
return;
/* Allocate a cons cell to be the undo boundary after this command. */
if (NILP (pending_boundary))
pending_boundary = Fcons (Qnil, Qnil);
- if (!EQ (buffer, last_undo_buffer))
+ if (buf != last_undo_buffer)
boundary = 1;
- last_undo_buffer = buffer;
+ last_undo_buffer = buf;
/* Switch temporarily to the buffer that was changed. */
- current_buffer = XBUFFER (buffer);
+ current_buffer = buf;
if (boundary)
Fundo_boundary ();
@@ -323,6 +308,8 @@ but another undo command will undo to the previous boundary. */)
else
current_buffer->undo_list = Fcons (Qnil, current_buffer->undo_list);
}
+ last_boundary_position = PT;
+ last_boundary_buffer = current_buffer;
return Qnil;
}
@@ -332,8 +319,7 @@ but another undo command will undo to the previous boundary. */)
In some cases this works by calling undo-outer-limit-function. */
void
-truncate_undo_list (b)
- struct buffer *b;
+truncate_undo_list (struct buffer *b)
{
Lisp_Object list;
Lisp_Object prev, next, last_boundary;
@@ -398,7 +384,8 @@ truncate_undo_list (b)
&& size_so_far > XINT (Vundo_outer_limit)
&& !NILP (Vundo_outer_limit_function))
{
- Lisp_Object temp = last_undo_buffer, tem;
+ Lisp_Object tem;
+ struct buffer *temp = last_undo_buffer;
/* Normally the function this calls is undo-outer-limit-truncate. */
tem = call1 (Vundo_outer_limit_function, make_number (size_so_far));
@@ -668,17 +655,20 @@ Return what remains of the list. */)
}
void
-syms_of_undo ()
+syms_of_undo (void)
{
- Qinhibit_read_only = intern ("inhibit-read-only");
+ Qinhibit_read_only = intern_c_string ("inhibit-read-only");
staticpro (&Qinhibit_read_only);
- Qapply = intern ("apply");
+ Qapply = intern_c_string ("apply");
staticpro (&Qapply);
pending_boundary = Qnil;
staticpro (&pending_boundary);
+ last_undo_buffer = NULL;
+ last_boundary_buffer = NULL;
+
defsubr (&Sprimitive_undo);
defsubr (&Sundo_boundary);
@@ -690,7 +680,7 @@ value, the earlier commands that came before it are forgotten.
The size is counted as the number of bytes occupied,
which includes both saved text and other data. */);
- undo_limit = 20000;
+ undo_limit = 80000;
DEFVAR_INT ("undo-strong-limit", &undo_strong_limit,
doc: /* Don't keep more than this much size of undo information.
@@ -702,7 +692,7 @@ is never discarded for this reason.
The size is counted as the number of bytes occupied,
which includes both saved text and other data. */);
- undo_strong_limit = 30000;
+ undo_strong_limit = 120000;
DEFVAR_LISP ("undo-outer-limit", &Vundo_outer_limit,
doc: /* Outer limit on size of undo information for one command.
@@ -719,7 +709,7 @@ In fact, this calls the function which is the value of
`undo-outer-limit-function' with one argument, the size.
The text above describes the behavior of the function
that variable usually specifies. */);
- Vundo_outer_limit = make_number (3000000);
+ Vundo_outer_limit = make_number (12000000);
DEFVAR_LISP ("undo-outer-limit-function", &Vundo_outer_limit_function,
doc: /* Function to call when an undo list exceeds `undo-outer-limit'.