Mercurial > emacs
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 } |