Commit 6396140a authored by Stefan Monnier's avatar Stefan Monnier

(record_point): New fun.

(record_delete, record_insert): Use it.
parent b3bbfb96
...@@ -36,19 +36,15 @@ Lisp_Object Qinhibit_read_only; ...@@ -36,19 +36,15 @@ Lisp_Object Qinhibit_read_only;
an undo-boundary. */ an undo-boundary. */
Lisp_Object pending_boundary; Lisp_Object pending_boundary;
/* Record an insertion that just happened or is about to happen, /* Record point as it was at beginning of this command (if necessary)
for LENGTH characters at position BEG. And prepare the undo info for recording a change.
(It is possible to record an insertion before or after the fact PT is the position of point that will naturally occur as a result of the
because we don't need to record the contents.) */ undo record that will be added just after this command terminates. */
void static void
record_insert (beg, length) record_point (pt)
int beg, length;
{ {
Lisp_Object lbeg, lend; int at_boundary;
if (EQ (current_buffer->undo_list, Qt))
return;
/* Allocate a cons cell to be the undo boundary after this command. */ /* Allocate a cons cell to be the undo boundary after this command. */
if (NILP (pending_boundary)) if (NILP (pending_boundary))
...@@ -59,9 +55,58 @@ record_insert (beg, length) ...@@ -59,9 +55,58 @@ record_insert (beg, length)
Fundo_boundary (); Fundo_boundary ();
XSETBUFFER (last_undo_buffer, current_buffer); XSETBUFFER (last_undo_buffer, current_buffer);
if (CONSP (current_buffer->undo_list))
{
/* Set AT_BOUNDARY to 1 only when we have nothing other than
marker adjustment before undo boundary. */
Lisp_Object tail = current_buffer->undo_list, elt;
while (1)
{
if (NILP (tail))
elt = Qnil;
else
elt = XCAR (tail);
if (NILP (elt) || ! (CONSP (elt) && MARKERP (XCAR (elt))))
break;
tail = XCDR (tail);
}
at_boundary = NILP (elt);
}
else
at_boundary = 1;
if (MODIFF <= SAVE_MODIFF) if (MODIFF <= SAVE_MODIFF)
record_first_change (); record_first_change ();
/* If we are just after an undo boundary, and
point wasn't at start of deleted range, record where it was. */
if (at_boundary
&& last_point_position != pt
/* If we're called from batch mode, this could be nil. */
&& BUFFERP (last_point_position_buffer)
&& current_buffer == XBUFFER (last_point_position_buffer))
current_buffer->undo_list
= Fcons (make_number (last_point_position), current_buffer->undo_list);
}
/* Record an insertion that just happened or is about to happen,
for LENGTH characters at position BEG.
(It is possible to record an insertion before or after the fact
because we don't need to record the contents.) */
void
record_insert (beg, length)
int beg, length;
{
Lisp_Object lbeg, lend;
if (EQ (current_buffer->undo_list, Qt))
return;
record_point (beg);
/* If this is following another insertion and consecutive with it /* If this is following another insertion and consecutive with it
in the buffer, combine the two. */ in the buffer, combine the two. */
if (CONSP (current_buffer->undo_list)) if (CONSP (current_buffer->undo_list))
...@@ -93,59 +138,20 @@ record_delete (beg, string) ...@@ -93,59 +138,20 @@ record_delete (beg, string)
Lisp_Object string; Lisp_Object string;
{ {
Lisp_Object sbeg; Lisp_Object sbeg;
int at_boundary;
if (EQ (current_buffer->undo_list, Qt)) if (EQ (current_buffer->undo_list, Qt))
return; return;
/* Allocate a cons cell to be the undo boundary after this command. */ if (PT == beg + XSTRING (string)->size)
if (NILP (pending_boundary))
pending_boundary = Fcons (Qnil, Qnil);
if (BUFFERP (last_undo_buffer)
&& current_buffer != XBUFFER (last_undo_buffer))
Fundo_boundary ();
XSETBUFFER (last_undo_buffer, current_buffer);
if (CONSP (current_buffer->undo_list))
{ {
/* Set AT_BOUNDARY to 1 only when we have nothing other than XSETINT (sbeg, -beg);
marker adjustment before undo boundary. */ record_point (PT);
Lisp_Object tail = current_buffer->undo_list, elt;
while (1)
{
if (NILP (tail))
elt = Qnil;
else
elt = XCAR (tail);
if (NILP (elt) || ! (CONSP (elt) && MARKERP (XCAR (elt))))
break;
tail = XCDR (tail);
}
at_boundary = NILP (elt);
} }
else else
at_boundary = 0; {
XSETFASTINT (sbeg, beg);
if (MODIFF <= SAVE_MODIFF) record_point (beg);
record_first_change (); }
if (PT == beg + XSTRING (string)->size)
XSETINT (sbeg, -beg);
else
XSETFASTINT (sbeg, beg);
/* If we are just after an undo boundary, and
point wasn't at start of deleted range, record where it was. */
if (at_boundary
&& last_point_position != XFASTINT (sbeg)
/* If we're called from batch mode, this could be nil. */
&& BUFFERP (last_point_position_buffer)
&& current_buffer == XBUFFER (last_point_position_buffer))
current_buffer->undo_list
= Fcons (make_number (last_point_position), current_buffer->undo_list);
current_buffer->undo_list current_buffer->undo_list
= Fcons (Fcons (string, sbeg), current_buffer->undo_list); = Fcons (Fcons (string, sbeg), current_buffer->undo_list);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment