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, int, int));
42 static void adjust_markers_for_delete
P_ ((int, int, int, int));
43 static void adjust_markers_for_record_delete
P_ ((int, int, int, int));
44 static void adjust_point
P_ ((int, int));
46 Lisp_Object
Fcombine_after_change_execute ();
48 /* Non-nil means don't call the after-change-functions right away,
49 just record an element in Vcombine_after_change_calls_list. */
50 Lisp_Object Vcombine_after_change_calls
;
52 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
53 describing changes which happened while combine_after_change_calls
54 was nonzero. We use this to decide how to call them
55 once the deferral ends.
58 BEG-UNCHANGED is the number of chars before the changed range.
59 END-UNCHANGED is the number of chars after the changed range,
60 and CHANGE-AMOUNT is the number of characters inserted by the change
61 (negative for a deletion). */
62 Lisp_Object combine_after_change_list
;
64 /* Buffer which combine_after_change_list is about. */
65 Lisp_Object combine_after_change_buffer
;
67 /* Check all markers in the current buffer, looking for something invalid. */
69 static int check_markers_debug_flag
;
71 #define CHECK_MARKERS() \
72 if (check_markers_debug_flag) \
79 register Lisp_Object tail
, prev
, next
;
81 tail
= BUF_MARKERS (current_buffer
);
83 while (XSYMBOL (tail
) != XSYMBOL (Qnil
))
85 if (XMARKER (tail
)->buffer
->text
!= current_buffer
->text
)
87 if (XMARKER (tail
)->charpos
> Z
)
89 if (XMARKER (tail
)->bytepos
> Z_BYTE
)
92 tail
= XMARKER (tail
)->chain
;
96 /* Move gap to position CHARPOS.
97 Note that this can quit! */
103 move_gap_both (charpos
, charpos_to_bytepos (charpos
));
106 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
107 Note that this can quit! */
110 move_gap_both (charpos
, bytepos
)
111 int charpos
, bytepos
;
113 if (bytepos
< GPT_BYTE
)
114 gap_left (charpos
, bytepos
, 0);
115 else if (bytepos
> GPT_BYTE
)
116 gap_right (charpos
, bytepos
);
119 /* Move the gap to a position less than the current GPT.
120 BYTEPOS describes the new position as a byte position,
121 and CHARPOS is the corresponding char position.
122 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
125 gap_left (charpos
, bytepos
, newgap
)
126 register int charpos
, bytepos
;
129 register unsigned char *to
, *from
;
135 if (unchanged_modified
== MODIFF
136 && overlay_unchanged_modified
== OVERLAY_MODIFF
)
138 beg_unchanged
= charpos
- BEG
;
139 end_unchanged
= Z
- charpos
;
143 if (Z
- GPT
< end_unchanged
)
144 end_unchanged
= Z
- GPT
;
145 if (charpos
< beg_unchanged
)
146 beg_unchanged
= charpos
- BEG
;
155 /* Now copy the characters. To move the gap down,
156 copy characters up. */
160 /* I gets number of characters left to copy. */
161 i
= new_s1
- bytepos
;
164 /* If a quit is requested, stop copying now.
165 Change BYTEPOS to be where we have actually moved the gap to. */
169 charpos
= BYTE_TO_CHAR (bytepos
);
172 /* Move at most 32000 chars before checking again for a quit. */
177 /* bcopy is safe if the two areas of memory do not overlap
178 or on systems where bcopy is always safe for moving upward. */
179 && (BCOPY_UPWARD_SAFE
180 || to
- from
>= 128))
182 /* If overlap is not safe, avoid it by not moving too many
183 characters at once. */
184 if (!BCOPY_UPWARD_SAFE
&& i
> to
- from
)
199 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
200 BYTEPOS is where the loop above stopped, which may be what was specified
201 or may be where a quit was detected. */
202 adjust_markers_gap_motion (bytepos
, GPT_BYTE
, GAP_SIZE
);
205 if (bytepos
< charpos
)
207 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
211 /* Move the gap to a position greater than than the current GPT.
212 BYTEPOS describes the new position as a byte position,
213 and CHARPOS is the corresponding char position. */
216 gap_right (charpos
, bytepos
)
217 register int charpos
, bytepos
;
219 register unsigned char *to
, *from
;
223 if (unchanged_modified
== MODIFF
224 && overlay_unchanged_modified
== OVERLAY_MODIFF
)
226 beg_unchanged
= charpos
- BEG
;
227 end_unchanged
= Z
- charpos
;
231 if (Z
- charpos
- 1 < end_unchanged
)
232 end_unchanged
= Z
- charpos
;
233 if (GPT
- BEG
< beg_unchanged
)
234 beg_unchanged
= GPT
- BEG
;
242 /* Now copy the characters. To move the gap up,
243 copy characters down. */
247 /* I gets number of characters left to copy. */
248 i
= bytepos
- new_s1
;
251 /* If a quit is requested, stop copying now.
252 Change BYTEPOS to be where we have actually moved the gap to. */
256 charpos
= BYTE_TO_CHAR (bytepos
);
259 /* Move at most 32000 chars before checking again for a quit. */
264 /* bcopy is safe if the two areas of memory do not overlap
265 or on systems where bcopy is always safe for moving downward. */
266 && (BCOPY_DOWNWARD_SAFE
267 || from
- to
>= 128))
269 /* If overlap is not safe, avoid it by not moving too many
270 characters at once. */
271 if (!BCOPY_DOWNWARD_SAFE
&& i
> from
- to
)
286 adjust_markers_gap_motion (GPT_BYTE
+ GAP_SIZE
, bytepos
+ GAP_SIZE
,
290 if (bytepos
< charpos
)
292 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
296 /* Add AMOUNT to the byte position of every marker in the current buffer
297 whose current byte position is between FROM (exclusive) and TO (inclusive).
299 Also, any markers past the outside of that interval, in the direction
300 of adjustment, are first moved back to the near end of the interval
301 and then adjusted by AMOUNT.
303 When the latter adjustment is done, if AMOUNT is negative,
304 we record the adjustment for undo. (This case happens only for
307 The markers' character positions are not altered,
308 because gap motion does not affect character positions. */
310 int adjust_markers_test
;
313 adjust_markers_gap_motion (from
, to
, amount
)
314 register int from
, to
, amount
;
316 /* Now that a marker has a bytepos, not counting the gap,
317 nothing needs to be done here. */
320 register struct Lisp_Marker
*m
;
323 marker
= BUF_MARKERS (current_buffer
);
325 while (!NILP (marker
))
327 m
= XMARKER (marker
);
331 if (mpos
> to
&& mpos
< to
+ amount
)
333 if (adjust_markers_test
)
340 /* Here's the case where a marker is inside text being deleted.
341 AMOUNT can be negative for gap motion, too,
342 but then this range contains no markers. */
343 if (mpos
> from
+ amount
&& mpos
<= from
)
345 if (adjust_markers_test
)
347 mpos
= from
+ amount
;
350 if (mpos
> from
&& mpos
<= to
)
358 /* Adjust all markers for a deletion
359 whose range in bytes is FROM_BYTE to TO_BYTE.
360 The range in charpos is FROM to TO.
362 This function assumes that the gap is adjacent to
363 or inside of the range being deleted. */
366 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
)
367 register int from
, from_byte
, to
, to_byte
;
370 register struct Lisp_Marker
*m
;
371 register int charpos
;
373 marker
= BUF_MARKERS (current_buffer
);
375 while (!NILP (marker
))
377 m
= XMARKER (marker
);
378 charpos
= m
->charpos
;
383 /* If the marker is after the deletion,
384 relocate by number of chars / bytes deleted. */
387 m
->charpos
-= to
- from
;
388 m
->bytepos
-= to_byte
- from_byte
;
391 /* Here's the case where a marker is inside text being deleted. */
392 else if (charpos
> from
)
394 record_marker_adjustment (marker
, from
- charpos
);
396 m
->bytepos
= from_byte
;
403 /* Adjust all markers for calling record_delete for combining bytes.
404 whose range in bytes is FROM_BYTE to TO_BYTE.
405 The range in charpos is FROM to TO. */
408 adjust_markers_for_record_delete (from
, from_byte
, to
, to_byte
)
409 register int from
, from_byte
, to
, to_byte
;
412 register struct Lisp_Marker
*m
;
413 register int charpos
;
415 marker
= BUF_MARKERS (current_buffer
);
417 while (!NILP (marker
))
419 m
= XMARKER (marker
);
420 charpos
= m
->charpos
;
422 /* If the marker is after the deletion,
423 relocate by number of chars / bytes deleted. */
426 /* Here's the case where a marker is inside text being deleted. */
427 else if (charpos
> from
)
428 record_marker_adjustment (marker
, from
- charpos
);
434 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
435 to TO / TO_BYTE. We have to relocate the charpos of every marker
436 that points after the insertion (but not their bytepos).
438 COMBINED_BEFORE_BYTES is the number of bytes at the start of the insertion
439 that combine into one character with the text before the insertion.
440 COMBINED_AFTER_BYTES is the number of bytes after the insertion
441 that combine into one character with the last inserted bytes.
443 When a marker points at the insertion point,
444 we advance it if either its insertion-type is t
445 or BEFORE_MARKERS is true. */
448 adjust_markers_for_insert (from
, from_byte
, to
, to_byte
,
449 combined_before_bytes
, combined_after_bytes
,
451 register int from
, from_byte
, to
, to_byte
;
452 int combined_before_bytes
, combined_after_bytes
, before_markers
;
456 int nchars
= to
- from
;
457 int nbytes
= to_byte
- from_byte
;
459 marker
= BUF_MARKERS (current_buffer
);
461 while (!NILP (marker
))
463 register struct Lisp_Marker
*m
= XMARKER (marker
);
465 /* In a single-byte buffer, a marker's two positions must be equal.
466 (If this insertion is going to combine characters, Z will
467 become different from Z_BYTE, but they might be the same now.
468 If so, the two OLD positions of the marker should be equal.) */
471 if (m
->charpos
!= m
->bytepos
)
475 if (m
->bytepos
== from_byte
)
477 if (m
->insertion_type
|| before_markers
)
479 m
->bytepos
+= nbytes
+ combined_after_bytes
;
480 m
->charpos
+= nchars
+ !!combined_after_bytes
;
481 /* Point the marker before the combined character,
482 so that undoing the insertion puts it back where it was. */
483 if (combined_after_bytes
)
484 DEC_BOTH (m
->charpos
, m
->bytepos
);
485 if (m
->insertion_type
)
488 else if (combined_before_bytes
)
490 /* This marker doesn't "need relocation",
491 but don't leave it pointing in the middle of a character.
492 Point the marker after the combined character,
493 so that undoing the insertion puts it back where it was. */
495 /* Here we depend on the fact that the gap is after
496 all of the combining bytes that we are going to skip over. */
497 DEC_BOTH (m
->charpos
, m
->bytepos
);
498 INC_BOTH (m
->charpos
, m
->bytepos
);
501 /* If a marker was pointing into the combining bytes
502 after the insertion, don't leave it there
503 in the middle of a character. */
504 else if (combined_after_bytes
&& m
->bytepos
>= from_byte
505 && m
->bytepos
< from_byte
+ combined_after_bytes
)
507 /* Put it after the combining bytes. */
508 m
->bytepos
= to_byte
+ combined_after_bytes
;
510 /* Now move it back before the combined character,
511 so that undoing the insertion will put it where it was. */
512 DEC_BOTH (m
->charpos
, m
->bytepos
);
514 else if (m
->bytepos
> from_byte
)
516 m
->bytepos
+= nbytes
;
517 m
->charpos
+= nchars
;
523 /* Adjusting only markers whose insertion-type is t may result in
524 disordered overlays in the slot `overlays_before'. */
526 fix_overlays_before (current_buffer
, from
, to
);
529 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
531 This is used only when the value of point changes due to an insert
532 or delete; it does not represent a conceptual change in point as a
533 marker. In particular, point is not crossing any interval
534 boundaries, so there's no need to use the usual SET_PT macro. In
535 fact it would be incorrect to do so, because either the old or the
536 new value of point is out of sync with the current set of
540 adjust_point (nchars
, nbytes
)
543 BUF_PT (current_buffer
) += nchars
;
544 BUF_PT_BYTE (current_buffer
) += nbytes
;
546 /* In a single-byte buffer, the two positions must be equal. */
552 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
553 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
556 See the comment of adjust_markers_for_insert for the args
557 COMBINED_BEFORE_BYTES and COMBINED_AFTER_BYTES. */
560 adjust_markers_for_replace (from
, from_byte
, old_chars
, old_bytes
,
561 new_chars
, new_bytes
,
562 combined_before_bytes
, combined_after_bytes
)
563 int from
, from_byte
, old_chars
, old_bytes
, new_chars
, new_bytes
;
564 int combined_before_bytes
, combined_after_bytes
;
566 Lisp_Object marker
= BUF_MARKERS (current_buffer
);
567 int prev_to_byte
= from_byte
+ old_bytes
;
568 int diff_chars
= new_chars
- old_chars
;
569 int diff_bytes
= new_bytes
- old_bytes
;
571 while (!NILP (marker
))
573 register struct Lisp_Marker
*m
= XMARKER (marker
);
575 if (m
->bytepos
>= prev_to_byte
)
577 if (m
->bytepos
< prev_to_byte
+ combined_after_bytes
)
579 /* Put it after the combining bytes. */
580 m
->bytepos
= from_byte
+ new_bytes
;
581 m
->charpos
= from
+ new_chars
;
585 m
->charpos
+= diff_chars
;
586 m
->bytepos
+= diff_bytes
;
588 if (m
->charpos
== from
+ new_chars
)
589 record_marker_adjustment (marker
, - old_chars
);
591 else if (m
->bytepos
> from_byte
)
593 record_marker_adjustment (marker
, from
- m
->charpos
);
595 m
->bytepos
= from_byte
;
597 else if (m
->bytepos
== from_byte
)
599 if (combined_before_bytes
)
601 DEC_BOTH (m
->charpos
, m
->bytepos
);
602 INC_BOTH (m
->charpos
, m
->bytepos
);
611 /* Make the gap NBYTES_ADDED bytes longer. */
614 make_gap (nbytes_added
)
617 unsigned char *result
;
620 int real_gap_loc_byte
;
623 /* If we have to get more space, get enough to last a while. */
624 nbytes_added
+= 2000;
626 /* Don't allow a buffer size that won't fit in an int
627 even if it will fit in a Lisp integer.
628 That won't work because so many places use `int'. */
630 if (Z_BYTE
- BEG_BYTE
+ GAP_SIZE
+ nbytes_added
631 >= ((unsigned) 1 << (min (BITS_PER_INT
, VALBITS
) - 1)))
632 error ("Buffer exceeds maximum size");
635 /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */
636 result
= BUFFER_REALLOC (BEG_ADDR
, (Z_BYTE
- BEG_BYTE
637 + GAP_SIZE
+ nbytes_added
+ 1));
645 /* We can't unblock until the new address is properly stored. */
649 /* Prevent quitting in move_gap. */
654 real_gap_loc_byte
= GPT_BYTE
;
655 old_gap_size
= GAP_SIZE
;
657 /* Call the newly allocated space a gap at the end of the whole space. */
659 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
660 GAP_SIZE
= nbytes_added
;
662 /* Move the new gap down to be consecutive with the end of the old one.
663 This adjusts the markers properly too. */
664 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
666 /* Now combine the two into one large gap. */
667 GAP_SIZE
+= old_gap_size
;
669 GPT_BYTE
= real_gap_loc_byte
;
677 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
678 FROM_MULTIBYTE says whether the incoming text is multibyte.
679 TO_MULTIBYTE says whether to store the text as multibyte.
680 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
682 Return the number of bytes stored at TO_ADDR. */
685 copy_text (from_addr
, to_addr
, nbytes
,
686 from_multibyte
, to_multibyte
)
687 unsigned char *from_addr
;
688 unsigned char *to_addr
;
690 int from_multibyte
, to_multibyte
;
692 if (from_multibyte
== to_multibyte
)
694 bcopy (from_addr
, to_addr
, nbytes
);
697 else if (from_multibyte
)
700 int bytes_left
= nbytes
;
702 /* Convert multibyte to single byte. */
703 while (bytes_left
> 0)
706 c
= STRING_CHAR_AND_LENGTH (from_addr
, bytes_left
, thislen
);
707 *to_addr
++ = SINGLE_BYTE_CHAR_P (c
) ? c
: (c
& 0177) + 0200;
708 from_addr
+= thislen
;
716 unsigned char *initial_to_addr
= to_addr
;
718 /* Convert single-byte to multibyte. */
721 int c
= *from_addr
++;
722 unsigned char workbuf
[4], *str
;
725 if (c
>= 0240 && c
< 0400)
727 c
= unibyte_char_to_multibyte (c
);
728 len
= CHAR_STRING (c
, workbuf
, str
);
729 bcopy (str
, to_addr
, len
);
734 /* Special case for speed. */
735 *to_addr
++ = c
, nbytes
--;
737 return to_addr
- initial_to_addr
;
741 /* Return the number of bytes it would take
742 to convert some single-byte text to multibyte.
743 The single-byte text consists of NBYTES bytes at PTR. */
746 count_size_as_multibyte (ptr
, nbytes
)
751 int outgoing_nbytes
= 0;
753 for (i
= 0; i
< nbytes
; i
++)
755 unsigned int c
= *ptr
++;
761 c
= unibyte_char_to_multibyte (c
);
762 outgoing_nbytes
+= XINT (Fchar_bytes (make_number (c
)));
766 return outgoing_nbytes
;
769 /* Insert a string of specified length before point.
770 This function judges multibyteness based on
771 enable_multibyte_characters in the current buffer;
772 it never converts between single-byte and multibyte.
774 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
775 prepare_to_modify_buffer could relocate the text. */
778 insert (string
, nbytes
)
779 register unsigned char *string
;
785 insert_1 (string
, nbytes
, 0, 1, 0);
786 signal_after_change (opoint
, 0, PT
- opoint
);
790 /* Likewise, but inherit text properties from neighboring characters. */
793 insert_and_inherit (string
, nbytes
)
794 register unsigned char *string
;
800 insert_1 (string
, nbytes
, 1, 1, 0);
801 signal_after_change (opoint
, 0, PT
- opoint
);
805 /* Insert the character C before point. Do not inherit text properties. */
811 unsigned char workbuf
[4], *str
;
814 if (! NILP (current_buffer
->enable_multibyte_characters
))
815 len
= CHAR_STRING (c
, workbuf
, str
);
826 /* Insert the null-terminated string S before point. */
832 insert (s
, strlen (s
));
835 /* Like `insert' except that all markers pointing at the place where
836 the insertion happens are adjusted to point after it.
837 Don't use this function to insert part of a Lisp string,
838 since gc could happen and relocate it. */
841 insert_before_markers (string
, nbytes
)
842 unsigned char *string
;
849 insert_1 (string
, nbytes
, 0, 1, 1);
850 signal_after_change (opoint
, 0, PT
- opoint
);
854 /* Likewise, but inherit text properties from neighboring characters. */
857 insert_before_markers_and_inherit (string
, nbytes
)
858 unsigned char *string
;
865 insert_1 (string
, nbytes
, 1, 1, 1);
866 signal_after_change (opoint
, 0, PT
- opoint
);
870 /* Subroutine used by the insert functions above. */
873 insert_1 (string
, nbytes
, inherit
, prepare
, before_markers
)
874 register unsigned char *string
;
876 int inherit
, prepare
, before_markers
;
878 insert_1_both (string
, chars_in_text (string
, nbytes
), nbytes
,
879 inherit
, prepare
, before_markers
);
882 /* See if the bytes before POS/POS_BYTE combine with bytes
883 at the start of STRING to form a single character.
884 If so, return the number of bytes at the start of STRING
885 which combine in this way. Otherwise, return 0. */
888 count_combining_before (string
, length
, pos
, pos_byte
)
889 unsigned char *string
;
893 int opos
= pos
, opos_byte
= pos_byte
;
895 unsigned char *p
= string
;
897 if (NILP (current_buffer
->enable_multibyte_characters
))
899 if (length
== 0 || CHAR_HEAD_P (*string
))
903 c
= FETCH_BYTE (pos_byte
- 1);
904 if (ASCII_BYTE_P (c
))
906 DEC_BOTH (pos
, pos_byte
);
907 c
= FETCH_BYTE (pos_byte
);
908 if (! BASE_LEADING_CODE_P (c
))
911 /* We have a combination situation.
912 Count the bytes at STRING that will combine. */
913 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
919 /* See if the bytes after POS/POS_BYTE combine with bytes
920 at the end of STRING to form a single character.
921 If so, return the number of bytes after POS/POS_BYTE
922 which combine in this way. Otherwise, return 0. */
925 count_combining_after (string
, length
, pos
, pos_byte
)
926 unsigned char *string
;
930 int opos
= pos
, opos_byte
= pos_byte
;
934 if (NILP (current_buffer
->enable_multibyte_characters
))
936 if (length
== 0 || ASCII_BYTE_P (string
[length
- 1]))
939 while (i
> 0 && ! CHAR_HEAD_P (string
[i
]))
943 if (! BASE_LEADING_CODE_P (string
[i
]))
948 c
= FETCH_BYTE (pos_byte
);
951 while (pos_byte
< ZV_BYTE
)
953 c
= FETCH_BYTE (pos_byte
);
959 return pos_byte
- opos_byte
;
962 /* Adjust the position TARGET/TARGET_BYTE for the combining of NBYTES
963 following the position POS/POS_BYTE to the character preceding POS.
964 If TARGET is after POS+NBYTES, we only have to adjust the character
965 position TARGET, else, if TARGET is after POS, we have to adjust
966 both the character position TARGET and the byte position
967 TARGET_BYTE, else we don't have to do any adjustment. */
969 #define ADJUST_CHAR_POS(target, target_byte) \
971 if (target > pos + nbytes) \
973 else if (target >= pos) \
976 target_byte = pos_byte + nbytes; \
980 /* Combine NBYTES stray trailing-codes, which were formerly separate
981 characters, with the preceding character. These bytes
982 are located after position POS / POS_BYTE, and the preceding character
983 is located just before that position. */
986 combine_bytes (pos
, pos_byte
, nbytes
)
987 int pos
, pos_byte
, nbytes
;
989 /* Adjust all markers. */
990 adjust_markers_for_delete (pos
, pos_byte
, pos
+ nbytes
, pos_byte
);
992 adjust_overlays_for_delete (pos
, nbytes
);
994 ADJUST_CHAR_POS (BUF_PT (current_buffer
), BUF_PT_BYTE (current_buffer
));
995 ADJUST_CHAR_POS (GPT
, GPT_BYTE
);
996 ADJUST_CHAR_POS (Z
, Z_BYTE
);
997 ADJUST_CHAR_POS (ZV
, ZV_BYTE
);
999 if (BUF_INTERVALS (current_buffer
) != 0)
1000 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
1001 offset_intervals (current_buffer
, pos
, - nbytes
);
1006 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1007 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
1008 are the same as in insert_1. */
1011 insert_1_both (string
, nchars
, nbytes
, inherit
, prepare
, before_markers
)
1012 register unsigned char *string
;
1013 register int nchars
, nbytes
;
1014 int inherit
, prepare
, before_markers
;
1016 register Lisp_Object temp
, deletion
;
1017 int combined_before_bytes
, combined_after_bytes
;
1019 if (NILP (current_buffer
->enable_multibyte_characters
))
1023 move_gap_both (PT
, PT_BYTE
);
1024 if (GAP_SIZE
< nbytes
)
1025 make_gap (nbytes
- GAP_SIZE
);
1028 prepare_to_modify_buffer (PT
, PT
, NULL
);
1030 combined_before_bytes
1031 = count_combining_before (string
, nbytes
, PT
, PT_BYTE
);
1032 combined_after_bytes
1033 = count_combining_after (string
, nbytes
, PT
, PT_BYTE
);
1035 /* Record deletion of the surrounding text that combines with
1036 the insertion. This, together with recording the insertion,
1037 will add up to the right stuff in the undo list.
1039 But there is no need to actually delete the combining bytes
1040 from the buffer and reinsert them. */
1042 if (combined_after_bytes
)
1044 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1045 PT
+ combined_after_bytes
,
1046 PT_BYTE
+ combined_after_bytes
, 1);
1048 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1049 PT
+ combined_after_bytes
,
1050 PT_BYTE
+ combined_after_bytes
);
1051 record_delete (PT
, deletion
);
1054 if (combined_before_bytes
)
1056 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1058 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1060 record_delete (PT
- 1, deletion
);
1063 record_insert (PT
- !!combined_before_bytes
,
1064 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1067 bcopy (string
, GPT_ADDR
, nbytes
);
1070 /* When we have combining at the end of the insertion,
1071 this is the character position before the combined character. */
1078 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1080 if (combined_after_bytes
)
1081 move_gap_both (GPT
+ combined_after_bytes
,
1082 GPT_BYTE
+ combined_after_bytes
);
1087 adjust_overlays_for_insert (PT
, nchars
);
1088 adjust_markers_for_insert (PT
, PT_BYTE
,
1089 PT
+ nchars
, PT_BYTE
+ nbytes
,
1090 combined_before_bytes
, combined_after_bytes
,
1093 #ifdef USE_TEXT_PROPERTIES
1094 if (BUF_INTERVALS (current_buffer
) != 0)
1095 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
1096 offset_intervals (current_buffer
, PT
, nchars
);
1098 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
1099 Fset_text_properties (make_number (PT
), make_number (PT
+ nchars
),
1104 int pos
= PT
, pos_byte
= PT_BYTE
;
1106 adjust_point (nchars
+ combined_after_bytes
,
1107 nbytes
+ combined_after_bytes
);
1109 if (combined_after_bytes
)
1110 combine_bytes (pos
+ nchars
, pos_byte
+ nbytes
, combined_after_bytes
);
1112 if (combined_before_bytes
)
1113 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1117 /* Insert the part of the text of STRING, a Lisp object assumed to be
1118 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1119 starting at position POS / POS_BYTE. If the text of STRING has properties,
1120 copy them into the buffer.
1122 It does not work to use `insert' for this, because a GC could happen
1123 before we bcopy the stuff into the buffer, and relocate the string
1124 without insert noticing. */
1127 insert_from_string (string
, pos
, pos_byte
, length
, length_byte
, inherit
)
1129 register int pos
, pos_byte
, length
, length_byte
;
1135 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1137 signal_after_change (opoint
, 0, PT
- opoint
);
1141 /* Like `insert_from_string' except that all markers pointing
1142 at the place where the insertion happens are adjusted to point after it. */
1145 insert_from_string_before_markers (string
, pos
, pos_byte
,
1146 length
, length_byte
, inherit
)
1148 register int pos
, pos_byte
, length
, length_byte
;
1154 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1156 signal_after_change (opoint
, 0, PT
- opoint
);
1160 /* Subroutine of the insertion functions above. */
1163 insert_from_string_1 (string
, pos
, pos_byte
, nchars
, nbytes
,
1164 inherit
, before_markers
)
1166 register int pos
, pos_byte
, nchars
, nbytes
;
1167 int inherit
, before_markers
;
1169 register Lisp_Object temp
;
1170 struct gcpro gcpro1
;
1171 int outgoing_nbytes
= nbytes
;
1172 int combined_before_bytes
, combined_after_bytes
;
1173 int adjusted_nchars
;
1175 Lisp_Object deletion
;
1177 /* Make OUTGOING_NBYTES describe the text
1178 as it will be inserted in this buffer. */
1180 if (NILP (current_buffer
->enable_multibyte_characters
))
1181 outgoing_nbytes
= nchars
;
1182 else if (! STRING_MULTIBYTE (string
))
1184 = count_size_as_multibyte (&XSTRING (string
)->data
[pos_byte
],
1187 /* Make sure point-max won't overflow after this insertion. */
1188 XSETINT (temp
, outgoing_nbytes
+ Z
);
1189 if (outgoing_nbytes
+ Z
!= XINT (temp
))
1190 error ("Maximum buffer size exceeded");
1193 prepare_to_modify_buffer (PT
, PT
, NULL
);
1196 move_gap_both (PT
, PT_BYTE
);
1197 if (GAP_SIZE
< nbytes
)
1198 make_gap (outgoing_nbytes
- GAP_SIZE
);
1201 /* Copy the string text into the buffer, perhaps converting
1202 between single-byte and multibyte. */
1203 copy_text (XSTRING (string
)->data
+ pos_byte
, GPT_ADDR
, nbytes
,
1204 STRING_MULTIBYTE (string
),
1205 ! NILP (current_buffer
->enable_multibyte_characters
));
1207 /* We have copied text into the gap, but we have not altered
1208 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1209 to these functions and get the same results as we would
1210 have got earlier on. Meanwhile, PT_ADDR does point to
1211 the text that has been stored by copy_text. */
1213 combined_before_bytes
1214 = count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1215 combined_after_bytes
1216 = count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1218 /* Record deletion of the surrounding text that combines with
1219 the insertion. This, together with recording the insertion,
1220 will add up to the right stuff in the undo list.
1222 But there is no need to actually delete the combining bytes
1223 from the buffer and reinsert them. */
1225 if (combined_after_bytes
)
1227 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1228 PT
+ combined_after_bytes
,
1229 PT_BYTE
+ combined_after_bytes
, 1);
1231 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1232 PT
+ combined_after_bytes
,
1233 PT_BYTE
+ combined_after_bytes
);
1234 record_delete (PT
, deletion
);
1237 if (combined_before_bytes
)
1239 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1241 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1243 record_delete (PT
- 1, deletion
);
1246 record_insert (PT
- !!combined_before_bytes
,
1247 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1250 GAP_SIZE
-= outgoing_nbytes
;
1254 GPT_BYTE
+= outgoing_nbytes
;
1255 ZV_BYTE
+= outgoing_nbytes
;
1256 Z_BYTE
+= outgoing_nbytes
;
1257 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1259 if (combined_after_bytes
)
1260 move_gap_both (GPT
+ combined_after_bytes
,
1261 GPT_BYTE
+ combined_after_bytes
);
1266 adjust_overlays_for_insert (PT
, nchars
);
1267 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1268 PT_BYTE
+ outgoing_nbytes
,
1269 combined_before_bytes
, combined_after_bytes
,
1272 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1273 offset_intervals (current_buffer
, PT
, nchars
);
1275 intervals
= XSTRING (string
)->intervals
;
1276 /* Get the intervals for the part of the string we are inserting--
1277 not including the combined-before bytes. */
1278 if (nbytes
< STRING_BYTES (XSTRING (string
)))
1279 intervals
= copy_intervals (intervals
, pos
, nchars
);
1281 /* Insert those intervals. */
1282 graft_intervals_into_buffer (intervals
, PT
, nchars
,
1283 current_buffer
, inherit
);
1286 int pos
= PT
, pos_byte
= PT_BYTE
;
1288 adjust_point (nchars
+ combined_after_bytes
,
1289 outgoing_nbytes
+ combined_after_bytes
);
1291 if (combined_after_bytes
)
1292 combine_bytes (pos
+ nchars
, pos_byte
+ outgoing_nbytes
,
1293 combined_after_bytes
);
1295 if (combined_before_bytes
)
1296 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1300 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1301 current buffer. If the text in BUF has properties, they are absorbed
1302 into the current buffer.
1304 It does not work to use `insert' for this, because a malloc could happen
1305 and relocate BUF's text before the bcopy happens. */
1308 insert_from_buffer (buf
, charpos
, nchars
, inherit
)
1310 int charpos
, nchars
;
1317 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1318 signal_after_change (opoint
, 0, PT
- opoint
);
1323 insert_from_buffer_1 (buf
, from
, nchars
, inherit
)
1328 register Lisp_Object temp
, deletion
;
1330 int from_byte
= buf_charpos_to_bytepos (buf
, from
);
1331 int to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1332 int incoming_nbytes
= to_byte
- from_byte
;
1333 int outgoing_nbytes
= incoming_nbytes
;
1334 int combined_before_bytes
, combined_after_bytes
;
1335 int adjusted_nchars
;
1338 /* Make OUTGOING_NBYTES describe the text
1339 as it will be inserted in this buffer. */
1341 if (NILP (current_buffer
->enable_multibyte_characters
))
1342 outgoing_nbytes
= nchars
;
1343 else if (NILP (buf
->enable_multibyte_characters
))
1345 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1348 /* Make sure point-max won't overflow after this insertion. */
1349 XSETINT (temp
, outgoing_nbytes
+ Z
);
1350 if (outgoing_nbytes
+ Z
!= XINT (temp
))
1351 error ("Maximum buffer size exceeded");
1353 prepare_to_modify_buffer (PT
, PT
, NULL
);
1356 move_gap_both (PT
, PT_BYTE
);
1357 if (GAP_SIZE
< outgoing_nbytes
)
1358 make_gap (outgoing_nbytes
- GAP_SIZE
);
1360 if (from
< BUF_GPT (buf
))
1362 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1363 if (chunk
> incoming_nbytes
)
1364 chunk
= incoming_nbytes
;
1365 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1367 ! NILP (buf
->enable_multibyte_characters
),
1368 ! NILP (current_buffer
->enable_multibyte_characters
));
1372 if (chunk
< incoming_nbytes
)
1373 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1374 GPT_ADDR
+ chunk
, incoming_nbytes
- chunk
,
1375 ! NILP (buf
->enable_multibyte_characters
),
1376 ! NILP (current_buffer
->enable_multibyte_characters
));
1378 /* We have copied text into the gap, but we have not altered
1379 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1380 to these functions and get the same results as we would
1381 have got earlier on. Meanwhile, GPT_ADDR does point to
1382 the text that has been stored by copy_text. */
1383 combined_before_bytes
1384 = count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1385 combined_after_bytes
1386 = count_combining_after (GPT_ADDR
, outgoing_nbytes
,
1389 /* Record deletion of the surrounding text that combines with
1390 the insertion. This, together with recording the insertion,
1391 will add up to the right stuff in the undo list.
1393 But there is no need to actually delete the combining bytes
1394 from the buffer and reinsert them. */
1396 if (combined_after_bytes
)
1398 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1399 PT
+ combined_after_bytes
,
1400 PT_BYTE
+ combined_after_bytes
, 1);
1402 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1403 PT
+ combined_after_bytes
,
1404 PT_BYTE
+ combined_after_bytes
);
1405 record_delete (PT
, deletion
);
1408 if (combined_before_bytes
)
1410 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1412 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1414 record_delete (PT
- 1, deletion
);
1417 record_insert (PT
- !!combined_before_bytes
,
1418 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1421 GAP_SIZE
-= outgoing_nbytes
;
1425 GPT_BYTE
+= outgoing_nbytes
;
1426 ZV_BYTE
+= outgoing_nbytes
;
1427 Z_BYTE
+= outgoing_nbytes
;
1428 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1430 if (combined_after_bytes
)
1431 move_gap_both (GPT
+ combined_after_bytes
,
1432 GPT_BYTE
+ combined_after_bytes
);
1437 adjust_overlays_for_insert (PT
, nchars
);
1438 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1439 PT_BYTE
+ outgoing_nbytes
,
1440 combined_before_bytes
, combined_after_bytes
, 0);
1442 #ifdef USE_TEXT_PROPERTIES
1443 if (BUF_INTERVALS (current_buffer
) != 0)
1444 offset_intervals (current_buffer
, PT
, nchars
);
1447 /* Get the intervals for the part of the string we are inserting--
1448 not including the combined-before bytes. */
1449 intervals
= BUF_INTERVALS (buf
);
1450 if (outgoing_nbytes
< BUF_Z_BYTE (buf
) - BUF_BEG_BYTE (buf
))
1451 intervals
= copy_intervals (intervals
, from
, nchars
);
1453 /* Insert those intervals. */
1454 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1457 int pos
= PT
, pos_byte
= PT_BYTE
;
1459 adjust_point (nchars
+ combined_after_bytes
,
1460 outgoing_nbytes
+ combined_after_bytes
);
1462 if (combined_after_bytes
)
1463 combine_bytes (pos
+ nchars
, pos_byte
+ outgoing_nbytes
,
1464 combined_after_bytes
);
1466 if (combined_before_bytes
)
1467 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1471 /* This function should be called after moving gap to FROM and before
1472 altering text between FROM and TO. This adjusts various position
1473 keepers and markers as if the text is deleted. Don't forget to
1474 call adjust_after_replace after you actually alter the text. */
1477 adjust_before_replace (from
, from_byte
, to
, to_byte
)
1478 int from
, from_byte
, to
, to_byte
;
1480 Lisp_Object deletion
;
1481 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1485 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1486 record_delete (from
, deletion
);
1487 adjust_overlays_for_delete (from
, to
- from
);
1490 /* Record undo information and adjust markers and position keepers for
1491 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1492 chars (LEN_BYTE bytes) which resides in the gap just after
1495 PREV_TEXT nil means the new text was just inserted. */
1498 adjust_after_replace (from
, from_byte
, prev_text
, len
, len_byte
)
1499 int from
, from_byte
, len
, len_byte
;
1500 Lisp_Object prev_text
;
1502 int combined_before_bytes
1503 = count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
);
1504 int combined_after_bytes
1505 = count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
);
1506 Lisp_Object deletion
;
1507 int nchars_del
= 0, nbytes_del
= 0;
1509 if (combined_after_bytes
)
1511 deletion
= make_buffer_string_both (from
, from_byte
,
1512 from
+ combined_after_bytes
,
1513 from_byte
+ combined_after_bytes
, 1);
1515 adjust_markers_for_record_delete (from
, from_byte
,
1516 from
+ combined_after_bytes
,
1517 from_byte
+ combined_after_bytes
);
1518 record_delete (from
, deletion
);
1521 if (combined_before_bytes
)
1523 deletion
= make_buffer_string_both (from
- 1, CHAR_TO_BYTE (from
- 1),
1524 from
, from_byte
, 1);
1525 adjust_markers_for_record_delete (from
- 1, CHAR_TO_BYTE (from
- 1),
1527 record_delete (from
- 1, deletion
);
1530 /* Update various buffer positions for the new text. */
1531 GAP_SIZE
-= len_byte
;
1533 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1534 GPT
+= len
; GPT_BYTE
+= len_byte
;
1535 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1537 if (combined_after_bytes
)
1538 move_gap_both (GPT
+ combined_after_bytes
,
1539 GPT_BYTE
+ combined_after_bytes
);
1541 if (STRINGP (prev_text
))
1543 nchars_del
= XSTRING (prev_text
)->size
;
1544 nbytes_del
= STRING_BYTES (XSTRING (prev_text
));
1546 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1548 combined_before_bytes
, combined_after_bytes
);
1549 if (STRINGP (prev_text
))
1550 record_delete (from
, prev_text
);
1551 record_insert (from
- !!combined_before_bytes
,
1552 len
- combined_before_bytes
+ !!combined_before_bytes
);
1554 if (len
> nchars_del
)
1555 adjust_overlays_for_insert (from
, len
- nchars_del
);
1556 else if (len
< nchars_del
)
1557 adjust_overlays_for_delete (from
, nchars_del
- len
);
1558 #ifdef USE_TEXT_PROPERTIES
1559 if (BUF_INTERVALS (current_buffer
) != 0)
1560 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1564 int pos
= PT
, pos_byte
= PT_BYTE
;
1567 adjust_point (len
- nchars_del
+ combined_after_bytes
,
1568 len_byte
- nbytes_del
+ combined_after_bytes
);
1569 else if (from
== PT
&& combined_before_bytes
)
1570 adjust_point (0, combined_before_bytes
);
1572 if (combined_after_bytes
)
1573 combine_bytes (from
+ len
, from_byte
+ len_byte
, combined_after_bytes
);
1575 if (combined_before_bytes
)
1576 combine_bytes (from
, from_byte
, combined_before_bytes
);
1582 evaporate_overlays (from
);
1586 /* Record undo information, adjust markers and position keepers for an
1587 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1588 text already exists in the current buffer but character length (TO
1589 - FROM) may be incorrect, the correct length is NEWLEN. */
1592 adjust_after_insert (from
, from_byte
, to
, to_byte
, newlen
)
1593 int from
, from_byte
, to
, to_byte
, newlen
;
1595 int len
= to
- from
, len_byte
= to_byte
- from_byte
;
1598 move_gap_both (to
, to_byte
);
1599 GAP_SIZE
+= len_byte
;
1600 GPT
-= len
; GPT_BYTE
-= len_byte
;
1601 ZV
-= len
; ZV_BYTE
-= len_byte
;
1602 Z
-= len
; Z_BYTE
-= len_byte
;
1603 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1606 /* Replace the text from character positions FROM to TO with NEW,
1607 If PREPARE is nonzero, call prepare_to_modify_buffer.
1608 If INHERIT, the newly inserted text should inherit text properties
1609 from the surrounding non-deleted text. */
1611 /* Note that this does not yet handle markers quite right.
1612 Also it needs to record a single undo-entry that does a replacement
1613 rather than a separate delete and insert.
1614 That way, undo will also handle markers properly. */
1617 replace_range (from
, to
, new, prepare
, inherit
, nomarkers
)
1619 int from
, to
, prepare
, inherit
, nomarkers
;
1621 int inschars
= XSTRING (new)->size
;
1622 int insbytes
= STRING_BYTES (XSTRING (new));
1623 int from_byte
, to_byte
;
1624 int nbytes_del
, nchars_del
;
1625 register Lisp_Object temp
;
1626 struct gcpro gcpro1
;
1627 int combined_before_bytes
, combined_after_bytes
;
1628 int adjusted_inschars
;
1630 int outgoing_insbytes
= insbytes
;
1631 Lisp_Object deletion
;
1639 int range_length
= to
- from
;
1640 prepare_to_modify_buffer (from
, to
, &from
);
1641 to
= from
+ range_length
;
1646 /* Make args be valid */
1652 from_byte
= CHAR_TO_BYTE (from
);
1653 to_byte
= CHAR_TO_BYTE (to
);
1655 nchars_del
= to
- from
;
1656 nbytes_del
= to_byte
- from_byte
;
1658 if (nbytes_del
<= 0 && insbytes
== 0)
1661 /* Make OUTGOING_INSBYTES describe the text
1662 as it will be inserted in this buffer. */
1664 if (NILP (current_buffer
->enable_multibyte_characters
))
1665 outgoing_insbytes
= inschars
;
1666 else if (! STRING_MULTIBYTE (new))
1668 = count_size_as_multibyte (XSTRING (new)->data
, insbytes
);
1670 /* Make sure point-max won't overflow after this insertion. */
1671 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1672 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1673 error ("Maximum buffer size exceeded");
1677 /* Make sure the gap is somewhere in or next to what we are deleting. */
1679 gap_right (from
, from_byte
);
1681 gap_left (to
, to_byte
, 0);
1683 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1686 /* Relocate all markers pointing into the new, larger gap
1687 to point at the end of the text before the gap.
1688 Do this before recording the deletion,
1689 so that undo handles this after reinserting the text. */
1690 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1692 record_delete (from
, deletion
);
1694 GAP_SIZE
+= nbytes_del
;
1697 ZV_BYTE
-= nbytes_del
;
1698 Z_BYTE
-= nbytes_del
;
1700 GPT_BYTE
= from_byte
;
1701 *(GPT_ADDR
) = 0; /* Put an anchor. */
1706 if (GPT
- BEG
< beg_unchanged
)
1707 beg_unchanged
= GPT
- BEG
;
1708 if (Z
- GPT
< end_unchanged
)
1709 end_unchanged
= Z
- GPT
;
1711 if (GAP_SIZE
< insbytes
)
1712 make_gap (insbytes
- GAP_SIZE
);
1714 /* Copy the string text into the buffer, perhaps converting
1715 between single-byte and multibyte. */
1716 copy_text (XSTRING (new)->data
, GPT_ADDR
, insbytes
,
1717 STRING_MULTIBYTE (new),
1718 ! NILP (current_buffer
->enable_multibyte_characters
));
1720 /* We have copied text into the gap, but we have not altered
1721 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1722 to these functions and get the same results as we would
1723 have got earlier on. Meanwhile, GPT_ADDR does point to
1724 the text that has been stored by copy_text. */
1726 combined_before_bytes
1727 = count_combining_before (GPT_ADDR
, outgoing_insbytes
, PT
, PT_BYTE
);
1728 combined_after_bytes
1729 = count_combining_after (GPT_ADDR
, outgoing_insbytes
, PT
, PT_BYTE
);
1731 /* Record deletion of the surrounding text that combines with
1732 the insertion. This, together with recording the insertion,
1733 will add up to the right stuff in the undo list.
1735 But there is no need to actually delete the combining bytes
1736 from the buffer and reinsert them. */
1738 if (combined_after_bytes
)
1740 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1741 PT
+ combined_after_bytes
,
1742 PT_BYTE
+ combined_after_bytes
, 1);
1744 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1745 PT
+ combined_after_bytes
,
1746 PT_BYTE
+ combined_after_bytes
);
1747 record_delete (PT
, deletion
);
1750 if (combined_before_bytes
)
1752 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1754 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1756 record_delete (PT
- 1, deletion
);
1759 record_insert (PT
- !!combined_before_bytes
,
1760 inschars
- combined_before_bytes
+ !!combined_before_bytes
);
1762 GAP_SIZE
-= outgoing_insbytes
;
1766 GPT_BYTE
+= outgoing_insbytes
;
1767 ZV_BYTE
+= outgoing_insbytes
;
1768 Z_BYTE
+= outgoing_insbytes
;
1769 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1771 if (combined_after_bytes
)
1772 move_gap_both (GPT
+ combined_after_bytes
,
1773 GPT_BYTE
+ combined_after_bytes
);
1778 /* Adjust the overlay center as needed. This must be done after
1779 adjusting the markers that bound the overlays. */
1780 adjust_overlays_for_delete (from
, nchars_del
);
1781 adjust_overlays_for_insert (from
, inschars
);
1783 adjust_markers_for_insert (from
, from_byte
,
1784 from
+ inschars
, from_byte
+ outgoing_insbytes
,
1785 combined_before_bytes
, combined_after_bytes
, 0);
1787 #ifdef USE_TEXT_PROPERTIES
1788 offset_intervals (current_buffer
, PT
, inschars
- nchars_del
);
1790 /* Get the intervals for the part of the string we are inserting--
1791 not including the combined-before bytes. */
1792 intervals
= XSTRING (new)->intervals
;
1793 /* Insert those intervals. */
1794 graft_intervals_into_buffer (intervals
, from
, inschars
,
1795 current_buffer
, inherit
);
1798 /* Relocate point as if it were a marker. */
1800 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)
1801 + combined_after_bytes
),
1802 (from_byte
+ outgoing_insbytes
1803 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)
1804 + combined_after_bytes
));
1806 if (combined_after_bytes
)
1807 combine_bytes (from
+ inschars
, from_byte
+ outgoing_insbytes
,
1808 combined_after_bytes
);
1810 if (combined_before_bytes
)
1811 combine_bytes (from
, from_byte
, combined_before_bytes
);
1813 if (outgoing_insbytes
== 0)
1814 evaporate_overlays (from
);
1821 signal_after_change (from
, nchars_del
, PT
- from
);
1824 /* Delete characters in current buffer
1825 from FROM up to (but not including) TO.
1826 If TO comes before FROM, we delete nothing. */
1829 del_range (from
, to
)
1830 register int from
, to
;
1832 del_range_1 (from
, to
, 1);
1835 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
1838 del_range_1 (from
, to
, prepare
)
1839 int from
, to
, prepare
;
1841 int from_byte
, to_byte
;
1843 /* Make args be valid */
1854 int range_length
= to
- from
;
1855 prepare_to_modify_buffer (from
, to
, &from
);
1856 to
= from
+ range_length
;
1859 from_byte
= CHAR_TO_BYTE (from
);
1860 to_byte
= CHAR_TO_BYTE (to
);
1862 del_range_2 (from
, from_byte
, to
, to_byte
);
1865 /* Like del_range_1 but args are byte positions, not char positions. */
1868 del_range_byte (from_byte
, to_byte
, prepare
)
1869 int from_byte
, to_byte
, prepare
;
1873 /* Make args be valid */
1874 if (from_byte
< BEGV_BYTE
)
1875 from_byte
= BEGV_BYTE
;
1876 if (to_byte
> ZV_BYTE
)
1879 if (to_byte
<= from_byte
)
1882 from
= BYTE_TO_CHAR (from_byte
);
1883 to
= BYTE_TO_CHAR (to_byte
);
1887 int old_from
= from
, old_to
= Z
- to
;
1888 int range_length
= to
- from
;
1889 prepare_to_modify_buffer (from
, to
, &from
);
1890 to
= from
+ range_length
;
1892 if (old_from
!= from
)
1893 from_byte
= CHAR_TO_BYTE (from
);
1894 if (old_to
== Z
- to
)
1895 to_byte
= CHAR_TO_BYTE (to
);
1898 del_range_2 (from
, from_byte
, to
, to_byte
);
1901 /* Like del_range_1, but positions are specified both as charpos
1905 del_range_both (from
, from_byte
, to
, to_byte
, prepare
)
1906 int from
, from_byte
, to
, to_byte
, prepare
;
1908 /* Make args be valid */
1909 if (from_byte
< BEGV_BYTE
)
1910 from_byte
= BEGV_BYTE
;
1911 if (to_byte
> ZV_BYTE
)
1914 if (to_byte
<= from_byte
)
1924 int old_from
= from
, old_to
= Z
- to
;
1925 int range_length
= to
- from
;
1926 prepare_to_modify_buffer (from
, to
, &from
);
1927 to
= from
+ range_length
;
1929 if (old_from
!= from
)
1930 from_byte
= CHAR_TO_BYTE (from
);
1931 if (old_to
== Z
- to
)
1932 to_byte
= CHAR_TO_BYTE (to
);
1935 del_range_2 (from
, from_byte
, to
, to_byte
);
1938 /* Delete a range of text, specified both as character positions
1939 and byte positions. FROM and TO are character positions,
1940 while FROM_BYTE and TO_BYTE are byte positions. */
1943 del_range_2 (from
, from_byte
, to
, to_byte
)
1944 int from
, from_byte
, to
, to_byte
;
1946 register int nbytes_del
, nchars_del
;
1947 int combined_after_bytes
;
1948 Lisp_Object deletion
;
1953 nchars_del
= to
- from
;
1954 nbytes_del
= to_byte
- from_byte
;
1956 /* Make sure the gap is somewhere in or next to what we are deleting. */
1958 gap_right (from
, from_byte
);
1960 gap_left (to
, to_byte
, 0);
1962 combined_after_bytes
1963 = count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
1964 ZV_BYTE
- to_byte
, from
, from_byte
);
1965 if (combined_after_bytes
)
1967 from_byte_1
= from_byte
;
1968 DEC_POS (from_byte_1
);
1971 from_byte_1
= from_byte
;
1974 = make_buffer_string_both (from
- !!combined_after_bytes
,
1976 to
+ combined_after_bytes
,
1977 to_byte
+ combined_after_bytes
, 1);
1978 if (combined_after_bytes
)
1979 /* COMBINED_AFTER_BYTES nonzero means that the above code moved
1980 the gap. We must move the gap again to a proper place. */
1981 move_gap_both (from
, from_byte
);
1983 /* Relocate all markers pointing into the new, larger gap
1984 to point at the end of the text before the gap.
1985 Do this before recording the deletion,
1986 so that undo handles this after reinserting the text. */
1987 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1988 if (combined_after_bytes
)
1990 /* Adjust markers for the phony deletion
1991 that we are about to call record_undo for. */
1993 /* Here we delete the markers that formerly
1994 pointed at TO ... TO + COMBINED_AFTER_BYTES.
1995 But because of the call to adjust_markers_for_delete, above,
1996 they now point at FROM ... FROM + COMBINED_AFTER_BYTES. */
1997 adjust_markers_for_record_delete (from
, from_byte
,
1998 from
+ combined_after_bytes
,
1999 from_byte
+ combined_after_bytes
);
2001 adjust_markers_for_record_delete (from
- 1, from_byte_1
,
2004 record_delete (from
- !!combined_after_bytes
, deletion
);
2007 /* Relocate point as if it were a marker. */
2009 adjust_point (from
- (PT
< to
? PT
: to
),
2010 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
2012 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
2013 offset_intervals (current_buffer
, from
, - nchars_del
);
2015 /* Adjust the overlay center as needed. This must be done after
2016 adjusting the markers that bound the overlays. */
2017 adjust_overlays_for_delete (from
, nchars_del
);
2019 GAP_SIZE
+= nbytes_del
;
2020 ZV_BYTE
-= nbytes_del
;
2021 Z_BYTE
-= nbytes_del
;
2025 GPT_BYTE
= from_byte
;
2027 if (combined_after_bytes
)
2028 move_gap_both (GPT
+ combined_after_bytes
,
2029 GPT_BYTE
+ combined_after_bytes
);
2031 *(GPT_ADDR
) = 0; /* Put an anchor. */
2036 if (GPT
- BEG
< beg_unchanged
)
2037 beg_unchanged
= GPT
- BEG
;
2038 if (Z
- GPT
< end_unchanged
)
2039 end_unchanged
= Z
- GPT
;
2041 if (combined_after_bytes
)
2043 combine_bytes (from
, from_byte
, combined_after_bytes
);
2045 record_insert (GPT
- 1, 1);
2050 evaporate_overlays (from
);
2051 signal_after_change (from
, nchars_del
, 0);
2054 /* Call this if you're about to change the region of BUFFER from
2055 character positions START to END. This checks the read-only
2056 properties of the region, calls the necessary modification hooks,
2057 and warns the next redisplay that it should pay attention to that
2061 modify_region (buffer
, start
, end
)
2062 struct buffer
*buffer
;
2065 struct buffer
*old_buffer
= current_buffer
;
2067 if (buffer
!= old_buffer
)
2068 set_buffer_internal (buffer
);
2070 prepare_to_modify_buffer (start
, end
, NULL
);
2072 if (start
- 1 < beg_unchanged
2073 || (unchanged_modified
== MODIFF
2074 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
2075 beg_unchanged
= start
- 1;
2076 if (Z
- end
< end_unchanged
2077 || (unchanged_modified
== MODIFF
2078 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
2079 end_unchanged
= Z
- end
;
2081 if (MODIFF
<= SAVE_MODIFF
)
2082 record_first_change ();
2085 buffer
->point_before_scroll
= Qnil
;
2087 if (buffer
!= old_buffer
)
2088 set_buffer_internal (old_buffer
);
2091 /* Check that it is okay to modify the buffer between START and END,
2092 which are char positions.
2094 Run the before-change-function, if any. If intervals are in use,
2095 verify that the text to be modified is not read-only, and call
2096 any modification properties the text may have.
2098 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2099 by holding its value temporarily in a marker. */
2102 prepare_to_modify_buffer (start
, end
, preserve_ptr
)
2106 if (!NILP (current_buffer
->read_only
))
2107 Fbarf_if_buffer_read_only ();
2109 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
2110 if (BUF_INTERVALS (current_buffer
) != 0)
2114 Lisp_Object preserve_marker
;
2115 struct gcpro gcpro1
;
2116 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
2117 GCPRO1 (preserve_marker
);
2118 verify_interval_modification (current_buffer
, start
, end
);
2119 *preserve_ptr
= marker_position (preserve_marker
);
2120 unchain_marker (preserve_marker
);
2124 verify_interval_modification (current_buffer
, start
, end
);
2127 #ifdef CLASH_DETECTION
2128 if (!NILP (current_buffer
->file_truename
)
2129 /* Make binding buffer-file-name to nil effective. */
2130 && !NILP (current_buffer
->filename
)
2131 && SAVE_MODIFF
>= MODIFF
)
2132 lock_file (current_buffer
->file_truename
);
2134 /* At least warn if this file has changed on disk since it was visited. */
2135 if (!NILP (current_buffer
->filename
)
2136 && SAVE_MODIFF
>= MODIFF
2137 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2138 && !NILP (Ffile_exists_p (current_buffer
->filename
)))
2139 call1 (intern ("ask-user-about-supersession-threat"),
2140 current_buffer
->filename
);
2141 #endif /* not CLASH_DETECTION */
2143 signal_before_change (start
, end
, preserve_ptr
);
2145 if (current_buffer
->newline_cache
)
2146 invalidate_region_cache (current_buffer
,
2147 current_buffer
->newline_cache
,
2148 start
- BEG
, Z
- end
);
2149 if (current_buffer
->width_run_cache
)
2150 invalidate_region_cache (current_buffer
,
2151 current_buffer
->width_run_cache
,
2152 start
- BEG
, Z
- end
);
2154 Vdeactivate_mark
= Qt
;
2157 /* These macros work with an argument named `preserve_ptr'
2158 and a local variable named `preserve_marker'. */
2160 #define PRESERVE_VALUE \
2161 if (preserve_ptr && NILP (preserve_marker)) \
2162 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2164 #define RESTORE_VALUE \
2165 if (! NILP (preserve_marker)) \
2167 *preserve_ptr = marker_position (preserve_marker); \
2168 unchain_marker (preserve_marker); \
2171 #define PRESERVE_START_END \
2172 if (NILP (start_marker)) \
2173 start_marker = Fcopy_marker (start, Qnil); \
2174 if (NILP (end_marker)) \
2175 end_marker = Fcopy_marker (end, Qnil);
2177 #define FETCH_START \
2178 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2181 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2183 /* Signal a change to the buffer immediately before it happens.
2184 START_INT and END_INT are the bounds of the text to be changed.
2186 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2187 by holding its value temporarily in a marker. */
2190 signal_before_change (start_int
, end_int
, preserve_ptr
)
2191 int start_int
, end_int
;
2194 Lisp_Object start
, end
;
2195 Lisp_Object start_marker
, end_marker
;
2196 Lisp_Object preserve_marker
;
2197 struct gcpro gcpro1
, gcpro2
, gcpro3
;
2199 start
= make_number (start_int
);
2200 end
= make_number (end_int
);
2201 preserve_marker
= Qnil
;
2202 start_marker
= Qnil
;
2204 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
2206 /* If buffer is unmodified, run a special hook for that case. */
2207 if (SAVE_MODIFF
>= MODIFF
2208 && !NILP (Vfirst_change_hook
)
2209 && !NILP (Vrun_hooks
))
2213 call1 (Vrun_hooks
, Qfirst_change_hook
);
2216 /* Run the before-change-function if any.
2217 We don't bother "binding" this variable to nil
2218 because it is obsolete anyway and new code should not use it. */
2219 if (!NILP (Vbefore_change_function
))
2223 call2 (Vbefore_change_function
, FETCH_START
, FETCH_END
);
2226 /* Now run the before-change-functions if any. */
2227 if (!NILP (Vbefore_change_functions
))
2229 Lisp_Object args
[3];
2230 Lisp_Object before_change_functions
;
2231 Lisp_Object after_change_functions
;
2232 struct gcpro gcpro1
, gcpro2
;
2237 /* "Bind" before-change-functions and after-change-functions
2238 to nil--but in a way that errors don't know about.
2239 That way, if there's an error in them, they will stay nil. */
2240 before_change_functions
= Vbefore_change_functions
;
2241 after_change_functions
= Vafter_change_functions
;
2242 Vbefore_change_functions
= Qnil
;
2243 Vafter_change_functions
= Qnil
;
2244 GCPRO2 (before_change_functions
, after_change_functions
);
2246 /* Actually run the hook functions. */
2247 args
[0] = Qbefore_change_functions
;
2248 args
[1] = FETCH_START
;
2249 args
[2] = FETCH_END
;
2250 run_hook_list_with_args (before_change_functions
, 3, args
);
2252 /* "Unbind" the variables we "bound" to nil. */
2253 Vbefore_change_functions
= before_change_functions
;
2254 Vafter_change_functions
= after_change_functions
;
2258 if (!NILP (current_buffer
->overlays_before
)
2259 || !NILP (current_buffer
->overlays_after
))
2262 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
2263 FETCH_START
, FETCH_END
, Qnil
);
2266 if (! NILP (start_marker
))
2267 free_marker (start_marker
);
2268 if (! NILP (end_marker
))
2269 free_marker (end_marker
);
2274 /* Signal a change immediately after it happens.
2275 CHARPOS is the character position of the start of the changed text.
2276 LENDEL is the number of characters of the text before the change.
2277 (Not the whole buffer; just the part that was changed.)
2278 LENINS is the number of characters in that part of the text
2279 after the change. */
2282 signal_after_change (charpos
, lendel
, lenins
)
2283 int charpos
, lendel
, lenins
;
2285 /* If we are deferring calls to the after-change functions
2286 and there are no before-change functions,
2287 just record the args that we were going to use. */
2288 if (! NILP (Vcombine_after_change_calls
)
2289 && NILP (Vbefore_change_function
) && NILP (Vbefore_change_functions
)
2290 && NILP (current_buffer
->overlays_before
)
2291 && NILP (current_buffer
->overlays_after
))
2295 if (!NILP (combine_after_change_list
)
2296 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2297 Fcombine_after_change_execute ();
2299 elt
= Fcons (make_number (charpos
- BEG
),
2300 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2301 Fcons (make_number (lenins
- lendel
), Qnil
)));
2302 combine_after_change_list
2303 = Fcons (elt
, combine_after_change_list
);
2304 combine_after_change_buffer
= Fcurrent_buffer ();
2309 if (!NILP (combine_after_change_list
))
2310 Fcombine_after_change_execute ();
2312 /* Run the after-change-function if any.
2313 We don't bother "binding" this variable to nil
2314 because it is obsolete anyway and new code should not use it. */
2315 if (!NILP (Vafter_change_function
))
2316 call3 (Vafter_change_function
,
2317 make_number (charpos
), make_number (charpos
+ lenins
),
2318 make_number (lendel
));
2320 if (!NILP (Vafter_change_functions
))
2322 Lisp_Object args
[4];
2323 Lisp_Object before_change_functions
;
2324 Lisp_Object after_change_functions
;
2325 struct gcpro gcpro1
, gcpro2
;
2327 /* "Bind" before-change-functions and after-change-functions
2328 to nil--but in a way that errors don't know about.
2329 That way, if there's an error in them, they will stay nil. */
2330 before_change_functions
= Vbefore_change_functions
;
2331 after_change_functions
= Vafter_change_functions
;
2332 Vbefore_change_functions
= Qnil
;
2333 Vafter_change_functions
= Qnil
;
2334 GCPRO2 (before_change_functions
, after_change_functions
);
2336 /* Actually run the hook functions. */
2337 args
[0] = Qafter_change_functions
;
2338 XSETFASTINT (args
[1], charpos
);
2339 XSETFASTINT (args
[2], charpos
+ lenins
);
2340 XSETFASTINT (args
[3], lendel
);
2341 run_hook_list_with_args (after_change_functions
,
2344 /* "Unbind" the variables we "bound" to nil. */
2345 Vbefore_change_functions
= before_change_functions
;
2346 Vafter_change_functions
= after_change_functions
;
2350 if (!NILP (current_buffer
->overlays_before
)
2351 || !NILP (current_buffer
->overlays_after
))
2352 report_overlay_modification (make_number (charpos
),
2353 make_number (charpos
+ lenins
),
2355 make_number (charpos
),
2356 make_number (charpos
+ lenins
),
2357 make_number (lendel
));
2359 /* After an insertion, call the text properties
2360 insert-behind-hooks or insert-in-front-hooks. */
2362 report_interval_modification (charpos
, charpos
+ lenins
);
2366 Fcombine_after_change_execute_1 (val
)
2369 Vcombine_after_change_calls
= val
;
2373 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2374 Scombine_after_change_execute
, 0, 0, 0,
2375 "This function is for use internally in `combine-after-change-calls'.")
2378 register Lisp_Object val
;
2379 int count
= specpdl_ptr
- specpdl
;
2380 int beg
, end
, change
;
2384 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2386 Fset_buffer (combine_after_change_buffer
);
2388 /* # chars unchanged at beginning of buffer. */
2390 /* # chars unchanged at end of buffer. */
2392 /* Total amount of insertion (negative for deletion). */
2395 /* Scan the various individual changes,
2396 accumulating the range info in BEG, END and CHANGE. */
2397 for (tail
= combine_after_change_list
; CONSP (tail
);
2398 tail
= XCONS (tail
)->cdr
)
2401 int thisbeg
, thisend
, thischange
;
2403 /* Extract the info from the next element. */
2404 elt
= XCONS (tail
)->car
;
2407 thisbeg
= XINT (XCONS (elt
)->car
);
2409 elt
= XCONS (elt
)->cdr
;
2412 thisend
= XINT (XCONS (elt
)->car
);
2414 elt
= XCONS (elt
)->cdr
;
2417 thischange
= XINT (XCONS (elt
)->car
);
2419 /* Merge this range into the accumulated range. */
2420 change
+= thischange
;
2427 /* Get the current start and end positions of the range
2428 that was changed. */
2432 /* We are about to handle these, so discard them. */
2433 combine_after_change_list
= Qnil
;
2435 /* Now run the after-change functions for real.
2436 Turn off the flag that defers them. */
2437 record_unwind_protect (Fcombine_after_change_execute_1
,
2438 Vcombine_after_change_calls
);
2439 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2441 return unbind_to (count
, val
);
2446 staticpro (&combine_after_change_list
);
2447 combine_after_change_list
= Qnil
;
2449 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag
,
2450 "Non-nil means enable debugging checks for invalid marker positions.");
2451 check_markers_debug_flag
= 0;
2452 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls
,
2453 "Used internally by the `combine-after-change-calls' macro.");
2454 Vcombine_after_change_calls
= Qnil
;
2456 defsubr (&Scombine_after_change_execute
);