aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1992-09-28 13:10:43 +0000
committerRichard M. Stallman1992-09-28 13:10:43 +0000
commit350bce561c76197979c747bcab73ffa6fa5aee2b (patch)
tree3c85d6364d9c776f3cf45763c0ae65139d3f74bb /src
parentbe09561e2a423bd8d9699ff254c1199cc103254e (diff)
downloademacs-350bce561c76197979c747bcab73ffa6fa5aee2b.tar.gz
emacs-350bce561c76197979c747bcab73ffa6fa5aee2b.zip
(record_delete): Record pos before the deletion.
(Fprimitive_undo): Go back to recorded position.
Diffstat (limited to 'src')
-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)
89 XFASTINT (sbeg) = beg; 89 XFASTINT (sbeg) = beg;
90 XFASTINT (lbeg) = beg; 90 XFASTINT (lbeg) = beg;
91 XFASTINT (lend) = beg + length; 91 XFASTINT (lend) = beg + length;
92
93 /* If point isn't at start of deleted range, record where it is. */
94 if (PT != sbeg)
95 current_buffer->undo_list
96 = Fcons (make_number (PT), current_buffer->undo_list);
97
92 current_buffer->undo_list 98 current_buffer->undo_list
93 = Fcons (Fcons (Fbuffer_substring (lbeg, lend), sbeg), 99 = Fcons (Fcons (Fbuffer_substring (lbeg, lend), sbeg),
94 current_buffer->undo_list); 100 current_buffer->undo_list);
@@ -258,66 +264,81 @@ Return what remains of the list.")
258 { 264 {
259 while (1) 265 while (1)
260 { 266 {
261 Lisp_Object next, car, cdr; 267 Lisp_Object next;
262 next = Fcar (list); 268 next = Fcar (list);
263 list = Fcdr (list); 269 list = Fcdr (list);
270 /* Exit inner loop at undo boundary. */
264 if (NILP (next)) 271 if (NILP (next))
265 break; 272 break;
266 car = Fcar (next); 273 /* Handle an integer by setting point to that value. */
267 cdr = Fcdr (next); 274 if (XTYPE (next) == Lisp_Int)
268 if (EQ (car, Qt)) 275 SET_PT (clip_to_bounds (BEGV, XINT (next), ZV));
269 { 276 else if (XTYPE (next) == Lisp_Cons)
270 Lisp_Object high, low;
271 int mod_time;
272 high = Fcar (cdr);
273 low = Fcdr (cdr);
274 mod_time = (high << 16) + low;
275 /* If this records an obsolete save
276 (not matching the actual disk file)
277 then don't mark unmodified. */
278 if (mod_time != current_buffer->modtime)
279 break;
280#ifdef CLASH_DETECTION
281 Funlock_buffer ();
282#endif /* CLASH_DETECTION */
283 Fset_buffer_modified_p (Qnil);
284 }
285 else if (XTYPE (car) == Lisp_Int && XTYPE (cdr) == Lisp_Int)
286 {
287 Lisp_Object end;
288 if (XINT (car) < BEGV
289 || XINT (cdr) > ZV)
290 error ("Changes to be undone are outside visible portion of buffer");
291 Fdelete_region (car, cdr);
292 Fgoto_char (car);
293 }
294 else if (XTYPE (car) == Lisp_String && XTYPE (cdr) == Lisp_Int)
295 { 277 {
296 Lisp_Object membuf; 278 Lisp_Object car, cdr;
297 int pos = XINT (cdr); 279
298 membuf = car; 280 car = Fcar (next);
299 if (pos < 0) 281 cdr = Fcdr (next);
282 if (EQ (car, Qt))
300 { 283 {
301 if (-pos < BEGV || -pos > ZV) 284 /* Element (t high . low) records previous modtime. */
302 error ("Changes to be undone are outside visible portion of buffer"); 285 Lisp_Object high, low;
303 SET_PT (-pos); 286 int mod_time;
304 Finsert (1, &membuf); 287
288 high = Fcar (cdr);
289 low = Fcdr (cdr);
290 mod_time = (high << 16) + low;
291 /* If this records an obsolete save
292 (not matching the actual disk file)
293 then don't mark unmodified. */
294 if (mod_time != current_buffer->modtime)
295 break;
296 #ifdef CLASH_DETECTION
297 Funlock_buffer ();
298 #endif /* CLASH_DETECTION */
299 Fset_buffer_modified_p (Qnil);
305 } 300 }
306 else 301 else if (XTYPE (car) == Lisp_Int && XTYPE (cdr) == Lisp_Int)
307 { 302 {
308 if (pos < BEGV || pos > ZV) 303 /* Element (BEG . END) means range was inserted. */
304 Lisp_Object end;
305
306 if (XINT (car) < BEGV
307 || XINT (cdr) > ZV)
309 error ("Changes to be undone are outside visible portion of buffer"); 308 error ("Changes to be undone are outside visible portion of buffer");
310 SET_PT (pos); 309 Fdelete_region (car, cdr);
311 310 Fgoto_char (car);
312 /* Insert before markers so that if the mark is 311 }
313 currently on the boundary of this deletion, it 312 else if (XTYPE (car) == Lisp_String && XTYPE (cdr) == Lisp_Int)
314 ends up on the other side of the now-undeleted 313 {
315 text from point. Since undo doesn't even keep 314 /* Element (STRING . POS) means STRING was deleted. */
316 track of the mark, this isn't really necessary, 315 Lisp_Object membuf;
317 but it may lead to better behavior in certain 316 int pos = XINT (cdr);
318 situations. */ 317
319 Finsert_before_markers (1, &membuf); 318 membuf = car;
320 SET_PT (pos); 319 if (pos < 0)
320 {
321 if (-pos < BEGV || -pos > ZV)
322 error ("Changes to be undone are outside visible portion of buffer");
323 SET_PT (-pos);
324 Finsert (1, &membuf);
325 }
326 else
327 {
328 if (pos < BEGV || pos > ZV)
329 error ("Changes to be undone are outside visible portion of buffer");
330 SET_PT (pos);
331
332 /* Insert before markers so that if the mark is
333 currently on the boundary of this deletion, it
334 ends up on the other side of the now-undeleted
335 text from point. Since undo doesn't even keep
336 track of the mark, this isn't really necessary,
337 but it may lead to better behavior in certain
338 situations. */
339 Finsert_before_markers (1, &membuf);
340 SET_PT (pos);
341 }
321 } 342 }
322 } 343 }
323 } 344 }