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)
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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
24 #include "intervals.h"
28 #include "blockinput.h"
30 #define min(x, y) ((x) < (y) ? (x) : (y))
32 static void insert_from_string_1 ();
33 static void insert_from_buffer_1 ();
34 static void gap_left ();
35 static void gap_right ();
36 static void adjust_markers ();
37 static void adjust_point ();
39 Lisp_Object
Fcombine_after_change_execute ();
41 /* Non-nil means don't call the after-change-functions right away,
42 just record an element in Vcombine_after_change_calls_list. */
43 Lisp_Object Vcombine_after_change_calls
;
45 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
46 describing changes which happened while combine_after_change_calls
47 was nonzero. We use this to decide how to call them
48 once the deferral ends.
51 BEG-UNCHANGED is the number of chars before the changed range.
52 END-UNCHANGED is the number of chars after the changed range,
53 and CHANGE-AMOUNT is the number of characters inserted by the change
54 (negative for a deletion). */
55 Lisp_Object combine_after_change_list
;
57 /* Buffer which combine_after_change_list is about. */
58 Lisp_Object combine_after_change_buffer
;
60 /* Move gap to position `pos'.
61 Note that this can quit! */
73 /* Move the gap to POS, which is less than the current GPT.
74 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
77 gap_left (pos
, newgap
)
81 register unsigned char *to
, *from
;
89 if (unchanged_modified
== MODIFF
90 && overlay_unchanged_modified
== OVERLAY_MODIFF
)
93 end_unchanged
= Z
- pos
- 1;
97 if (Z
- GPT
< end_unchanged
)
98 end_unchanged
= Z
- GPT
;
99 if (pos
< beg_unchanged
)
109 /* Now copy the characters. To move the gap down,
110 copy characters up. */
114 /* I gets number of characters left to copy. */
118 /* If a quit is requested, stop copying now.
119 Change POS to be where we have actually moved the gap to. */
125 /* Move at most 32000 chars before checking again for a quit. */
130 /* bcopy is safe if the two areas of memory do not overlap
131 or on systems where bcopy is always safe for moving upward. */
132 && (BCOPY_UPWARD_SAFE
133 || to
- from
>= 128))
135 /* If overlap is not safe, avoid it by not moving too many
136 characters at once. */
137 if (!BCOPY_UPWARD_SAFE
&& i
> to
- from
)
152 /* Adjust markers, and buffer data structure, to put the gap at POS.
153 POS is where the loop above stopped, which may be what was specified
154 or may be where a quit was detected. */
155 adjust_markers (pos
+ 1, GPT
, GAP_SIZE
);
157 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
165 register unsigned char *to
, *from
;
171 if (unchanged_modified
== MODIFF
172 && overlay_unchanged_modified
== OVERLAY_MODIFF
)
176 end_unchanged
= Z
- pos
- 1;
180 if (Z
- pos
- 1 < end_unchanged
)
181 end_unchanged
= Z
- pos
- 1;
182 if (GPT
- BEG
< beg_unchanged
)
183 beg_unchanged
= GPT
- BEG
;
191 /* Now copy the characters. To move the gap up,
192 copy characters down. */
196 /* I gets number of characters left to copy. */
200 /* If a quit is requested, stop copying now.
201 Change POS to be where we have actually moved the gap to. */
207 /* Move at most 32000 chars before checking again for a quit. */
212 /* bcopy is safe if the two areas of memory do not overlap
213 or on systems where bcopy is always safe for moving downward. */
214 && (BCOPY_DOWNWARD_SAFE
215 || from
- to
>= 128))
217 /* If overlap is not safe, avoid it by not moving too many
218 characters at once. */
219 if (!BCOPY_DOWNWARD_SAFE
&& i
> from
- to
)
234 adjust_markers (GPT
+ GAP_SIZE
, pos
+ 1 + GAP_SIZE
, - GAP_SIZE
);
236 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
240 /* Add AMOUNT to the position of every marker in the current buffer
241 whose current position is between FROM (exclusive) and TO (inclusive).
243 Also, any markers past the outside of that interval, in the direction
244 of adjustment, are first moved back to the near end of the interval
245 and then adjusted by AMOUNT.
247 When the latter adjustment is done, if AMOUNT is negative,
248 we record the adjustment for undo. (This case happens only for
252 adjust_markers (from
, to
, amount
)
253 register int from
, to
, amount
;
256 register struct Lisp_Marker
*m
;
259 marker
= BUF_MARKERS (current_buffer
);
261 while (!NILP (marker
))
263 m
= XMARKER (marker
);
267 if (mpos
> to
&& mpos
< to
+ amount
)
272 /* Here's the case where a marker is inside text being deleted.
273 AMOUNT can be negative for gap motion, too,
274 but then this range contains no markers. */
275 if (mpos
> from
+ amount
&& mpos
<= from
)
278 int after
= from
+ amount
;
282 /* Compute the before and after positions
283 as buffer positions. */
284 if (before
> GPT
+ GAP_SIZE
)
286 else if (before
> GPT
)
289 if (after
> GPT
+ GAP_SIZE
)
291 else if (after
> GPT
)
294 record_marker_adjustment (marker
, after
- before
);
297 if (mpos
> from
&& mpos
<= to
)
304 /* Adjust markers whose insertion-type is t
305 for an insertion of AMOUNT characters at POS. */
308 adjust_markers_for_insert (pos
, amount
)
309 register int pos
, amount
;
314 marker
= BUF_MARKERS (current_buffer
);
316 while (!NILP (marker
))
318 register struct Lisp_Marker
*m
= XMARKER (marker
);
319 if (m
->insertion_type
&& m
->bufpos
== pos
)
327 /* Adjusting only markers whose insertion-type is t may result in
328 disordered overlays in the slot `overlays_before'. */
329 fix_overlays_before (current_buffer
, pos
, pos
+ amount
);
332 /* Add the specified amount to point. This is used only when the value
333 of point changes due to an insert or delete; it does not represent
334 a conceptual change in point as a marker. In particular, point is
335 not crossing any interval boundaries, so there's no need to use the
336 usual SET_PT macro. In fact it would be incorrect to do so, because
337 either the old or the new value of point is out of sync with the
338 current set of intervals. */
340 adjust_point (amount
)
343 BUF_PT (current_buffer
) += amount
;
346 /* Make the gap INCREMENT characters longer. */
352 unsigned char *result
;
357 /* If we have to get more space, get enough to last a while. */
360 /* Don't allow a buffer size that won't fit in an int
361 even if it will fit in a Lisp integer.
362 That won't work because so many places use `int'. */
364 if (Z
- BEG
+ GAP_SIZE
+ increment
365 >= ((unsigned) 1 << (min (BITS_PER_INT
, VALBITS
) - 1)))
366 error ("Buffer exceeds maximum size");
369 /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */
370 result
= BUFFER_REALLOC (BEG_ADDR
, (Z
- BEG
+ GAP_SIZE
+ increment
+ 1));
378 /* We can't unblock until the new address is properly stored. */
382 /* Prevent quitting in move_gap. */
387 old_gap_size
= GAP_SIZE
;
389 /* Call the newly allocated space a gap at the end of the whole space. */
391 GAP_SIZE
= increment
;
393 /* Move the new gap down to be consecutive with the end of the old one.
394 This adjusts the markers properly too. */
395 gap_left (real_gap_loc
+ old_gap_size
, 1);
397 /* Now combine the two into one large gap. */
398 GAP_SIZE
+= old_gap_size
;
407 /* Insert a string of specified length before point.
408 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
409 prepare_to_modify_buffer could relocate the text. */
412 insert (string
, length
)
413 register unsigned char *string
;
418 insert_1 (string
, length
, 0, 1);
419 signal_after_change (PT
-length
, 0, length
);
424 insert_and_inherit (string
, length
)
425 register unsigned char *string
;
430 insert_1 (string
, length
, 1, 1);
431 signal_after_change (PT
-length
, 0, length
);
436 insert_1 (string
, length
, inherit
, prepare
)
437 register unsigned char *string
;
439 int inherit
, prepare
;
441 register Lisp_Object temp
;
444 prepare_to_modify_buffer (PT
, PT
);
448 if (GAP_SIZE
< length
)
449 make_gap (length
- GAP_SIZE
);
451 record_insert (PT
, length
);
454 bcopy (string
, GPT_ADDR
, length
);
456 #ifdef USE_TEXT_PROPERTIES
457 if (BUF_INTERVALS (current_buffer
) != 0)
458 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
459 offset_intervals (current_buffer
, PT
, length
);
466 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
467 adjust_overlays_for_insert (PT
, length
);
468 adjust_markers_for_insert (PT
, length
);
469 adjust_point (length
);
471 #ifdef USE_TEXT_PROPERTIES
472 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
473 Fset_text_properties (make_number (PT
- length
), make_number (PT
),
478 /* Insert the part of the text of STRING, a Lisp object assumed to be
479 of type string, consisting of the LENGTH characters starting at
480 position POS. If the text of STRING has properties, they are absorbed
483 It does not work to use `insert' for this, because a GC could happen
484 before we bcopy the stuff into the buffer, and relocate the string
485 without insert noticing. */
488 insert_from_string (string
, pos
, length
, inherit
)
490 register int pos
, length
;
495 insert_from_string_1 (string
, pos
, length
, inherit
);
496 signal_after_change (PT
-length
, 0, length
);
501 insert_from_string_1 (string
, pos
, length
, inherit
)
503 register int pos
, length
;
506 register Lisp_Object temp
;
509 /* Make sure point-max won't overflow after this insertion. */
510 XSETINT (temp
, length
+ Z
);
511 if (length
+ Z
!= XINT (temp
))
512 error ("maximum buffer size exceeded");
515 prepare_to_modify_buffer (PT
, PT
);
519 if (GAP_SIZE
< length
)
520 make_gap (length
- GAP_SIZE
);
522 record_insert (PT
, length
);
526 bcopy (XSTRING (string
)->data
, GPT_ADDR
, length
);
528 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
529 offset_intervals (current_buffer
, PT
, length
);
535 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
536 adjust_overlays_for_insert (PT
, length
);
537 adjust_markers_for_insert (PT
, length
);
539 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
540 graft_intervals_into_buffer (XSTRING (string
)->intervals
, PT
, length
,
541 current_buffer
, inherit
);
543 adjust_point (length
);
546 /* Insert text from BUF, starting at POS and having length LENGTH, into the
547 current buffer. If the text in BUF has properties, they are absorbed
548 into the current buffer.
550 It does not work to use `insert' for this, because a malloc could happen
551 and relocate BUF's text before the bcopy happens. */
554 insert_from_buffer (buf
, pos
, length
, inherit
)
561 insert_from_buffer_1 (buf
, pos
, length
, inherit
);
562 signal_after_change (PT
-length
, 0, length
);
567 insert_from_buffer_1 (buf
, pos
, length
, inherit
)
572 register Lisp_Object temp
;
575 /* Make sure point-max won't overflow after this insertion. */
576 XSETINT (temp
, length
+ Z
);
577 if (length
+ Z
!= XINT (temp
))
578 error ("maximum buffer size exceeded");
580 prepare_to_modify_buffer (PT
, PT
);
584 if (GAP_SIZE
< length
)
585 make_gap (length
- GAP_SIZE
);
587 record_insert (PT
, length
);
590 if (pos
< BUF_GPT (buf
))
592 chunk
= BUF_GPT (buf
) - pos
;
595 bcopy (BUF_CHAR_ADDRESS (buf
, pos
), GPT_ADDR
, chunk
);
600 bcopy (BUF_CHAR_ADDRESS (buf
, pos
+ chunk
),
601 GPT_ADDR
+ chunk
, length
- chunk
);
603 #ifdef USE_TEXT_PROPERTIES
604 if (BUF_INTERVALS (current_buffer
) != 0)
605 offset_intervals (current_buffer
, PT
, length
);
612 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
613 adjust_overlays_for_insert (PT
, length
);
614 adjust_markers_for_insert (PT
, length
);
615 adjust_point (length
);
617 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
618 graft_intervals_into_buffer (copy_intervals (BUF_INTERVALS (buf
),
620 PT
- length
, length
, current_buffer
, inherit
);
623 /* Insert the character C before point */
629 unsigned char workbuf
[4], *str
;
630 int len
= CHAR_STRING (c
, workbuf
, str
);
635 /* Insert the null-terminated string S before point */
641 insert (s
, strlen (s
));
644 /* Like `insert' except that all markers pointing at the place where
645 the insertion happens are adjusted to point after it.
646 Don't use this function to insert part of a Lisp string,
647 since gc could happen and relocate it. */
650 insert_before_markers (string
, length
)
651 unsigned char *string
;
656 register int opoint
= PT
;
657 insert_1 (string
, length
, 0, 1);
658 adjust_markers (opoint
- 1, opoint
, length
);
659 signal_after_change (PT
-length
, 0, length
);
664 insert_before_markers_and_inherit (string
, length
)
665 unsigned char *string
;
670 register int opoint
= PT
;
671 insert_1 (string
, length
, 1, 1);
672 adjust_markers (opoint
- 1, opoint
, length
);
673 signal_after_change (PT
-length
, 0, length
);
677 /* Insert part of a Lisp string, relocating markers after. */
680 insert_from_string_before_markers (string
, pos
, length
, inherit
)
682 register int pos
, length
;
687 register int opoint
= PT
;
688 insert_from_string_1 (string
, pos
, length
, inherit
);
689 adjust_markers (opoint
- 1, opoint
, length
);
690 signal_after_change (PT
-length
, 0, length
);
694 /* Delete characters in current buffer
695 from FROM up to (but not including) TO. */
699 register int from
, to
;
701 del_range_1 (from
, to
, 1);
704 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
707 del_range_1 (from
, to
, prepare
)
708 register int from
, to
, prepare
;
712 /* Make args be valid */
718 if ((numdel
= to
- from
) <= 0)
721 /* Make sure the gap is somewhere in or next to what we are deleting. */
728 prepare_to_modify_buffer (from
, to
);
730 /* Relocate all markers pointing into the new, larger gap
731 to point at the end of the text before the gap.
732 This has to be done before recording the deletion,
733 so undo handles this after reinserting the text. */
734 adjust_markers (to
+ GAP_SIZE
, to
+ GAP_SIZE
, - numdel
- GAP_SIZE
);
736 record_delete (from
, numdel
);
739 /* Relocate point as if it were a marker. */
741 adjust_point (from
- (PT
< to
? PT
: to
));
743 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
744 offset_intervals (current_buffer
, from
, - numdel
);
746 /* Adjust the overlay center as needed. This must be done after
747 adjusting the markers that bound the overlays. */
748 adjust_overlays_for_delete (from
, numdel
);
754 *(GPT_ADDR
) = 0; /* Put an anchor. */
756 if (GPT
- BEG
< beg_unchanged
)
757 beg_unchanged
= GPT
- BEG
;
758 if (Z
- GPT
< end_unchanged
)
759 end_unchanged
= Z
- GPT
;
761 evaporate_overlays (from
);
762 signal_after_change (from
, numdel
, 0);
765 /* Call this if you're about to change the region of BUFFER from START
766 to END. This checks the read-only properties of the region, calls
767 the necessary modification hooks, and warns the next redisplay that
768 it should pay attention to that area. */
770 modify_region (buffer
, start
, end
)
771 struct buffer
*buffer
;
774 struct buffer
*old_buffer
= current_buffer
;
776 if (buffer
!= old_buffer
)
777 set_buffer_internal (buffer
);
779 prepare_to_modify_buffer (start
, end
);
781 if (start
- 1 < beg_unchanged
782 || (unchanged_modified
== MODIFF
783 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
784 beg_unchanged
= start
- 1;
785 if (Z
- end
< end_unchanged
786 || (unchanged_modified
== MODIFF
787 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
788 end_unchanged
= Z
- end
;
790 if (MODIFF
<= SAVE_MODIFF
)
791 record_first_change ();
794 buffer
->point_before_scroll
= Qnil
;
796 if (buffer
!= old_buffer
)
797 set_buffer_internal (old_buffer
);
800 /* Check that it is okay to modify the buffer between START and END.
801 Run the before-change-function, if any. If intervals are in use,
802 verify that the text to be modified is not read-only, and call
803 any modification properties the text may have. */
806 prepare_to_modify_buffer (start
, end
)
809 if (!NILP (current_buffer
->read_only
))
810 Fbarf_if_buffer_read_only ();
812 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
813 if (BUF_INTERVALS (current_buffer
) != 0)
814 verify_interval_modification (current_buffer
, start
, end
);
816 #ifdef CLASH_DETECTION
817 if (!NILP (current_buffer
->file_truename
)
818 /* Make binding buffer-file-name to nil effective. */
819 && !NILP (current_buffer
->filename
)
820 && SAVE_MODIFF
>= MODIFF
)
821 lock_file (current_buffer
->file_truename
);
823 /* At least warn if this file has changed on disk since it was visited. */
824 if (!NILP (current_buffer
->filename
)
825 && SAVE_MODIFF
>= MODIFF
826 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
827 && !NILP (Ffile_exists_p (current_buffer
->filename
)))
828 call1 (intern ("ask-user-about-supersession-threat"),
829 current_buffer
->filename
);
830 #endif /* not CLASH_DETECTION */
832 signal_before_change (start
, end
);
834 if (current_buffer
->newline_cache
)
835 invalidate_region_cache (current_buffer
,
836 current_buffer
->newline_cache
,
837 start
- BEG
, Z
- end
);
838 if (current_buffer
->width_run_cache
)
839 invalidate_region_cache (current_buffer
,
840 current_buffer
->width_run_cache
,
841 start
- BEG
, Z
- end
);
843 Vdeactivate_mark
= Qt
;
846 /* Signal a change to the buffer immediately before it happens.
847 START_INT and END_INT are the bounds of the text to be changed. */
850 signal_before_change (start_int
, end_int
)
851 int start_int
, end_int
;
853 Lisp_Object start
, end
;
855 start
= make_number (start_int
);
856 end
= make_number (end_int
);
858 /* If buffer is unmodified, run a special hook for that case. */
859 if (SAVE_MODIFF
>= MODIFF
860 && !NILP (Vfirst_change_hook
)
861 && !NILP (Vrun_hooks
))
862 call1 (Vrun_hooks
, Qfirst_change_hook
);
864 /* Run the before-change-function if any.
865 We don't bother "binding" this variable to nil
866 because it is obsolete anyway and new code should not use it. */
867 if (!NILP (Vbefore_change_function
))
868 call2 (Vbefore_change_function
, start
, end
);
870 /* Now run the before-change-functions if any. */
871 if (!NILP (Vbefore_change_functions
))
874 Lisp_Object before_change_functions
;
875 Lisp_Object after_change_functions
;
876 struct gcpro gcpro1
, gcpro2
;
878 /* "Bind" before-change-functions and after-change-functions
879 to nil--but in a way that errors don't know about.
880 That way, if there's an error in them, they will stay nil. */
881 before_change_functions
= Vbefore_change_functions
;
882 after_change_functions
= Vafter_change_functions
;
883 Vbefore_change_functions
= Qnil
;
884 Vafter_change_functions
= Qnil
;
885 GCPRO2 (before_change_functions
, after_change_functions
);
887 /* Actually run the hook functions. */
888 args
[0] = Qbefore_change_functions
;
891 run_hook_list_with_args (before_change_functions
, 3, args
);
893 /* "Unbind" the variables we "bound" to nil. */
894 Vbefore_change_functions
= before_change_functions
;
895 Vafter_change_functions
= after_change_functions
;
899 if (!NILP (current_buffer
->overlays_before
)
900 || !NILP (current_buffer
->overlays_after
))
901 report_overlay_modification (start
, end
, 0, start
, end
, Qnil
);
904 /* Signal a change immediately after it happens.
905 POS is the address of the start of the changed text.
906 LENDEL is the number of characters of the text before the change.
907 (Not the whole buffer; just the part that was changed.)
908 LENINS is the number of characters in that part of the text
912 signal_after_change (pos
, lendel
, lenins
)
913 int pos
, lendel
, lenins
;
915 /* If we are deferring calls to the after-change functions
916 and there are no before-change functions,
917 just record the args that we were going to use. */
918 if (! NILP (Vcombine_after_change_calls
)
919 && NILP (Vbefore_change_function
) && NILP (Vbefore_change_functions
)
920 && NILP (current_buffer
->overlays_before
)
921 && NILP (current_buffer
->overlays_after
))
925 if (!NILP (combine_after_change_list
)
926 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
927 Fcombine_after_change_execute ();
929 elt
= Fcons (make_number (pos
- BEG
),
930 Fcons (make_number (Z
- (pos
- lendel
+ lenins
)),
931 Fcons (make_number (lenins
- lendel
), Qnil
)));
932 combine_after_change_list
933 = Fcons (elt
, combine_after_change_list
);
934 combine_after_change_buffer
= Fcurrent_buffer ();
939 if (!NILP (combine_after_change_list
))
940 Fcombine_after_change_execute ();
942 /* Run the after-change-function if any.
943 We don't bother "binding" this variable to nil
944 because it is obsolete anyway and new code should not use it. */
945 if (!NILP (Vafter_change_function
))
946 call3 (Vafter_change_function
,
947 make_number (pos
), make_number (pos
+ lenins
),
948 make_number (lendel
));
950 if (!NILP (Vafter_change_functions
))
953 Lisp_Object before_change_functions
;
954 Lisp_Object after_change_functions
;
955 struct gcpro gcpro1
, gcpro2
;
957 /* "Bind" before-change-functions and after-change-functions
958 to nil--but in a way that errors don't know about.
959 That way, if there's an error in them, they will stay nil. */
960 before_change_functions
= Vbefore_change_functions
;
961 after_change_functions
= Vafter_change_functions
;
962 Vbefore_change_functions
= Qnil
;
963 Vafter_change_functions
= Qnil
;
964 GCPRO2 (before_change_functions
, after_change_functions
);
966 /* Actually run the hook functions. */
967 args
[0] = Qafter_change_functions
;
968 XSETFASTINT (args
[1], pos
);
969 XSETFASTINT (args
[2], pos
+ lenins
);
970 XSETFASTINT (args
[3], lendel
);
971 run_hook_list_with_args (after_change_functions
,
974 /* "Unbind" the variables we "bound" to nil. */
975 Vbefore_change_functions
= before_change_functions
;
976 Vafter_change_functions
= after_change_functions
;
980 if (!NILP (current_buffer
->overlays_before
)
981 || !NILP (current_buffer
->overlays_after
))
982 report_overlay_modification (make_number (pos
),
983 make_number (pos
+ lenins
),
985 make_number (pos
), make_number (pos
+ lenins
),
986 make_number (lendel
));
988 /* After an insertion, call the text properties
989 insert-behind-hooks or insert-in-front-hooks. */
991 report_interval_modification (pos
, pos
+ lenins
);
995 Fcombine_after_change_execute_1 (val
)
998 Vcombine_after_change_calls
= val
;
1002 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
1003 Scombine_after_change_execute
, 0, 0, 0,
1004 "This function is for use internally in `combine-after-change-calls'.")
1007 register Lisp_Object val
;
1008 int count
= specpdl_ptr
- specpdl
;
1009 int beg
, end
, change
;
1013 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
1015 Fset_buffer (combine_after_change_buffer
);
1017 /* # chars unchanged at beginning of buffer. */
1019 /* # chars unchanged at end of buffer. */
1021 /* Total amount of insertion (negative for deletion). */
1024 /* Scan the various individual changes,
1025 accumulating the range info in BEG, END and CHANGE. */
1026 for (tail
= combine_after_change_list
; CONSP (tail
);
1027 tail
= XCONS (tail
)->cdr
)
1030 int thisbeg
, thisend
, thischange
;
1032 /* Extract the info from the next element. */
1033 elt
= XCONS (tail
)->car
;
1036 thisbeg
= XINT (XCONS (elt
)->car
);
1038 elt
= XCONS (elt
)->cdr
;
1041 thisend
= XINT (XCONS (elt
)->car
);
1043 elt
= XCONS (elt
)->cdr
;
1046 thischange
= XINT (XCONS (elt
)->car
);
1048 /* Merge this range into the accumulated range. */
1049 change
+= thischange
;
1056 /* Get the current start and end positions of the range
1057 that was changed. */
1061 /* We are about to handle these, so discard them. */
1062 combine_after_change_list
= Qnil
;
1064 /* Now run the after-change functions for real.
1065 Turn off the flag that defers them. */
1066 record_unwind_protect (Fcombine_after_change_execute_1
,
1067 Vcombine_after_change_calls
);
1068 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
1070 return unbind_to (count
, val
);
1075 staticpro (&combine_after_change_list
);
1076 combine_after_change_list
= Qnil
;
1078 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls
,
1079 "Used internally by the `combine-after-change-calls' macro.");
1080 Vcombine_after_change_calls
= Qnil
;
1082 defsubr (&Scombine_after_change_execute
);