1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 86, 93, 94, 95, 97, 1998 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"
34 #define min(x, y) ((x) < (y) ? (x) : (y))
36 static void insert_from_string_1
P_ ((Lisp_Object
, int, int, int, int, int, int));
37 static void insert_from_buffer_1 ();
38 static void gap_left
P_ ((int, int, int));
39 static void gap_right
P_ ((int, int));
40 static void adjust_markers_gap_motion
P_ ((int, int, int));
41 static void adjust_markers_for_insert
P_ ((int, int, int, int, int));
42 static void adjust_markers_for_delete
P_ ((int, int, int, int));
43 static void adjust_point
P_ ((int, int));
45 Lisp_Object
Fcombine_after_change_execute ();
47 /* Non-nil means don't call the after-change-functions right away,
48 just record an element in Vcombine_after_change_calls_list. */
49 Lisp_Object Vcombine_after_change_calls
;
51 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
52 describing changes which happened while combine_after_change_calls
53 was nonzero. We use this to decide how to call them
54 once the deferral ends.
57 BEG-UNCHANGED is the number of chars before the changed range.
58 END-UNCHANGED is the number of chars after the changed range,
59 and CHANGE-AMOUNT is the number of characters inserted by the change
60 (negative for a deletion). */
61 Lisp_Object combine_after_change_list
;
63 /* Buffer which combine_after_change_list is about. */
64 Lisp_Object combine_after_change_buffer
;
66 #define DEFAULT_NONASCII_INSERT_OFFSET 0x800
68 /* Move gap to position CHARPOS.
69 Note that this can quit! */
75 move_gap_both (charpos
, charpos_to_bytepos (charpos
));
78 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
79 Note that this can quit! */
82 move_gap_both (charpos
, bytepos
)
85 if (bytepos
< GPT_BYTE
)
86 gap_left (charpos
, bytepos
, 0);
87 else if (bytepos
> GPT_BYTE
)
88 gap_right (charpos
, bytepos
);
91 /* Move the gap to a position less than the current GPT.
92 BYTEPOS describes the new position as a byte position,
93 and CHARPOS is the corresponding char position.
94 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
97 gap_left (charpos
, bytepos
, newgap
)
98 register int charpos
, bytepos
;
101 register unsigned char *to
, *from
;
107 if (unchanged_modified
== MODIFF
108 && overlay_unchanged_modified
== OVERLAY_MODIFF
)
110 beg_unchanged
= charpos
- BEG
;
111 end_unchanged
= Z
- charpos
;
115 if (Z
- GPT
< end_unchanged
)
116 end_unchanged
= Z
- GPT
;
117 if (charpos
< beg_unchanged
)
118 beg_unchanged
= charpos
- BEG
;
127 /* Now copy the characters. To move the gap down,
128 copy characters up. */
132 /* I gets number of characters left to copy. */
133 i
= new_s1
- bytepos
;
136 /* If a quit is requested, stop copying now.
137 Change BYTEPOS to be where we have actually moved the gap to. */
141 charpos
= BYTE_TO_CHAR (bytepos
);
144 /* Move at most 32000 chars before checking again for a quit. */
149 /* bcopy is safe if the two areas of memory do not overlap
150 or on systems where bcopy is always safe for moving upward. */
151 && (BCOPY_UPWARD_SAFE
152 || to
- from
>= 128))
154 /* If overlap is not safe, avoid it by not moving too many
155 characters at once. */
156 if (!BCOPY_UPWARD_SAFE
&& i
> to
- from
)
171 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
172 BYTEPOS is where the loop above stopped, which may be what was specified
173 or may be where a quit was detected. */
174 adjust_markers_gap_motion (bytepos
, GPT_BYTE
, GAP_SIZE
);
177 if (bytepos
< charpos
)
179 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
183 /* Move the gap to a position greater than than the current GPT.
184 BYTEPOS describes the new position as a byte position,
185 and CHARPOS is the corresponding char position. */
188 gap_right (charpos
, bytepos
)
189 register int charpos
, bytepos
;
191 register unsigned char *to
, *from
;
195 if (unchanged_modified
== MODIFF
196 && overlay_unchanged_modified
== OVERLAY_MODIFF
)
198 beg_unchanged
= charpos
- BEG
;
199 end_unchanged
= Z
- charpos
;
203 if (Z
- charpos
- 1 < end_unchanged
)
204 end_unchanged
= Z
- charpos
;
205 if (GPT
- BEG
< beg_unchanged
)
206 beg_unchanged
= GPT
- BEG
;
214 /* Now copy the characters. To move the gap up,
215 copy characters down. */
219 /* I gets number of characters left to copy. */
220 i
= bytepos
- new_s1
;
223 /* If a quit is requested, stop copying now.
224 Change BYTEPOS to be where we have actually moved the gap to. */
228 charpos
= BYTE_TO_CHAR (bytepos
);
231 /* Move at most 32000 chars before checking again for a quit. */
236 /* bcopy is safe if the two areas of memory do not overlap
237 or on systems where bcopy is always safe for moving downward. */
238 && (BCOPY_DOWNWARD_SAFE
239 || from
- to
>= 128))
241 /* If overlap is not safe, avoid it by not moving too many
242 characters at once. */
243 if (!BCOPY_DOWNWARD_SAFE
&& i
> from
- to
)
258 adjust_markers_gap_motion (GPT_BYTE
+ GAP_SIZE
, bytepos
+ GAP_SIZE
,
262 if (bytepos
< charpos
)
264 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
268 /* Add AMOUNT to the byte position of every marker in the current buffer
269 whose current byte position is between FROM (exclusive) and TO (inclusive).
271 Also, any markers past the outside of that interval, in the direction
272 of adjustment, are first moved back to the near end of the interval
273 and then adjusted by AMOUNT.
275 When the latter adjustment is done, if AMOUNT is negative,
276 we record the adjustment for undo. (This case happens only for
279 The markers' character positions are not altered,
280 because gap motion does not affect character positions. */
282 int adjust_markers_test
;
285 adjust_markers_gap_motion (from
, to
, amount
)
286 register int from
, to
, amount
;
288 /* Now that a marker has a bytepos, not counting the gap,
289 nothing needs to be done here. */
292 register struct Lisp_Marker
*m
;
295 marker
= BUF_MARKERS (current_buffer
);
297 while (!NILP (marker
))
299 m
= XMARKER (marker
);
303 if (mpos
> to
&& mpos
< to
+ amount
)
305 if (adjust_markers_test
)
312 /* Here's the case where a marker is inside text being deleted.
313 AMOUNT can be negative for gap motion, too,
314 but then this range contains no markers. */
315 if (mpos
> from
+ amount
&& mpos
<= from
)
317 if (adjust_markers_test
)
319 mpos
= from
+ amount
;
322 if (mpos
> from
&& mpos
<= to
)
330 /* Adjust all markers for a deletion
331 whose range in bytes is FROM_BYTE to TO_BYTE.
332 The range in charpos is FROM to TO.
334 This function assumes that the gap is adjacent to
335 or inside of the range being deleted. */
338 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
)
339 register int from
, from_byte
, to
, to_byte
;
342 register struct Lisp_Marker
*m
;
343 register int charpos
;
344 /* This is what GAP_SIZE will be when this deletion is finished. */
345 int coming_gap_size
= GAP_SIZE
+ to_byte
- from_byte
;
347 marker
= BUF_MARKERS (current_buffer
);
349 while (!NILP (marker
))
351 m
= XMARKER (marker
);
352 charpos
= m
->charpos
;
357 /* If the marker is after the deletion,
358 relocate by number of chars / bytes deleted. */
361 m
->charpos
-= to
- from
;
362 m
->bytepos
-= to_byte
- from_byte
;
365 /* Here's the case where a marker is inside text being deleted. */
366 else if (charpos
> from
)
368 record_marker_adjustment (marker
, from
- charpos
);
370 m
->bytepos
= from_byte
;
373 /* In a single-byte buffer, a marker's two positions must be equal. */
376 register int i
= m
->bytepos
;
379 /* We use FROM_BYTE here instead of GPT_BYTE
380 because FROM_BYTE is where the gap will be after the deletion. */
381 if (i
> from_byte
+ coming_gap_size
)
382 i
-= coming_gap_size
;
383 else if (i
> from_byte
)
395 /* Adjust markers for an insertion at CHARPOS / BYTEPOS
396 consisting of NCHARS chars, which are NBYTES bytes.
398 We have to relocate the charpos of every marker that points
399 after the insertion (but not their bytepos).
401 When a marker points at the insertion point,
402 we advance it if either its insertion-type is t
403 or BEFORE_MARKERS is true. */
406 adjust_markers_for_insert (from
, from_byte
, to
, to_byte
, before_markers
)
407 register int from
, from_byte
, to
, to_byte
, before_markers
;
411 int nchars
= to
- from
;
412 int nbytes
= to_byte
- from_byte
;
414 marker
= BUF_MARKERS (current_buffer
);
416 while (!NILP (marker
))
418 register struct Lisp_Marker
*m
= XMARKER (marker
);
419 if (m
->bytepos
== from_byte
420 && (m
->insertion_type
|| before_markers
))
422 m
->bytepos
+= nbytes
;
423 m
->charpos
+= nchars
;
424 if (m
->insertion_type
)
427 else if (m
->bytepos
> from_byte
)
429 m
->bytepos
+= nbytes
;
430 m
->charpos
+= nchars
;
433 /* In a single-byte buffer, a marker's two positions must be equal. */
436 register int i
= m
->bytepos
;
439 if (i
> GPT_BYTE
+ GAP_SIZE
)
441 else if (i
> GPT_BYTE
)
452 /* Adjusting only markers whose insertion-type is t may result in
453 disordered overlays in the slot `overlays_before'. */
455 fix_overlays_before (current_buffer
, from
, to
);
458 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
460 This is used only when the value of point changes due to an insert
461 or delete; it does not represent a conceptual change in point as a
462 marker. In particular, point is not crossing any interval
463 boundaries, so there's no need to use the usual SET_PT macro. In
464 fact it would be incorrect to do so, because either the old or the
465 new value of point is out of sync with the current set of
469 adjust_point (nchars
, nbytes
)
472 BUF_PT (current_buffer
) += nchars
;
473 BUF_PT_BYTE (current_buffer
) += nbytes
;
475 /* In a single-byte buffer, the two positions must be equal. */
481 /* Make the gap NBYTES_ADDED bytes longer. */
484 make_gap (nbytes_added
)
487 unsigned char *result
;
490 int real_gap_loc_byte
;
493 /* If we have to get more space, get enough to last a while. */
494 nbytes_added
+= 2000;
496 /* Don't allow a buffer size that won't fit in an int
497 even if it will fit in a Lisp integer.
498 That won't work because so many places use `int'. */
500 if (Z_BYTE
- BEG_BYTE
+ GAP_SIZE
+ nbytes_added
501 >= ((unsigned) 1 << (min (BITS_PER_INT
, VALBITS
) - 1)))
502 error ("Buffer exceeds maximum size");
505 /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */
506 result
= BUFFER_REALLOC (BEG_ADDR
, (Z_BYTE
- BEG_BYTE
507 + GAP_SIZE
+ nbytes_added
+ 1));
515 /* We can't unblock until the new address is properly stored. */
519 /* Prevent quitting in move_gap. */
524 real_gap_loc_byte
= GPT_BYTE
;
525 old_gap_size
= GAP_SIZE
;
527 /* Call the newly allocated space a gap at the end of the whole space. */
529 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
530 GAP_SIZE
= nbytes_added
;
532 /* Move the new gap down to be consecutive with the end of the old one.
533 This adjusts the markers properly too. */
534 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
536 /* Now combine the two into one large gap. */
537 GAP_SIZE
+= old_gap_size
;
539 GPT_BYTE
= real_gap_loc_byte
;
547 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
548 FROM_MULTIBYTE says whether the incoming text is multibyte.
549 TO_MULTIBYTE says whether to store the text as multibyte.
550 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
552 Return the number of bytes stored at TO_ADDR. */
555 copy_text (from_addr
, to_addr
, nbytes
,
556 from_multibyte
, to_multibyte
)
557 unsigned char *from_addr
;
558 unsigned char *to_addr
;
560 int from_multibyte
, to_multibyte
;
562 if (from_multibyte
== to_multibyte
)
564 bcopy (from_addr
, to_addr
, nbytes
);
567 else if (from_multibyte
)
570 int bytes_left
= nbytes
;
572 /* Convert multibyte to single byte. */
573 while (bytes_left
> 0)
576 c
= STRING_CHAR_AND_LENGTH (from_addr
, bytes_left
, thislen
);
577 *to_addr
++ = SINGLE_BYTE_CHAR_P (c
) ? c
: (c
& 0177) + 0200;
578 from_addr
+= thislen
;
586 unsigned char *initial_to_addr
= to_addr
;
588 /* Convert single-byte to multibyte. */
591 int c
= *from_addr
++;
592 unsigned char workbuf
[4], *str
;
595 if (c
>= 0200 && c
< 0400)
597 if (! NILP (Vnonascii_translate_table
))
598 c
= XINT (Faref (Vnonascii_translate_table
, make_number (c
)));
599 else if (nonascii_insert_offset
> 0)
600 c
+= nonascii_insert_offset
;
602 c
+= DEFAULT_NONASCII_INSERT_OFFSET
;
604 len
= CHAR_STRING (c
, workbuf
, str
);
605 bcopy (str
, to_addr
, len
);
610 /* Special case for speed. */
611 *to_addr
++ = c
, nbytes
--;
613 return to_addr
- initial_to_addr
;
617 /* Return the number of bytes it would take
618 to convert some single-byte text to multibyte.
619 The single-byte text consists of NBYTES bytes at PTR. */
622 count_size_as_multibyte (ptr
, nbytes
)
627 int outgoing_nbytes
= 0;
629 for (i
= 0; i
< nbytes
; i
++)
631 unsigned int c
= *ptr
++;
632 if (c
>= 0200 && c
< 0400)
634 if (! NILP (Vnonascii_translate_table
))
635 c
= XINT (Faref (Vnonascii_translate_table
, make_number (c
)));
636 else if (nonascii_insert_offset
> 0)
637 c
+= nonascii_insert_offset
;
639 c
+= DEFAULT_NONASCII_INSERT_OFFSET
;
641 outgoing_nbytes
+= XINT (Fchar_bytes (make_number (c
)));
644 return outgoing_nbytes
;
647 /* Insert a string of specified length before point.
648 This function judges multibyteness based on
649 enable_multibyte_characters in the current buffer;
650 it never converts between single-byte and multibyte.
652 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
653 prepare_to_modify_buffer could relocate the text. */
656 insert (string
, nbytes
)
657 register unsigned char *string
;
663 insert_1 (string
, nbytes
, 0, 1, 0);
664 signal_after_change (opoint
, 0, PT
- opoint
);
668 /* Likewise, but inherit text properties from neighboring characters. */
671 insert_and_inherit (string
, nbytes
)
672 register unsigned char *string
;
678 insert_1 (string
, nbytes
, 1, 1, 0);
679 signal_after_change (opoint
, 0, PT
- opoint
);
683 /* Insert the character C before point. Do not inherit text properties. */
689 unsigned char workbuf
[4], *str
;
692 if (! NILP (current_buffer
->enable_multibyte_characters
))
693 len
= CHAR_STRING (c
, workbuf
, str
);
704 /* Insert the null-terminated string S before point. */
710 insert (s
, strlen (s
));
713 /* Like `insert' except that all markers pointing at the place where
714 the insertion happens are adjusted to point after it.
715 Don't use this function to insert part of a Lisp string,
716 since gc could happen and relocate it. */
719 insert_before_markers (string
, nbytes
)
720 unsigned char *string
;
727 insert_1 (string
, nbytes
, 0, 1, 1);
728 signal_after_change (opoint
, 0, PT
- opoint
);
732 /* Likewise, but inherit text properties from neighboring characters. */
735 insert_before_markers_and_inherit (string
, nbytes
)
736 unsigned char *string
;
743 insert_1 (string
, nbytes
, 1, 1, 1);
744 signal_after_change (opoint
, 0, PT
- opoint
);
748 /* Subroutine used by the insert functions above. */
751 insert_1 (string
, nbytes
, inherit
, prepare
, before_markers
)
752 register unsigned char *string
;
754 int inherit
, prepare
, before_markers
;
756 register Lisp_Object temp
;
757 int nchars
= chars_in_text (string
, nbytes
);
760 prepare_to_modify_buffer (PT
, PT
, NULL
);
763 move_gap_both (PT
, PT_BYTE
);
764 if (GAP_SIZE
< nbytes
)
765 make_gap (nbytes
- GAP_SIZE
);
767 record_insert (PT
, nchars
);
770 bcopy (string
, GPT_ADDR
, nbytes
);
772 #ifdef USE_TEXT_PROPERTIES
773 if (BUF_INTERVALS (current_buffer
) != 0)
774 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
775 offset_intervals (current_buffer
, PT
, nchars
);
785 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
786 adjust_overlays_for_insert (PT
, nchars
);
787 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
, PT_BYTE
+ nbytes
,
789 adjust_point (nchars
, nbytes
);
794 #ifdef USE_TEXT_PROPERTIES
795 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
796 Fset_text_properties (make_number (PT
- nchars
), make_number (PT
),
801 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
802 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
803 are the same as in insert_1. */
806 insert_1_both (string
, nchars
, nbytes
, inherit
, prepare
, before_markers
)
807 register unsigned char *string
;
808 register int nchars
, nbytes
;
809 int inherit
, prepare
, before_markers
;
811 register Lisp_Object temp
;
814 prepare_to_modify_buffer (PT
, PT
, NULL
);
817 move_gap_both (PT
, PT_BYTE
);
818 if (GAP_SIZE
< nbytes
)
819 make_gap (nbytes
- GAP_SIZE
);
821 record_insert (PT
, nchars
);
824 bcopy (string
, GPT_ADDR
, nbytes
);
826 #ifdef USE_TEXT_PROPERTIES
827 if (BUF_INTERVALS (current_buffer
) != 0)
828 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
829 offset_intervals (current_buffer
, PT
, nchars
);
839 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
840 adjust_overlays_for_insert (PT
, nchars
);
841 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
, PT_BYTE
+ nbytes
,
843 adjust_point (nchars
, nbytes
);
848 #ifdef USE_TEXT_PROPERTIES
849 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
850 Fset_text_properties (make_number (PT
- nchars
), make_number (PT
),
855 /* Insert the part of the text of STRING, a Lisp object assumed to be
856 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
857 starting at position POS / POS_BYTE. If the text of STRING has properties,
858 copy them into the buffer.
860 It does not work to use `insert' for this, because a GC could happen
861 before we bcopy the stuff into the buffer, and relocate the string
862 without insert noticing. */
865 insert_from_string (string
, pos
, pos_byte
, length
, length_byte
, inherit
)
867 register int pos
, pos_byte
, length
, length_byte
;
873 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
875 signal_after_change (opoint
, 0, PT
- opoint
);
879 /* Like `insert_from_string' except that all markers pointing
880 at the place where the insertion happens are adjusted to point after it. */
883 insert_from_string_before_markers (string
, pos
, pos_byte
,
884 length
, length_byte
, inherit
)
886 register int pos
, pos_byte
, length
, length_byte
;
892 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
894 signal_after_change (opoint
, 0, PT
- opoint
);
898 /* Subroutine of the insertion functions above. */
901 insert_from_string_1 (string
, pos
, pos_byte
, nchars
, nbytes
,
902 inherit
, before_markers
)
904 register int pos
, pos_byte
, nchars
, nbytes
;
905 int inherit
, before_markers
;
907 register Lisp_Object temp
;
909 int outgoing_nbytes
= nbytes
;
911 /* Make OUTGOING_NBYTES describe the text
912 as it will be inserted in this buffer. */
914 if (NILP (current_buffer
->enable_multibyte_characters
))
915 outgoing_nbytes
= nchars
;
916 else if (nchars
== nbytes
)
918 = count_size_as_multibyte (&XSTRING (string
)->data
[pos_byte
],
921 /* Make sure point-max won't overflow after this insertion. */
922 XSETINT (temp
, outgoing_nbytes
+ Z
);
923 if (outgoing_nbytes
+ Z
!= XINT (temp
))
924 error ("Maximum buffer size exceeded");
927 prepare_to_modify_buffer (PT
, PT
, NULL
);
930 move_gap_both (PT
, PT_BYTE
);
931 if (GAP_SIZE
< nbytes
)
932 make_gap (outgoing_nbytes
- GAP_SIZE
);
934 record_insert (PT
, nchars
);
938 /* Copy the string text into the buffer, perhaps converting
939 between single-byte and multibyte. */
940 copy_text (XSTRING (string
)->data
+ pos_byte
, GPT_ADDR
, nbytes
,
941 /* If these are equal, it is a single-byte string.
942 Its chars are either ASCII, in which case copy_text
943 won't change it, or single-byte non-ASCII chars,
944 that need to be changed. */
946 ! NILP (current_buffer
->enable_multibyte_characters
));
948 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
949 offset_intervals (current_buffer
, PT
, nchars
);
951 GAP_SIZE
-= outgoing_nbytes
;
955 GPT_BYTE
+= outgoing_nbytes
;
956 ZV_BYTE
+= outgoing_nbytes
;
957 Z_BYTE
+= outgoing_nbytes
;
958 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
959 adjust_overlays_for_insert (PT
, nchars
);
960 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
961 PT_BYTE
+ outgoing_nbytes
,
967 graft_intervals_into_buffer (XSTRING (string
)->intervals
, PT
, nchars
,
968 current_buffer
, inherit
);
970 adjust_point (nchars
, outgoing_nbytes
);
973 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
974 current buffer. If the text in BUF has properties, they are absorbed
975 into the current buffer.
977 It does not work to use `insert' for this, because a malloc could happen
978 and relocate BUF's text before the bcopy happens. */
981 insert_from_buffer (buf
, charpos
, nchars
, inherit
)
990 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
991 signal_after_change (opoint
, 0, PT
- opoint
);
996 insert_from_buffer_1 (buf
, from
, nchars
, inherit
)
1001 register Lisp_Object temp
;
1003 int from_byte
= buf_charpos_to_bytepos (buf
, from
);
1004 int to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1005 int incoming_nbytes
= to_byte
- from_byte
;
1006 int outgoing_nbytes
= incoming_nbytes
;
1008 /* Make OUTGOING_NBYTES describe the text
1009 as it will be inserted in this buffer. */
1011 if (NILP (current_buffer
->enable_multibyte_characters
))
1012 outgoing_nbytes
= nchars
;
1013 else if (NILP (buf
->enable_multibyte_characters
))
1015 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1018 /* Make sure point-max won't overflow after this insertion. */
1019 XSETINT (temp
, outgoing_nbytes
+ Z
);
1020 if (outgoing_nbytes
+ Z
!= XINT (temp
))
1021 error ("Maximum buffer size exceeded");
1023 prepare_to_modify_buffer (PT
, PT
, NULL
);
1026 move_gap_both (PT
, PT_BYTE
);
1027 if (GAP_SIZE
< outgoing_nbytes
)
1028 make_gap (outgoing_nbytes
- GAP_SIZE
);
1030 record_insert (PT
, nchars
);
1033 if (from
< BUF_GPT (buf
))
1035 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1036 if (chunk
> incoming_nbytes
)
1037 chunk
= incoming_nbytes
;
1038 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1040 ! NILP (buf
->enable_multibyte_characters
),
1041 ! NILP (current_buffer
->enable_multibyte_characters
));
1045 if (chunk
< incoming_nbytes
)
1046 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1047 GPT_ADDR
+ chunk
, incoming_nbytes
- chunk
,
1048 ! NILP (buf
->enable_multibyte_characters
),
1049 ! NILP (current_buffer
->enable_multibyte_characters
));
1051 #ifdef USE_TEXT_PROPERTIES
1052 if (BUF_INTERVALS (current_buffer
) != 0)
1053 offset_intervals (current_buffer
, PT
, nchars
);
1056 GAP_SIZE
-= outgoing_nbytes
;
1060 GPT_BYTE
+= outgoing_nbytes
;
1061 ZV_BYTE
+= outgoing_nbytes
;
1062 Z_BYTE
+= outgoing_nbytes
;
1063 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1064 adjust_overlays_for_insert (PT
, nchars
);
1065 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1066 PT_BYTE
+ outgoing_nbytes
, 0);
1067 adjust_point (nchars
, outgoing_nbytes
);
1072 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1073 graft_intervals_into_buffer (copy_intervals (BUF_INTERVALS (buf
),
1075 PT
- nchars
, nchars
,
1076 current_buffer
, inherit
);
1079 /* This function should be called after moving gap to FROM and before
1080 altering LEN chars of text starting from FROM. This adjusts
1081 various position keepers and markers and as if the text is deleted.
1082 Don't forget to call adjust_after_replace after you actually alter
1086 adjust_before_replace (from
, from_byte
, to
, to_byte
)
1087 int from
, from_byte
, to
, to_byte
;
1089 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1090 record_delete (from
, to
- from
);
1093 /* This function should be called after altering the text between FROM
1094 and TO to a new text of LEN chars (LEN_BYTE bytes). */
1097 adjust_after_replace (from
, from_byte
, to
, to_byte
, len
, len_byte
)
1098 int from
, from_byte
, to
, to_byte
, len
, len_byte
;
1100 record_insert (from
, len
);
1102 adjust_point (len
- (to
- from
), len_byte
- (to_byte
- from_byte
));
1103 #ifdef USE_TEXT_PROPERTIES
1104 offset_intervals (current_buffer
, PT
, len
- (to
- from
));
1106 adjust_overlays_for_delete (from
, to
- from
);
1107 adjust_overlays_for_insert (from
, len
);
1108 adjust_markers_for_insert (from
, from_byte
,
1109 from
+ len
, from_byte
+ len_byte
, 0);
1111 evaporate_overlays (from
);
1115 /* Replace the text from character positions FROM to TO with NEW,
1116 If PREPARE is nonzero, call prepare_to_modify_buffer.
1117 If INHERIT, the newly inserted text should inherit text properties
1118 from the surrounding non-deleted text. */
1120 /* Note that this does not yet handle markers quite right.
1121 Also it needs to record a single undo-entry that does a replacement
1122 rather than a separate delete and insert.
1123 That way, undo will also handle markers properly. */
1126 replace_range (from
, to
, new, prepare
, inherit
)
1128 int from
, to
, prepare
, inherit
;
1130 int inschars
= XSTRING (new)->size
;
1131 int insbytes
= XSTRING (new)->size_byte
;
1132 int from_byte
, to_byte
;
1133 int nbytes_del
, nchars_del
;
1134 register Lisp_Object temp
;
1135 struct gcpro gcpro1
;
1141 int range_length
= to
- from
;
1142 prepare_to_modify_buffer (from
, to
, &from
);
1143 to
= from
+ range_length
;
1148 /* Make args be valid */
1154 from_byte
= CHAR_TO_BYTE (from
);
1155 to_byte
= CHAR_TO_BYTE (to
);
1157 nchars_del
= to
- from
;
1158 nbytes_del
= to_byte
- from_byte
;
1160 if (nbytes_del
<= 0 && insbytes
== 0)
1163 /* Make sure point-max won't overflow after this insertion. */
1164 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1165 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1166 error ("Maximum buffer size exceeded");
1170 /* Make sure the gap is somewhere in or next to what we are deleting. */
1172 gap_right (from
, from_byte
);
1174 gap_left (to
, to_byte
, 0);
1176 /* Relocate all markers pointing into the new, larger gap
1177 to point at the end of the text before the gap.
1178 Do this before recording the deletion,
1179 so that undo handles this after reinserting the text. */
1180 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1182 record_delete (from
, nchars_del
);
1184 GAP_SIZE
+= nbytes_del
;
1187 ZV_BYTE
-= nbytes_del
;
1188 Z_BYTE
-= nbytes_del
;
1190 GPT_BYTE
= from_byte
;
1191 *(GPT_ADDR
) = 0; /* Put an anchor. */
1196 if (GPT
- BEG
< beg_unchanged
)
1197 beg_unchanged
= GPT
- BEG
;
1198 if (Z
- GPT
< end_unchanged
)
1199 end_unchanged
= Z
- GPT
;
1201 if (GAP_SIZE
< insbytes
)
1202 make_gap (insbytes
- GAP_SIZE
);
1204 record_insert (from
, inschars
);
1206 bcopy (XSTRING (new)->data
, GPT_ADDR
, insbytes
);
1208 /* Relocate point as if it were a marker. */
1210 adjust_point (from
+ inschars
- (PT
< to
? PT
: to
),
1211 (from_byte
+ insbytes
1212 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1214 #ifdef USE_TEXT_PROPERTIES
1215 offset_intervals (current_buffer
, PT
, inschars
- nchars_del
);
1218 GAP_SIZE
-= insbytes
;
1222 GPT_BYTE
+= insbytes
;
1223 ZV_BYTE
+= insbytes
;
1224 ZV_BYTE
+= insbytes
;
1225 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1230 /* Adjust the overlay center as needed. This must be done after
1231 adjusting the markers that bound the overlays. */
1232 adjust_overlays_for_delete (from
, nchars_del
);
1233 adjust_overlays_for_insert (from
, inschars
);
1234 adjust_markers_for_insert (from
, from_byte
, from
+ inschars
,
1235 from_byte
+ insbytes
, 0);
1237 #ifdef USE_TEXT_PROPERTIES
1238 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1239 graft_intervals_into_buffer (XSTRING (new)->intervals
, from
,
1240 inschars
, current_buffer
, inherit
);
1244 evaporate_overlays (from
);
1249 signal_after_change (from
, nchars_del
, inschars
);
1252 /* Delete characters in current buffer
1253 from FROM up to (but not including) TO.
1254 If TO comes before FROM, we delete nothing. */
1257 del_range (from
, to
)
1258 register int from
, to
;
1260 del_range_1 (from
, to
, 1);
1263 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
1266 del_range_1 (from
, to
, prepare
)
1267 int from
, to
, prepare
;
1269 int from_byte
, to_byte
;
1271 /* Make args be valid */
1282 int range_length
= to
- from
;
1283 prepare_to_modify_buffer (from
, to
, &from
);
1284 to
= from
+ range_length
;
1287 from_byte
= CHAR_TO_BYTE (from
);
1288 to_byte
= CHAR_TO_BYTE (to
);
1290 del_range_2 (from
, to
, from_byte
, to_byte
);
1293 /* Like del_range_1 but args are byte positions, not char positions. */
1296 del_range_byte (from_byte
, to_byte
, prepare
)
1297 int from_byte
, to_byte
, prepare
;
1301 /* Make args be valid */
1302 if (from_byte
< BEGV_BYTE
)
1303 from_byte
= BEGV_BYTE
;
1304 if (to_byte
> ZV_BYTE
)
1307 if (to_byte
<= from_byte
)
1310 from
= BYTE_TO_CHAR (from_byte
);
1311 to
= BYTE_TO_CHAR (to_byte
);
1315 int old_from
= from
, old_to
= Z
- to
;
1316 int range_length
= to
- from
;
1317 prepare_to_modify_buffer (from
, to
, &from
);
1318 to
= from
+ range_length
;
1320 if (old_from
!= from
)
1321 from_byte
= CHAR_TO_BYTE (from
);
1322 if (old_to
== Z
- to
)
1323 to_byte
= CHAR_TO_BYTE (to
);
1326 del_range_2 (from
, to
, from_byte
, to_byte
);
1329 /* Like del_range_1, but positions are specified both as charpos
1333 del_range_both (from
, to
, from_byte
, to_byte
, prepare
)
1334 int from
, to
, from_byte
, to_byte
, prepare
;
1336 /* Make args be valid */
1337 if (from_byte
< BEGV_BYTE
)
1338 from_byte
= BEGV_BYTE
;
1339 if (to_byte
> ZV_BYTE
)
1342 if (to_byte
<= from_byte
)
1352 int old_from
= from
, old_to
= Z
- to
;
1353 int range_length
= to
- from
;
1354 prepare_to_modify_buffer (from
, to
, &from
);
1355 to
= from
+ range_length
;
1357 if (old_from
!= from
)
1358 from_byte
= CHAR_TO_BYTE (from
);
1359 if (old_to
== Z
- to
)
1360 to_byte
= CHAR_TO_BYTE (to
);
1363 del_range_2 (from
, to
, from_byte
, to_byte
);
1366 /* Delete a range of text, specified both as character positions
1367 and byte positions. FROM and TO are character positions,
1368 while FROM_BYTE and TO_BYTE are byte positions. */
1371 del_range_2 (from
, to
, from_byte
, to_byte
)
1372 int from
, to
, from_byte
, to_byte
;
1374 register int nbytes_del
, nchars_del
;
1376 nchars_del
= to
- from
;
1377 nbytes_del
= to_byte
- from_byte
;
1379 /* Make sure the gap is somewhere in or next to what we are deleting. */
1381 gap_right (from
, from_byte
);
1383 gap_left (to
, to_byte
, 0);
1385 /* Relocate all markers pointing into the new, larger gap
1386 to point at the end of the text before the gap.
1387 Do this before recording the deletion,
1388 so that undo handles this after reinserting the text. */
1389 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1391 record_delete (from
, nchars_del
);
1394 /* Relocate point as if it were a marker. */
1396 adjust_point (from
- (PT
< to
? PT
: to
),
1397 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
1399 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1400 offset_intervals (current_buffer
, from
, - nchars_del
);
1402 /* Adjust the overlay center as needed. This must be done after
1403 adjusting the markers that bound the overlays. */
1404 adjust_overlays_for_delete (from_byte
, nchars_del
);
1406 GAP_SIZE
+= nbytes_del
;
1407 ZV_BYTE
-= nbytes_del
;
1408 Z_BYTE
-= nbytes_del
;
1412 GPT_BYTE
= from_byte
;
1413 *(GPT_ADDR
) = 0; /* Put an anchor. */
1418 if (GPT
- BEG
< beg_unchanged
)
1419 beg_unchanged
= GPT
- BEG
;
1420 if (Z
- GPT
< end_unchanged
)
1421 end_unchanged
= Z
- GPT
;
1423 evaporate_overlays (from
);
1424 signal_after_change (from
, nchars_del
, 0);
1427 /* Call this if you're about to change the region of BUFFER from
1428 character positions START to END. This checks the read-only
1429 properties of the region, calls the necessary modification hooks,
1430 and warns the next redisplay that it should pay attention to that
1434 modify_region (buffer
, start
, end
)
1435 struct buffer
*buffer
;
1438 struct buffer
*old_buffer
= current_buffer
;
1440 if (buffer
!= old_buffer
)
1441 set_buffer_internal (buffer
);
1443 prepare_to_modify_buffer (start
, end
, NULL
);
1445 if (start
- 1 < beg_unchanged
1446 || (unchanged_modified
== MODIFF
1447 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
1448 beg_unchanged
= start
- 1;
1449 if (Z
- end
< end_unchanged
1450 || (unchanged_modified
== MODIFF
1451 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
1452 end_unchanged
= Z
- end
;
1454 if (MODIFF
<= SAVE_MODIFF
)
1455 record_first_change ();
1458 buffer
->point_before_scroll
= Qnil
;
1460 if (buffer
!= old_buffer
)
1461 set_buffer_internal (old_buffer
);
1464 /* Check that it is okay to modify the buffer between START and END,
1465 which are char positions.
1467 Run the before-change-function, if any. If intervals are in use,
1468 verify that the text to be modified is not read-only, and call
1469 any modification properties the text may have.
1471 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1472 by holding its value temporarily in a marker. */
1475 prepare_to_modify_buffer (start
, end
, preserve_ptr
)
1479 if (!NILP (current_buffer
->read_only
))
1480 Fbarf_if_buffer_read_only ();
1482 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1483 if (BUF_INTERVALS (current_buffer
) != 0)
1487 Lisp_Object preserve_marker
;
1488 struct gcpro gcpro1
;
1489 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
1490 GCPRO1 (preserve_marker
);
1491 verify_interval_modification (current_buffer
, start
, end
);
1492 *preserve_ptr
= marker_position (preserve_marker
);
1493 unchain_marker (preserve_marker
);
1497 verify_interval_modification (current_buffer
, start
, end
);
1500 #ifdef CLASH_DETECTION
1501 if (!NILP (current_buffer
->file_truename
)
1502 /* Make binding buffer-file-name to nil effective. */
1503 && !NILP (current_buffer
->filename
)
1504 && SAVE_MODIFF
>= MODIFF
)
1505 lock_file (current_buffer
->file_truename
);
1507 /* At least warn if this file has changed on disk since it was visited. */
1508 if (!NILP (current_buffer
->filename
)
1509 && SAVE_MODIFF
>= MODIFF
1510 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
1511 && !NILP (Ffile_exists_p (current_buffer
->filename
)))
1512 call1 (intern ("ask-user-about-supersession-threat"),
1513 current_buffer
->filename
);
1514 #endif /* not CLASH_DETECTION */
1516 signal_before_change (start
, end
, preserve_ptr
);
1518 if (current_buffer
->newline_cache
)
1519 invalidate_region_cache (current_buffer
,
1520 current_buffer
->newline_cache
,
1521 start
- BEG
, Z
- end
);
1522 if (current_buffer
->width_run_cache
)
1523 invalidate_region_cache (current_buffer
,
1524 current_buffer
->width_run_cache
,
1525 start
- BEG
, Z
- end
);
1527 Vdeactivate_mark
= Qt
;
1530 /* These macros work with an argument named `preserve_ptr'
1531 and a local variable named `preserve_marker'. */
1533 #define PRESERVE_VALUE \
1534 if (preserve_ptr && NILP (preserve_marker)) \
1535 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
1537 #define RESTORE_VALUE \
1538 if (! NILP (preserve_marker)) \
1540 *preserve_ptr = marker_position (preserve_marker); \
1541 unchain_marker (preserve_marker); \
1544 #define PRESERVE_START_END \
1545 if (NILP (start_marker)) \
1546 start_marker = Fcopy_marker (start, Qnil); \
1547 if (NILP (end_marker)) \
1548 end_marker = Fcopy_marker (end, Qnil);
1550 #define FETCH_START \
1551 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
1554 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
1556 /* Signal a change to the buffer immediately before it happens.
1557 START_INT and END_INT are the bounds of the text to be changed.
1559 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1560 by holding its value temporarily in a marker. */
1563 signal_before_change (start_int
, end_int
, preserve_ptr
)
1564 int start_int
, end_int
;
1567 Lisp_Object start
, end
;
1568 Lisp_Object start_marker
, end_marker
;
1569 Lisp_Object preserve_marker
;
1570 struct gcpro gcpro1
, gcpro2
, gcpro3
;
1572 start
= make_number (start_int
);
1573 end
= make_number (end_int
);
1574 preserve_marker
= Qnil
;
1575 start_marker
= Qnil
;
1577 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
1579 /* If buffer is unmodified, run a special hook for that case. */
1580 if (SAVE_MODIFF
>= MODIFF
1581 && !NILP (Vfirst_change_hook
)
1582 && !NILP (Vrun_hooks
))
1586 call1 (Vrun_hooks
, Qfirst_change_hook
);
1589 /* Run the before-change-function if any.
1590 We don't bother "binding" this variable to nil
1591 because it is obsolete anyway and new code should not use it. */
1592 if (!NILP (Vbefore_change_function
))
1596 call2 (Vbefore_change_function
, FETCH_START
, FETCH_END
);
1599 /* Now run the before-change-functions if any. */
1600 if (!NILP (Vbefore_change_functions
))
1602 Lisp_Object args
[3];
1603 Lisp_Object before_change_functions
;
1604 Lisp_Object after_change_functions
;
1605 struct gcpro gcpro1
, gcpro2
;
1610 /* "Bind" before-change-functions and after-change-functions
1611 to nil--but in a way that errors don't know about.
1612 That way, if there's an error in them, they will stay nil. */
1613 before_change_functions
= Vbefore_change_functions
;
1614 after_change_functions
= Vafter_change_functions
;
1615 Vbefore_change_functions
= Qnil
;
1616 Vafter_change_functions
= Qnil
;
1617 GCPRO2 (before_change_functions
, after_change_functions
);
1619 /* Actually run the hook functions. */
1620 args
[0] = Qbefore_change_functions
;
1621 args
[1] = FETCH_START
;
1622 args
[2] = FETCH_END
;
1623 run_hook_list_with_args (before_change_functions
, 3, args
);
1625 /* "Unbind" the variables we "bound" to nil. */
1626 Vbefore_change_functions
= before_change_functions
;
1627 Vafter_change_functions
= after_change_functions
;
1631 if (!NILP (current_buffer
->overlays_before
)
1632 || !NILP (current_buffer
->overlays_after
))
1635 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
1636 FETCH_START
, FETCH_END
, Qnil
);
1639 if (! NILP (start_marker
))
1640 free_marker (start_marker
);
1641 if (! NILP (end_marker
))
1642 free_marker (end_marker
);
1647 /* Signal a change immediately after it happens.
1648 CHARPOS is the character position of the start of the changed text.
1649 LENDEL is the number of characters of the text before the change.
1650 (Not the whole buffer; just the part that was changed.)
1651 LENINS is the number of characters in that part of the text
1652 after the change. */
1655 signal_after_change (charpos
, lendel
, lenins
)
1656 int charpos
, lendel
, lenins
;
1658 /* If we are deferring calls to the after-change functions
1659 and there are no before-change functions,
1660 just record the args that we were going to use. */
1661 if (! NILP (Vcombine_after_change_calls
)
1662 && NILP (Vbefore_change_function
) && NILP (Vbefore_change_functions
)
1663 && NILP (current_buffer
->overlays_before
)
1664 && NILP (current_buffer
->overlays_after
))
1668 if (!NILP (combine_after_change_list
)
1669 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
1670 Fcombine_after_change_execute ();
1672 elt
= Fcons (make_number (charpos
- BEG
),
1673 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
1674 Fcons (make_number (lenins
- lendel
), Qnil
)));
1675 combine_after_change_list
1676 = Fcons (elt
, combine_after_change_list
);
1677 combine_after_change_buffer
= Fcurrent_buffer ();
1682 if (!NILP (combine_after_change_list
))
1683 Fcombine_after_change_execute ();
1685 /* Run the after-change-function if any.
1686 We don't bother "binding" this variable to nil
1687 because it is obsolete anyway and new code should not use it. */
1688 if (!NILP (Vafter_change_function
))
1689 call3 (Vafter_change_function
,
1690 make_number (charpos
), make_number (charpos
+ lenins
),
1691 make_number (lendel
));
1693 if (!NILP (Vafter_change_functions
))
1695 Lisp_Object args
[4];
1696 Lisp_Object before_change_functions
;
1697 Lisp_Object after_change_functions
;
1698 struct gcpro gcpro1
, gcpro2
;
1700 /* "Bind" before-change-functions and after-change-functions
1701 to nil--but in a way that errors don't know about.
1702 That way, if there's an error in them, they will stay nil. */
1703 before_change_functions
= Vbefore_change_functions
;
1704 after_change_functions
= Vafter_change_functions
;
1705 Vbefore_change_functions
= Qnil
;
1706 Vafter_change_functions
= Qnil
;
1707 GCPRO2 (before_change_functions
, after_change_functions
);
1709 /* Actually run the hook functions. */
1710 args
[0] = Qafter_change_functions
;
1711 XSETFASTINT (args
[1], charpos
);
1712 XSETFASTINT (args
[2], charpos
+ lenins
);
1713 XSETFASTINT (args
[3], lendel
);
1714 run_hook_list_with_args (after_change_functions
,
1717 /* "Unbind" the variables we "bound" to nil. */
1718 Vbefore_change_functions
= before_change_functions
;
1719 Vafter_change_functions
= after_change_functions
;
1723 if (!NILP (current_buffer
->overlays_before
)
1724 || !NILP (current_buffer
->overlays_after
))
1725 report_overlay_modification (make_number (charpos
),
1726 make_number (charpos
+ lenins
),
1728 make_number (charpos
),
1729 make_number (charpos
+ lenins
),
1730 make_number (lendel
));
1732 /* After an insertion, call the text properties
1733 insert-behind-hooks or insert-in-front-hooks. */
1735 report_interval_modification (charpos
, charpos
+ lenins
);
1739 Fcombine_after_change_execute_1 (val
)
1742 Vcombine_after_change_calls
= val
;
1746 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
1747 Scombine_after_change_execute
, 0, 0, 0,
1748 "This function is for use internally in `combine-after-change-calls'.")
1751 register Lisp_Object val
;
1752 int count
= specpdl_ptr
- specpdl
;
1753 int beg
, end
, change
;
1757 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
1759 Fset_buffer (combine_after_change_buffer
);
1761 /* # chars unchanged at beginning of buffer. */
1763 /* # chars unchanged at end of buffer. */
1765 /* Total amount of insertion (negative for deletion). */
1768 /* Scan the various individual changes,
1769 accumulating the range info in BEG, END and CHANGE. */
1770 for (tail
= combine_after_change_list
; CONSP (tail
);
1771 tail
= XCONS (tail
)->cdr
)
1774 int thisbeg
, thisend
, thischange
;
1776 /* Extract the info from the next element. */
1777 elt
= XCONS (tail
)->car
;
1780 thisbeg
= XINT (XCONS (elt
)->car
);
1782 elt
= XCONS (elt
)->cdr
;
1785 thisend
= XINT (XCONS (elt
)->car
);
1787 elt
= XCONS (elt
)->cdr
;
1790 thischange
= XINT (XCONS (elt
)->car
);
1792 /* Merge this range into the accumulated range. */
1793 change
+= thischange
;
1800 /* Get the current start and end positions of the range
1801 that was changed. */
1805 /* We are about to handle these, so discard them. */
1806 combine_after_change_list
= Qnil
;
1808 /* Now run the after-change functions for real.
1809 Turn off the flag that defers them. */
1810 record_unwind_protect (Fcombine_after_change_execute_1
,
1811 Vcombine_after_change_calls
);
1812 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
1814 return unbind_to (count
, val
);
1819 staticpro (&combine_after_change_list
);
1820 combine_after_change_list
= Qnil
;
1822 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls
,
1823 "Used internally by the `combine-after-change-calls' macro.");
1824 Vcombine_after_change_calls
= Qnil
;
1826 defsubr (&Scombine_after_change_execute
);