Correct initial line typo.
[emacs.git] / src / insdel.c
blobe68676470075852a37495afa278ebf6e8630aaf3
1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 1986, 1993, 1994, 1995 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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.
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.
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. */
21 #include <config.h>
22 #include "lisp.h"
23 #include "intervals.h"
24 #include "buffer.h"
25 #include "window.h"
26 #include "blockinput.h"
28 #define min(x, y) ((x) < (y) ? (x) : (y))
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 ();
37 /* Move gap to position `pos'.
38 Note that this can quit! */
40 void
41 move_gap (pos)
42 int pos;
44 if (pos < GPT)
45 gap_left (pos, 0);
46 else if (pos > GPT)
47 gap_right (pos);
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. */
53 static void
54 gap_left (pos, newgap)
55 register int pos;
56 int newgap;
58 register unsigned char *to, *from;
59 register int i;
60 int new_s1;
62 pos--;
64 if (!newgap)
66 if (unchanged_modified == MODIFF)
68 beg_unchanged = pos;
69 end_unchanged = Z - pos - 1;
71 else
73 if (Z - GPT < end_unchanged)
74 end_unchanged = Z - GPT;
75 if (pos < beg_unchanged)
76 beg_unchanged = pos;
80 i = GPT;
81 to = GAP_END_ADDR;
82 from = GPT_ADDR;
83 new_s1 = GPT - BEG;
85 /* Now copy the characters. To move the gap down,
86 copy characters up. */
88 while (1)
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)
98 pos = new_s1;
99 break;
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))
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);
119 else
120 #endif
122 new_s1 -= i;
123 while (--i >= 0)
124 *--to = *--from;
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;
136 static void
137 gap_right (pos)
138 register int pos;
140 register unsigned char *to, *from;
141 register int i;
142 int new_s1;
144 pos--;
146 if (unchanged_modified == MODIFF)
148 beg_unchanged = pos;
149 end_unchanged = Z - pos - 1;
151 else
153 if (Z - pos - 1 < end_unchanged)
154 end_unchanged = Z - pos - 1;
155 if (GPT - BEG < beg_unchanged)
156 beg_unchanged = GPT - BEG;
159 i = GPT;
160 from = GAP_END_ADDR;
161 to = GPT_ADDR;
162 new_s1 = GPT - 1;
164 /* Now copy the characters. To move the gap up,
165 copy characters down. */
167 while (1)
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)
177 pos = new_s1;
178 break;
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))
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;
198 else
199 #endif
201 new_s1 += i;
202 while (--i >= 0)
203 *to++ = *from++;
207 adjust_markers (GPT + GAP_SIZE, pos + 1 + GAP_SIZE, - GAP_SIZE);
208 GPT = pos + 1;
209 QUIT;
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'. */
218 static void
219 adjust_markers (from, to, amount)
220 register int from, to, amount;
222 Lisp_Object marker;
223 register struct Lisp_Marker *m;
224 register int mpos;
226 marker = BUF_MARKERS (current_buffer);
228 while (!NILP (marker))
230 m = XMARKER (marker);
231 mpos = m->bufpos;
232 if (amount > 0)
234 if (mpos > to && mpos < to + amount)
235 mpos = to + amount;
237 else
239 if (mpos > from + amount && mpos <= from)
240 mpos = from + amount;
242 if (mpos > from && mpos <= to)
243 mpos += amount;
244 m->bufpos = mpos;
245 marker = m->chain;
249 /* Adjust markers whose insertion-type is t
250 for an insertion of AMOUNT characters at POS. */
252 static void
253 adjust_markers_for_insert (pos, amount)
254 register int pos, amount;
256 Lisp_Object marker;
258 marker = BUF_MARKERS (current_buffer);
260 while (!NILP (marker))
262 register struct Lisp_Marker *m = XMARKER (marker);
263 if (m->insertion_type && m->bufpos == pos)
264 m->bufpos += amount;
265 marker = m->chain;
269 /* Add the specified amount to point. This is used only when the value
270 of point changes due to an insert or delete; it does not represent
271 a conceptual change in point as a marker. In particular, point is
272 not crossing any interval boundaries, so there's no need to use the
273 usual SET_PT macro. In fact it would be incorrect to do so, because
274 either the old or the new value of point is out of synch with the
275 current set of intervals. */
276 static void
277 adjust_point (amount)
278 int amount;
280 BUF_PT (current_buffer) += amount;
283 /* Make the gap INCREMENT characters longer. */
285 void
286 make_gap (increment)
287 int increment;
289 unsigned char *result;
290 Lisp_Object tem;
291 int real_gap_loc;
292 int old_gap_size;
294 /* If we have to get more space, get enough to last a while. */
295 increment += 2000;
297 /* Don't allow a buffer size that won't fit in an int
298 even if it will fit in a Lisp integer.
299 That won't work because so many places use `int'. */
301 if (Z - BEG + GAP_SIZE + increment
302 >= ((unsigned) 1 << (min (INTBITS, VALBITS) - 1)))
303 error ("Buffer exceeds maximum size");
305 BLOCK_INPUT;
306 result = BUFFER_REALLOC (BEG_ADDR, (Z - BEG + GAP_SIZE + increment));
308 if (result == 0)
310 UNBLOCK_INPUT;
311 memory_full ();
314 /* We can't unblock until the new address is properly stored. */
315 BEG_ADDR = result;
316 UNBLOCK_INPUT;
318 /* Prevent quitting in move_gap. */
319 tem = Vinhibit_quit;
320 Vinhibit_quit = Qt;
322 real_gap_loc = GPT;
323 old_gap_size = GAP_SIZE;
325 /* Call the newly allocated space a gap at the end of the whole space. */
326 GPT = Z + GAP_SIZE;
327 GAP_SIZE = increment;
329 /* Move the new gap down to be consecutive with the end of the old one.
330 This adjusts the markers properly too. */
331 gap_left (real_gap_loc + old_gap_size, 1);
333 /* Now combine the two into one large gap. */
334 GAP_SIZE += old_gap_size;
335 GPT = real_gap_loc;
337 Vinhibit_quit = tem;
340 /* Insert a string of specified length before point.
341 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
342 prepare_to_modify_buffer could relocate the text. */
344 void
345 insert (string, length)
346 register unsigned char *string;
347 register length;
349 if (length > 0)
351 insert_1 (string, length, 0, 1);
352 signal_after_change (PT-length, 0, length);
356 void
357 insert_and_inherit (string, length)
358 register unsigned char *string;
359 register length;
361 if (length > 0)
363 insert_1 (string, length, 1, 1);
364 signal_after_change (PT-length, 0, length);
368 void
369 insert_1 (string, length, inherit, prepare)
370 register unsigned char *string;
371 register int length;
372 int inherit, prepare;
374 register Lisp_Object temp;
376 if (prepare)
377 prepare_to_modify_buffer (PT, PT);
379 if (PT != GPT)
380 move_gap (PT);
381 if (GAP_SIZE < length)
382 make_gap (length - GAP_SIZE);
384 record_insert (PT, length);
385 MODIFF++;
387 bcopy (string, GPT_ADDR, length);
389 #ifdef USE_TEXT_PROPERTIES
390 if (BUF_INTERVALS (current_buffer) != 0)
391 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
392 offset_intervals (current_buffer, PT, length);
393 #endif
395 GAP_SIZE -= length;
396 GPT += length;
397 ZV += length;
398 Z += length;
399 adjust_overlays_for_insert (PT, length);
400 adjust_markers_for_insert (PT, length);
401 adjust_point (length);
403 #ifdef USE_TEXT_PROPERTIES
404 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
405 Fset_text_properties (make_number (PT - length), make_number (PT),
406 Qnil, Qnil);
407 #endif
410 /* Insert the part of the text of STRING, a Lisp object assumed to be
411 of type string, consisting of the LENGTH characters starting at
412 position POS. If the text of STRING has properties, they are absorbed
413 into the buffer.
415 It does not work to use `insert' for this, because a GC could happen
416 before we bcopy the stuff into the buffer, and relocate the string
417 without insert noticing. */
419 void
420 insert_from_string (string, pos, length, inherit)
421 Lisp_Object string;
422 register int pos, length;
423 int inherit;
425 if (length > 0)
427 insert_from_string_1 (string, pos, length, inherit);
428 signal_after_change (PT-length, 0, length);
432 static void
433 insert_from_string_1 (string, pos, length, inherit)
434 Lisp_Object string;
435 register int pos, length;
436 int inherit;
438 register Lisp_Object temp;
439 struct gcpro gcpro1;
441 /* Make sure point-max won't overflow after this insertion. */
442 XSETINT (temp, length + Z);
443 if (length + Z != XINT (temp))
444 error ("maximum buffer size exceeded");
446 GCPRO1 (string);
447 prepare_to_modify_buffer (PT, PT);
449 if (PT != GPT)
450 move_gap (PT);
451 if (GAP_SIZE < length)
452 make_gap (length - GAP_SIZE);
454 record_insert (PT, length);
455 MODIFF++;
456 UNGCPRO;
458 bcopy (XSTRING (string)->data, GPT_ADDR, length);
460 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
461 offset_intervals (current_buffer, PT, length);
463 GAP_SIZE -= length;
464 GPT += length;
465 ZV += length;
466 Z += length;
467 adjust_overlays_for_insert (PT, length);
468 adjust_markers_for_insert (PT, length);
470 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
471 graft_intervals_into_buffer (XSTRING (string)->intervals, PT, length,
472 current_buffer, inherit);
474 adjust_point (length);
477 /* Insert text from BUF, starting at POS and having length LENGTH, into the
478 current buffer. If the text in BUF has properties, they are absorbed
479 into the current buffer.
481 It does not work to use `insert' for this, because a malloc could happen
482 and relocate BUF's text before the bcopy happens. */
484 void
485 insert_from_buffer (buf, pos, length, inherit)
486 struct buffer *buf;
487 int pos, length;
488 int inherit;
490 if (length > 0)
492 insert_from_buffer_1 (buf, pos, length, inherit);
493 signal_after_change (PT-length, 0, length);
497 static void
498 insert_from_buffer_1 (buf, pos, length, inherit)
499 struct buffer *buf;
500 int pos, length;
501 int inherit;
503 register Lisp_Object temp;
504 int chunk;
506 /* Make sure point-max won't overflow after this insertion. */
507 XSETINT (temp, length + Z);
508 if (length + Z != XINT (temp))
509 error ("maximum buffer size exceeded");
511 prepare_to_modify_buffer (PT, PT);
513 if (PT != GPT)
514 move_gap (PT);
515 if (GAP_SIZE < length)
516 make_gap (length - GAP_SIZE);
518 record_insert (PT, length);
519 MODIFF++;
521 if (pos < BUF_GPT (buf))
523 chunk = BUF_GPT (buf) - pos;
524 if (chunk > length)
525 chunk = length;
526 bcopy (BUF_CHAR_ADDRESS (buf, pos), GPT_ADDR, chunk);
528 else
529 chunk = 0;
530 if (chunk < length)
531 bcopy (BUF_CHAR_ADDRESS (buf, pos + chunk),
532 GPT_ADDR + chunk, length - chunk);
534 #ifdef USE_TEXT_PROPERTIES
535 if (BUF_INTERVALS (current_buffer) != 0)
536 offset_intervals (current_buffer, PT, length);
537 #endif
539 GAP_SIZE -= length;
540 GPT += length;
541 ZV += length;
542 Z += length;
543 adjust_overlays_for_insert (PT, length);
544 adjust_markers_for_insert (PT, length);
545 adjust_point (length);
547 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
548 graft_intervals_into_buffer (copy_intervals (BUF_INTERVALS (buf),
549 pos, length),
550 PT - length, length, current_buffer, inherit);
553 /* Insert the character C before point */
555 void
556 insert_char (c)
557 unsigned char c;
559 insert (&c, 1);
562 /* Insert the null-terminated string S before point */
564 void
565 insert_string (s)
566 char *s;
568 insert (s, strlen (s));
571 /* Like `insert' except that all markers pointing at the place where
572 the insertion happens are adjusted to point after it.
573 Don't use this function to insert part of a Lisp string,
574 since gc could happen and relocate it. */
576 void
577 insert_before_markers (string, length)
578 unsigned char *string;
579 register int length;
581 if (length > 0)
583 register int opoint = PT;
584 insert_1 (string, length, 0, 1);
585 adjust_markers (opoint - 1, opoint, length);
586 signal_after_change (PT-length, 0, length);
590 void
591 insert_before_markers_and_inherit (string, length)
592 unsigned char *string;
593 register int length;
595 if (length > 0)
597 register int opoint = PT;
598 insert_1 (string, length, 1, 1);
599 adjust_markers (opoint - 1, opoint, length);
600 signal_after_change (PT-length, 0, length);
604 /* Insert part of a Lisp string, relocating markers after. */
606 void
607 insert_from_string_before_markers (string, pos, length, inherit)
608 Lisp_Object string;
609 register int pos, length;
610 int inherit;
612 if (length > 0)
614 register int opoint = PT;
615 insert_from_string_1 (string, pos, length, inherit);
616 adjust_markers (opoint - 1, opoint, length);
617 signal_after_change (PT-length, 0, length);
621 /* Delete characters in current buffer
622 from FROM up to (but not including) TO. */
624 void
625 del_range (from, to)
626 register int from, to;
628 del_range_1 (from, to, 1);
631 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
633 void
634 del_range_1 (from, to, prepare)
635 register int from, to, prepare;
637 register int numdel;
639 /* Make args be valid */
640 if (from < BEGV)
641 from = BEGV;
642 if (to > ZV)
643 to = ZV;
645 if ((numdel = to - from) <= 0)
646 return;
648 /* Make sure the gap is somewhere in or next to what we are deleting. */
649 if (from > GPT)
650 gap_right (from);
651 if (to < GPT)
652 gap_left (to, 0);
654 if (prepare)
655 prepare_to_modify_buffer (from, to);
657 record_delete (from, numdel);
658 MODIFF++;
660 /* Relocate point as if it were a marker. */
661 if (from < PT)
662 adjust_point (from - (PT < to ? PT : to));
664 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
665 offset_intervals (current_buffer, from, - numdel);
667 /* Relocate all markers pointing into the new, larger gap
668 to point at the end of the text before the gap. */
669 adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE);
671 /* Adjust the overlay center as needed. This must be done after
672 adjusting the markers that bound the overlays. */
673 adjust_overlays_for_delete (from, numdel);
675 GAP_SIZE += numdel;
676 ZV -= numdel;
677 Z -= numdel;
678 GPT = from;
680 if (GPT - BEG < beg_unchanged)
681 beg_unchanged = GPT - BEG;
682 if (Z - GPT < end_unchanged)
683 end_unchanged = Z - GPT;
685 evaporate_overlays (from);
686 signal_after_change (from, numdel, 0);
689 /* Call this if you're about to change the region of BUFFER from START
690 to END. This checks the read-only properties of the region, calls
691 the necessary modification hooks, and warns the next redisplay that
692 it should pay attention to that area. */
693 void
694 modify_region (buffer, start, end)
695 struct buffer *buffer;
696 int start, end;
698 struct buffer *old_buffer = current_buffer;
700 if (buffer != old_buffer)
701 set_buffer_internal (buffer);
703 prepare_to_modify_buffer (start, end);
705 if (start - 1 < beg_unchanged || unchanged_modified == MODIFF)
706 beg_unchanged = start - 1;
707 if (Z - end < end_unchanged
708 || unchanged_modified == MODIFF)
709 end_unchanged = Z - end;
711 if (MODIFF <= SAVE_MODIFF)
712 record_first_change ();
713 MODIFF++;
715 buffer->point_before_scroll = Qnil;
717 if (buffer != old_buffer)
718 set_buffer_internal (old_buffer);
721 /* Check that it is okay to modify the buffer between START and END.
722 Run the before-change-function, if any. If intervals are in use,
723 verify that the text to be modified is not read-only, and call
724 any modification properties the text may have. */
726 void
727 prepare_to_modify_buffer (start, end)
728 Lisp_Object start, end;
730 if (!NILP (current_buffer->read_only))
731 Fbarf_if_buffer_read_only ();
733 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
734 if (BUF_INTERVALS (current_buffer) != 0)
735 verify_interval_modification (current_buffer, start, end);
737 #ifdef CLASH_DETECTION
738 if (!NILP (current_buffer->file_truename)
739 /* Make binding buffer-file-name to nil effective. */
740 && !NILP (current_buffer->filename)
741 && SAVE_MODIFF >= MODIFF)
742 lock_file (current_buffer->file_truename);
743 #else
744 /* At least warn if this file has changed on disk since it was visited. */
745 if (!NILP (current_buffer->filename)
746 && SAVE_MODIFF >= MODIFF
747 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
748 && !NILP (Ffile_exists_p (current_buffer->filename)))
749 call1 (intern ("ask-user-about-supersession-threat"),
750 current_buffer->filename);
751 #endif /* not CLASH_DETECTION */
753 signal_before_change (start, end);
755 if (current_buffer->newline_cache)
756 invalidate_region_cache (current_buffer,
757 current_buffer->newline_cache,
758 start - BEG, Z - end);
759 if (current_buffer->width_run_cache)
760 invalidate_region_cache (current_buffer,
761 current_buffer->width_run_cache,
762 start - BEG, Z - end);
764 Vdeactivate_mark = Qt;
767 /* Signal a change to the buffer immediately before it happens.
768 START and END are the bounds of the text to be changed,
769 as Lisp objects. */
771 void
772 signal_before_change (start, end)
773 Lisp_Object start, end;
775 /* If buffer is unmodified, run a special hook for that case. */
776 if (SAVE_MODIFF >= MODIFF
777 && !NILP (Vfirst_change_hook)
778 && !NILP (Vrun_hooks))
779 call1 (Vrun_hooks, Qfirst_change_hook);
781 /* Run the before-change-function if any.
782 We don't bother "binding" this variable to nil
783 because it is obsolete anyway and new code should not use it. */
784 if (!NILP (Vbefore_change_function))
785 call2 (Vbefore_change_function, start, end);
787 /* Now run the before-change-functions if any. */
788 if (!NILP (Vbefore_change_functions))
790 Lisp_Object args[3];
791 Lisp_Object before_change_functions;
792 Lisp_Object after_change_functions;
793 struct gcpro gcpro1, gcpro2;
795 /* "Bind" before-change-functions and after-change-functions
796 to nil--but in a way that errors don't know about.
797 That way, if there's an error in them, they will stay nil. */
798 before_change_functions = Vbefore_change_functions;
799 after_change_functions = Vafter_change_functions;
800 Vbefore_change_functions = Qnil;
801 Vafter_change_functions = Qnil;
802 GCPRO2 (before_change_functions, after_change_functions);
804 /* Actually run the hook functions. */
805 args[0] = Qbefore_change_functions;
806 args[1] = start;
807 args[2] = end;
808 run_hook_list_with_args (before_change_functions, 3, args);
810 /* "Unbind" the variables we "bound" to nil. */
811 Vbefore_change_functions = before_change_functions;
812 Vafter_change_functions = after_change_functions;
813 UNGCPRO;
816 if (!NILP (current_buffer->overlays_before)
817 || !NILP (current_buffer->overlays_after))
818 report_overlay_modification (start, end, 0, start, end, Qnil);
821 /* Signal a change immediately after it happens.
822 POS is the address of the start of the changed text.
823 LENDEL is the number of characters of the text before the change.
824 (Not the whole buffer; just the part that was changed.)
825 LENINS is the number of characters in the changed text.
827 (Hence POS + LENINS - LENDEL is the position after the changed text.) */
829 void
830 signal_after_change (pos, lendel, lenins)
831 int pos, lendel, lenins;
833 /* Run the after-change-function if any.
834 We don't bother "binding" this variable to nil
835 because it is obsolete anyway and new code should not use it. */
836 if (!NILP (Vafter_change_function))
837 call3 (Vafter_change_function,
838 make_number (pos), make_number (pos + lenins),
839 make_number (lendel));
841 if (!NILP (Vafter_change_functions))
843 Lisp_Object args[4];
844 Lisp_Object before_change_functions;
845 Lisp_Object after_change_functions;
846 struct gcpro gcpro1, gcpro2;
848 /* "Bind" before-change-functions and after-change-functions
849 to nil--but in a way that errors don't know about.
850 That way, if there's an error in them, they will stay nil. */
851 before_change_functions = Vbefore_change_functions;
852 after_change_functions = Vafter_change_functions;
853 Vbefore_change_functions = Qnil;
854 Vafter_change_functions = Qnil;
855 GCPRO2 (before_change_functions, after_change_functions);
857 /* Actually run the hook functions. */
858 args[0] = Qafter_change_functions;
859 XSETFASTINT (args[1], pos);
860 XSETFASTINT (args[2], pos + lenins);
861 XSETFASTINT (args[3], lendel);
862 run_hook_list_with_args (after_change_functions,
863 4, args);
865 /* "Unbind" the variables we "bound" to nil. */
866 Vbefore_change_functions = before_change_functions;
867 Vafter_change_functions = after_change_functions;
868 UNGCPRO;
871 if (!NILP (current_buffer->overlays_before)
872 || !NILP (current_buffer->overlays_after))
873 report_overlay_modification (make_number (pos),
874 make_number (pos + lenins - lendel),
876 make_number (pos), make_number (pos + lenins),
877 make_number (lendel));
879 /* After an insertion, call the text properties
880 insert-behind-hooks or insert-in-front-hooks. */
881 if (lendel == 0)
882 report_interval_modification (pos, pos + lenins);