comparison src/undo.c @ 1248:68c77558d34b

(record_delete): Record pos before the deletion. (Fprimitive_undo): Go back to recorded position.
author Richard M. Stallman <rms@gnu.org>
date Mon, 28 Sep 1992 13:10:43 +0000
parents 47f6041d85e6
children c45c4e0cae7d
comparison
equal deleted inserted replaced
1247:8dce1588f37f 1248:68c77558d34b
87 XSET (sbeg, Lisp_Int, -beg); 87 XSET (sbeg, Lisp_Int, -beg);
88 else 88 else
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);
95 } 101 }
96 102
256 262
257 while (arg > 0) 263 while (arg > 0)
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));
276 else if (XTYPE (next) == Lisp_Cons)
269 { 277 {
270 Lisp_Object high, low; 278 Lisp_Object car, cdr;
271 int mod_time; 279
272 high = Fcar (cdr); 280 car = Fcar (next);
273 low = Fcdr (cdr); 281 cdr = Fcdr (next);
274 mod_time = (high << 16) + low; 282 if (EQ (car, Qt))
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 {
296 Lisp_Object membuf;
297 int pos = XINT (cdr);
298 membuf = car;
299 if (pos < 0)
300 { 283 {
301 if (-pos < BEGV || -pos > ZV) 284 /* Element (t high . low) records previous modtime. */
285 Lisp_Object high, low;
286 int mod_time;
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);
300 }
301 else if (XTYPE (car) == Lisp_Int && XTYPE (cdr) == Lisp_Int)
302 {
303 /* Element (BEG . END) means range was inserted. */
304 Lisp_Object end;
305
306 if (XINT (car) < BEGV
307 || XINT (cdr) > ZV)
302 error ("Changes to be undone are outside visible portion of buffer"); 308 error ("Changes to be undone are outside visible portion of buffer");
303 SET_PT (-pos); 309 Fdelete_region (car, cdr);
304 Finsert (1, &membuf); 310 Fgoto_char (car);
305 } 311 }
306 else 312 else if (XTYPE (car) == Lisp_String && XTYPE (cdr) == Lisp_Int)
307 { 313 {
308 if (pos < BEGV || pos > ZV) 314 /* Element (STRING . POS) means STRING was deleted. */
309 error ("Changes to be undone are outside visible portion of buffer"); 315 Lisp_Object membuf;
310 SET_PT (pos); 316 int pos = XINT (cdr);
311 317
312 /* Insert before markers so that if the mark is 318 membuf = car;
313 currently on the boundary of this deletion, it 319 if (pos < 0)
314 ends up on the other side of the now-undeleted 320 {
315 text from point. Since undo doesn't even keep 321 if (-pos < BEGV || -pos > ZV)
316 track of the mark, this isn't really necessary, 322 error ("Changes to be undone are outside visible portion of buffer");
317 but it may lead to better behavior in certain 323 SET_PT (-pos);
318 situations. */ 324 Finsert (1, &membuf);
319 Finsert_before_markers (1, &membuf); 325 }
320 SET_PT (pos); 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 }
324 arg--; 345 arg--;
325 } 346 }