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