diff options
| author | Miles Bader | 2004-12-25 02:00:25 +0000 |
|---|---|---|
| committer | Miles Bader | 2004-12-25 02:00:25 +0000 |
| commit | 6a89b7e95a771e5141bb1718e8278dcf892359ea (patch) | |
| tree | 189a864da85f49e73c6f9220b7231f0c54250e6e /src/undo.c | |
| parent | 054b6b53c3554c83ae02d24a772a74b63ebb08cd (diff) | |
| parent | 70d16390a08dc9d94c961eb380be8e1b5b496963 (diff) | |
| download | emacs-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.c | 156 |
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 | |||
| 29 | EMACS_INT undo_limit; | ||
| 30 | EMACS_INT undo_strong_limit; | ||
| 31 | |||
| 32 | Lisp_Object Vundo_outer_limit; | ||
| 33 | |||
| 34 | /* Function to call when undo_outer_limit is exceeded. */ | ||
| 35 | |||
| 36 | Lisp_Object Vundo_outer_limit_function; | ||
| 37 | |||
| 27 | /* Last buffer for which undo information was recorded. */ | 38 | /* Last buffer for which undo information was recorded. */ |
| 28 | Lisp_Object last_undo_buffer; | 39 | Lisp_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. */ | 309 | void |
| 299 | 310 | truncate_undo_list (b) | |
| 300 | Lisp_Object | 311 | struct buffer *b; |
| 301 | truncate_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 | ||
| 405 | DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0, | 443 | DEFUN ("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. | ||
| 607 | This limit is applied when garbage collection happens. | ||
| 608 | When a previous command increases the total undo list size past this | ||
| 609 | value, the earlier commands that came before it are forgotten. | ||
| 610 | |||
| 611 | The size is counted as the number of bytes occupied, | ||
| 612 | which 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. | ||
| 617 | This limit is applied when garbage collection happens. | ||
| 618 | When a previous command increases the total undo list size past this | ||
| 619 | value, that command and the earlier commands that came before it are forgotten. | ||
| 620 | However, the most recent buffer-modifying command's undo info | ||
| 621 | is never discarded for this reason. | ||
| 622 | |||
| 623 | The size is counted as the number of bytes occupied, | ||
| 624 | which 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. | ||
| 629 | At garbage collection time, if the current command has produced | ||
| 630 | more than this much undo information, it asks you whether to delete | ||
| 631 | the information. This is a last-ditch limit to prevent memory overflow. | ||
| 632 | |||
| 633 | The size is counted as the number of bytes occupied, | ||
| 634 | which includes both saved text and other data. | ||
| 635 | |||
| 636 | In fact, this calls the function which is the value of | ||
| 637 | `undo-outer-limit-function' with one argument, the size. | ||
| 638 | The text above describes the behavior of the function | ||
| 639 | that 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'. | ||
| 644 | This function is called with one argument, the current undo list size | ||
| 645 | for the most recent command (since the last undo boundary). | ||
| 646 | If the function returns t, that means truncation has been fully handled. | ||
| 647 | If it returns nil, the other forms of truncation are done. | ||
| 648 | |||
| 649 | Garbage collection is inhibited around the call to this function, | ||
| 650 | so 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 |