summaryrefslogtreecommitdiff
path: root/src/undo.c
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1992-09-28 13:10:43 +0000
committerRichard M. Stallman <rms@gnu.org>1992-09-28 13:10:43 +0000
commit350bce561c76197979c747bcab73ffa6fa5aee2b (patch)
tree3c85d6364d9c776f3cf45763c0ae65139d3f74bb /src/undo.c
parentbe09561e2a423bd8d9699ff254c1199cc103254e (diff)
downloademacs-350bce561c76197979c747bcab73ffa6fa5aee2b.tar.gz
(record_delete): Record pos before the deletion.
(Fprimitive_undo): Go back to recorded position.
Diffstat (limited to 'src/undo.c')
-rw-r--r--src/undo.c123
1 files changed, 72 insertions, 51 deletions
diff --git a/src/undo.c b/src/undo.c
index 21f24b3c156..b966ab3e79b 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -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);
+ }
}
}
}