Comment change.
[bpt/emacs.git] / src / insdel.c
1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 1986, 1993, 1994, 1995 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 #include <config.h>
22 #include "lisp.h"
23 #include "intervals.h"
24 #include "buffer.h"
25 #include "window.h"
26 #include "blockinput.h"
27
28 #define min(x, y) ((x) < (y) ? (x) : (y))
29
30 static void insert_from_string_1 ();
31 static void insert_from_buffer_1 ();
32 static void gap_left ();
33 static void gap_right ();
34 static void adjust_markers ();
35 static void adjust_point ();
36
37 /* Move gap to position `pos'.
38 Note that this can quit! */
39
40 void
41 move_gap (pos)
42 int pos;
43 {
44 if (pos < GPT)
45 gap_left (pos, 0);
46 else if (pos > GPT)
47 gap_right (pos);
48 }
49
50 /* Move the gap to POS, which is less than the current GPT.
51 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
52
53 static void
54 gap_left (pos, newgap)
55 register int pos;
56 int newgap;
57 {
58 register unsigned char *to, *from;
59 register int i;
60 int new_s1;
61
62 pos--;
63
64 if (!newgap)
65 {
66 if (unchanged_modified == MODIFF)
67 {
68 beg_unchanged = pos;
69 end_unchanged = Z - pos - 1;
70 }
71 else
72 {
73 if (Z - GPT < end_unchanged)
74 end_unchanged = Z - GPT;
75 if (pos < beg_unchanged)
76 beg_unchanged = pos;
77 }
78 }
79
80 i = GPT;
81 to = GAP_END_ADDR;
82 from = GPT_ADDR;
83 new_s1 = GPT - BEG;
84
85 /* Now copy the characters. To move the gap down,
86 copy characters up. */
87
88 while (1)
89 {
90 /* I gets number of characters left to copy. */
91 i = new_s1 - pos;
92 if (i == 0)
93 break;
94 /* If a quit is requested, stop copying now.
95 Change POS to be where we have actually moved the gap to. */
96 if (QUITP)
97 {
98 pos = new_s1;
99 break;
100 }
101 /* Move at most 32000 chars before checking again for a quit. */
102 if (i > 32000)
103 i = 32000;
104 #ifdef GAP_USE_BCOPY
105 if (i >= 128
106 /* bcopy is safe if the two areas of memory do not overlap
107 or on systems where bcopy is always safe for moving upward. */
108 && (BCOPY_UPWARD_SAFE
109 || to - from >= 128))
110 {
111 /* If overlap is not safe, avoid it by not moving too many
112 characters at once. */
113 if (!BCOPY_UPWARD_SAFE && i > to - from)
114 i = to - from;
115 new_s1 -= i;
116 from -= i, to -= i;
117 bcopy (from, to, i);
118 }
119 else
120 #endif
121 {
122 new_s1 -= i;
123 while (--i >= 0)
124 *--to = *--from;
125 }
126 }
127
128 /* Adjust markers, and buffer data structure, to put the gap at POS.
129 POS is where the loop above stopped, which may be what was specified
130 or may be where a quit was detected. */
131 adjust_markers (pos + 1, GPT, GAP_SIZE);
132 GPT = pos + 1;
133 QUIT;
134 }
135
136 static void
137 gap_right (pos)
138 register int pos;
139 {
140 register unsigned char *to, *from;
141 register int i;
142 int new_s1;
143
144 pos--;
145
146 if (unchanged_modified == MODIFF)
147 {
148 beg_unchanged = pos;
149 end_unchanged = Z - pos - 1;
150 }
151 else
152 {
153 if (Z - pos - 1 < end_unchanged)
154 end_unchanged = Z - pos - 1;
155 if (GPT - BEG < beg_unchanged)
156 beg_unchanged = GPT - BEG;
157 }
158
159 i = GPT;
160 from = GAP_END_ADDR;
161 to = GPT_ADDR;
162 new_s1 = GPT - 1;
163
164 /* Now copy the characters. To move the gap up,
165 copy characters down. */
166
167 while (1)
168 {
169 /* I gets number of characters left to copy. */
170 i = pos - new_s1;
171 if (i == 0)
172 break;
173 /* If a quit is requested, stop copying now.
174 Change POS to be where we have actually moved the gap to. */
175 if (QUITP)
176 {
177 pos = new_s1;
178 break;
179 }
180 /* Move at most 32000 chars before checking again for a quit. */
181 if (i > 32000)
182 i = 32000;
183 #ifdef GAP_USE_BCOPY
184 if (i >= 128
185 /* bcopy is safe if the two areas of memory do not overlap
186 or on systems where bcopy is always safe for moving downward. */
187 && (BCOPY_DOWNWARD_SAFE
188 || from - to >= 128))
189 {
190 /* If overlap is not safe, avoid it by not moving too many
191 characters at once. */
192 if (!BCOPY_DOWNWARD_SAFE && i > from - to)
193 i = from - to;
194 new_s1 += i;
195 bcopy (from, to, i);
196 from += i, to += i;
197 }
198 else
199 #endif
200 {
201 new_s1 += i;
202 while (--i >= 0)
203 *to++ = *from++;
204 }
205 }
206
207 adjust_markers (GPT + GAP_SIZE, pos + 1 + GAP_SIZE, - GAP_SIZE);
208 GPT = pos + 1;
209 QUIT;
210 }
211
212 /* Add `amount' to the position of every marker in the current buffer
213 whose current position is between `from' (exclusive) and `to' (inclusive).
214 Also, any markers past the outside of that interval, in the direction
215 of adjustment, are first moved back to the near end of the interval
216 and then adjusted by `amount'. */
217
218 static void
219 adjust_markers (from, to, amount)
220 register int from, to, amount;
221 {
222 Lisp_Object marker;
223 register struct Lisp_Marker *m;
224 register int mpos;
225
226 marker = BUF_MARKERS (current_buffer);
227
228 while (!NILP (marker))
229 {
230 m = XMARKER (marker);
231 mpos = m->bufpos;
232 if (amount > 0)
233 {
234 if (mpos > to && mpos < to + amount)
235 mpos = to + amount;
236 }
237 else
238 {
239 if (mpos > from + amount && mpos <= from)
240 mpos = from + amount;
241 }
242 if (mpos > from && mpos <= to)
243 mpos += amount;
244 m->bufpos = mpos;
245 marker = m->chain;
246 }
247 }
248
249 /* Add the specified amount to point. This is used only when the value
250 of point changes due to an insert or delete; it does not represent
251 a conceptual change in point as a marker. In particular, point is
252 not crossing any interval boundaries, so there's no need to use the
253 usual SET_PT macro. In fact it would be incorrect to do so, because
254 either the old or the new value of point is out of synch with the
255 current set of intervals. */
256 static void
257 adjust_point (amount)
258 int amount;
259 {
260 BUF_PT (current_buffer) += amount;
261 }
262 \f
263 /* Make the gap INCREMENT characters longer. */
264
265 void
266 make_gap (increment)
267 int increment;
268 {
269 unsigned char *result;
270 Lisp_Object tem;
271 int real_gap_loc;
272 int old_gap_size;
273
274 /* If we have to get more space, get enough to last a while. */
275 increment += 2000;
276
277 /* Don't allow a buffer size that won't fit in an int
278 even if it will fit in a Lisp integer.
279 That won't work because so many places use `int'. */
280
281 if (Z - BEG + GAP_SIZE + increment
282 >= ((unsigned) 1 << (min (INTBITS, VALBITS) - 1)))
283 error ("Buffer exceeds maximum size");
284
285 BLOCK_INPUT;
286 result = BUFFER_REALLOC (BEG_ADDR, (Z - BEG + GAP_SIZE + increment));
287
288 if (result == 0)
289 {
290 UNBLOCK_INPUT;
291 memory_full ();
292 }
293
294 /* We can't unblock until the new address is properly stored. */
295 BEG_ADDR = result;
296 UNBLOCK_INPUT;
297
298 /* Prevent quitting in move_gap. */
299 tem = Vinhibit_quit;
300 Vinhibit_quit = Qt;
301
302 real_gap_loc = GPT;
303 old_gap_size = GAP_SIZE;
304
305 /* Call the newly allocated space a gap at the end of the whole space. */
306 GPT = Z + GAP_SIZE;
307 GAP_SIZE = increment;
308
309 /* Move the new gap down to be consecutive with the end of the old one.
310 This adjusts the markers properly too. */
311 gap_left (real_gap_loc + old_gap_size, 1);
312
313 /* Now combine the two into one large gap. */
314 GAP_SIZE += old_gap_size;
315 GPT = real_gap_loc;
316
317 Vinhibit_quit = tem;
318 }
319 \f
320 /* Insert a string of specified length before point.
321 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
322 prepare_to_modify_buffer could relocate the text. */
323
324 void
325 insert (string, length)
326 register unsigned char *string;
327 register length;
328 {
329 if (length > 0)
330 {
331 insert_1 (string, length, 0, 1);
332 signal_after_change (PT-length, 0, length);
333 }
334 }
335
336 void
337 insert_and_inherit (string, length)
338 register unsigned char *string;
339 register length;
340 {
341 if (length > 0)
342 {
343 insert_1 (string, length, 1, 1);
344 signal_after_change (PT-length, 0, length);
345 }
346 }
347
348 void
349 insert_1 (string, length, inherit, prepare)
350 register unsigned char *string;
351 register int length;
352 int inherit, prepare;
353 {
354 register Lisp_Object temp;
355
356 if (prepare)
357 prepare_to_modify_buffer (PT, PT);
358
359 if (PT != GPT)
360 move_gap (PT);
361 if (GAP_SIZE < length)
362 make_gap (length - GAP_SIZE);
363
364 record_insert (PT, length);
365 MODIFF++;
366
367 bcopy (string, GPT_ADDR, length);
368
369 #ifdef USE_TEXT_PROPERTIES
370 if (BUF_INTERVALS (current_buffer) != 0)
371 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
372 offset_intervals (current_buffer, PT, length);
373 #endif
374
375 GAP_SIZE -= length;
376 GPT += length;
377 ZV += length;
378 Z += length;
379 adjust_overlays_for_insert (PT, length);
380 adjust_point (length);
381
382 #ifdef USE_TEXT_PROPERTIES
383 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
384 Fset_text_properties (make_number (PT - length), make_number (PT),
385 Qnil, Qnil);
386 #endif
387 }
388
389 /* Insert the part of the text of STRING, a Lisp object assumed to be
390 of type string, consisting of the LENGTH characters starting at
391 position POS. If the text of STRING has properties, they are absorbed
392 into the buffer.
393
394 It does not work to use `insert' for this, because a GC could happen
395 before we bcopy the stuff into the buffer, and relocate the string
396 without insert noticing. */
397
398 void
399 insert_from_string (string, pos, length, inherit)
400 Lisp_Object string;
401 register int pos, length;
402 int inherit;
403 {
404 if (length > 0)
405 {
406 insert_from_string_1 (string, pos, length, inherit);
407 signal_after_change (PT-length, 0, length);
408 }
409 }
410
411 static void
412 insert_from_string_1 (string, pos, length, inherit)
413 Lisp_Object string;
414 register int pos, length;
415 int inherit;
416 {
417 register Lisp_Object temp;
418 struct gcpro gcpro1;
419
420 /* Make sure point-max won't overflow after this insertion. */
421 XSETINT (temp, length + Z);
422 if (length + Z != XINT (temp))
423 error ("maximum buffer size exceeded");
424
425 GCPRO1 (string);
426 prepare_to_modify_buffer (PT, PT);
427
428 if (PT != GPT)
429 move_gap (PT);
430 if (GAP_SIZE < length)
431 make_gap (length - GAP_SIZE);
432
433 record_insert (PT, length);
434 MODIFF++;
435 UNGCPRO;
436
437 bcopy (XSTRING (string)->data, GPT_ADDR, length);
438
439 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
440 offset_intervals (current_buffer, PT, length);
441
442 GAP_SIZE -= length;
443 GPT += length;
444 ZV += length;
445 Z += length;
446 adjust_overlays_for_insert (PT, length);
447
448 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
449 graft_intervals_into_buffer (XSTRING (string)->intervals, PT, length,
450 current_buffer, inherit);
451
452 adjust_point (length);
453 }
454
455 /* Insert text from BUF, starting at POS and having length LENGTH, into the
456 current buffer. If the text in BUF has properties, they are absorbed
457 into the current buffer.
458
459 It does not work to use `insert' for this, because a malloc could happen
460 and relocate BUF's text before the bcopy happens. */
461
462 void
463 insert_from_buffer (buf, pos, length, inherit)
464 struct buffer *buf;
465 int pos, length;
466 int inherit;
467 {
468 if (length > 0)
469 {
470 insert_from_buffer_1 (buf, pos, length, inherit);
471 signal_after_change (PT-length, 0, length);
472 }
473 }
474
475 static void
476 insert_from_buffer_1 (buf, pos, length, inherit)
477 struct buffer *buf;
478 int pos, length;
479 int inherit;
480 {
481 register Lisp_Object temp;
482 int chunk;
483
484 /* Make sure point-max won't overflow after this insertion. */
485 XSETINT (temp, length + Z);
486 if (length + Z != XINT (temp))
487 error ("maximum buffer size exceeded");
488
489 prepare_to_modify_buffer (PT, PT);
490
491 if (PT != GPT)
492 move_gap (PT);
493 if (GAP_SIZE < length)
494 make_gap (length - GAP_SIZE);
495
496 record_insert (PT, length);
497 MODIFF++;
498
499 if (pos < BUF_GPT (buf))
500 {
501 chunk = BUF_GPT (buf) - pos;
502 if (chunk > length)
503 chunk = length;
504 bcopy (BUF_CHAR_ADDRESS (buf, pos), GPT_ADDR, chunk);
505 }
506 else
507 chunk = 0;
508 if (chunk < length)
509 bcopy (BUF_CHAR_ADDRESS (buf, pos + chunk),
510 GPT_ADDR + chunk, length - chunk);
511
512 #ifdef USE_TEXT_PROPERTIES
513 if (BUF_INTERVALS (current_buffer) != 0)
514 offset_intervals (current_buffer, PT, length);
515 #endif
516
517 GAP_SIZE -= length;
518 GPT += length;
519 ZV += length;
520 Z += length;
521 adjust_overlays_for_insert (PT, length);
522 adjust_point (length);
523
524 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
525 graft_intervals_into_buffer (copy_intervals (BUF_INTERVALS (buf),
526 pos, length),
527 PT - length, length, current_buffer, inherit);
528 }
529
530 /* Insert the character C before point */
531
532 void
533 insert_char (c)
534 unsigned char c;
535 {
536 insert (&c, 1);
537 }
538
539 /* Insert the null-terminated string S before point */
540
541 void
542 insert_string (s)
543 char *s;
544 {
545 insert (s, strlen (s));
546 }
547
548 /* Like `insert' except that all markers pointing at the place where
549 the insertion happens are adjusted to point after it.
550 Don't use this function to insert part of a Lisp string,
551 since gc could happen and relocate it. */
552
553 void
554 insert_before_markers (string, length)
555 unsigned char *string;
556 register int length;
557 {
558 if (length > 0)
559 {
560 register int opoint = PT;
561 insert_1 (string, length, 0, 1);
562 adjust_markers (opoint - 1, opoint, length);
563 signal_after_change (PT-length, 0, length);
564 }
565 }
566
567 void
568 insert_before_markers_and_inherit (string, length)
569 unsigned char *string;
570 register int length;
571 {
572 if (length > 0)
573 {
574 register int opoint = PT;
575 insert_1 (string, length, 1, 1);
576 adjust_markers (opoint - 1, opoint, length);
577 signal_after_change (PT-length, 0, length);
578 }
579 }
580
581 /* Insert part of a Lisp string, relocating markers after. */
582
583 void
584 insert_from_string_before_markers (string, pos, length, inherit)
585 Lisp_Object string;
586 register int pos, length;
587 int inherit;
588 {
589 if (length > 0)
590 {
591 register int opoint = PT;
592 insert_from_string_1 (string, pos, length, inherit);
593 adjust_markers (opoint - 1, opoint, length);
594 signal_after_change (PT-length, 0, length);
595 }
596 }
597 \f
598 /* Delete characters in current buffer
599 from FROM up to (but not including) TO. */
600
601 void
602 del_range (from, to)
603 register int from, to;
604 {
605 del_range_1 (from, to, 1);
606 }
607
608 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
609
610 void
611 del_range_1 (from, to, prepare)
612 register int from, to, prepare;
613 {
614 register int numdel;
615
616 /* Make args be valid */
617 if (from < BEGV)
618 from = BEGV;
619 if (to > ZV)
620 to = ZV;
621
622 if ((numdel = to - from) <= 0)
623 return;
624
625 /* Make sure the gap is somewhere in or next to what we are deleting. */
626 if (from > GPT)
627 gap_right (from);
628 if (to < GPT)
629 gap_left (to, 0);
630
631 if (prepare)
632 prepare_to_modify_buffer (from, to);
633
634 record_delete (from, numdel);
635 MODIFF++;
636
637 /* Relocate point as if it were a marker. */
638 if (from < PT)
639 adjust_point (from - (PT < to ? PT : to));
640
641 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
642 offset_intervals (current_buffer, from, - numdel);
643
644 /* Relocate all markers pointing into the new, larger gap
645 to point at the end of the text before the gap. */
646 adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE);
647
648 /* Adjust the overlay center as needed. This must be done after
649 adjusting the markers that bound the overlays. */
650 adjust_overlays_for_delete (from, numdel);
651
652 GAP_SIZE += numdel;
653 ZV -= numdel;
654 Z -= numdel;
655 GPT = from;
656
657 if (GPT - BEG < beg_unchanged)
658 beg_unchanged = GPT - BEG;
659 if (Z - GPT < end_unchanged)
660 end_unchanged = Z - GPT;
661
662 evaporate_overlays (from);
663 signal_after_change (from, numdel, 0);
664 }
665 \f
666 /* Call this if you're about to change the region of BUFFER from START
667 to END. This checks the read-only properties of the region, calls
668 the necessary modification hooks, and warns the next redisplay that
669 it should pay attention to that area. */
670 void
671 modify_region (buffer, start, end)
672 struct buffer *buffer;
673 int start, end;
674 {
675 struct buffer *old_buffer = current_buffer;
676
677 if (buffer != old_buffer)
678 set_buffer_internal (buffer);
679
680 prepare_to_modify_buffer (start, end);
681
682 if (start - 1 < beg_unchanged || unchanged_modified == MODIFF)
683 beg_unchanged = start - 1;
684 if (Z - end < end_unchanged
685 || unchanged_modified == MODIFF)
686 end_unchanged = Z - end;
687
688 if (MODIFF <= SAVE_MODIFF)
689 record_first_change ();
690 MODIFF++;
691
692 buffer->point_before_scroll = Qnil;
693
694 if (buffer != old_buffer)
695 set_buffer_internal (old_buffer);
696 }
697
698 /* Check that it is okay to modify the buffer between START and END.
699 Run the before-change-function, if any. If intervals are in use,
700 verify that the text to be modified is not read-only, and call
701 any modification properties the text may have. */
702
703 void
704 prepare_to_modify_buffer (start, end)
705 Lisp_Object start, end;
706 {
707 if (!NILP (current_buffer->read_only))
708 Fbarf_if_buffer_read_only ();
709
710 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
711 if (BUF_INTERVALS (current_buffer) != 0)
712 verify_interval_modification (current_buffer, start, end);
713
714 #ifdef CLASH_DETECTION
715 if (!NILP (current_buffer->file_truename)
716 && SAVE_MODIFF >= MODIFF)
717 lock_file (current_buffer->file_truename);
718 #else
719 /* At least warn if this file has changed on disk since it was visited. */
720 if (!NILP (current_buffer->filename)
721 && SAVE_MODIFF >= MODIFF
722 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
723 && !NILP (Ffile_exists_p (current_buffer->filename)))
724 call1 (intern ("ask-user-about-supersession-threat"),
725 current_buffer->filename);
726 #endif /* not CLASH_DETECTION */
727
728 signal_before_change (start, end);
729
730 if (current_buffer->newline_cache)
731 invalidate_region_cache (current_buffer,
732 current_buffer->newline_cache,
733 start - BEG, Z - end);
734 if (current_buffer->width_run_cache)
735 invalidate_region_cache (current_buffer,
736 current_buffer->width_run_cache,
737 start - BEG, Z - end);
738
739 Vdeactivate_mark = Qt;
740 }
741 \f
742 static Lisp_Object
743 before_change_function_restore (value)
744 Lisp_Object value;
745 {
746 Vbefore_change_function = value;
747 }
748
749 static Lisp_Object
750 after_change_function_restore (value)
751 Lisp_Object value;
752 {
753 Vafter_change_function = value;
754 }
755
756 static Lisp_Object
757 before_change_functions_restore (value)
758 Lisp_Object value;
759 {
760 Vbefore_change_functions = value;
761 }
762
763 static Lisp_Object
764 after_change_functions_restore (value)
765 Lisp_Object value;
766 {
767 Vafter_change_functions = value;
768 }
769
770 /* Signal a change to the buffer immediately before it happens.
771 START and END are the bounds of the text to be changed,
772 as Lisp objects. */
773
774 void
775 signal_before_change (start, end)
776 Lisp_Object start, end;
777 {
778 /* If buffer is unmodified, run a special hook for that case. */
779 if (SAVE_MODIFF >= MODIFF
780 && !NILP (Vfirst_change_hook)
781 && !NILP (Vrun_hooks))
782 call1 (Vrun_hooks, Qfirst_change_hook);
783
784 /* Now in any case run the before-change-function if any. */
785 if (!NILP (Vbefore_change_function))
786 {
787 int count = specpdl_ptr - specpdl;
788 Lisp_Object function;
789
790 function = Vbefore_change_function;
791
792 record_unwind_protect (after_change_function_restore,
793 Vafter_change_function);
794 record_unwind_protect (before_change_function_restore,
795 Vbefore_change_function);
796 record_unwind_protect (after_change_functions_restore,
797 Vafter_change_functions);
798 record_unwind_protect (before_change_functions_restore,
799 Vbefore_change_functions);
800 Vafter_change_function = Qnil;
801 Vbefore_change_function = Qnil;
802 Vafter_change_functions = Qnil;
803 Vbefore_change_functions = Qnil;
804
805 call2 (function, start, end);
806 unbind_to (count, Qnil);
807 }
808
809 /* Now in any case run the before-change-function if any. */
810 if (!NILP (Vbefore_change_functions))
811 {
812 int count = specpdl_ptr - specpdl;
813 Lisp_Object functions;
814
815 functions = Vbefore_change_functions;
816
817 record_unwind_protect (after_change_function_restore,
818 Vafter_change_function);
819 record_unwind_protect (before_change_function_restore,
820 Vbefore_change_function);
821 record_unwind_protect (after_change_functions_restore,
822 Vafter_change_functions);
823 record_unwind_protect (before_change_functions_restore,
824 Vbefore_change_functions);
825 Vafter_change_function = Qnil;
826 Vbefore_change_function = Qnil;
827 Vafter_change_functions = Qnil;
828 Vbefore_change_functions = Qnil;
829
830 while (CONSP (functions))
831 {
832 call2 (XCONS (functions)->car, start, end);
833 functions = XCONS (functions)->cdr;
834 }
835 unbind_to (count, Qnil);
836 }
837
838 if (!NILP (current_buffer->overlays_before)
839 || !NILP (current_buffer->overlays_after))
840 report_overlay_modification (start, end, 0, start, end, Qnil);
841 }
842
843 /* Signal a change immediately after it happens.
844 POS is the address of the start of the changed text.
845 LENDEL is the number of characters of the text before the change.
846 (Not the whole buffer; just the part that was changed.)
847 LENINS is the number of characters in the changed text.
848
849 (Hence POS + LENINS - LENDEL is the position after the changed text.) */
850
851 void
852 signal_after_change (pos, lendel, lenins)
853 int pos, lendel, lenins;
854 {
855 if (!NILP (Vafter_change_function))
856 {
857 int count = specpdl_ptr - specpdl;
858 Lisp_Object function;
859 function = Vafter_change_function;
860
861 record_unwind_protect (after_change_function_restore,
862 Vafter_change_function);
863 record_unwind_protect (before_change_function_restore,
864 Vbefore_change_function);
865 record_unwind_protect (after_change_functions_restore,
866 Vafter_change_functions);
867 record_unwind_protect (before_change_functions_restore,
868 Vbefore_change_functions);
869 Vafter_change_function = Qnil;
870 Vbefore_change_function = Qnil;
871 Vafter_change_functions = Qnil;
872 Vbefore_change_functions = Qnil;
873
874 call3 (function, make_number (pos), make_number (pos + lenins),
875 make_number (lendel));
876 unbind_to (count, Qnil);
877 }
878 if (!NILP (Vafter_change_functions))
879 {
880 int count = specpdl_ptr - specpdl;
881 Lisp_Object functions;
882 functions = Vafter_change_functions;
883
884 record_unwind_protect (after_change_function_restore,
885 Vafter_change_function);
886 record_unwind_protect (before_change_function_restore,
887 Vbefore_change_function);
888 record_unwind_protect (after_change_functions_restore,
889 Vafter_change_functions);
890 record_unwind_protect (before_change_functions_restore,
891 Vbefore_change_functions);
892 Vafter_change_function = Qnil;
893 Vbefore_change_function = Qnil;
894 Vafter_change_functions = Qnil;
895 Vbefore_change_functions = Qnil;
896
897 while (CONSP (functions))
898 {
899 call3 (XCONS (functions)->car,
900 make_number (pos), make_number (pos + lenins),
901 make_number (lendel));
902 functions = XCONS (functions)->cdr;
903 }
904 unbind_to (count, Qnil);
905 }
906
907 if (!NILP (current_buffer->overlays_before)
908 || !NILP (current_buffer->overlays_after))
909 report_overlay_modification (make_number (pos),
910 make_number (pos + lenins - lendel),
911 1,
912 make_number (pos), make_number (pos + lenins),
913 make_number (lendel));
914 }