aboutsummaryrefslogtreecommitdiffstats
path: root/src/undo.c
diff options
context:
space:
mode:
authorMiles Bader2004-12-25 02:00:25 +0000
committerMiles Bader2004-12-25 02:00:25 +0000
commit6a89b7e95a771e5141bb1718e8278dcf892359ea (patch)
tree189a864da85f49e73c6f9220b7231f0c54250e6e /src/undo.c
parent054b6b53c3554c83ae02d24a772a74b63ebb08cd (diff)
parent70d16390a08dc9d94c961eb380be8e1b5b496963 (diff)
downloademacs-6a89b7e95a771e5141bb1718e8278dcf892359ea.tar.gz
emacs-6a89b7e95a771e5141bb1718e8278dcf892359ea.zip
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-79
Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-735 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-747 Update from CVS
Diffstat (limited to 'src/undo.c')
-rw-r--r--src/undo.c156
1 files changed, 121 insertions, 35 deletions
diff --git a/src/undo.c b/src/undo.c
index 9fdc46a3b13..df4b8d08cd6 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -24,6 +24,17 @@ Boston, MA 02111-1307, USA. */
24#include "buffer.h" 24#include "buffer.h"
25#include "commands.h" 25#include "commands.h"
26 26
27/* Limits controlling how much undo information to keep. */
28
29EMACS_INT undo_limit;
30EMACS_INT undo_strong_limit;
31
32Lisp_Object Vundo_outer_limit;
33
34/* Function to call when undo_outer_limit is exceeded. */
35
36Lisp_Object Vundo_outer_limit_function;
37
27/* Last buffer for which undo information was recorded. */ 38/* Last buffer for which undo information was recorded. */
28Lisp_Object last_undo_buffer; 39Lisp_Object last_undo_buffer;
29 40
@@ -291,31 +302,35 @@ but another undo command will undo to the previous boundary. */)
291} 302}
292 303
293/* At garbage collection time, make an undo list shorter at the end, 304/* At garbage collection time, make an undo list shorter at the end,
294 returning the truncated list. 305 returning the truncated list. How this is done depends on the
295 MINSIZE, MAXSIZE and LIMITSIZE are the limits on size allowed, 306 variables undo-limit, undo-strong-limit and undo-outer-limit.
296 as described below. 307 In some cases this works by calling undo-outer-limit-function. */
297 In practice, these are the values of undo-limit, 308
298 undo-strong-limit, and undo-outer-limit. */ 309void
299 310truncate_undo_list (b)
300Lisp_Object 311 struct buffer *b;
301truncate_undo_list (list, minsize, maxsize, limitsize)
302 Lisp_Object list;
303 int minsize, maxsize, limitsize;
304{ 312{
313 Lisp_Object list;
305 Lisp_Object prev, next, last_boundary; 314 Lisp_Object prev, next, last_boundary;
306 int size_so_far = 0; 315 int size_so_far = 0;
307 316
317 /* Make sure that calling undo-outer-limit-function
318 won't cause another GC. */
319 int count = inhibit_garbage_collection ();
320
321 /* Make the buffer current to get its local values of variables such
322 as undo_limit. Also so that Vundo_outer_limit_function can
323 tell which buffer to operate on. */
324 record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ());
325 set_buffer_internal (b);
326
327 list = b->undo_list;
328
308 prev = Qnil; 329 prev = Qnil;
309 next = list; 330 next = list;
310 last_boundary = Qnil; 331 last_boundary = Qnil;
311 332
312 /* Always preserve at least the most recent undo record 333 /* If the first element is an undo boundary, skip past it. */
313 unless it is really horribly big.
314 If the first element is an undo boundary, skip past it.
315
316 Skip, skip, skip the undo, skip, skip, skip the undo,
317 Skip, skip, skip the undo, skip to the undo bound'ry.
318 (Get it? "Skip to my Loo?") */
319 if (CONSP (next) && NILP (XCAR (next))) 334 if (CONSP (next) && NILP (XCAR (next)))
320 { 335 {
321 /* Add in the space occupied by this element and its chain link. */ 336 /* Add in the space occupied by this element and its chain link. */
@@ -326,6 +341,12 @@ truncate_undo_list (list, minsize, maxsize, limitsize)
326 next = XCDR (next); 341 next = XCDR (next);
327 } 342 }
328 343
344 /* Always preserve at least the most recent undo record
345 unless it is really horribly big.
346
347 Skip, skip, skip the undo, skip, skip, skip the undo,
348 Skip, skip, skip the undo, skip to the undo bound'ry. */
349
329 while (CONSP (next) && ! NILP (XCAR (next))) 350 while (CONSP (next) && ! NILP (XCAR (next)))
330 { 351 {
331 Lisp_Object elt; 352 Lisp_Object elt;
@@ -341,35 +362,53 @@ truncate_undo_list (list, minsize, maxsize, limitsize)
341 + SCHARS (XCAR (elt))); 362 + SCHARS (XCAR (elt)));
342 } 363 }
343 364
344 /* If we reach LIMITSIZE before the first boundary,
345 we're heading for memory full, so truncate the list to nothing. */
346 if (size_so_far > limitsize)
347 return Qnil;
348
349 /* Advance to next element. */ 365 /* Advance to next element. */
350 prev = next; 366 prev = next;
351 next = XCDR (next); 367 next = XCDR (next);
352 } 368 }
353 369
370 /* If by the first boundary we have already passed undo_outer_limit,
371 we're heading for memory full, so offer to clear out the list. */
372 if (INTEGERP (Vundo_outer_limit)
373 && size_so_far > XINT (Vundo_outer_limit)
374 && !NILP (Vundo_outer_limit_function))
375 {
376 Lisp_Object temp = last_undo_buffer;
377
378 /* Normally the function this calls is undo-outer-limit-truncate. */
379 if (! NILP (call1 (Vundo_outer_limit_function,
380 make_number (size_so_far))))
381 {
382 /* The function is responsible for making
383 any desired changes in buffer-undo-list. */
384 unbind_to (count, Qnil);
385 return;
386 }
387 /* That function probably used the minibuffer, and if so, that
388 changed last_undo_buffer. Change it back so that we don't
389 force next change to make an undo boundary here. */
390 last_undo_buffer = temp;
391 }
392
354 if (CONSP (next)) 393 if (CONSP (next))
355 last_boundary = prev; 394 last_boundary = prev;
356 395
357 /* Keep more if it fits. */ 396 /* Keep additional undo data, if it fits in the limits. */
358 while (CONSP (next)) 397 while (CONSP (next))
359 { 398 {
360 Lisp_Object elt; 399 Lisp_Object elt;
361 elt = XCAR (next); 400 elt = XCAR (next);
362 401
363 /* When we get to a boundary, decide whether to truncate 402 /* When we get to a boundary, decide whether to truncate
364 either before or after it. The lower threshold, MINSIZE, 403 either before or after it. The lower threshold, undo_limit,
365 tells us to truncate after it. If its size pushes past 404 tells us to truncate after it. If its size pushes past
366 the higher threshold MAXSIZE as well, we truncate before it. */ 405 the higher threshold undo_strong_limit, we truncate before it. */
367 if (NILP (elt)) 406 if (NILP (elt))
368 { 407 {
369 if (size_so_far > maxsize) 408 if (size_so_far > undo_strong_limit)
370 break; 409 break;
371 last_boundary = prev; 410 last_boundary = prev;
372 if (size_so_far > minsize) 411 if (size_so_far > undo_limit)
373 break; 412 break;
374 } 413 }
375 414
@@ -390,16 +429,15 @@ truncate_undo_list (list, minsize, maxsize, limitsize)
390 429
391 /* If we scanned the whole list, it is short enough; don't change it. */ 430 /* If we scanned the whole list, it is short enough; don't change it. */
392 if (NILP (next)) 431 if (NILP (next))
393 return list; 432 ;
394
395 /* Truncate at the boundary where we decided to truncate. */ 433 /* Truncate at the boundary where we decided to truncate. */
396 if (!NILP (last_boundary)) 434 else if (!NILP (last_boundary))
397 { 435 XSETCDR (last_boundary, Qnil);
398 XSETCDR (last_boundary, Qnil); 436 /* There's nothing we decided to keep, so clear it out. */
399 return list;
400 }
401 else 437 else
402 return Qnil; 438 b->undo_list = Qnil;
439
440 unbind_to (count, Qnil);
403} 441}
404 442
405DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0, 443DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0,
@@ -563,6 +601,54 @@ syms_of_undo ()
563 601
564 defsubr (&Sprimitive_undo); 602 defsubr (&Sprimitive_undo);
565 defsubr (&Sundo_boundary); 603 defsubr (&Sundo_boundary);
604
605 DEFVAR_INT ("undo-limit", &undo_limit,
606 doc: /* Keep no more undo information once it exceeds this size.
607This limit is applied when garbage collection happens.
608When a previous command increases the total undo list size past this
609value, the earlier commands that came before it are forgotten.
610
611The size is counted as the number of bytes occupied,
612which includes both saved text and other data. */);
613 undo_limit = 20000;
614
615 DEFVAR_INT ("undo-strong-limit", &undo_strong_limit,
616 doc: /* Don't keep more than this much size of undo information.
617This limit is applied when garbage collection happens.
618When a previous command increases the total undo list size past this
619value, that command and the earlier commands that came before it are forgotten.
620However, the most recent buffer-modifying command's undo info
621is never discarded for this reason.
622
623The size is counted as the number of bytes occupied,
624which includes both saved text and other data. */);
625 undo_strong_limit = 30000;
626
627 DEFVAR_LISP ("undo-outer-limit", &Vundo_outer_limit,
628 doc: /* Outer limit on size of undo information for one command.
629At garbage collection time, if the current command has produced
630more than this much undo information, it asks you whether to delete
631the information. This is a last-ditch limit to prevent memory overflow.
632
633The size is counted as the number of bytes occupied,
634which includes both saved text and other data.
635
636In fact, this calls the function which is the value of
637`undo-outer-limit-function' with one argument, the size.
638The text above describes the behavior of the function
639that variable usually specifies. */);
640 Vundo_outer_limit = make_number (300000);
641
642 DEFVAR_LISP ("undo-outer-limit-function", &Vundo_outer_limit_function,
643 doc: /* Function to call when an undo list exceeds `undo-outer-limit'.
644This function is called with one argument, the current undo list size
645for the most recent command (since the last undo boundary).
646If the function returns t, that means truncation has been fully handled.
647If it returns nil, the other forms of truncation are done.
648
649Garbage collection is inhibited around the call to this function,
650so it must make sure not to do a lot of consing. */);
651 Vundo_outer_limit_function = Qnil;
566} 652}
567 653
568/* arch-tag: d546ee01-4aed-4ffb-bb8b-eefaae50d38a 654/* arch-tag: d546ee01-4aed-4ffb-bb8b-eefaae50d38a