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