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