comparison src/undo.c @ 59048:2daab60919ed

(truncate_undo_list): Return void. Take just one argument, the buffer. Make it current, and inhibit recursive GC. Access and update the undo list directly; return void. Refer to the undo...limit variables directly. Test undo_outer_limit only after counting the whole current command. When it's exceeded, call the function in undo-outer-limit-function. (undo_limit, undo_strong_limit, undo_outer_limit): Moved from alloc.c. (Vundo_outer_limit_function): New variable. (syms_of_undo): Define undo-limit, undo-strong-limit and undo-outer-limit here, and undo-outer-limit-function. Doc fixes.
author Richard M. Stallman <rms@gnu.org>
date Tue, 21 Dec 2004 11:31:24 +0000
parents 9e7829a684df
children 27371673eba8
comparison
equal deleted inserted replaced
59047:0d2678a6add0 59048:2daab60919ed
21 21
22 #include <config.h> 22 #include <config.h>
23 #include "lisp.h" 23 #include "lisp.h"
24 #include "buffer.h" 24 #include "buffer.h"
25 #include "commands.h" 25 #include "commands.h"
26
27 /* Limits controlling how much undo information to keep. */
28
29 EMACS_INT undo_limit;
30 EMACS_INT undo_strong_limit;
31 EMACS_INT undo_outer_limit;
32
33 /* Function to call when undo_outer_limit is exceeded. */
34
35 Lisp_Object Vundo_outer_limit_function;
26 36
27 /* Last buffer for which undo information was recorded. */ 37 /* Last buffer for which undo information was recorded. */
28 Lisp_Object last_undo_buffer; 38 Lisp_Object last_undo_buffer;
29 39
30 Lisp_Object Qinhibit_read_only; 40 Lisp_Object Qinhibit_read_only;
289 } 299 }
290 return Qnil; 300 return Qnil;
291 } 301 }
292 302
293 /* At garbage collection time, make an undo list shorter at the end, 303 /* At garbage collection time, make an undo list shorter at the end,
294 returning the truncated list. 304 returning the truncated list. How this is done depends on the
295 MINSIZE, MAXSIZE and LIMITSIZE are the limits on size allowed, 305 variables undo-limit, undo-strong-limit and undo-outer-limit.
296 as described below. 306 In some cases this works by calling undo-outer-limit-function. */
297 In practice, these are the values of undo-limit, 307
298 undo-strong-limit, and undo-outer-limit. */ 308 void
299 309 truncate_undo_list (b)
300 Lisp_Object 310 struct buffer *b;
301 truncate_undo_list (list, minsize, maxsize, limitsize) 311 {
302 Lisp_Object list; 312 Lisp_Object list;
303 int minsize, maxsize, limitsize;
304 {
305 Lisp_Object prev, next, last_boundary; 313 Lisp_Object prev, next, last_boundary;
306 int size_so_far = 0; 314 int size_so_far = 0;
315
316 /* Make sure that calling undo-outer-limit-function
317 won't cause another GC. */
318 int count = inhibit_garbage_collection ();
319
320 /* Make the buffer current to get its local values of variables such
321 as undo_limit. Also so that Vundo_outer_limit_function can
322 tell which buffer to operate on. */
323 record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ());
324 set_buffer_internal (b);
325
326 list = b->undo_list;
307 327
308 prev = Qnil; 328 prev = Qnil;
309 next = list; 329 next = list;
310 last_boundary = Qnil; 330 last_boundary = Qnil;
311 331
312 /* Always preserve at least the most recent undo record 332 /* 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))) 333 if (CONSP (next) && NILP (XCAR (next)))
320 { 334 {
321 /* Add in the space occupied by this element and its chain link. */ 335 /* Add in the space occupied by this element and its chain link. */
322 size_so_far += sizeof (struct Lisp_Cons); 336 size_so_far += sizeof (struct Lisp_Cons);
323 337
324 /* Advance to next element. */ 338 /* Advance to next element. */
325 prev = next; 339 prev = next;
326 next = XCDR (next); 340 next = XCDR (next);
327 } 341 }
342
343 /* Always preserve at least the most recent undo record
344 unless it is really horribly big.
345
346 Skip, skip, skip the undo, skip, skip, skip the undo,
347 Skip, skip, skip the undo, skip to the undo bound'ry. */
328 348
329 while (CONSP (next) && ! NILP (XCAR (next))) 349 while (CONSP (next) && ! NILP (XCAR (next)))
330 { 350 {
331 Lisp_Object elt; 351 Lisp_Object elt;
332 elt = XCAR (next); 352 elt = XCAR (next);
339 if (STRINGP (XCAR (elt))) 359 if (STRINGP (XCAR (elt)))
340 size_so_far += (sizeof (struct Lisp_String) - 1 360 size_so_far += (sizeof (struct Lisp_String) - 1
341 + SCHARS (XCAR (elt))); 361 + SCHARS (XCAR (elt)));
342 } 362 }
343 363
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. */ 364 /* Advance to next element. */
350 prev = next; 365 prev = next;
351 next = XCDR (next); 366 next = XCDR (next);
352 } 367 }
353 368
369 /* If by the first boundary we have already passed undo_outer_limit,
370 we're heading for memory full, so offer to clear out the list. */
371 if (size_so_far > undo_outer_limit
372 && !NILP (Vundo_outer_limit_function))
373 {
374 Lisp_Object temp = last_undo_buffer;
375
376 /* Normally the function this calls is undo-outer-limit-truncate. */
377 if (! NILP (call1 (Vundo_outer_limit_function,
378 make_number (size_so_far))))
379 {
380 /* The function is responsible for making
381 any desired changes in buffer-undo-list. */
382 unbind_to (count, Qnil);
383 return;
384 }
385 /* That function probably used the minibuffer, and if so, that
386 changed last_undo_buffer. Change it back so that we don't
387 force next change to make an undo boundary here. */
388 last_undo_buffer = temp;
389 }
390
354 if (CONSP (next)) 391 if (CONSP (next))
355 last_boundary = prev; 392 last_boundary = prev;
356 393
357 /* Keep more if it fits. */ 394 /* Keep additional undo data, if it fits in the limits. */
358 while (CONSP (next)) 395 while (CONSP (next))
359 { 396 {
360 Lisp_Object elt; 397 Lisp_Object elt;
361 elt = XCAR (next); 398 elt = XCAR (next);
362 399
363 /* When we get to a boundary, decide whether to truncate 400 /* When we get to a boundary, decide whether to truncate
364 either before or after it. The lower threshold, MINSIZE, 401 either before or after it. The lower threshold, undo_limit,
365 tells us to truncate after it. If its size pushes past 402 tells us to truncate after it. If its size pushes past
366 the higher threshold MAXSIZE as well, we truncate before it. */ 403 the higher threshold undo_strong_limit, we truncate before it. */
367 if (NILP (elt)) 404 if (NILP (elt))
368 { 405 {
369 if (size_so_far > maxsize) 406 if (size_so_far > undo_strong_limit)
370 break; 407 break;
371 last_boundary = prev; 408 last_boundary = prev;
372 if (size_so_far > minsize) 409 if (size_so_far > undo_limit)
373 break; 410 break;
374 } 411 }
375 412
376 /* Add in the space occupied by this element and its chain link. */ 413 /* Add in the space occupied by this element and its chain link. */
377 size_so_far += sizeof (struct Lisp_Cons); 414 size_so_far += sizeof (struct Lisp_Cons);
388 next = XCDR (next); 425 next = XCDR (next);
389 } 426 }
390 427
391 /* If we scanned the whole list, it is short enough; don't change it. */ 428 /* If we scanned the whole list, it is short enough; don't change it. */
392 if (NILP (next)) 429 if (NILP (next))
393 return list; 430 ;
394
395 /* Truncate at the boundary where we decided to truncate. */ 431 /* Truncate at the boundary where we decided to truncate. */
396 if (!NILP (last_boundary)) 432 else if (!NILP (last_boundary))
397 { 433 XSETCDR (last_boundary, Qnil);
398 XSETCDR (last_boundary, Qnil); 434 /* There's nothing we decided to keep, so clear it out. */
399 return list;
400 }
401 else 435 else
402 return Qnil; 436 b->undo_list = Qnil;
437
438 unbind_to (count, Qnil);
403 } 439 }
404 440
405 DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0, 441 DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0,
406 doc: /* Undo N records from the front of the list LIST. 442 doc: /* Undo N records from the front of the list LIST.
407 Return what remains of the list. */) 443 Return what remains of the list. */)
561 pending_boundary = Qnil; 597 pending_boundary = Qnil;
562 staticpro (&pending_boundary); 598 staticpro (&pending_boundary);
563 599
564 defsubr (&Sprimitive_undo); 600 defsubr (&Sprimitive_undo);
565 defsubr (&Sundo_boundary); 601 defsubr (&Sundo_boundary);
602
603 DEFVAR_INT ("undo-limit", &undo_limit,
604 doc: /* Keep no more undo information once it exceeds this size.
605 This limit is applied when garbage collection happens.
606 When a previous command increases the total undo list size past this
607 value, the earlier commands that came before it are forgotten.
608
609 The size is counted as the number of bytes occupied,
610 which includes both saved text and other data. */);
611 undo_limit = 20000;
612
613 DEFVAR_INT ("undo-strong-limit", &undo_strong_limit,
614 doc: /* Don't keep more than this much size of undo information.
615 This limit is applied when garbage collection happens.
616 When a previous command increases the total undo list size past this
617 value, that command and the earlier commands that came before it are forgotten.
618 However, the most recent buffer-modifying command's undo info
619 is never discarded for this reason.
620
621 The size is counted as the number of bytes occupied,
622 which includes both saved text and other data. */);
623 undo_strong_limit = 30000;
624
625 DEFVAR_INT ("undo-outer-limit", &undo_outer_limit,
626 doc: /* Outer limit on size of undo information for one command.
627 At garbage collection time, if the current command has produced
628 more than this much undo information, it asks you whether to delete
629 the information. This is a last-ditch limit to prevent memory overflow.
630
631 The size is counted as the number of bytes occupied,
632 which includes both saved text and other data.
633
634 In fact, this calls the function which is the value of
635 `undo-outer-limit-function' with one argument, the size.
636 The text above describes the behavior of the function
637 that variable usually specifies. */);
638 undo_outer_limit = 300000;
639
640 DEFVAR_LISP ("undo-outer-limit-function", &Vundo_outer_limit_function,
641 doc: /* Function to call when an undo list exceeds `undo-outer-limit'.
642 This function is called with one argument, the current undo list size
643 for the most recent command (since the last undo boundary).
644 If the function returns t, that means truncation has been fully handled.
645 If it returns nil, the other forms of truncation are done.
646
647 Garbage collection is inhibited around the call to this function,
648 so it must make sure not to do a lot of consing. */);
649 Vundo_outer_limit_function = Qnil;
566 } 650 }
567 651
568 /* arch-tag: d546ee01-4aed-4ffb-bb8b-eefaae50d38a 652 /* arch-tag: d546ee01-4aed-4ffb-bb8b-eefaae50d38a
569 (do not change this comment) */ 653 (do not change this comment) */