Mercurial > emacs
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) */ |