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