*** empty log message ***
[bpt/emacs.git] / src / undo.c
CommitLineData
c6953be1 1/* undo handling for GNU Emacs.
392e96d4 2 Copyright (C) 1990, 1993, 1994, 2000 Free Software Foundation, Inc.
c6953be1
JB
3
4This file is part of GNU Emacs.
5
3b7ad313
EN
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
c6953be1 11GNU Emacs is distributed in the hope that it will be useful,
3b7ad313
EN
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
c6953be1
JB
20
21
18160b98 22#include <config.h>
c6953be1
JB
23#include "lisp.h"
24#include "buffer.h"
4e665715 25#include "commands.h"
c6953be1 26
137e23ea
RS
27/* Limits controlling how much undo information to keep. */
28
29EMACS_INT undo_limit;
30EMACS_INT undo_strong_limit;
31EMACS_INT undo_outer_limit;
32
33/* Function to call when undo_outer_limit is exceeded. */
34
35Lisp_Object Vundo_outer_limit_function;
36
c6953be1
JB
37/* Last buffer for which undo information was recorded. */
38Lisp_Object last_undo_buffer;
39
f87a68b3
RS
40Lisp_Object Qinhibit_read_only;
41
c58632fc
RS
42/* The first time a command records something for undo.
43 it also allocates the undo-boundary object
44 which will be added to the list at the end of the command.
45 This ensures we can't run out of space while trying to make
46 an undo-boundary. */
47Lisp_Object pending_boundary;
48
6396140a
SM
49/* Record point as it was at beginning of this command (if necessary)
50 And prepare the undo info for recording a change.
51 PT is the position of point that will naturally occur as a result of the
52 undo record that will be added just after this command terminates. */
c6953be1 53
6396140a
SM
54static void
55record_point (pt)
f45bedd4 56 int pt;
c6953be1 57{
6396140a 58 int at_boundary;
bdbe6f28 59
c58632fc
RS
60 /* Allocate a cons cell to be the undo boundary after this command. */
61 if (NILP (pending_boundary))
62 pending_boundary = Fcons (Qnil, Qnil);
63
8801a864
KR
64 if (!BUFFERP (last_undo_buffer)
65 || current_buffer != XBUFFER (last_undo_buffer))
c6953be1 66 Fundo_boundary ();
552bdbcf 67 XSETBUFFER (last_undo_buffer, current_buffer);
c6953be1 68
6396140a
SM
69 if (CONSP (current_buffer->undo_list))
70 {
71 /* Set AT_BOUNDARY to 1 only when we have nothing other than
72 marker adjustment before undo boundary. */
73
74 Lisp_Object tail = current_buffer->undo_list, elt;
75
76 while (1)
77 {
78 if (NILP (tail))
79 elt = Qnil;
80 else
81 elt = XCAR (tail);
82 if (NILP (elt) || ! (CONSP (elt) && MARKERP (XCAR (elt))))
83 break;
84 tail = XCDR (tail);
85 }
86 at_boundary = NILP (elt);
87 }
88 else
89 at_boundary = 1;
90
ad9cdce4 91 if (MODIFF <= SAVE_MODIFF)
c6953be1
JB
92 record_first_change ();
93
177c0ea7 94 /* If we are just after an undo boundary, and
6396140a
SM
95 point wasn't at start of deleted range, record where it was. */
96 if (at_boundary
97 && last_point_position != pt
98 /* If we're called from batch mode, this could be nil. */
99 && BUFFERP (last_point_position_buffer)
100 && current_buffer == XBUFFER (last_point_position_buffer))
101 current_buffer->undo_list
102 = Fcons (make_number (last_point_position), current_buffer->undo_list);
103}
104
105/* Record an insertion that just happened or is about to happen,
106 for LENGTH characters at position BEG.
107 (It is possible to record an insertion before or after the fact
108 because we don't need to record the contents.) */
109
110void
111record_insert (beg, length)
112 int beg, length;
113{
114 Lisp_Object lbeg, lend;
115
116 if (EQ (current_buffer->undo_list, Qt))
117 return;
118
119 record_point (beg);
120
c6953be1
JB
121 /* If this is following another insertion and consecutive with it
122 in the buffer, combine the two. */
38c0d37c 123 if (CONSP (current_buffer->undo_list))
c6953be1
JB
124 {
125 Lisp_Object elt;
c1d497be 126 elt = XCAR (current_buffer->undo_list);
38c0d37c 127 if (CONSP (elt)
c1d497be
KR
128 && INTEGERP (XCAR (elt))
129 && INTEGERP (XCDR (elt))
130 && XINT (XCDR (elt)) == beg)
c6953be1 131 {
f3fbd155 132 XSETCDR (elt, make_number (beg + length));
c6953be1
JB
133 return;
134 }
135 }
136
53480e99
KH
137 XSETFASTINT (lbeg, beg);
138 XSETINT (lend, beg + length);
213861c7
JB
139 current_buffer->undo_list = Fcons (Fcons (lbeg, lend),
140 current_buffer->undo_list);
c6953be1
JB
141}
142
143/* Record that a deletion is about to take place,
e928d437 144 of the characters in STRING, at location BEG. */
c6953be1 145
ff1aa840 146void
e928d437
RS
147record_delete (beg, string)
148 int beg;
149 Lisp_Object string;
c6953be1 150{
e928d437 151 Lisp_Object sbeg;
c6953be1 152
bdbe6f28
RS
153 if (EQ (current_buffer->undo_list, Qt))
154 return;
155
d5db4077 156 if (PT == beg + SCHARS (string))
cbc1b668 157 {
6396140a
SM
158 XSETINT (sbeg, -beg);
159 record_point (PT);
cbc1b668
KH
160 }
161 else
6396140a
SM
162 {
163 XSETFASTINT (sbeg, beg);
164 record_point (beg);
165 }
350bce56 166
c6953be1 167 current_buffer->undo_list
e928d437 168 = Fcons (Fcons (string, sbeg), current_buffer->undo_list);
c6953be1
JB
169}
170
714bced9
RS
171/* Record the fact that MARKER is about to be adjusted by ADJUSTMENT.
172 This is done only when a marker points within text being deleted,
173 because that's the only case where an automatic marker adjustment
174 won't be inverted automatically by undoing the buffer modification. */
175
ff1aa840 176void
714bced9
RS
177record_marker_adjustment (marker, adjustment)
178 Lisp_Object marker;
179 int adjustment;
180{
181 if (EQ (current_buffer->undo_list, Qt))
182 return;
183
184 /* Allocate a cons cell to be the undo boundary after this command. */
185 if (NILP (pending_boundary))
186 pending_boundary = Fcons (Qnil, Qnil);
187
177c0ea7 188 if (!BUFFERP (last_undo_buffer)
2f33f38a 189 || current_buffer != XBUFFER (last_undo_buffer))
714bced9
RS
190 Fundo_boundary ();
191 XSETBUFFER (last_undo_buffer, current_buffer);
192
193 current_buffer->undo_list
194 = Fcons (Fcons (marker, make_number (adjustment)),
195 current_buffer->undo_list);
196}
197
c6953be1
JB
198/* Record that a replacement is about to take place,
199 for LENGTH characters at location BEG.
e928d437 200 The replacement must not change the number of characters. */
c6953be1 201
ff1aa840 202void
c6953be1
JB
203record_change (beg, length)
204 int beg, length;
205{
e928d437 206 record_delete (beg, make_buffer_string (beg, beg + length, 1));
c6953be1
JB
207 record_insert (beg, length);
208}
209\f
210/* Record that an unmodified buffer is about to be changed.
211 Record the file modification date so that when undoing this entry
212 we can tell whether it is obsolete because the file was saved again. */
213
90dd3e4f 214void
c6953be1
JB
215record_first_change ()
216{
217 Lisp_Object high, low;
ad9cdce4 218 struct buffer *base_buffer = current_buffer;
0736cafe
RS
219
220 if (EQ (current_buffer->undo_list, Qt))
221 return;
222
2f33f38a
GM
223 if (!BUFFERP (last_undo_buffer)
224 || current_buffer != XBUFFER (last_undo_buffer))
0736cafe 225 Fundo_boundary ();
552bdbcf 226 XSETBUFFER (last_undo_buffer, current_buffer);
0736cafe 227
ad9cdce4
RS
228 if (base_buffer->base_buffer)
229 base_buffer = base_buffer->base_buffer;
230
231 XSETFASTINT (high, (base_buffer->modtime >> 16) & 0xffff);
232 XSETFASTINT (low, base_buffer->modtime & 0xffff);
c6953be1
JB
233 current_buffer->undo_list = Fcons (Fcons (Qt, Fcons (high, low)), current_buffer->undo_list);
234}
235
da9319d5
RS
236/* Record a change in property PROP (whose old value was VAL)
237 for LENGTH characters starting at position BEG in BUFFER. */
238
90dd3e4f 239void
da9319d5
RS
240record_property_change (beg, length, prop, value, buffer)
241 int beg, length;
242 Lisp_Object prop, value, buffer;
243{
244 Lisp_Object lbeg, lend, entry;
245 struct buffer *obuf = current_buffer;
246 int boundary = 0;
247
0736cafe 248 if (EQ (XBUFFER (buffer)->undo_list, Qt))
bdbe6f28
RS
249 return;
250
c58632fc
RS
251 /* Allocate a cons cell to be the undo boundary after this command. */
252 if (NILP (pending_boundary))
253 pending_boundary = Fcons (Qnil, Qnil);
254
da9319d5
RS
255 if (!EQ (buffer, last_undo_buffer))
256 boundary = 1;
257 last_undo_buffer = buffer;
258
da9319d5
RS
259 /* Switch temporarily to the buffer that was changed. */
260 current_buffer = XBUFFER (buffer);
261
262 if (boundary)
263 Fundo_boundary ();
264
ad9cdce4 265 if (MODIFF <= SAVE_MODIFF)
da9319d5
RS
266 record_first_change ();
267
552bdbcf
KH
268 XSETINT (lbeg, beg);
269 XSETINT (lend, beg + length);
da9319d5
RS
270 entry = Fcons (Qnil, Fcons (prop, Fcons (value, Fcons (lbeg, lend))));
271 current_buffer->undo_list = Fcons (entry, current_buffer->undo_list);
272
273 current_buffer = obuf;
274}
275
c6953be1 276DEFUN ("undo-boundary", Fundo_boundary, Sundo_boundary, 0, 0, 0,
8c1a1077
PJ
277 doc: /* Mark a boundary between units of undo.
278An undo command will stop at this point,
279but another undo command will undo to the previous boundary. */)
280 ()
c6953be1
JB
281{
282 Lisp_Object tem;
283 if (EQ (current_buffer->undo_list, Qt))
284 return Qnil;
285 tem = Fcar (current_buffer->undo_list);
265a9e55 286 if (!NILP (tem))
c58632fc
RS
287 {
288 /* One way or another, cons nil onto the front of the undo list. */
289 if (!NILP (pending_boundary))
290 {
291 /* If we have preallocated the cons cell to use here,
292 use that one. */
f3fbd155 293 XSETCDR (pending_boundary, current_buffer->undo_list);
c58632fc
RS
294 current_buffer->undo_list = pending_boundary;
295 pending_boundary = Qnil;
296 }
297 else
298 current_buffer->undo_list = Fcons (Qnil, current_buffer->undo_list);
299 }
c6953be1
JB
300 return Qnil;
301}
302
303/* At garbage collection time, make an undo list shorter at the end,
137e23ea
RS
304 returning the truncated list. How this is done depends on the
305 variables undo-limit, undo-strong-limit and undo-outer-limit.
306 In some cases this works by calling undo-outer-limit-function. */
307
308void
309truncate_undo_list (b)
310 struct buffer *b;
c6953be1 311{
137e23ea 312 Lisp_Object list;
c6953be1
JB
313 Lisp_Object prev, next, last_boundary;
314 int size_so_far = 0;
315
137e23ea
RS
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;
327
c6953be1
JB
328 prev = Qnil;
329 next = list;
330 last_boundary = Qnil;
331
137e23ea 332 /* If the first element is an undo boundary, skip past it. */
c1d497be 333 if (CONSP (next) && NILP (XCAR (next)))
c6953be1
JB
334 {
335 /* Add in the space occupied by this element and its chain link. */
336 size_so_far += sizeof (struct Lisp_Cons);
337
338 /* Advance to next element. */
339 prev = next;
c1d497be 340 next = XCDR (next);
c6953be1 341 }
e3d5ca1e 342
137e23ea
RS
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. */
348
c1d497be 349 while (CONSP (next) && ! NILP (XCAR (next)))
c6953be1
JB
350 {
351 Lisp_Object elt;
c1d497be 352 elt = XCAR (next);
c6953be1
JB
353
354 /* Add in the space occupied by this element and its chain link. */
355 size_so_far += sizeof (struct Lisp_Cons);
38c0d37c 356 if (CONSP (elt))
c6953be1
JB
357 {
358 size_so_far += sizeof (struct Lisp_Cons);
c1d497be 359 if (STRINGP (XCAR (elt)))
c6953be1 360 size_so_far += (sizeof (struct Lisp_String) - 1
d5db4077 361 + SCHARS (XCAR (elt)));
c6953be1
JB
362 }
363
364 /* Advance to next element. */
365 prev = next;
c1d497be 366 next = XCDR (next);
c6953be1 367 }
e3d5ca1e 368
137e23ea
RS
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
38c0d37c 391 if (CONSP (next))
c6953be1
JB
392 last_boundary = prev;
393
137e23ea 394 /* Keep additional undo data, if it fits in the limits. */
38c0d37c 395 while (CONSP (next))
c6953be1
JB
396 {
397 Lisp_Object elt;
c1d497be 398 elt = XCAR (next);
c6953be1
JB
399
400 /* When we get to a boundary, decide whether to truncate
137e23ea 401 either before or after it. The lower threshold, undo_limit,
c6953be1 402 tells us to truncate after it. If its size pushes past
137e23ea 403 the higher threshold undo_strong_limit, we truncate before it. */
265a9e55 404 if (NILP (elt))
c6953be1 405 {
137e23ea 406 if (size_so_far > undo_strong_limit)
c6953be1
JB
407 break;
408 last_boundary = prev;
137e23ea 409 if (size_so_far > undo_limit)
c6953be1
JB
410 break;
411 }
412
413 /* Add in the space occupied by this element and its chain link. */
414 size_so_far += sizeof (struct Lisp_Cons);
38c0d37c 415 if (CONSP (elt))
c6953be1
JB
416 {
417 size_so_far += sizeof (struct Lisp_Cons);
c1d497be 418 if (STRINGP (XCAR (elt)))
c6953be1 419 size_so_far += (sizeof (struct Lisp_String) - 1
d5db4077 420 + SCHARS (XCAR (elt)));
c6953be1
JB
421 }
422
423 /* Advance to next element. */
424 prev = next;
c1d497be 425 next = XCDR (next);
c6953be1
JB
426 }
427
428 /* If we scanned the whole list, it is short enough; don't change it. */
265a9e55 429 if (NILP (next))
137e23ea 430 ;
c6953be1 431 /* Truncate at the boundary where we decided to truncate. */
137e23ea
RS
432 else if (!NILP (last_boundary))
433 XSETCDR (last_boundary, Qnil);
434 /* There's nothing we decided to keep, so clear it out. */
c6953be1 435 else
137e23ea
RS
436 b->undo_list = Qnil;
437
438 unbind_to (count, Qnil);
c6953be1
JB
439}
440\f
441DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0,
8c1a1077
PJ
442 doc: /* Undo N records from the front of the list LIST.
443Return what remains of the list. */)
444 (n, list)
063fb61f 445 Lisp_Object n, list;
c6953be1 446{
de65837b
KH
447 struct gcpro gcpro1, gcpro2;
448 Lisp_Object next;
331379bf 449 int count = SPECPDL_INDEX ();
de65837b 450 register int arg;
177c0ea7 451
c6953be1
JB
452#if 0 /* This is a good feature, but would make undo-start
453 unable to do what is expected. */
454 Lisp_Object tem;
455
456 /* If the head of the list is a boundary, it is the boundary
457 preceding this command. Get rid of it and don't count it. */
458 tem = Fcar (list);
265a9e55 459 if (NILP (tem))
c6953be1
JB
460 list = Fcdr (list);
461#endif
462
b7826503 463 CHECK_NUMBER (n);
de65837b
KH
464 arg = XINT (n);
465 next = Qnil;
466 GCPRO2 (next, list);
467
38d56be3
GM
468 /* In a writable buffer, enable undoing read-only text that is so
469 because of text properties. */
470 if (NILP (current_buffer->read_only))
f87a68b3
RS
471 specbind (Qinhibit_read_only, Qt);
472
8c757fd7
GM
473 /* Don't let `intangible' properties interfere with undo. */
474 specbind (Qinhibit_point_motion_hooks, Qt);
475
c6953be1
JB
476 while (arg > 0)
477 {
c3b09bbf 478 while (CONSP (list))
c6953be1 479 {
c3b09bbf
SM
480 next = XCAR (list);
481 list = XCDR (list);
350bce56 482 /* Exit inner loop at undo boundary. */
265a9e55 483 if (NILP (next))
c6953be1 484 break;
350bce56 485 /* Handle an integer by setting point to that value. */
38c0d37c 486 if (INTEGERP (next))
350bce56 487 SET_PT (clip_to_bounds (BEGV, XINT (next), ZV));
38c0d37c 488 else if (CONSP (next))
c6953be1 489 {
350bce56
RS
490 Lisp_Object car, cdr;
491
c3b09bbf
SM
492 car = XCAR (next);
493 cdr = XCDR (next);
350bce56 494 if (EQ (car, Qt))
c6953be1 495 {
350bce56
RS
496 /* Element (t high . low) records previous modtime. */
497 Lisp_Object high, low;
498 int mod_time;
ad9cdce4 499 struct buffer *base_buffer = current_buffer;
350bce56
RS
500
501 high = Fcar (cdr);
502 low = Fcdr (cdr);
d8552b2f 503 mod_time = (XFASTINT (high) << 16) + XFASTINT (low);
ad9cdce4
RS
504
505 if (current_buffer->base_buffer)
506 base_buffer = current_buffer->base_buffer;
507
350bce56
RS
508 /* If this records an obsolete save
509 (not matching the actual disk file)
510 then don't mark unmodified. */
ad9cdce4 511 if (mod_time != base_buffer->modtime)
103dcb38 512 continue;
e6dd6080 513#ifdef CLASH_DETECTION
350bce56 514 Funlock_buffer ();
e6dd6080 515#endif /* CLASH_DETECTION */
350bce56 516 Fset_buffer_modified_p (Qnil);
c6953be1 517 }
d8552b2f 518 else if (EQ (car, Qnil))
da9319d5 519 {
d8552b2f 520 /* Element (nil prop val beg . end) is property change. */
da9319d5
RS
521 Lisp_Object beg, end, prop, val;
522
523 prop = Fcar (cdr);
524 cdr = Fcdr (cdr);
525 val = Fcar (cdr);
526 cdr = Fcdr (cdr);
527 beg = Fcar (cdr);
528 end = Fcdr (cdr);
529
530 Fput_text_property (beg, end, prop, val, Qnil);
531 }
38c0d37c 532 else if (INTEGERP (car) && INTEGERP (cdr))
c6953be1 533 {
350bce56 534 /* Element (BEG . END) means range was inserted. */
350bce56
RS
535
536 if (XINT (car) < BEGV
537 || XINT (cdr) > ZV)
c6953be1 538 error ("Changes to be undone are outside visible portion of buffer");
f28f04cc
RS
539 /* Set point first thing, so that undoing this undo
540 does not send point back to where it is now. */
350bce56 541 Fgoto_char (car);
f28f04cc 542 Fdelete_region (car, cdr);
350bce56 543 }
38c0d37c 544 else if (STRINGP (car) && INTEGERP (cdr))
350bce56
RS
545 {
546 /* Element (STRING . POS) means STRING was deleted. */
547 Lisp_Object membuf;
548 int pos = XINT (cdr);
549
550 membuf = car;
551 if (pos < 0)
552 {
553 if (-pos < BEGV || -pos > ZV)
554 error ("Changes to be undone are outside visible portion of buffer");
555 SET_PT (-pos);
556 Finsert (1, &membuf);
557 }
558 else
559 {
560 if (pos < BEGV || pos > ZV)
561 error ("Changes to be undone are outside visible portion of buffer");
562 SET_PT (pos);
563
b2adc409
RS
564 /* Now that we record marker adjustments
565 (caused by deletion) for undo,
566 we should always insert after markers,
567 so that undoing the marker adjustments
568 put the markers back in the right place. */
569 Finsert (1, &membuf);
350bce56
RS
570 SET_PT (pos);
571 }
c6953be1 572 }
714bced9
RS
573 else if (MARKERP (car) && INTEGERP (cdr))
574 {
575 /* (MARKER . INTEGER) means a marker MARKER
576 was adjusted by INTEGER. */
577 if (XMARKER (car)->buffer)
578 Fset_marker (car,
579 make_number (marker_position (car) - XINT (cdr)),
580 Fmarker_buffer (car));
581 }
c6953be1
JB
582 }
583 }
584 arg--;
585 }
586
de65837b 587 UNGCPRO;
f87a68b3 588 return unbind_to (count, list);
c6953be1
JB
589}
590
dfcf069d 591void
c6953be1
JB
592syms_of_undo ()
593{
f87a68b3
RS
594 Qinhibit_read_only = intern ("inhibit-read-only");
595 staticpro (&Qinhibit_read_only);
596
c58632fc
RS
597 pending_boundary = Qnil;
598 staticpro (&pending_boundary);
599
c6953be1
JB
600 defsubr (&Sprimitive_undo);
601 defsubr (&Sundo_boundary);
137e23ea
RS
602
603 DEFVAR_INT ("undo-limit", &undo_limit,
604 doc: /* Keep no more undo information once it exceeds this size.
605This limit is applied when garbage collection happens.
606When a previous command increases the total undo list size past this
607value, the earlier commands that came before it are forgotten.
608
609The size is counted as the number of bytes occupied,
610which 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.
615This limit is applied when garbage collection happens.
616When a previous command increases the total undo list size past this
617value, that command and the earlier commands that came before it are forgotten.
618However, the most recent buffer-modifying command's undo info
619is never discarded for this reason.
620
621The size is counted as the number of bytes occupied,
622which 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.
627At garbage collection time, if the current command has produced
628more than this much undo information, it asks you whether to delete
629the information. This is a last-ditch limit to prevent memory overflow.
630
631The size is counted as the number of bytes occupied,
632which includes both saved text and other data.
633
634In fact, this calls the function which is the value of
635`undo-outer-limit-function' with one argument, the size.
636The text above describes the behavior of the function
637that 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'.
642This function is called with one argument, the current undo list size
643for the most recent command (since the last undo boundary).
644If the function returns t, that means truncation has been fully handled.
645If it returns nil, the other forms of truncation are done.
646
647Garbage collection is inhibited around the call to this function,
648so it must make sure not to do a lot of consing. */);
649 Vundo_outer_limit_function = Qnil;
c6953be1 650}
ab5796a9
MB
651
652/* arch-tag: d546ee01-4aed-4ffb-bb8b-eefaae50d38a
653 (do not change this comment) */