Commit 350bce56 authored by Richard M. Stallman's avatar Richard M. Stallman

(record_delete): Record pos before the deletion.

(Fprimitive_undo): Go back to recorded position.
parent be09561e
......@@ -89,6 +89,12 @@ record_delete (beg, length)
XFASTINT (sbeg) = beg;
XFASTINT (lbeg) = beg;
XFASTINT (lend) = beg + length;
/* If point isn't at start of deleted range, record where it is. */
if (PT != sbeg)
current_buffer->undo_list
= Fcons (make_number (PT), current_buffer->undo_list);
current_buffer->undo_list
= Fcons (Fcons (Fbuffer_substring (lbeg, lend), sbeg),
current_buffer->undo_list);
......@@ -258,66 +264,81 @@ Return what remains of the list.")
{
while (1)
{
Lisp_Object next, car, cdr;
Lisp_Object next;
next = Fcar (list);
list = Fcdr (list);
/* Exit inner loop at undo boundary. */
if (NILP (next))
break;
car = Fcar (next);
cdr = Fcdr (next);
if (EQ (car, Qt))
{
Lisp_Object high, low;
int mod_time;
high = Fcar (cdr);
low = Fcdr (cdr);
mod_time = (high << 16) + low;
/* If this records an obsolete save
(not matching the actual disk file)
then don't mark unmodified. */
if (mod_time != current_buffer->modtime)
break;
#ifdef CLASH_DETECTION
Funlock_buffer ();
#endif /* CLASH_DETECTION */
Fset_buffer_modified_p (Qnil);
}
else if (XTYPE (car) == Lisp_Int && XTYPE (cdr) == Lisp_Int)
{
Lisp_Object end;
if (XINT (car) < BEGV
|| XINT (cdr) > ZV)
error ("Changes to be undone are outside visible portion of buffer");
Fdelete_region (car, cdr);
Fgoto_char (car);
}
else if (XTYPE (car) == Lisp_String && XTYPE (cdr) == Lisp_Int)
/* Handle an integer by setting point to that value. */
if (XTYPE (next) == Lisp_Int)
SET_PT (clip_to_bounds (BEGV, XINT (next), ZV));
else if (XTYPE (next) == Lisp_Cons)
{
Lisp_Object membuf;
int pos = XINT (cdr);
membuf = car;
if (pos < 0)
Lisp_Object car, cdr;
car = Fcar (next);
cdr = Fcdr (next);
if (EQ (car, Qt))
{
if (-pos < BEGV || -pos > ZV)
error ("Changes to be undone are outside visible portion of buffer");
SET_PT (-pos);
Finsert (1, &membuf);
/* Element (t high . low) records previous modtime. */
Lisp_Object high, low;
int mod_time;
high = Fcar (cdr);
low = Fcdr (cdr);
mod_time = (high << 16) + low;
/* If this records an obsolete save
(not matching the actual disk file)
then don't mark unmodified. */
if (mod_time != current_buffer->modtime)
break;
#ifdef CLASH_DETECTION
Funlock_buffer ();
#endif /* CLASH_DETECTION */
Fset_buffer_modified_p (Qnil);
}
else
else if (XTYPE (car) == Lisp_Int && XTYPE (cdr) == Lisp_Int)
{
if (pos < BEGV || pos > ZV)
/* Element (BEG . END) means range was inserted. */
Lisp_Object end;
if (XINT (car) < BEGV
|| XINT (cdr) > ZV)
error ("Changes to be undone are outside visible portion of buffer");
SET_PT (pos);
/* Insert before markers so that if the mark is
currently on the boundary of this deletion, it
ends up on the other side of the now-undeleted
text from point. Since undo doesn't even keep
track of the mark, this isn't really necessary,
but it may lead to better behavior in certain
situations. */
Finsert_before_markers (1, &membuf);
SET_PT (pos);
Fdelete_region (car, cdr);
Fgoto_char (car);
}
else if (XTYPE (car) == Lisp_String && XTYPE (cdr) == Lisp_Int)
{
/* Element (STRING . POS) means STRING was deleted. */
Lisp_Object membuf;
int pos = XINT (cdr);
membuf = car;
if (pos < 0)
{
if (-pos < BEGV || -pos > ZV)
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");
SET_PT (pos);
/* Insert before markers so that if the mark is
currently on the boundary of this deletion, it
ends up on the other side of the now-undeleted
text from point. Since undo doesn't even keep
track of the mark, this isn't really necessary,
but it may lead to better behavior in certain
situations. */
Finsert_before_markers (1, &membuf);
SET_PT (pos);
}
}
}
}
......
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